Remove empty DragonFly CVS IDs.
[dragonfly.git] / sys / dev / netif / ath / hal / ath_hal / ar5212 / ar5212_xmit.c
1 /*
2  * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3  * Copyright (c) 2002-2008 Atheros Communications, Inc.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  *
17  * $FreeBSD: head/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c 194135 2009-06-13 23:36:54Z sam $
18  */
19 #include "opt_ah.h"
20
21 #include "ah.h"
22 #include "ah_internal.h"
23
24 #include "ar5212/ar5212.h"
25 #include "ar5212/ar5212reg.h"
26 #include "ar5212/ar5212desc.h"
27 #include "ar5212/ar5212phy.h"
28 #ifdef AH_SUPPORT_5311
29 #include "ar5212/ar5311reg.h"
30 #endif
31
32 #ifdef AH_NEED_DESC_SWAP
33 static void ar5212SwapTxDesc(struct ath_desc *ds);
34 #endif
35
36 /*
37  * Update Tx FIFO trigger level.
38  *
39  * Set bIncTrigLevel to TRUE to increase the trigger level.
40  * Set bIncTrigLevel to FALSE to decrease the trigger level.
41  *
42  * Returns TRUE if the trigger level was updated
43  */
44 HAL_BOOL
45 ar5212UpdateTxTrigLevel(struct ath_hal *ah, HAL_BOOL bIncTrigLevel)
46 {
47         struct ath_hal_5212 *ahp = AH5212(ah);
48         uint32_t txcfg, curLevel, newLevel;
49         HAL_INT omask;
50
51         if (ahp->ah_txTrigLev >= ahp->ah_maxTxTrigLev)
52                 return AH_FALSE;
53
54         /*
55          * Disable interrupts while futzing with the fifo level.
56          */
57         omask = ath_hal_setInterrupts(ah, ahp->ah_maskReg &~ HAL_INT_GLOBAL);
58
59         txcfg = OS_REG_READ(ah, AR_TXCFG);
60         curLevel = MS(txcfg, AR_FTRIG);
61         newLevel = curLevel;
62         if (bIncTrigLevel) {            /* increase the trigger level */
63                 if (curLevel < ahp->ah_maxTxTrigLev)
64                         newLevel++;
65         } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
66                 newLevel--;
67         if (newLevel != curLevel)
68                 /* Update the trigger level */
69                 OS_REG_WRITE(ah, AR_TXCFG,
70                         (txcfg &~ AR_FTRIG) | SM(newLevel, AR_FTRIG));
71
72         ahp->ah_txTrigLev = newLevel;
73
74         /* re-enable chip interrupts */
75         ath_hal_setInterrupts(ah, omask);
76
77         return (newLevel != curLevel);
78 }
79
80 /*
81  * Set the properties of the tx queue with the parameters
82  * from qInfo.  
83  */
84 HAL_BOOL
85 ar5212SetTxQueueProps(struct ath_hal *ah, int q, const HAL_TXQ_INFO *qInfo)
86 {
87         struct ath_hal_5212 *ahp = AH5212(ah);
88         HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
89
90         if (q >= pCap->halTotalQueues) {
91                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid queue num %u\n",
92                     __func__, q);
93                 return AH_FALSE;
94         }
95         return ath_hal_setTxQProps(ah, &ahp->ah_txq[q], qInfo);
96 }
97
98 /*
99  * Return the properties for the specified tx queue.
100  */
101 HAL_BOOL
102 ar5212GetTxQueueProps(struct ath_hal *ah, int q, HAL_TXQ_INFO *qInfo)
103 {
104         struct ath_hal_5212 *ahp = AH5212(ah);
105         HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
106
107
108         if (q >= pCap->halTotalQueues) {
109                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid queue num %u\n",
110                     __func__, q);
111                 return AH_FALSE;
112         }
113         return ath_hal_getTxQProps(ah, qInfo, &ahp->ah_txq[q]);
114 }
115
116 /*
117  * Allocate and initialize a tx DCU/QCU combination.
118  */
119 int
120 ar5212SetupTxQueue(struct ath_hal *ah, HAL_TX_QUEUE type,
121         const HAL_TXQ_INFO *qInfo)
122 {
123         struct ath_hal_5212 *ahp = AH5212(ah);
124         HAL_TX_QUEUE_INFO *qi;
125         HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
126         int q, defqflags;
127
128         /* by default enable OK+ERR+DESC+URN interrupts */
129         defqflags = HAL_TXQ_TXOKINT_ENABLE
130                   | HAL_TXQ_TXERRINT_ENABLE
131                   | HAL_TXQ_TXDESCINT_ENABLE
132                   | HAL_TXQ_TXURNINT_ENABLE;
133         /* XXX move queue assignment to driver */
134         switch (type) {
135         case HAL_TX_QUEUE_BEACON:
136                 q = pCap->halTotalQueues-1;     /* highest priority */
137                 defqflags |= HAL_TXQ_DBA_GATED
138                        | HAL_TXQ_CBR_DIS_QEMPTY
139                        | HAL_TXQ_ARB_LOCKOUT_GLOBAL
140                        | HAL_TXQ_BACKOFF_DISABLE;
141                 break;
142         case HAL_TX_QUEUE_CAB:
143                 q = pCap->halTotalQueues-2;     /* next highest priority */
144                 defqflags |= HAL_TXQ_DBA_GATED
145                        | HAL_TXQ_CBR_DIS_QEMPTY
146                        | HAL_TXQ_CBR_DIS_BEMPTY
147                        | HAL_TXQ_ARB_LOCKOUT_GLOBAL
148                        | HAL_TXQ_BACKOFF_DISABLE;
149                 break;
150         case HAL_TX_QUEUE_UAPSD:
151                 q = pCap->halTotalQueues-3;     /* nextest highest priority */
152                 if (ahp->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE) {
153                         HALDEBUG(ah, HAL_DEBUG_ANY,
154                             "%s: no available UAPSD tx queue\n", __func__);
155                         return -1;
156                 }
157                 break;
158         case HAL_TX_QUEUE_DATA:
159                 for (q = 0; q < pCap->halTotalQueues; q++)
160                         if (ahp->ah_txq[q].tqi_type == HAL_TX_QUEUE_INACTIVE)
161                                 break;
162                 if (q == pCap->halTotalQueues) {
163                         HALDEBUG(ah, HAL_DEBUG_ANY,
164                             "%s: no available tx queue\n", __func__);
165                         return -1;
166                 }
167                 break;
168         default:
169                 HALDEBUG(ah, HAL_DEBUG_ANY,
170                     "%s: bad tx queue type %u\n", __func__, type);
171                 return -1;
172         }
173
174         HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: queue %u\n", __func__, q);
175
176         qi = &ahp->ah_txq[q];
177         if (qi->tqi_type != HAL_TX_QUEUE_INACTIVE) {
178                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: tx queue %u already active\n",
179                     __func__, q);
180                 return -1;
181         }
182         OS_MEMZERO(qi, sizeof(HAL_TX_QUEUE_INFO));
183         qi->tqi_type = type;
184         if (qInfo == AH_NULL) {
185                 qi->tqi_qflags = defqflags;
186                 qi->tqi_aifs = INIT_AIFS;
187                 qi->tqi_cwmin = HAL_TXQ_USEDEFAULT;     /* NB: do at reset */
188                 qi->tqi_cwmax = INIT_CWMAX;
189                 qi->tqi_shretry = INIT_SH_RETRY;
190                 qi->tqi_lgretry = INIT_LG_RETRY;
191                 qi->tqi_physCompBuf = 0;
192         } else {
193                 qi->tqi_physCompBuf = qInfo->tqi_compBuf;
194                 (void) ar5212SetTxQueueProps(ah, q, qInfo);
195         }
196         /* NB: must be followed by ar5212ResetTxQueue */
197         return q;
198 }
199
200 /*
201  * Update the h/w interrupt registers to reflect a tx q's configuration.
202  */
203 static void
204 setTxQInterrupts(struct ath_hal *ah, HAL_TX_QUEUE_INFO *qi)
205 {
206         struct ath_hal_5212 *ahp = AH5212(ah);
207
208         HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
209             "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", __func__,
210             ahp->ah_txOkInterruptMask, ahp->ah_txErrInterruptMask,
211             ahp->ah_txDescInterruptMask, ahp->ah_txEolInterruptMask,
212             ahp->ah_txUrnInterruptMask);
213
214         OS_REG_WRITE(ah, AR_IMR_S0,
215                   SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
216                 | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC)
217         );
218         OS_REG_WRITE(ah, AR_IMR_S1,
219                   SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
220                 | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL)
221         );
222         OS_REG_RMW_FIELD(ah, AR_IMR_S2,
223                 AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
224 }
225
226 /*
227  * Free a tx DCU/QCU combination.
228  */
229 HAL_BOOL
230 ar5212ReleaseTxQueue(struct ath_hal *ah, u_int q)
231 {
232         struct ath_hal_5212 *ahp = AH5212(ah);
233         HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
234         HAL_TX_QUEUE_INFO *qi;
235
236         if (q >= pCap->halTotalQueues) {
237                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid queue num %u\n",
238                     __func__, q);
239                 return AH_FALSE;
240         }
241         qi = &ahp->ah_txq[q];
242         if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
243                 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: inactive queue %u\n",
244                     __func__, q);
245                 return AH_FALSE;
246         }
247
248         HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: release queue %u\n", __func__, q);
249
250         qi->tqi_type = HAL_TX_QUEUE_INACTIVE;
251         ahp->ah_txOkInterruptMask &= ~(1 << q);
252         ahp->ah_txErrInterruptMask &= ~(1 << q);
253         ahp->ah_txDescInterruptMask &= ~(1 << q);
254         ahp->ah_txEolInterruptMask &= ~(1 << q);
255         ahp->ah_txUrnInterruptMask &= ~(1 << q);
256         setTxQInterrupts(ah, qi);
257
258         return AH_TRUE;
259 }
260
261 /*
262  * Set the retry, aifs, cwmin/max, readyTime regs for specified queue
263  * Assumes:
264  *  phwChannel has been set to point to the current channel
265  */
266 HAL_BOOL
267 ar5212ResetTxQueue(struct ath_hal *ah, u_int q)
268 {
269         struct ath_hal_5212 *ahp = AH5212(ah);
270         HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
271         const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
272         HAL_TX_QUEUE_INFO *qi;
273         uint32_t cwMin, chanCwMin, value, qmisc, dmisc;
274
275         if (q >= pCap->halTotalQueues) {
276                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid queue num %u\n",
277                     __func__, q);
278                 return AH_FALSE;
279         }
280         qi = &ahp->ah_txq[q];
281         if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
282                 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: inactive queue %u\n",
283                     __func__, q);
284                 return AH_TRUE;         /* XXX??? */
285         }
286
287         HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: reset queue %u\n", __func__, q);
288
289         if (qi->tqi_cwmin == HAL_TXQ_USEDEFAULT) {
290                 /*
291                  * Select cwmin according to channel type.
292                  * NB: chan can be NULL during attach
293                  */
294                 if (chan && IEEE80211_IS_CHAN_B(chan))
295                         chanCwMin = INIT_CWMIN_11B;
296                 else
297                         chanCwMin = INIT_CWMIN;
298                 /* make sure that the CWmin is of the form (2^n - 1) */
299                 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1)
300                         ;
301         } else
302                 cwMin = qi->tqi_cwmin;
303
304         /* set cwMin/Max and AIFS values */
305         OS_REG_WRITE(ah, AR_DLCL_IFS(q),
306                   SM(cwMin, AR_D_LCL_IFS_CWMIN)
307                 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
308                 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
309
310         /* Set retry limit values */
311         OS_REG_WRITE(ah, AR_DRETRY_LIMIT(q), 
312                    SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
313                  | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
314                  | SM(qi->tqi_lgretry, AR_D_RETRY_LIMIT_FR_LG)
315                  | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
316         );
317
318         /* NB: always enable early termination on the QCU */
319         qmisc = AR_Q_MISC_DCU_EARLY_TERM_REQ
320               | SM(AR_Q_MISC_FSP_ASAP, AR_Q_MISC_FSP);
321
322         /* NB: always enable DCU to wait for next fragment from QCU */
323         dmisc = AR_D_MISC_FRAG_WAIT_EN;
324
325 #ifdef AH_SUPPORT_5311
326         if (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_OAHU) {
327                 /* Configure DCU to use the global sequence count */
328                 dmisc |= AR5311_D_MISC_SEQ_NUM_CONTROL;
329         }
330 #endif
331         /* multiqueue support */
332         if (qi->tqi_cbrPeriod) {
333                 OS_REG_WRITE(ah, AR_QCBRCFG(q), 
334                           SM(qi->tqi_cbrPeriod,AR_Q_CBRCFG_CBR_INTERVAL)
335                         | SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_CBR_OVF_THRESH));
336                 qmisc = (qmisc &~ AR_Q_MISC_FSP) | AR_Q_MISC_FSP_CBR;
337                 if (qi->tqi_cbrOverflowLimit)
338                         qmisc |= AR_Q_MISC_CBR_EXP_CNTR_LIMIT;
339         }
340         if (qi->tqi_readyTime) {
341                 OS_REG_WRITE(ah, AR_QRDYTIMECFG(q),
342                           SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_INT)
343                         | AR_Q_RDYTIMECFG_ENA);
344         }
345         
346         OS_REG_WRITE(ah, AR_DCHNTIME(q),
347                   SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR)
348                 | (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
349
350         if (qi->tqi_readyTime &&
351             (qi->tqi_qflags & HAL_TXQ_RDYTIME_EXP_POLICY_ENABLE))
352                 qmisc |= AR_Q_MISC_RDYTIME_EXP_POLICY;
353         if (qi->tqi_qflags & HAL_TXQ_DBA_GATED)
354                 qmisc = (qmisc &~ AR_Q_MISC_FSP) | AR_Q_MISC_FSP_DBA_GATED;
355         if (MS(qmisc, AR_Q_MISC_FSP) != AR_Q_MISC_FSP_ASAP) {
356                 /*
357                  * These are meangingful only when not scheduled asap.
358                  */
359                 if (qi->tqi_qflags & HAL_TXQ_CBR_DIS_BEMPTY)
360                         qmisc |= AR_Q_MISC_CBR_INCR_DIS0;
361                 else
362                         qmisc &= ~AR_Q_MISC_CBR_INCR_DIS0;
363                 if (qi->tqi_qflags & HAL_TXQ_CBR_DIS_QEMPTY)
364                         qmisc |= AR_Q_MISC_CBR_INCR_DIS1;
365                 else
366                         qmisc &= ~AR_Q_MISC_CBR_INCR_DIS1;
367         }
368
369         if (qi->tqi_qflags & HAL_TXQ_BACKOFF_DISABLE)
370                 dmisc |= AR_D_MISC_POST_FR_BKOFF_DIS;
371         if (qi->tqi_qflags & HAL_TXQ_FRAG_BURST_BACKOFF_ENABLE)
372                 dmisc |= AR_D_MISC_FRAG_BKOFF_EN;
373         if (qi->tqi_qflags & HAL_TXQ_ARB_LOCKOUT_GLOBAL)
374                 dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
375                             AR_D_MISC_ARB_LOCKOUT_CNTRL);
376         else if (qi->tqi_qflags & HAL_TXQ_ARB_LOCKOUT_INTRA)
377                 dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_INTRA_FR,
378                             AR_D_MISC_ARB_LOCKOUT_CNTRL);
379         if (qi->tqi_qflags & HAL_TXQ_IGNORE_VIRTCOL)
380                 dmisc |= SM(AR_D_MISC_VIR_COL_HANDLING_IGNORE,
381                             AR_D_MISC_VIR_COL_HANDLING);
382         if (qi->tqi_qflags & HAL_TXQ_SEQNUM_INC_DIS)
383                 dmisc |= AR_D_MISC_SEQ_NUM_INCR_DIS;
384
385         /*
386          * Fillin type-dependent bits.  Most of this can be
387          * removed by specifying the queue parameters in the
388          * driver; it's here for backwards compatibility.
389          */
390         switch (qi->tqi_type) {
391         case HAL_TX_QUEUE_BEACON:               /* beacon frames */
392                 qmisc |= AR_Q_MISC_FSP_DBA_GATED
393                       |  AR_Q_MISC_BEACON_USE
394                       |  AR_Q_MISC_CBR_INCR_DIS1;
395
396                 dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
397                             AR_D_MISC_ARB_LOCKOUT_CNTRL)
398                       |  AR_D_MISC_BEACON_USE
399                       |  AR_D_MISC_POST_FR_BKOFF_DIS;
400                 break;
401         case HAL_TX_QUEUE_CAB:                  /* CAB  frames */
402                 /* 
403                  * No longer Enable AR_Q_MISC_RDYTIME_EXP_POLICY,
404                  * There is an issue with the CAB Queue
405                  * not properly refreshing the Tx descriptor if
406                  * the TXE clear setting is used.
407                  */
408                 qmisc |= AR_Q_MISC_FSP_DBA_GATED
409                       |  AR_Q_MISC_CBR_INCR_DIS1
410                       |  AR_Q_MISC_CBR_INCR_DIS0;
411
412                 if (!qi->tqi_readyTime) {
413                         /*
414                          * NB: don't set default ready time if driver
415                          * has explicitly specified something.  This is
416                          * here solely for backwards compatibility.
417                          */
418                         value = (ahp->ah_beaconInterval
419                                 - (ath_hal_sw_beacon_response_time -
420                                         ath_hal_dma_beacon_response_time)
421                                 - ath_hal_additional_swba_backoff) * 1024;
422                         OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), value | AR_Q_RDYTIMECFG_ENA);
423                 }
424                 dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
425                             AR_D_MISC_ARB_LOCKOUT_CNTRL);
426                 break;
427         default:                        /* NB: silence compiler */
428                 break;
429         }
430
431         OS_REG_WRITE(ah, AR_QMISC(q), qmisc);
432         OS_REG_WRITE(ah, AR_DMISC(q), dmisc);
433
434         /* Setup compression scratchpad buffer */
435         /* 
436          * XXX: calling this asynchronously to queue operation can
437          *      cause unexpected behavior!!!
438          */
439         if (qi->tqi_physCompBuf) {
440                 HALASSERT(qi->tqi_type == HAL_TX_QUEUE_DATA ||
441                           qi->tqi_type == HAL_TX_QUEUE_UAPSD);
442                 OS_REG_WRITE(ah, AR_Q_CBBS, (80 + 2*q));
443                 OS_REG_WRITE(ah, AR_Q_CBBA, qi->tqi_physCompBuf);
444                 OS_REG_WRITE(ah, AR_Q_CBC,  HAL_COMP_BUF_MAX_SIZE/1024);
445                 OS_REG_WRITE(ah, AR_Q0_MISC + 4*q,
446                              OS_REG_READ(ah, AR_Q0_MISC + 4*q)
447                              | AR_Q_MISC_QCU_COMP_EN);
448         }
449         
450         /*
451          * Always update the secondary interrupt mask registers - this
452          * could be a new queue getting enabled in a running system or
453          * hw getting re-initialized during a reset!
454          *
455          * Since we don't differentiate between tx interrupts corresponding
456          * to individual queues - secondary tx mask regs are always unmasked;
457          * tx interrupts are enabled/disabled for all queues collectively
458          * using the primary mask reg
459          */
460         if (qi->tqi_qflags & HAL_TXQ_TXOKINT_ENABLE)
461                 ahp->ah_txOkInterruptMask |= 1 << q;
462         else
463                 ahp->ah_txOkInterruptMask &= ~(1 << q);
464         if (qi->tqi_qflags & HAL_TXQ_TXERRINT_ENABLE)
465                 ahp->ah_txErrInterruptMask |= 1 << q;
466         else
467                 ahp->ah_txErrInterruptMask &= ~(1 << q);
468         if (qi->tqi_qflags & HAL_TXQ_TXDESCINT_ENABLE)
469                 ahp->ah_txDescInterruptMask |= 1 << q;
470         else
471                 ahp->ah_txDescInterruptMask &= ~(1 << q);
472         if (qi->tqi_qflags & HAL_TXQ_TXEOLINT_ENABLE)
473                 ahp->ah_txEolInterruptMask |= 1 << q;
474         else
475                 ahp->ah_txEolInterruptMask &= ~(1 << q);
476         if (qi->tqi_qflags & HAL_TXQ_TXURNINT_ENABLE)
477                 ahp->ah_txUrnInterruptMask |= 1 << q;
478         else
479                 ahp->ah_txUrnInterruptMask &= ~(1 << q);
480         setTxQInterrupts(ah, qi);
481
482         return AH_TRUE;
483 }
484
485 /*
486  * Get the TXDP for the specified queue
487  */
488 uint32_t
489 ar5212GetTxDP(struct ath_hal *ah, u_int q)
490 {
491         HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
492         return OS_REG_READ(ah, AR_QTXDP(q));
493 }
494
495 /*
496  * Set the TxDP for the specified queue
497  */
498 HAL_BOOL
499 ar5212SetTxDP(struct ath_hal *ah, u_int q, uint32_t txdp)
500 {
501         HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
502         HALASSERT(AH5212(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE);
503
504         /*
505          * Make sure that TXE is deasserted before setting the TXDP.  If TXE
506          * is still asserted, setting TXDP will have no effect.
507          */
508         HALASSERT((OS_REG_READ(ah, AR_Q_TXE) & (1 << q)) == 0);
509
510         OS_REG_WRITE(ah, AR_QTXDP(q), txdp);
511
512         return AH_TRUE;
513 }
514
515 /*
516  * Set Transmit Enable bits for the specified queue
517  */
518 HAL_BOOL
519 ar5212StartTxDma(struct ath_hal *ah, u_int q)
520 {
521         HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
522
523         HALASSERT(AH5212(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE);
524
525         HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: queue %u\n", __func__, q);
526
527         /* Check to be sure we're not enabling a q that has its TXD bit set. */
528         HALASSERT((OS_REG_READ(ah, AR_Q_TXD) & (1 << q)) == 0);
529
530         OS_REG_WRITE(ah, AR_Q_TXE, 1 << q);
531         return AH_TRUE;
532 }
533
534 /*
535  * Return the number of pending frames or 0 if the specified
536  * queue is stopped.
537  */
538 uint32_t
539 ar5212NumTxPending(struct ath_hal *ah, u_int q)
540 {
541         uint32_t npend;
542
543         HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
544         HALASSERT(AH5212(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE);
545
546         npend = OS_REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
547         if (npend == 0) {
548                 /*
549                  * Pending frame count (PFC) can momentarily go to zero
550                  * while TXE remains asserted.  In other words a PFC of
551                  * zero is not sufficient to say that the queue has stopped.
552                  */
553                 if (OS_REG_READ(ah, AR_Q_TXE) & (1 << q))
554                         npend = 1;              /* arbitrarily return 1 */
555         }
556         return npend;
557 }
558
559 /*
560  * Stop transmit on the specified queue
561  */
562 HAL_BOOL
563 ar5212StopTxDma(struct ath_hal *ah, u_int q)
564 {
565         u_int i;
566         u_int wait;
567
568         HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
569
570         HALASSERT(AH5212(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE);
571
572         OS_REG_WRITE(ah, AR_Q_TXD, 1 << q);
573         for (i = 1000; i != 0; i--) {
574                 if (ar5212NumTxPending(ah, q) == 0)
575                         break;
576                 OS_DELAY(100);        /* XXX get actual value */
577         }
578 #ifdef AH_DEBUG
579         if (i == 0) {
580                 HALDEBUG(ah, HAL_DEBUG_ANY,
581                     "%s: queue %u DMA did not stop in 100 msec\n", __func__, q);
582                 HALDEBUG(ah, HAL_DEBUG_ANY,
583                     "%s: QSTS 0x%x Q_TXE 0x%x Q_TXD 0x%x Q_CBR 0x%x\n", __func__,
584                     OS_REG_READ(ah, AR_QSTS(q)), OS_REG_READ(ah, AR_Q_TXE),
585                     OS_REG_READ(ah, AR_Q_TXD), OS_REG_READ(ah, AR_QCBRCFG(q)));
586                 HALDEBUG(ah, HAL_DEBUG_ANY,
587                     "%s: Q_MISC 0x%x Q_RDYTIMECFG 0x%x Q_RDYTIMESHDN 0x%x\n",
588                     __func__, OS_REG_READ(ah, AR_QMISC(q)),
589                     OS_REG_READ(ah, AR_QRDYTIMECFG(q)),
590                     OS_REG_READ(ah, AR_Q_RDYTIMESHDN));
591         }
592 #endif /* AH_DEBUG */
593
594         /* 2413+ and up can kill packets at the PCU level */
595         if (ar5212NumTxPending(ah, q) &&
596             (IS_2413(ah) || IS_5413(ah) || IS_2425(ah) || IS_2417(ah))) {
597                 uint32_t tsfLow, j;
598                 
599                 HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
600                     "%s: Num of pending TX Frames %d on Q %d\n",
601                     __func__, ar5212NumTxPending(ah, q), q);
602                 
603                 /* Kill last PCU Tx Frame */
604                 /* TODO - save off and restore current values of Q1/Q2? */
605                 for (j = 0; j < 2; j++) {
606                         tsfLow = OS_REG_READ(ah, AR_TSF_L32);
607                         OS_REG_WRITE(ah, AR_QUIET2, SM(100, AR_QUIET2_QUIET_PER) |
608                                      SM(10, AR_QUIET2_QUIET_DUR));
609                         OS_REG_WRITE(ah, AR_QUIET1, AR_QUIET1_QUIET_ENABLE |
610                                      SM(tsfLow >> 10, AR_QUIET1_NEXT_QUIET));
611                         if ((OS_REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10)) {
612                                 break;
613                         }
614                         HALDEBUG(ah, HAL_DEBUG_ANY,
615                             "%s: TSF moved while trying to set quiet time "
616                             "TSF: 0x%08x\n", __func__, tsfLow);
617                         HALASSERT(j < 1); /* TSF shouldn't count twice or reg access is taking forever */
618                 }
619                 
620                 OS_REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_CHAN_IDLE);
621                 
622                 /* Allow the quiet mechanism to do its work */
623                 OS_DELAY(200);
624                 OS_REG_CLR_BIT(ah, AR_QUIET1, AR_QUIET1_QUIET_ENABLE);
625                 
626                 /* Give at least 1 millisec more to wait */
627                 wait = 100;
628                 
629                 /* Verify all transmit is dead */
630                 while (ar5212NumTxPending(ah, q)) {
631                         if ((--wait) == 0) {
632                                 HALDEBUG(ah, HAL_DEBUG_ANY,
633                                     "%s: Failed to stop Tx DMA in %d msec after killing last frame\n",
634                                     __func__, wait);
635                                 break;
636                         }
637                         OS_DELAY(10);
638                 }
639                 
640                 OS_REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_CHAN_IDLE);
641         }
642
643         OS_REG_WRITE(ah, AR_Q_TXD, 0);
644         return (i != 0);
645 }
646
647 /*
648  * Descriptor Access Functions
649  */
650
651 #define VALID_PKT_TYPES \
652         ((1<<HAL_PKT_TYPE_NORMAL)|(1<<HAL_PKT_TYPE_ATIM)|\
653          (1<<HAL_PKT_TYPE_PSPOLL)|(1<<HAL_PKT_TYPE_PROBE_RESP)|\
654          (1<<HAL_PKT_TYPE_BEACON))
655 #define isValidPktType(_t)      ((1<<(_t)) & VALID_PKT_TYPES)
656 #define VALID_TX_RATES \
657         ((1<<0x0b)|(1<<0x0f)|(1<<0x0a)|(1<<0x0e)|(1<<0x09)|(1<<0x0d)|\
658          (1<<0x08)|(1<<0x0c)|(1<<0x1b)|(1<<0x1a)|(1<<0x1e)|(1<<0x19)|\
659          (1<<0x1d)|(1<<0x18)|(1<<0x1c))
660 #define isValidTxRate(_r)       ((1<<(_r)) & VALID_TX_RATES)
661
662 HAL_BOOL
663 ar5212SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
664         u_int pktLen,
665         u_int hdrLen,
666         HAL_PKT_TYPE type,
667         u_int txPower,
668         u_int txRate0, u_int txTries0,
669         u_int keyIx,
670         u_int antMode,
671         u_int flags,
672         u_int rtsctsRate,
673         u_int rtsctsDuration,
674         u_int compicvLen,
675         u_int compivLen,
676         u_int comp)
677 {
678 #define RTSCTS  (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)
679         struct ar5212_desc *ads = AR5212DESC(ds);
680         struct ath_hal_5212 *ahp = AH5212(ah);
681
682         (void) hdrLen;
683
684         HALASSERT(txTries0 != 0);
685         HALASSERT(isValidPktType(type));
686         HALASSERT(isValidTxRate(txRate0));
687         HALASSERT((flags & RTSCTS) != RTSCTS);
688         /* XXX validate antMode */
689
690         txPower = (txPower + ahp->ah_txPowerIndexOffset );
691         if(txPower > 63)  txPower=63;
692
693         ads->ds_ctl0 = (pktLen & AR_FrameLen)
694                      | (txPower << AR_XmitPower_S)
695                      | (flags & HAL_TXDESC_VEOL ? AR_VEOL : 0)
696                      | (flags & HAL_TXDESC_CLRDMASK ? AR_ClearDestMask : 0)
697                      | SM(antMode, AR_AntModeXmit)
698                      | (flags & HAL_TXDESC_INTREQ ? AR_TxInterReq : 0)
699                      ;
700         ads->ds_ctl1 = (type << AR_FrmType_S)
701                      | (flags & HAL_TXDESC_NOACK ? AR_NoAck : 0)
702                      | (comp << AR_CompProc_S)
703                      | (compicvLen << AR_CompICVLen_S)
704                      | (compivLen << AR_CompIVLen_S)
705                      ;
706         ads->ds_ctl2 = SM(txTries0, AR_XmitDataTries0)
707                      | (flags & HAL_TXDESC_DURENA ? AR_DurUpdateEna : 0)
708                      ;
709         ads->ds_ctl3 = (txRate0 << AR_XmitRate0_S)
710                      ;
711         if (keyIx != HAL_TXKEYIX_INVALID) {
712                 /* XXX validate key index */
713                 ads->ds_ctl1 |= SM(keyIx, AR_DestIdx);
714                 ads->ds_ctl0 |= AR_DestIdxValid;
715         }
716         if (flags & RTSCTS) {
717                 if (!isValidTxRate(rtsctsRate)) {
718                         HALDEBUG(ah, HAL_DEBUG_ANY,
719                             "%s: invalid rts/cts rate 0x%x\n",
720                             __func__, rtsctsRate);
721                         return AH_FALSE;
722                 }
723                 /* XXX validate rtsctsDuration */
724                 ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0)
725                              | (flags & HAL_TXDESC_RTSENA ? AR_RTSCTSEnable : 0)
726                              ;
727                 ads->ds_ctl2 |= SM(rtsctsDuration, AR_RTSCTSDuration);
728                 ads->ds_ctl3 |= (rtsctsRate << AR_RTSCTSRate_S);
729         }
730         return AH_TRUE;
731 #undef RTSCTS
732 }
733
734 HAL_BOOL
735 ar5212SetupXTxDesc(struct ath_hal *ah, struct ath_desc *ds,
736         u_int txRate1, u_int txTries1,
737         u_int txRate2, u_int txTries2,
738         u_int txRate3, u_int txTries3)
739 {
740         struct ar5212_desc *ads = AR5212DESC(ds);
741
742         if (txTries1) {
743                 HALASSERT(isValidTxRate(txRate1));
744                 ads->ds_ctl2 |= SM(txTries1, AR_XmitDataTries1)
745                              |  AR_DurUpdateEna
746                              ;
747                 ads->ds_ctl3 |= (txRate1 << AR_XmitRate1_S);
748         }
749         if (txTries2) {
750                 HALASSERT(isValidTxRate(txRate2));
751                 ads->ds_ctl2 |= SM(txTries2, AR_XmitDataTries2)
752                              |  AR_DurUpdateEna
753                              ;
754                 ads->ds_ctl3 |= (txRate2 << AR_XmitRate2_S);
755         }
756         if (txTries3) {
757                 HALASSERT(isValidTxRate(txRate3));
758                 ads->ds_ctl2 |= SM(txTries3, AR_XmitDataTries3)
759                              |  AR_DurUpdateEna
760                              ;
761                 ads->ds_ctl3 |= (txRate3 << AR_XmitRate3_S);
762         }
763         return AH_TRUE;
764 }
765
766 void
767 ar5212IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *ds)
768 {
769         struct ar5212_desc *ads = AR5212DESC(ds);
770
771 #ifdef AH_NEED_DESC_SWAP
772         ads->ds_ctl0 |= __bswap32(AR_TxInterReq);
773 #else
774         ads->ds_ctl0 |= AR_TxInterReq;
775 #endif
776 }
777
778 HAL_BOOL
779 ar5212FillTxDesc(struct ath_hal *ah, struct ath_desc *ds,
780         u_int segLen, HAL_BOOL firstSeg, HAL_BOOL lastSeg,
781         const struct ath_desc *ds0)
782 {
783         struct ar5212_desc *ads = AR5212DESC(ds);
784
785         HALASSERT((segLen &~ AR_BufLen) == 0);
786
787         if (firstSeg) {
788                 /*
789                  * First descriptor, don't clobber xmit control data
790                  * setup by ar5212SetupTxDesc.
791                  */
792                 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_More);
793         } else if (lastSeg) {           /* !firstSeg && lastSeg */
794                 /*
795                  * Last descriptor in a multi-descriptor frame,
796                  * copy the multi-rate transmit parameters from
797                  * the first frame for processing on completion. 
798                  */
799                 ads->ds_ctl0 = 0;
800                 ads->ds_ctl1 = segLen;
801 #ifdef AH_NEED_DESC_SWAP
802                 ads->ds_ctl2 = __bswap32(AR5212DESC_CONST(ds0)->ds_ctl2);
803                 ads->ds_ctl3 = __bswap32(AR5212DESC_CONST(ds0)->ds_ctl3);
804 #else
805                 ads->ds_ctl2 = AR5212DESC_CONST(ds0)->ds_ctl2;
806                 ads->ds_ctl3 = AR5212DESC_CONST(ds0)->ds_ctl3;
807 #endif
808         } else {                        /* !firstSeg && !lastSeg */
809                 /*
810                  * Intermediate descriptor in a multi-descriptor frame.
811                  */
812                 ads->ds_ctl0 = 0;
813                 ads->ds_ctl1 = segLen | AR_More;
814                 ads->ds_ctl2 = 0;
815                 ads->ds_ctl3 = 0;
816         }
817         ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
818         return AH_TRUE;
819 }
820
821 #ifdef AH_NEED_DESC_SWAP
822 /* Swap transmit descriptor */
823 static __inline void
824 ar5212SwapTxDesc(struct ath_desc *ds)
825 {
826         ds->ds_data = __bswap32(ds->ds_data);
827         ds->ds_ctl0 = __bswap32(ds->ds_ctl0);
828         ds->ds_ctl1 = __bswap32(ds->ds_ctl1);
829         ds->ds_hw[0] = __bswap32(ds->ds_hw[0]);
830         ds->ds_hw[1] = __bswap32(ds->ds_hw[1]);
831         ds->ds_hw[2] = __bswap32(ds->ds_hw[2]);
832         ds->ds_hw[3] = __bswap32(ds->ds_hw[3]);
833 }
834 #endif
835
836 /*
837  * Processing of HW TX descriptor.
838  */
839 HAL_STATUS
840 ar5212ProcTxDesc(struct ath_hal *ah,
841         struct ath_desc *ds, struct ath_tx_status *ts)
842 {
843         struct ar5212_desc *ads = AR5212DESC(ds);
844
845 #ifdef AH_NEED_DESC_SWAP
846         if ((ads->ds_txstatus1 & __bswap32(AR_Done)) == 0)
847                 return HAL_EINPROGRESS;
848
849         ar5212SwapTxDesc(ds);
850 #else
851         if ((ads->ds_txstatus1 & AR_Done) == 0)
852                 return HAL_EINPROGRESS;
853 #endif
854
855         /* Update software copies of the HW status */
856         ts->ts_seqnum = MS(ads->ds_txstatus1, AR_SeqNum);
857         ts->ts_tstamp = MS(ads->ds_txstatus0, AR_SendTimestamp);
858         ts->ts_status = 0;
859         if ((ads->ds_txstatus0 & AR_FrmXmitOK) == 0) {
860                 if (ads->ds_txstatus0 & AR_ExcessiveRetries)
861                         ts->ts_status |= HAL_TXERR_XRETRY;
862                 if (ads->ds_txstatus0 & AR_Filtered)
863                         ts->ts_status |= HAL_TXERR_FILT;
864                 if (ads->ds_txstatus0 & AR_FIFOUnderrun)
865                         ts->ts_status |= HAL_TXERR_FIFO;
866         }
867         /*
868          * Extract the transmit rate used and mark the rate as
869          * ``alternate'' if it wasn't the series 0 rate.
870          */
871         ts->ts_finaltsi = MS(ads->ds_txstatus1, AR_FinalTSIndex);
872         switch (ts->ts_finaltsi) {
873         case 0:
874                 ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate0);
875                 break;
876         case 1:
877                 ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate1);
878                 break;
879         case 2:
880                 ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate2);
881                 break;
882         case 3:
883                 ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate3);
884                 break;
885         }
886         ts->ts_rssi = MS(ads->ds_txstatus1, AR_AckSigStrength);
887         ts->ts_shortretry = MS(ads->ds_txstatus0, AR_RTSFailCnt);
888         ts->ts_longretry = MS(ads->ds_txstatus0, AR_DataFailCnt);
889         /*
890          * The retry count has the number of un-acked tries for the
891          * final series used.  When doing multi-rate retry we must
892          * fixup the retry count by adding in the try counts for
893          * each series that was fully-processed.  Beware that this
894          * takes values from the try counts in the final descriptor.
895          * These are not required by the hardware.  We assume they
896          * are placed there by the driver as otherwise we have no
897          * access and the driver can't do the calculation because it
898          * doesn't know the descriptor format.
899          */
900         switch (ts->ts_finaltsi) {
901         case 3: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries2);
902         case 2: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries1);
903         case 1: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries0);
904         }
905         ts->ts_virtcol = MS(ads->ds_txstatus0, AR_VirtCollCnt);
906         ts->ts_antenna = (ads->ds_txstatus1 & AR_XmitAtenna ? 2 : 1);
907
908         return HAL_OK;
909 }
910
911 /*
912  * Determine which tx queues need interrupt servicing.
913  */
914 void
915 ar5212GetTxIntrQueue(struct ath_hal *ah, uint32_t *txqs)
916 {
917         struct ath_hal_5212 *ahp = AH5212(ah);
918         *txqs &= ahp->ah_intrTxqs;
919         ahp->ah_intrTxqs &= ~(*txqs);
920 }