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