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