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