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