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