ar5416_hw.c: remove ar5416GetCapability
[open-ath9k-htc-firmware.git] / target_firmware / wlan / ar5416_hw.c
1 /*
2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted (subject to the limitations in the
7  * disclaimer below) provided that the following conditions are met:
8  *
9  *  * Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  *  * Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the
15  *    distribution.
16  *
17  *  * Neither the name of Qualcomm Atheros nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
22  * GRANTED BY THIS LICENSE.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
23  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 #include "ah.h"
37 #include "ah_internal.h"
38 #include "ar5416.h"
39 #include "ar5416reg.h"
40 #include "ar5416desc.h"
41
42 #define N(a) (sizeof(a)/sizeof(a[0]))
43 #define AR_INTR_SPURIOUS 0xffffffff
44 #define ar5416_desc ar5416_desc_20
45 #define AR5416_ABORT_LOOPS 1000
46 #define AR5416_ABORT_WAIT  5
47 #define AR5416DESC         AR5416DESC_20
48 #define AR5416DESC_CONST   AR5416DESC_CONST_20
49
50 /*****************/
51 /* Attach/Detach */
52 /*****************/
53
54 static const struct ath_hal_private ar5416hal_10 = {{
55                 .ah_getRateTable        = ar5416GetRateTable,
56                 .ah_detach              = ar5416Detach,
57
58                 /* Transmit functions */
59                 .ah_updateTxTrigLevel   = ar5416UpdateTxTrigLevel,
60                 .ah_getTxDP             = ar5416GetTxDP,
61                 .ah_setTxDP             = ar5416SetTxDP,
62                 .ah_numTxPending        = ar5416NumTxPending,    
63                 .ah_startTxDma          = ar5416StartTxDma,
64                 .ah_stopTxDma           = ar5416StopTxDma,
65         
66                 .ah_getTxIntrQueue      = ar5416GetTxIntrQueue,
67                 .ah_abortTxDma          = ar5416AbortTxDma,
68
69                 /* Misc Functions */
70                 .ah_getTsf32            = ar5416GetTsf32,
71                 .ah_getTsf64            = ar5416GetTsf64,
72                 .ah_resetTsf            = ar5416ResetTsf,
73                 .ah_setRxFilter         = ar5416SetRxFilter,
74
75                 /* RX Functions */
76                 .ah_getRxDP             = ar5416GetRxDP,
77                 .ah_setRxDP             = ar5416SetRxDP,
78                 .ah_stopDmaReceive      = ar5416StopDmaReceive,
79                 .ah_enableReceive       = ar5416EnableReceive,
80                 .ah_startPcuReceive     = ar5416StartPcuReceive,
81                 .ah_stopPcuReceive      = ar5416StopPcuReceive,
82
83                 /* Interrupt Functions */
84                 .ah_isInterruptPending   = ar5416IsInterruptPending,
85                 .ah_getPendingInterrupts = ar5416GetPendingInterrupts,
86                 .ah_getInterrupts        = ar5416GetInterrupts,
87                 .ah_setInterrupts        = ar5416SetInterrupts,
88         },
89 };
90
91 void ar5416Detach(struct ath_hal *ah)
92 {
93         HALASSERT(ah != AH_NULL);
94         ath_hal_free(ah);
95 }
96
97 struct ath_hal *
98 ar5416Attach(a_uint32_t devid,HAL_SOFTC sc, adf_os_device_t dev,
99              a_uint32_t flags, HAL_STATUS *status)
100 {
101         struct ath_hal_5416 *ahp;
102         struct ath_hal *ah;
103
104         ahp = ath_hal_malloc(sizeof (struct ath_hal_5416));
105         if (ahp == AH_NULL) {
106                 *status = HAL_ENOMEM;
107                 return AH_NULL;
108         }
109         ah = &ahp->ah_priv.h;
110
111         OS_MEMCPY(&ahp->ah_priv, &ar5416hal_10, sizeof(struct ath_hal_private));
112
113         ah->ah_dev = dev;
114         ah->ah_sc = sc;
115         
116         /* If its a Owl 2.0 chip then change the hal structure to
117            point to the Owl 2.0 ar5416_hal_20 structure */
118         if(1) {
119                 ah->ah_set11nTxDesc        = ar5416Set11nTxDesc_20;
120                 ah->ah_set11nRateScenario  = ar5416Set11nRateScenario_20;
121                 ah->ah_set11nAggrFirst     = ar5416Set11nAggrFirst_20;
122                 ah->ah_set11nAggrMiddle    = ar5416Set11nAggrMiddle_20;
123                 ah->ah_set11nAggrLast      = ar5416Set11nAggrLast_20;
124                 ah->ah_clr11nAggr          = ar5416Clr11nAggr_20;
125                 ah->ah_set11nBurstDuration = ar5416Set11nBurstDuration_20;
126                 ah->ah_setupRxDesc         = ar5416SetupRxDesc_20;
127                 ah->ah_procRxDescFast      = ar5416ProcRxDescFast_20;
128                 ah->ah_updateCTSForBursting = NULL;
129                 ah->ah_setupTxDesc         = ar5416SetupTxDesc_20;
130                 ah->ah_reqTxIntrDesc       = ar5416IntrReqTxDesc_20;
131                 ah->ah_fillTxDesc          = ar5416FillTxDesc_20;
132                 ah->ah_fillKeyTxDesc       = ar5416FillKeyTxDesc_20;
133                 ah->ah_procTxDesc          = ar5416ProcTxDesc_20;
134                 ah->ah_set11nVirtualMoreFrag = ar5416Set11nVirtualMoreFrag_20;
135         }
136
137         return ah;
138 }
139
140 /**********************/
141 /* Interrupt Handling */
142 /**********************/
143
144 HAL_BOOL ar5416IsInterruptPending(struct ath_hal *ah)
145 {
146         a_uint32_t host_isr = OS_REG_READ(ah, AR_INTR_ASYNC_CAUSE);
147         /*
148          * Some platforms trigger our ISR before applying power to
149          * the card, so make sure.
150          */
151         return ((host_isr != AR_INTR_SPURIOUS) && (host_isr & AR_INTR_MAC_IRQ));
152 }
153
154 HAL_BOOL ar5416GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked)
155 {
156         a_uint32_t isr;
157 #ifndef AR9100
158         HAL_BOOL fatal_int = AH_FALSE;
159         a_uint32_t sync_cause;
160
161         if (OS_REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
162                 if ((OS_REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) != AR_RTC_STATUS_ON) {
163                         *masked = 0;
164                         return AH_FALSE;
165                 }
166         } else {
167                 *masked = 0;
168                 return AH_FALSE;
169         }
170 #endif
171         isr = OS_REG_READ(ah, AR_ISR_RAC);
172         if (isr == 0xffffffff) {
173                 *masked = 0;
174                 return AH_FALSE;
175         }
176
177         *masked = isr & HAL_INT_COMMON;
178
179 #ifdef AR5416_INT_MITIGATION
180         if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) {
181                 *masked |= HAL_INT_RX;
182         }
183         if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM)) {
184                 *masked |= HAL_INT_TX;
185         }
186 #endif
187
188         if (isr & AR_ISR_BCNMISC) {
189                 a_uint32_t s2_s;
190
191                 s2_s = OS_REG_READ(ah, AR_ISR_S2_S);
192
193                 if (s2_s & AR_ISR_S2_GTT) {
194                         *masked |= HAL_INT_GTT;
195                 }
196
197                 if (s2_s & AR_ISR_S2_CST) {
198                         *masked |= HAL_INT_CST;
199                 }
200         }
201
202         if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
203                 *masked |= HAL_INT_RX;
204         if (isr & (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR | AR_ISR_TXEOL)) {
205                 struct ath_hal_5416 *ahp = AH5416(ah);
206                 a_uint32_t           s0_s, s1_s;
207
208                 *masked |= HAL_INT_TX;
209                 s0_s = OS_REG_READ(ah, AR_ISR_S0_S);
210                 s1_s = OS_REG_READ(ah, AR_ISR_S1_S);
211                 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
212                 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
213                 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
214                 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
215         }
216
217 #ifndef AR9100
218         sync_cause = OS_REG_READ(ah, AR_INTR_SYNC_CAUSE);
219         fatal_int = ((sync_cause != AR_INTR_SPURIOUS) &&
220                      (sync_cause & (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))) ?
221                 AH_TRUE : AH_FALSE;
222
223         if (AH_TRUE == fatal_int) {
224                 OS_REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
225                 (void) OS_REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
226         }
227 #endif
228         return AH_TRUE;
229 }
230
231 HAL_INT ar5416GetInterrupts(struct ath_hal *ah)
232 {
233         return AH5416(ah)->ah_maskReg;
234 }
235
236 HAL_INT
237 ar5416SetInterrupts(struct ath_hal *ah, HAL_INT ints)
238 {
239         struct ath_hal_5416 *ahp = AH5416(ah);
240         a_uint32_t omask = ahp->ah_maskReg;
241         a_uint32_t mask;
242
243         if (omask & HAL_INT_GLOBAL) {
244                 OS_REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
245                 (void) OS_REG_READ(ah, AR_IER);
246         }
247
248         mask = ints & HAL_INT_COMMON;
249         if (ints & HAL_INT_TX) {
250 #ifdef AR5416_INT_MITIGATION
251                 mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM;
252 #else
253                 mask |= AR_IMR_TXOK;
254                 mask |= AR_IMR_TXDESC;
255 #endif
256                 mask |= AR_IMR_TXERR;
257                 mask |= AR_IMR_TXEOL;
258         }
259         if (ints & HAL_INT_RX) {
260                 mask |= AR_IMR_RXERR;
261 #ifdef AR5416_INT_MITIGATION
262                 mask |=  AR_IMR_RXMINTR | AR_IMR_RXINTM;
263 #else
264                 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
265 #endif
266         }
267
268         if (ints & (HAL_INT_GTT | HAL_INT_CST)) {
269                 mask |= AR_IMR_BCNMISC;
270         }
271
272         OS_REG_WRITE(ah, AR_IMR, mask);
273         (void) OS_REG_READ(ah, AR_IMR);
274         ahp->ah_maskReg = ints;
275
276         /* Re-enable interrupts if they were enabled before. */
277         if (ints & HAL_INT_GLOBAL) {
278                 OS_REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
279                 /* See explanation above... */
280                 (void) OS_REG_READ(ah, AR_IER);
281         }
282
283         OS_REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, AR_INTR_MAC_IRQ);
284         OS_REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
285         OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_ALL);
286
287         return omask;
288 }
289
290 /****************/
291 /* TSF Handling */
292 /****************/
293
294 u_int64_t ar5416GetTsf64(struct ath_hal *ah)
295 {
296         u_int64_t tsf;
297
298         tsf = OS_REG_READ(ah, AR_TSF_U32);
299         tsf = (tsf << 32) | OS_REG_READ(ah, AR_TSF_L32);
300
301         return tsf;
302 }
303
304 a_uint32_t ar5416GetTsf32(struct ath_hal *ah)
305 {
306         return OS_REG_READ(ah, AR_TSF_L32);
307 }
308
309 void ar5416ResetTsf(struct ath_hal *ah)
310 {
311         a_int32_t count;
312
313         count = 0;
314
315         while (OS_REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
316                 count++;
317                 if (count > 10) {
318                         break;
319                 }
320                 OS_DELAY(10);
321         }
322         OS_REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
323 }
324
325 /******/
326 /* RX */
327 /******/
328
329 a_uint32_t ar5416GetRxDP(struct ath_hal *ath)
330 {
331         return OS_REG_READ(ath, AR_RXDP);
332 }
333
334
335 void ar5416SetRxDP(struct ath_hal *ah, a_uint32_t rxdp)
336 {
337         OS_REG_WRITE(ah, AR_RXDP, rxdp);
338         HALASSERT(OS_REG_READ(ah, AR_RXDP) == rxdp);
339 }
340
341 void ar5416SetMulticastFilter(struct ath_hal *ah, a_uint32_t filter0, a_uint32_t filter1)
342 {
343         OS_REG_WRITE(ah, AR_MCAST_FIL0, filter0);
344         OS_REG_WRITE(ah, AR_MCAST_FIL1, filter1);
345 }
346
347 HAL_BOOL ar5416ClrMulticastFilterIndex(struct ath_hal *ah, a_uint32_t ix)
348 {
349         a_uint32_t val;
350
351         if (ix >= 64)
352                 return AH_FALSE;
353         if (ix >= 32) {
354                 val = OS_REG_READ(ah, AR_MCAST_FIL1);
355                 OS_REG_WRITE(ah, AR_MCAST_FIL1, (val &~ (1<<(ix-32))));
356         } else {
357                 val = OS_REG_READ(ah, AR_MCAST_FIL0);
358                 OS_REG_WRITE(ah, AR_MCAST_FIL0, (val &~ (1<<ix)));
359         }
360         return AH_TRUE;
361 }
362
363 HAL_BOOL ar5416StopDmaReceive(struct ath_hal *ah)
364 {
365         OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); /* Set receive disable bit */
366         if (!ath_hal_wait(ah, AR_CR, AR_CR_RXE, 0)) {
367                 return AH_FALSE;
368         } else {
369                 return AH_TRUE;
370         }
371 }
372
373 HAL_BOOL ar5416SetMulticastFilterIndex(struct ath_hal *ah, a_uint32_t ix)
374 {
375         a_uint32_t val;
376
377         if (ix >= 64)
378                 return AH_FALSE;
379         if (ix >= 32) {
380                 val = OS_REG_READ(ah, AR_MCAST_FIL1);
381                 OS_REG_WRITE(ah, AR_MCAST_FIL1, (val | (1<<(ix-32))));
382         } else {
383                 val = OS_REG_READ(ah, AR_MCAST_FIL0);
384                 OS_REG_WRITE(ah, AR_MCAST_FIL0, (val | (1<<ix)));
385         }
386         return AH_TRUE;
387 }
388
389 void ar5416StartPcuReceive(struct ath_hal *ah)
390 {
391         OS_REG_CLR_BIT(ah, AR_DIAG_SW,
392                        (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
393 }
394
395 void ar5416SetRxFilter(struct ath_hal *ah, a_uint32_t bits)
396 {
397         a_uint32_t phybits;
398     
399         OS_REG_WRITE(ah, AR_RX_FILTER, (bits & 0xff) | AR_RX_COMPR_BAR);
400         phybits = 0;
401         if (bits & HAL_RX_FILTER_PHYRADAR)
402                 phybits |= AR_PHY_ERR_RADAR;
403         if (bits & HAL_RX_FILTER_PHYERR)
404                 phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
405         OS_REG_WRITE(ah, AR_PHY_ERR, phybits);
406         if (phybits) {
407                 OS_REG_WRITE(ah, AR_RXCFG,OS_REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
408         } else {
409                 OS_REG_WRITE(ah, AR_RXCFG,OS_REG_READ(ah, AR_RXCFG) &~ AR_RXCFG_ZLFDMA);
410         }
411 }
412
413 void ar5416EnableReceive(struct ath_hal *ah)
414 {
415         OS_REG_WRITE(ah, AR_CR, AR_CR_RXE);
416 }
417
418 void ar5416StopPcuReceive(struct ath_hal *ah)
419 {
420         OS_REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
421 }
422
423 HAL_BOOL ar5416SetupRxDesc_20(struct ath_hal *ah, struct ath_rx_desc *ds,
424                               a_uint32_t size, a_uint32_t flags)
425 {
426         struct ar5416_desc *ads = AR5416DESC(ds);
427
428         HALASSERT((size &~ AR_BufLen) == 0);
429
430         ads->ds_ctl1 = size & AR_BufLen;
431         if (flags & HAL_RXDESC_INTREQ)
432                 ads->ds_ctl1 |= AR_RxIntrReq;
433
434         /* this should be enough */
435         ads->ds_rxstatus8 &= ~AR_RxDone;
436
437         return AH_TRUE;
438 }
439
440 HAL_STATUS ar5416ProcRxDescFast_20(struct ath_hal *ah, struct ath_rx_desc *ds,
441                                    a_uint32_t pa, struct ath_desc *nds,
442                                    struct ath_rx_status *rx_stats)
443 {
444         struct ar5416_desc ads;
445         struct ar5416_desc *adsp = AR5416DESC(ds);
446         struct ar5416_desc *ands = AR5416DESC(nds);
447
448         if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
449                 return HAL_EINPROGRESS;
450         /*
451          * Given the use of a self-linked tail be very sure that the hw is
452          * done with this descriptor; the hw may have done this descriptor
453          * once and picked it up again...make sure the hw has moved on.
454          */
455         if ((ands->ds_rxstatus8 & AR_RxDone) == 0
456             && OS_REG_READ(ah, AR_RXDP) == pa)
457                 return HAL_EINPROGRESS;
458
459         /*
460          * Now we need to get the stats from the descriptor. Since desc are 
461          * uncached, lets make a copy of the stats first. Note that, since we
462          * touch most of the rx stats, a memcpy would always be more efficient
463          *
464          * Next we fill in all values in a caller passed stack variable.
465          * This reduces the number of uncached accesses.
466          * Do this copy here, after the check so that when the checks fail, we
467          * dont end up copying the entire stats uselessly.
468          */
469         ads.u.rx = adsp->u.rx;
470
471         rx_stats->rs_status = 0;
472         rx_stats->rs_flags = 0;
473
474         rx_stats->rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
475         rx_stats->rs_tstamp =  ads.AR_RcvTimestamp;
476
477         /* XXX what about KeyCacheMiss? */
478         rx_stats->rs_rssi_combined = 
479                 MS(ads.ds_rxstatus4, AR_RxRSSICombined);
480         rx_stats->rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
481         rx_stats->rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
482         rx_stats->rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
483         rx_stats->rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
484         rx_stats->rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
485         rx_stats->rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
486         if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
487                 rx_stats->rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
488         else
489                 rx_stats->rs_keyix = HAL_RXKEYIX_INVALID;
490         /* NB: caller expected to do rate table mapping */
491         rx_stats->rs_rate = RXSTATUS_RATE(ah, (&ads));
492         rx_stats->rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
493
494         rx_stats->rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
495         rx_stats->rs_moreaggr = (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
496         rx_stats->rs_flags  |= (ads.ds_rxstatus3 & AR_GI) ? HAL_RX_GI : 0;
497         rx_stats->rs_flags  |= (ads.ds_rxstatus3 & AR_2040) ? HAL_RX_2040 : 0;
498
499         if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
500                 rx_stats->rs_flags |= HAL_RX_DELIM_CRC_PRE;
501         if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
502                 rx_stats->rs_flags |= HAL_RX_DELIM_CRC_POST;
503         if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
504                 rx_stats->rs_flags |= HAL_RX_DECRYPT_BUSY;
505
506         if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
507                 /*
508                  * These four bits should not be set together.  The
509                  * 5416 spec states a Michael error can only occur if
510                  * DecryptCRCErr not set (and TKIP is used).  Experience
511                  * indicates however that you can also get Michael errors
512                  * when a CRC error is detected, but these are specious.
513                  * Consequently we filter them out here so we don't
514                  * confuse and/or complicate drivers.
515                  */
516                 if (ads.ds_rxstatus8 & AR_CRCErr)
517                         rx_stats->rs_status |= HAL_RXERR_CRC;
518                 else if (ads.ds_rxstatus8 & AR_PHYErr) {
519                         a_uint32_t phyerr;
520
521                         rx_stats->rs_status |= HAL_RXERR_PHY;
522                         phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
523                         rx_stats->rs_phyerr = phyerr;
524                 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
525                         rx_stats->rs_status |= HAL_RXERR_DECRYPT;
526                 else if (ads.ds_rxstatus8 & AR_MichaelErr)
527                         rx_stats->rs_status |= HAL_RXERR_MIC;
528         }
529         rx_stats->evm0=ads.AR_RxEVM0;
530         rx_stats->evm1=ads.AR_RxEVM1;
531         rx_stats->evm2=ads.AR_RxEVM2;
532
533         return HAL_OK;
534 }
535
536 /******/
537 /* TX */
538 /******/
539
540 HAL_BOOL ar5416UpdateTxTrigLevel(struct ath_hal *ah, HAL_BOOL bIncTrigLevel)
541 {
542         struct ath_hal_5416 *ahp = AH5416(ah);
543         a_uint32_t txcfg, curLevel, newLevel;
544         HAL_INT omask;
545
546         /*
547          * Disable interrupts while futzing with the fifo level.
548          */
549         omask = ar5416SetInterrupts(ah, ahp->ah_maskReg &~ HAL_INT_GLOBAL);
550
551         txcfg = OS_REG_READ(ah, AR_TXCFG);
552         curLevel = MS(txcfg, AR_FTRIG);
553         newLevel = curLevel;
554
555         if (bIncTrigLevel)  {
556                 if (curLevel < MAX_TX_FIFO_THRESHOLD)
557                         newLevel ++;
558         } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
559                 newLevel--;
560         if (newLevel != curLevel)
561                 OS_REG_WRITE(ah, AR_TXCFG,
562                              (txcfg &~ AR_FTRIG) | SM(newLevel, AR_FTRIG));
563
564         /* re-enable chip interrupts */
565         ar5416SetInterrupts(ah, omask);
566
567         return (newLevel != curLevel);
568 }
569
570 a_uint32_t ar5416GetTxDP(struct ath_hal *ah, a_uint32_t q)
571 {
572         HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
573         return OS_REG_READ(ah, AR_QTXDP(q));
574 }
575
576 HAL_BOOL ar5416SetTxDP(struct ath_hal *ah, a_uint32_t q, a_uint32_t txdp)
577 {
578         HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
579         HALASSERT(AH5416(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE);
580
581         /*
582          * Make sure that TXE is deasserted before setting the TXDP.  If TXE
583          * is still asserted, setting TXDP will have no effect.
584          */
585         HALASSERT((OS_REG_READ(ah, AR_Q_TXE) & (1 << q)) == 0);
586
587         OS_REG_WRITE(ah, AR_QTXDP(q), txdp);
588
589         return AH_TRUE;
590 }
591
592 HAL_BOOL ar5416StartTxDma(struct ath_hal *ah, a_uint32_t q)
593 {
594         HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
595         HALASSERT(AH5416(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE);
596
597         /* Check to be sure we're not enabling a q that has its TXD bit set. */
598         HALASSERT((OS_REG_READ(ah, AR_Q_TXD) & (1 << q)) == 0);
599
600         OS_REG_WRITE(ah, AR_Q_TXE, 1 << q);
601
602         return AH_TRUE;
603 }
604
605 a_uint32_t ar5416NumTxPending(struct ath_hal *ah, a_uint32_t q)
606 {
607         a_uint32_t npend;
608
609         HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
610         HALASSERT(AH5416(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE);
611
612         npend = OS_REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
613         if (npend == 0) {
614                 /*
615                  * Pending frame count (PFC) can momentarily go to zero
616                  * while TXE remains asserted.  In other words a PFC of
617                  * zero is not sufficient to say that the queue has stopped.
618                  */
619                 if (OS_REG_READ(ah, AR_Q_TXE) & (1 << q))
620                         npend = 1;
621         }
622 #ifdef DEBUG
623         if (npend && (AH5416(ah)->ah_txq[q].tqi_type == HAL_TX_QUEUE_CAB)) {
624                 if (OS_REG_READ(ah, AR_Q_RDYTIMESHDN) & (1 << q)) {
625                         isrPrintf("RTSD on CAB queue\n");
626                         /* Clear the ReadyTime shutdown status bits */
627                         OS_REG_WRITE(ah, AR_Q_RDYTIMESHDN, 1 << q);
628                 }
629         }
630 #endif
631         return npend;
632 }
633
634 HAL_BOOL ar5416AbortTxDma(struct ath_hal *ah)
635 {
636         a_int32_t i, q;
637
638         /*
639          * set txd on all queues
640          */
641         OS_REG_WRITE(ah, AR_Q_TXD, AR_Q_TXD_M);
642
643         /*
644          * set tx abort bits
645          */
646         OS_REG_SET_BIT(ah, AR_PCU_MISC, (AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF));
647         OS_REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
648         OS_REG_SET_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
649
650         /*
651          * wait on all tx queues
652          */
653         for (q = 0; q < AR_NUM_QCU; q++) {
654                 for (i = 0; i < AR5416_ABORT_LOOPS; i++) {
655                         if (!ar5416NumTxPending(ah, q))
656                                 break;
657
658                         OS_DELAY(AR5416_ABORT_WAIT);
659                 }
660                 if (i == AR5416_ABORT_LOOPS) {
661                         return AH_FALSE;
662                 }
663         }
664
665         /*
666          * clear tx abort bits
667          */
668         OS_REG_CLR_BIT(ah, AR_PCU_MISC, (AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF));
669         OS_REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
670         OS_REG_CLR_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
671
672         /*
673          * clear txd
674          */
675         OS_REG_WRITE(ah, AR_Q_TXD, 0);
676
677         return AH_TRUE;
678 }
679
680 HAL_BOOL ar5416StopTxDma(struct ath_hal*ah, a_uint32_t q)
681 {
682         a_uint32_t i;
683         
684         HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
685
686         HALASSERT(AH5416(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE);
687
688         OS_REG_WRITE(ah, AR_Q_TXD, 1 << q);
689         for (i = 1000; i != 0; i--) {
690                 if (ar5416NumTxPending(ah, q) == 0)
691                         break;
692                 OS_DELAY(100);        /* XXX get actual value */
693         }
694
695         OS_REG_WRITE(ah, AR_Q_TXD, 0);
696         return (i != 0);
697 }
698
699 void ar5416GetTxIntrQueue(struct ath_hal *ah, a_uint32_t *txqs)
700 {
701         struct ath_hal_5416 *ahp = AH5416(ah);
702         *txqs &= ahp->ah_intrTxqs;
703         ahp->ah_intrTxqs &= ~(*txqs);
704 }
705
706 void ar5416IntrReqTxDesc_20(struct ath_hal *ah, struct ath_desc *ds)
707 {
708         struct ar5416_desc *ads = AR5416DESC(ds);
709         ads->ds_ctl0 |= AR_TxIntrReq;
710 }
711
712 HAL_BOOL ar5416SetupTxDesc_20(struct ath_hal *ah, struct ath_tx_desc *ds,
713                               a_uint32_t pktLen,
714                               a_uint32_t hdrLen,
715                               HAL_PKT_TYPE type,
716                               a_uint32_t txPower,
717                               a_uint32_t txRate0, a_uint32_t txTries0,
718                               a_uint32_t keyIx,
719                               a_uint32_t antMode,
720                               a_uint32_t flags,
721                               a_uint32_t rtsctsRate,
722                               a_uint32_t rtsctsDuration,
723                               a_uint32_t compicvLen,
724                               a_uint32_t compivLen,
725                               a_uint32_t comp)
726 {
727 #define RTSCTS  (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)
728
729         struct ar5416_desc *ads = AR5416DESC(ds);
730
731         (void) hdrLen;
732
733         ads->ds_txstatus9 &= ~AR_TxDone;
734
735         HALASSERT(txTries0 != 0);
736         HALASSERT(isValidPktType(type));
737         HALASSERT(isValidTxRate(txRate0));
738         HALASSERT((flags & RTSCTS) != RTSCTS);
739
740         if (txPower > 63)
741                 txPower=63;
742
743         ads->ds_ctl0 = (pktLen & AR_FrameLen)
744                 | (txPower << AR_XmitPower_S)
745                 | (flags & HAL_TXDESC_VEOL ? AR_VEOL : 0)
746                 | (flags & HAL_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
747                 | (flags & HAL_TXDESC_INTREQ ? AR_TxIntrReq : 0);
748
749         ads->ds_ctl1 = (type << AR_FrameType_S)
750                 | (flags & HAL_TXDESC_NOACK ? AR_NoAck : 0);
751         ads->ds_ctl2 = SM(txTries0, AR_XmitDataTries0);
752         ads->ds_ctl3 = (txRate0 << AR_XmitRate0_S);
753
754         ads->ds_ctl7 = SM(AR5416_LEGACY_CHAINMASK, AR_ChainSel0) 
755                 | SM(AR5416_LEGACY_CHAINMASK, AR_ChainSel1)
756                 | SM(AR5416_LEGACY_CHAINMASK, AR_ChainSel2) 
757                 | SM(AR5416_LEGACY_CHAINMASK, AR_ChainSel3);
758
759         if (keyIx != HAL_TXKEYIX_INVALID) {
760                 /* XXX validate key index */
761                 ads->ds_ctl1 |= SM(keyIx, AR_DestIdx);
762                 ads->ds_ctl0 |= AR_DestIdxValid;
763         }
764
765         if (flags & RTSCTS) {
766                 if (!isValidTxRate(rtsctsRate)) {
767                         return AH_FALSE;
768                 }
769                 /* XXX validate rtsctsDuration */
770                 ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0)
771                         | (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0);
772                 ads->ds_ctl2 |= SM(rtsctsDuration, AR_BurstDur);
773                 ads->ds_ctl3 |= (rtsctsRate << AR_RTSCTSRate_S);
774         }
775         return AH_TRUE;
776
777 #undef RTSCTS
778 }
779
780 HAL_BOOL ar5416FillTxDesc_20(struct ath_hal *ah, struct ath_tx_desc *ds,
781                              a_uint32_t segLen, HAL_BOOL firstSeg, HAL_BOOL lastSeg,
782                              const struct ath_tx_desc *ds0)
783 {
784         struct ar5416_desc *ads = AR5416DESC(ds);
785
786         HALASSERT((segLen &~ AR_BufLen) == 0);
787
788         if (firstSeg) {
789                 /*
790                  * First descriptor, don't clobber xmit control data
791                  * setup by ar5416SetupTxDesc.
792                  */
793                 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
794         } else if (lastSeg) {
795                 /*
796                  * Last descriptor in a multi-descriptor frame,
797                  * copy the multi-rate transmit parameters from
798                  * the first frame for processing on completion.
799                  */
800                 ads->ds_ctl0 = 0;
801                 ads->ds_ctl1 = segLen;
802                 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
803                 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
804         } else {
805                 /*
806                  * Intermediate descriptor in a multi-descriptor frame.
807                  */
808                 ads->ds_ctl0 = 0;
809                 ads->ds_ctl1 = segLen | AR_TxMore;
810                 ads->ds_ctl2 = 0;
811                 ads->ds_ctl3 = 0;
812         }
813         ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
814
815         return AH_TRUE;
816 }
817
818 HAL_BOOL ar5416FillKeyTxDesc_20(struct ath_hal *ah, struct ath_tx_desc *ds,
819                                 HAL_KEY_TYPE keyType)
820 {
821         struct ar5416_desc *ads = AR5416DESC(ds);
822
823         ads->ds_ctl6 = SM(keyType, AR_EncrType);
824         return AH_TRUE;
825 }
826
827 HAL_STATUS ar5416ProcTxDesc_20(struct ath_hal *ah, struct ath_tx_desc *gds)
828 {
829         struct ar5416_desc *ads = AR5416DESC(gds);
830         struct ath_tx_desc *ds = (struct ath_tx_desc *)gds;
831         
832         if ((ads->ds_txstatus9 & AR_TxDone) == 0)
833                 return HAL_EINPROGRESS;
834
835         ads->ds_txstatus9 &= ~AR_TxDone;
836
837         /* Update software copies of the HW status */
838         ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
839         ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
840         ds->ds_txstat.ts_status = 0;
841         ds->ds_txstat.ts_flags  = 0;
842
843         if (ads->ds_txstatus1 & AR_ExcessiveRetries)
844                 ds->ds_txstat.ts_status |= HAL_TXERR_XRETRY;
845         if (ads->ds_txstatus1 & AR_Filtered)
846                 ds->ds_txstat.ts_status |= HAL_TXERR_FILT;
847         if (ads->ds_txstatus1 & AR_FIFOUnderrun)
848                 ds->ds_txstat.ts_status |= HAL_TXERR_FIFO;
849         if (ads->ds_txstatus9 & AR_TxOpExceeded)
850                 ds->ds_txstat.ts_status |= HAL_TXERR_XTXOP;
851         if (ads->ds_txstatus1 & AR_TxTimerExpired)
852                 ds->ds_txstat.ts_status |= HAL_TXERR_TIMER_EXPIRED;
853
854         if (ads->ds_txstatus1 & AR_DescCfgErr)
855                 ds->ds_txstat.ts_flags |= HAL_TX_DESC_CFG_ERR;
856         if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
857                 ds->ds_txstat.ts_flags |= HAL_TX_DATA_UNDERRUN;
858                 ar5416UpdateTxTrigLevel(ah, AH_TRUE);
859         }
860         if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
861                 ds->ds_txstat.ts_flags |= HAL_TX_DELIM_UNDERRUN;
862                 ar5416UpdateTxTrigLevel(ah, AH_TRUE);
863         }
864         if (ads->ds_txstatus0 & AR_TxBaStatus) {
865                 ds->ds_txstat.ts_flags |= HAL_TX_BA;
866                 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
867                 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
868         }
869
870         /*
871          * Extract the transmit rate used and mark the rate as
872          * ``alternate'' if it wasn't the series 0 rate.
873          */
874         ds->ds_txstat.ts_rate = MS(ads->ds_txstatus9, AR_FinalTxIdx);
875         ds->ds_txstat.ts_rssi_combined = 
876                 MS(ads->ds_txstatus5, AR_TxRSSICombined);
877         ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
878         ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
879         ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
880         ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
881         ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
882         ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
883         ds->ds_txstat.evm0 = ads->AR_TxEVM0;
884         ds->ds_txstat.evm1 = ads->AR_TxEVM1;
885         ds->ds_txstat.evm2 = ads->AR_TxEVM2;
886         ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
887         ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
888         ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
889         ds->ds_txstat.ts_antenna = 0;           /* ignored for owl */
890
891         return HAL_OK;
892 }
893
894 void ar5416Set11nTxDesc_20(struct ath_hal *ah, struct ath_tx_desc *ds,
895                            a_uint32_t pktLen, HAL_PKT_TYPE type, a_uint32_t txPower,
896                            a_uint32_t keyIx, HAL_KEY_TYPE keyType,
897                            a_uint32_t flags)
898 {
899         struct ar5416_desc *ads = AR5416DESC(ds);
900
901         HALASSERT(isValidPktType(type));
902         HALASSERT(isValidKeyType(keyType));
903
904         if (txPower > 63)
905                 txPower = 63;
906
907         ads->ds_ctl0 = (pktLen & AR_FrameLen)
908                 | (flags & HAL_TXDESC_VMF ? AR_VirtMoreFrag : 0)
909                 | SM(txPower, AR_XmitPower)
910                 | (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0)
911                 | (flags & HAL_TXDESC_VEOL ? AR_VEOL : 0)
912                 | (flags & HAL_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
913                 | (flags & HAL_TXDESC_INTREQ ? AR_TxIntrReq : 0)
914                 | (keyIx != HAL_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
915                 | (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0);
916
917         ads->ds_ctl1 = (keyIx != HAL_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
918                 | SM(type, AR_FrameType)
919                 | (flags & HAL_TXDESC_NOACK ? AR_NoAck : 0)
920                 | (flags & HAL_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
921                 | (flags & HAL_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
922
923         ads->ds_ctl6 = SM(keyType, AR_EncrType);
924 }
925
926 #ifdef MAGPIE_MERLIN
927
928 void ar5416Set11nRateScenario_20(struct ath_hal *ah, struct ath_tx_desc *ds,
929                                  a_uint32_t durUpdateEn, a_uint32_t rtsctsRate,
930                                  a_uint32_t rtsctsDuration,
931                                  HAL_11N_RATE_SERIES series[], a_uint32_t nseries,
932                                  a_uint32_t flags)
933 {
934         struct ar5416_desc *ads = AR5416DESC(ds);
935         a_uint32_t ds_ctl0;
936
937         HALASSERT(nseries == 4);
938         (void)nseries;
939
940         /*
941          * Rate control settings override
942          */
943         ds_ctl0 = ads->ds_ctl0;
944
945         if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
946                 if (flags & HAL_TXDESC_RTSENA) {
947                         ds_ctl0 &= ~AR_CTSEnable;
948                         ds_ctl0 |= AR_RTSEnable;
949                 } else {
950                         ds_ctl0 &= ~AR_RTSEnable;
951                         ds_ctl0 |= AR_CTSEnable;
952                 }
953         } else {
954                 ds_ctl0 = (ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
955         }
956
957         ads->ds_ctl0 = ds_ctl0;
958
959         ads->ds_ctl2 = set11nTries(series, 0)
960                 |  set11nTries(series, 1)
961                 |  set11nTries(series, 2)
962                 |  set11nTries(series, 3)
963                 |  (durUpdateEn ? AR_DurUpdateEn : 0);
964
965         ads->ds_ctl3 = set11nRate(series, 0)
966                 |  set11nRate(series, 1)
967                 |  set11nRate(series, 2)
968                 |  set11nRate(series, 3);
969
970         ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
971                 |  set11nPktDurRTSCTS(series, 1);
972
973         ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
974                 |  set11nPktDurRTSCTS(series, 3);
975
976         ads->ds_ctl7 = set11nRateFlags(series, 0)
977                 |  set11nRateFlags(series, 1)
978                 |  set11nRateFlags(series, 2)
979                 |  set11nRateFlags(series, 3)
980                 | SM(rtsctsRate, AR_RTSCTSRate);
981 }
982
983 #else
984
985 void ar5416Set11nRateScenario_20(struct ath_hal *ah, struct ath_tx_desc *ds,
986                                  a_uint32_t durUpdateEn, a_uint32_t rtsctsRate,
987                                  a_uint32_t rtsctsDuration,
988                                  HAL_11N_RATE_SERIES series[], a_uint32_t nseries,
989                                  a_uint32_t flags)
990 {
991         struct ar5416_desc *ads = AR5416DESC(ds);
992         a_uint32_t ds_ctl0;
993
994         HALASSERT(nseries == 4);
995         (void)nseries;
996
997         /*
998          * Rate control settings override
999          */
1000         if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
1001                 ds_ctl0 = ads->ds_ctl0;
1002
1003                 if (flags & HAL_TXDESC_RTSENA) {
1004                         ds_ctl0 &= ~AR_CTSEnable;
1005                         ds_ctl0 |= AR_RTSEnable;
1006                 } else {
1007                         ds_ctl0 &= ~AR_RTSEnable;
1008                         ds_ctl0 |= AR_CTSEnable;
1009                 }
1010
1011                 ads->ds_ctl0 = ds_ctl0;
1012         }
1013
1014         ads->ds_ctl2 = set11nTries(series, 0)
1015                 |  set11nTries(series, 1)
1016                 |  set11nTries(series, 2)
1017                 |  set11nTries(series, 3)
1018                 |  (durUpdateEn ? AR_DurUpdateEn : 0);
1019
1020         ads->ds_ctl3 = set11nRate(series, 0)
1021                 |  set11nRate(series, 1)
1022                 |  set11nRate(series, 2)
1023                 |  set11nRate(series, 3);
1024
1025         ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
1026                 |  set11nPktDurRTSCTS(series, 1);
1027
1028         ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
1029                 |  set11nPktDurRTSCTS(series, 3);
1030
1031         ads->ds_ctl7 = set11nRateFlags(series, 0)
1032                 |  set11nRateFlags(series, 1)
1033                 |  set11nRateFlags(series, 2)
1034                 |  set11nRateFlags(series, 3)
1035                 | SM(rtsctsRate, AR_RTSCTSRate);
1036 }
1037
1038 #endif
1039
1040 void ar5416Set11nAggrFirst_20(struct ath_hal *ah, struct ath_tx_desc *ds, a_uint32_t aggrLen,
1041                               a_uint32_t numDelims)
1042 {
1043         struct ar5416_desc *ads = AR5416DESC(ds);
1044
1045         ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
1046
1047         ads->ds_ctl6 &= ~(AR_AggrLen | AR_PadDelim);
1048         ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen) |
1049                 SM(numDelims, AR_PadDelim);
1050 }
1051
1052 void ar5416Set11nAggrMiddle_20(struct ath_hal *ah, struct ath_tx_desc *ds, a_uint32_t numDelims)
1053 {
1054         struct ar5416_desc *ads = AR5416DESC(ds);
1055         a_uint32_t ctl6;
1056
1057         ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
1058
1059         /*
1060          * We use a stack variable to manipulate ctl6 to reduce uncached 
1061          * read modify, modfiy, write.
1062          */
1063         ctl6 = ads->ds_ctl6;
1064         ctl6 &= ~AR_PadDelim;
1065         ctl6 |= SM(numDelims, AR_PadDelim);
1066         ads->ds_ctl6 = ctl6;
1067 }
1068
1069 void ar5416Set11nAggrLast_20(struct ath_hal *ah, struct ath_tx_desc *ds)
1070 {
1071         struct ar5416_desc *ads = AR5416DESC(ds);
1072
1073         ads->ds_ctl1 |= AR_IsAggr;
1074         ads->ds_ctl1 &= ~AR_MoreAggr;
1075         ads->ds_ctl6 &= ~AR_PadDelim;
1076 }
1077
1078 void ar5416Clr11nAggr_20(struct ath_hal *ah, struct ath_tx_desc *ds)
1079 {
1080         struct ar5416_desc *ads = AR5416DESC(ds);
1081
1082         ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
1083 }
1084
1085 void ar5416Set11nBurstDuration_20(struct ath_hal *ah, struct ath_tx_desc *ds,
1086                                   a_uint32_t burstDuration)
1087 {
1088         struct ar5416_desc *ads = AR5416DESC(ds);
1089
1090         ads->ds_ctl2 &= ~AR_BurstDur;
1091         ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
1092 }
1093
1094 void ar5416Set11nVirtualMoreFrag_20(struct ath_hal *ah, struct ath_tx_desc *ds,
1095                                     a_uint32_t vmf)
1096 {
1097         struct ar5416_desc *ads = AR5416DESC(ds);
1098
1099         if (vmf) {
1100                 ads->ds_ctl0 |= AR_VirtMoreFrag;
1101         } else {
1102                 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
1103         }
1104 }