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