ath9k: Use cleaner debug masks
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / ath9k / mac.c
1 /*
2  * Copyright (c) 2008 Atheros Communications Inc.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include "core.h"
18 #include "hw.h"
19 #include "reg.h"
20 #include "phy.h"
21
22 static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
23                                         struct ath9k_tx_queue_info *qi)
24 {
25         struct ath_hal_5416 *ahp = AH5416(ah);
26
27         DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
28                 "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
29                 ahp->ah_txOkInterruptMask, ahp->ah_txErrInterruptMask,
30                 ahp->ah_txDescInterruptMask, ahp->ah_txEolInterruptMask,
31                 ahp->ah_txUrnInterruptMask);
32
33         REG_WRITE(ah, AR_IMR_S0,
34                   SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
35                   | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
36         REG_WRITE(ah, AR_IMR_S1,
37                   SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
38                   | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
39         REG_RMW_FIELD(ah, AR_IMR_S2,
40                       AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
41 }
42
43 void ath9k_hw_dmaRegDump(struct ath_hal *ah)
44 {
45         u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
46         int qcuOffset = 0, dcuOffset = 0;
47         u32 *qcuBase = &val[0], *dcuBase = &val[4];
48         int i;
49
50         REG_WRITE(ah, AR_MACMISC,
51                   ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
52                    (AR_MACMISC_MISC_OBS_BUS_1 <<
53                     AR_MACMISC_MISC_OBS_BUS_MSB_S)));
54
55         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "Raw DMA Debug values:\n");
56
57         for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
58                 if (i % 4 == 0)
59                         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
60
61                 val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
62                 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "%d: %08x ", i, val[i]);
63         }
64
65         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n\n");
66         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
67                 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
68
69         for (i = 0; i < ATH9K_NUM_QUEUES;
70              i++, qcuOffset += 4, dcuOffset += 5) {
71                 if (i == 8) {
72                         qcuOffset = 0;
73                         qcuBase++;
74                 }
75
76                 if (i == 6) {
77                         dcuOffset = 0;
78                         dcuBase++;
79                 }
80
81                 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
82                         "%2d          %2x      %1x     %2x           %2x\n",
83                         i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
84                         (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
85                         val[2] & (0x7 << (i * 3)) >> (i * 3),
86                         (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
87         }
88
89         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
90         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
91                 "qcu_stitch state:   %2x    qcu_fetch state:        %2x\n",
92                 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
93         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
94                 "qcu_complete state: %2x    dcu_complete state:     %2x\n",
95                 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
96         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
97                 "dcu_arb state:      %2x    dcu_fp state:           %2x\n",
98                 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
99         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
100                 "chan_idle_dur:     %3d    chan_idle_dur_valid:     %1d\n",
101                 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
102         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
103                 "txfifo_valid_0:      %1d    txfifo_valid_1:          %1d\n",
104                 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
105         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
106                 "txfifo_dcu_num_0:   %2d    txfifo_dcu_num_1:       %2d\n",
107                 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
108
109         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "pcu observe 0x%x \n",
110                 REG_READ(ah, AR_OBS_BUS_1));
111         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
112                 "AR_CR 0x%x \n", REG_READ(ah, AR_CR));
113 }
114
115 u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
116 {
117         return REG_READ(ah, AR_QTXDP(q));
118 }
119
120 bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp)
121 {
122         REG_WRITE(ah, AR_QTXDP(q), txdp);
123
124         return true;
125 }
126
127 bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
128 {
129         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
130
131         REG_WRITE(ah, AR_Q_TXE, 1 << q);
132
133         return true;
134 }
135
136 u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
137 {
138         u32 npend;
139
140         npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
141         if (npend == 0) {
142
143                 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
144                         npend = 1;
145         }
146
147         return npend;
148 }
149
150 bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
151 {
152         struct ath_hal_5416 *ahp = AH5416(ah);
153         u32 txcfg, curLevel, newLevel;
154         enum ath9k_int omask;
155
156         if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
157                 return false;
158
159         omask = ath9k_hw_set_interrupts(ah, ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
160
161         txcfg = REG_READ(ah, AR_TXCFG);
162         curLevel = MS(txcfg, AR_FTRIG);
163         newLevel = curLevel;
164         if (bIncTrigLevel) {
165                 if (curLevel < MAX_TX_FIFO_THRESHOLD)
166                         newLevel++;
167         } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
168                 newLevel--;
169         if (newLevel != curLevel)
170                 REG_WRITE(ah, AR_TXCFG,
171                           (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
172
173         ath9k_hw_set_interrupts(ah, omask);
174
175         ah->ah_txTrigLevel = newLevel;
176
177         return newLevel != curLevel;
178 }
179
180 bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
181 {
182         u32 tsfLow, j, wait;
183
184         REG_WRITE(ah, AR_Q_TXD, 1 << q);
185
186         for (wait = 1000; wait != 0; wait--) {
187                 if (ath9k_hw_numtxpending(ah, q) == 0)
188                         break;
189                 udelay(100);
190         }
191
192         if (ath9k_hw_numtxpending(ah, q)) {
193                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
194                         "%s: Num of pending TX Frames %d on Q %d\n",
195                         __func__, ath9k_hw_numtxpending(ah, q), q);
196
197                 for (j = 0; j < 2; j++) {
198                         tsfLow = REG_READ(ah, AR_TSF_L32);
199                         REG_WRITE(ah, AR_QUIET2,
200                                   SM(10, AR_QUIET2_QUIET_DUR));
201                         REG_WRITE(ah, AR_QUIET_PERIOD, 100);
202                         REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
203                         REG_SET_BIT(ah, AR_TIMER_MODE,
204                                        AR_QUIET_TIMER_EN);
205
206                         if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
207                                 break;
208
209                         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
210                                 "TSF have moved while trying to set "
211                                 "quiet time TSF: 0x%08x\n", tsfLow);
212                 }
213
214                 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
215
216                 udelay(200);
217                 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
218
219                 wait = 1000;
220
221                 while (ath9k_hw_numtxpending(ah, q)) {
222                         if ((--wait) == 0) {
223                                 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
224                                         "Failed to stop Tx DMA in 100 "
225                                         "msec after killing last frame\n");
226                                 break;
227                         }
228                         udelay(100);
229                 }
230
231                 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
232         }
233
234         REG_WRITE(ah, AR_Q_TXD, 0);
235
236         return wait != 0;
237 }
238
239 bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
240                          u32 segLen, bool firstSeg,
241                          bool lastSeg, const struct ath_desc *ds0)
242 {
243         struct ar5416_desc *ads = AR5416DESC(ds);
244
245         if (firstSeg) {
246                 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
247         } else if (lastSeg) {
248                 ads->ds_ctl0 = 0;
249                 ads->ds_ctl1 = segLen;
250                 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
251                 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
252         } else {
253                 ads->ds_ctl0 = 0;
254                 ads->ds_ctl1 = segLen | AR_TxMore;
255                 ads->ds_ctl2 = 0;
256                 ads->ds_ctl3 = 0;
257         }
258         ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
259         ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
260         ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
261         ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
262         ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
263
264         return true;
265 }
266
267 void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
268 {
269         struct ar5416_desc *ads = AR5416DESC(ds);
270
271         ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
272         ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
273         ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
274         ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
275         ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
276 }
277
278 int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
279 {
280         struct ar5416_desc *ads = AR5416DESC(ds);
281
282         if ((ads->ds_txstatus9 & AR_TxDone) == 0)
283                 return -EINPROGRESS;
284
285         ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
286         ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
287         ds->ds_txstat.ts_status = 0;
288         ds->ds_txstat.ts_flags = 0;
289
290         if (ads->ds_txstatus1 & AR_ExcessiveRetries)
291                 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
292         if (ads->ds_txstatus1 & AR_Filtered)
293                 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
294         if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
295                 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
296                 ath9k_hw_updatetxtriglevel(ah, true);
297         }
298         if (ads->ds_txstatus9 & AR_TxOpExceeded)
299                 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
300         if (ads->ds_txstatus1 & AR_TxTimerExpired)
301                 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
302
303         if (ads->ds_txstatus1 & AR_DescCfgErr)
304                 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
305         if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
306                 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
307                 ath9k_hw_updatetxtriglevel(ah, true);
308         }
309         if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
310                 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
311                 ath9k_hw_updatetxtriglevel(ah, true);
312         }
313         if (ads->ds_txstatus0 & AR_TxBaStatus) {
314                 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
315                 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
316                 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
317         }
318
319         ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
320         switch (ds->ds_txstat.ts_rateindex) {
321         case 0:
322                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
323                 break;
324         case 1:
325                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
326                 break;
327         case 2:
328                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
329                 break;
330         case 3:
331                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
332                 break;
333         }
334
335         ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
336         ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
337         ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
338         ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
339         ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
340         ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
341         ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
342         ds->ds_txstat.evm0 = ads->AR_TxEVM0;
343         ds->ds_txstat.evm1 = ads->AR_TxEVM1;
344         ds->ds_txstat.evm2 = ads->AR_TxEVM2;
345         ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
346         ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
347         ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
348         ds->ds_txstat.ts_antenna = 1;
349
350         return 0;
351 }
352
353 void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
354                             u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
355                             u32 keyIx, enum ath9k_key_type keyType, u32 flags)
356 {
357         struct ar5416_desc *ads = AR5416DESC(ds);
358         struct ath_hal_5416 *ahp = AH5416(ah);
359
360         txPower += ahp->ah_txPowerIndexOffset;
361         if (txPower > 63)
362                 txPower = 63;
363
364         ads->ds_ctl0 = (pktLen & AR_FrameLen)
365                 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
366                 | SM(txPower, AR_XmitPower)
367                 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
368                 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
369                 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
370                 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
371
372         ads->ds_ctl1 =
373                 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
374                 | SM(type, AR_FrameType)
375                 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
376                 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
377                 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
378
379         ads->ds_ctl6 = SM(keyType, AR_EncrType);
380
381         if (AR_SREV_9285(ah)) {
382                 ads->ds_ctl8 = 0;
383                 ads->ds_ctl9 = 0;
384                 ads->ds_ctl10 = 0;
385                 ads->ds_ctl11 = 0;
386         }
387 }
388
389 void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
390                                   struct ath_desc *lastds,
391                                   u32 durUpdateEn, u32 rtsctsRate,
392                                   u32 rtsctsDuration,
393                                   struct ath9k_11n_rate_series series[],
394                                   u32 nseries, u32 flags)
395 {
396         struct ar5416_desc *ads = AR5416DESC(ds);
397         struct ar5416_desc *last_ads = AR5416DESC(lastds);
398         u32 ds_ctl0;
399
400         (void) nseries;
401         (void) rtsctsDuration;
402
403         if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
404                 ds_ctl0 = ads->ds_ctl0;
405
406                 if (flags & ATH9K_TXDESC_RTSENA) {
407                         ds_ctl0 &= ~AR_CTSEnable;
408                         ds_ctl0 |= AR_RTSEnable;
409                 } else {
410                         ds_ctl0 &= ~AR_RTSEnable;
411                         ds_ctl0 |= AR_CTSEnable;
412                 }
413
414                 ads->ds_ctl0 = ds_ctl0;
415         } else {
416                 ads->ds_ctl0 =
417                         (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
418         }
419
420         ads->ds_ctl2 = set11nTries(series, 0)
421                 | set11nTries(series, 1)
422                 | set11nTries(series, 2)
423                 | set11nTries(series, 3)
424                 | (durUpdateEn ? AR_DurUpdateEna : 0)
425                 | SM(0, AR_BurstDur);
426
427         ads->ds_ctl3 = set11nRate(series, 0)
428                 | set11nRate(series, 1)
429                 | set11nRate(series, 2)
430                 | set11nRate(series, 3);
431
432         ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
433                 | set11nPktDurRTSCTS(series, 1);
434
435         ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
436                 | set11nPktDurRTSCTS(series, 3);
437
438         ads->ds_ctl7 = set11nRateFlags(series, 0)
439                 | set11nRateFlags(series, 1)
440                 | set11nRateFlags(series, 2)
441                 | set11nRateFlags(series, 3)
442                 | SM(rtsctsRate, AR_RTSCTSRate);
443         last_ads->ds_ctl2 = ads->ds_ctl2;
444         last_ads->ds_ctl3 = ads->ds_ctl3;
445 }
446
447 void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
448                                 u32 aggrLen)
449 {
450         struct ar5416_desc *ads = AR5416DESC(ds);
451
452         ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
453         ads->ds_ctl6 &= ~AR_AggrLen;
454         ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
455 }
456
457 void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
458                                  u32 numDelims)
459 {
460         struct ar5416_desc *ads = AR5416DESC(ds);
461         unsigned int ctl6;
462
463         ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
464
465         ctl6 = ads->ds_ctl6;
466         ctl6 &= ~AR_PadDelim;
467         ctl6 |= SM(numDelims, AR_PadDelim);
468         ads->ds_ctl6 = ctl6;
469 }
470
471 void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
472 {
473         struct ar5416_desc *ads = AR5416DESC(ds);
474
475         ads->ds_ctl1 |= AR_IsAggr;
476         ads->ds_ctl1 &= ~AR_MoreAggr;
477         ads->ds_ctl6 &= ~AR_PadDelim;
478 }
479
480 void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
481 {
482         struct ar5416_desc *ads = AR5416DESC(ds);
483
484         ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
485 }
486
487 void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
488                                    u32 burstDuration)
489 {
490         struct ar5416_desc *ads = AR5416DESC(ds);
491
492         ads->ds_ctl2 &= ~AR_BurstDur;
493         ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
494 }
495
496 void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
497                                      u32 vmf)
498 {
499         struct ar5416_desc *ads = AR5416DESC(ds);
500
501         if (vmf)
502                 ads->ds_ctl0 |= AR_VirtMoreFrag;
503         else
504                 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
505 }
506
507 void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
508 {
509         struct ath_hal_5416 *ahp = AH5416(ah);
510
511         *txqs &= ahp->ah_intrTxqs;
512         ahp->ah_intrTxqs &= ~(*txqs);
513 }
514
515 bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
516                             const struct ath9k_tx_queue_info *qinfo)
517 {
518         u32 cw;
519         struct ath_hal_5416 *ahp = AH5416(ah);
520         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
521         struct ath9k_tx_queue_info *qi;
522
523         if (q >= pCap->total_queues) {
524                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
525                 return false;
526         }
527
528         qi = &ahp->ah_txq[q];
529         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
530                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
531                 return false;
532         }
533
534         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %p\n", qi);
535
536         qi->tqi_ver = qinfo->tqi_ver;
537         qi->tqi_subtype = qinfo->tqi_subtype;
538         qi->tqi_qflags = qinfo->tqi_qflags;
539         qi->tqi_priority = qinfo->tqi_priority;
540         if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
541                 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
542         else
543                 qi->tqi_aifs = INIT_AIFS;
544         if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
545                 cw = min(qinfo->tqi_cwmin, 1024U);
546                 qi->tqi_cwmin = 1;
547                 while (qi->tqi_cwmin < cw)
548                         qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
549         } else
550                 qi->tqi_cwmin = qinfo->tqi_cwmin;
551         if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
552                 cw = min(qinfo->tqi_cwmax, 1024U);
553                 qi->tqi_cwmax = 1;
554                 while (qi->tqi_cwmax < cw)
555                         qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
556         } else
557                 qi->tqi_cwmax = INIT_CWMAX;
558
559         if (qinfo->tqi_shretry != 0)
560                 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
561         else
562                 qi->tqi_shretry = INIT_SH_RETRY;
563         if (qinfo->tqi_lgretry != 0)
564                 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
565         else
566                 qi->tqi_lgretry = INIT_LG_RETRY;
567         qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
568         qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
569         qi->tqi_burstTime = qinfo->tqi_burstTime;
570         qi->tqi_readyTime = qinfo->tqi_readyTime;
571
572         switch (qinfo->tqi_subtype) {
573         case ATH9K_WME_UPSD:
574                 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
575                         qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
576                 break;
577         default:
578                 break;
579         }
580
581         return true;
582 }
583
584 bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
585                             struct ath9k_tx_queue_info *qinfo)
586 {
587         struct ath_hal_5416 *ahp = AH5416(ah);
588         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
589         struct ath9k_tx_queue_info *qi;
590
591         if (q >= pCap->total_queues) {
592                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
593                 return false;
594         }
595
596         qi = &ahp->ah_txq[q];
597         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
598                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
599                 return false;
600         }
601
602         qinfo->tqi_qflags = qi->tqi_qflags;
603         qinfo->tqi_ver = qi->tqi_ver;
604         qinfo->tqi_subtype = qi->tqi_subtype;
605         qinfo->tqi_qflags = qi->tqi_qflags;
606         qinfo->tqi_priority = qi->tqi_priority;
607         qinfo->tqi_aifs = qi->tqi_aifs;
608         qinfo->tqi_cwmin = qi->tqi_cwmin;
609         qinfo->tqi_cwmax = qi->tqi_cwmax;
610         qinfo->tqi_shretry = qi->tqi_shretry;
611         qinfo->tqi_lgretry = qi->tqi_lgretry;
612         qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
613         qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
614         qinfo->tqi_burstTime = qi->tqi_burstTime;
615         qinfo->tqi_readyTime = qi->tqi_readyTime;
616
617         return true;
618 }
619
620 int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
621                           const struct ath9k_tx_queue_info *qinfo)
622 {
623         struct ath_hal_5416 *ahp = AH5416(ah);
624         struct ath9k_tx_queue_info *qi;
625         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
626         int q;
627
628         switch (type) {
629         case ATH9K_TX_QUEUE_BEACON:
630                 q = pCap->total_queues - 1;
631                 break;
632         case ATH9K_TX_QUEUE_CAB:
633                 q = pCap->total_queues - 2;
634                 break;
635         case ATH9K_TX_QUEUE_PSPOLL:
636                 q = 1;
637                 break;
638         case ATH9K_TX_QUEUE_UAPSD:
639                 q = pCap->total_queues - 3;
640                 break;
641         case ATH9K_TX_QUEUE_DATA:
642                 for (q = 0; q < pCap->total_queues; q++)
643                         if (ahp->ah_txq[q].tqi_type ==
644                             ATH9K_TX_QUEUE_INACTIVE)
645                                 break;
646                 if (q == pCap->total_queues) {
647                         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
648                                 "no available tx queue\n");
649                         return -1;
650                 }
651                 break;
652         default:
653                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "bad tx queue type %u\n", type);
654                 return -1;
655         }
656
657         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
658
659         qi = &ahp->ah_txq[q];
660         if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
661                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
662                         "tx queue %u already active\n", q);
663                 return -1;
664         }
665         memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
666         qi->tqi_type = type;
667         if (qinfo == NULL) {
668                 qi->tqi_qflags =
669                         TXQ_FLAG_TXOKINT_ENABLE
670                         | TXQ_FLAG_TXERRINT_ENABLE
671                         | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
672                 qi->tqi_aifs = INIT_AIFS;
673                 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
674                 qi->tqi_cwmax = INIT_CWMAX;
675                 qi->tqi_shretry = INIT_SH_RETRY;
676                 qi->tqi_lgretry = INIT_LG_RETRY;
677                 qi->tqi_physCompBuf = 0;
678         } else {
679                 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
680                 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
681         }
682
683         return q;
684 }
685
686 bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
687 {
688         struct ath_hal_5416 *ahp = AH5416(ah);
689         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
690         struct ath9k_tx_queue_info *qi;
691
692         if (q >= pCap->total_queues) {
693                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
694                 return false;
695         }
696         qi = &ahp->ah_txq[q];
697         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
698                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
699                 return false;
700         }
701
702         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "release queue %u\n", q);
703
704         qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
705         ahp->ah_txOkInterruptMask &= ~(1 << q);
706         ahp->ah_txErrInterruptMask &= ~(1 << q);
707         ahp->ah_txDescInterruptMask &= ~(1 << q);
708         ahp->ah_txEolInterruptMask &= ~(1 << q);
709         ahp->ah_txUrnInterruptMask &= ~(1 << q);
710         ath9k_hw_set_txq_interrupts(ah, qi);
711
712         return true;
713 }
714
715 bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
716 {
717         struct ath_hal_5416 *ahp = AH5416(ah);
718         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
719         struct ath9k_channel *chan = ah->ah_curchan;
720         struct ath9k_tx_queue_info *qi;
721         u32 cwMin, chanCwMin, value;
722
723         if (q >= pCap->total_queues) {
724                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
725                 return false;
726         }
727
728         qi = &ahp->ah_txq[q];
729         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
730                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
731                 return true;
732         }
733
734         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "reset queue %u\n", q);
735
736         if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
737                 if (chan && IS_CHAN_B(chan))
738                         chanCwMin = INIT_CWMIN_11B;
739                 else
740                         chanCwMin = INIT_CWMIN;
741
742                 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
743         } else
744                 cwMin = qi->tqi_cwmin;
745
746         REG_WRITE(ah, AR_DLCL_IFS(q),
747                   SM(cwMin, AR_D_LCL_IFS_CWMIN) |
748                   SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
749                   SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
750
751         REG_WRITE(ah, AR_DRETRY_LIMIT(q),
752                   SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) |
753                   SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) |
754                   SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
755
756         REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
757         REG_WRITE(ah, AR_DMISC(q),
758                   AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
759
760         if (qi->tqi_cbrPeriod) {
761                 REG_WRITE(ah, AR_QCBRCFG(q),
762                           SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
763                           SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
764                 REG_WRITE(ah, AR_QMISC(q),
765                           REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR |
766                           (qi->tqi_cbrOverflowLimit ?
767                            AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
768         }
769         if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
770                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
771                           SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
772                           AR_Q_RDYTIMECFG_EN);
773         }
774
775         REG_WRITE(ah, AR_DCHNTIME(q),
776                   SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
777                   (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
778
779         if (qi->tqi_burstTime
780             && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
781                 REG_WRITE(ah, AR_QMISC(q),
782                           REG_READ(ah, AR_QMISC(q)) |
783                           AR_Q_MISC_RDYTIME_EXP_POLICY);
784
785         }
786
787         if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
788                 REG_WRITE(ah, AR_DMISC(q),
789                           REG_READ(ah, AR_DMISC(q)) |
790                           AR_D_MISC_POST_FR_BKOFF_DIS);
791         }
792         if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
793                 REG_WRITE(ah, AR_DMISC(q),
794                           REG_READ(ah, AR_DMISC(q)) |
795                           AR_D_MISC_FRAG_BKOFF_EN);
796         }
797         switch (qi->tqi_type) {
798         case ATH9K_TX_QUEUE_BEACON:
799                 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
800                           | AR_Q_MISC_FSP_DBA_GATED
801                           | AR_Q_MISC_BEACON_USE
802                           | AR_Q_MISC_CBR_INCR_DIS1);
803
804                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
805                           | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
806                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
807                           | AR_D_MISC_BEACON_USE
808                           | AR_D_MISC_POST_FR_BKOFF_DIS);
809                 break;
810         case ATH9K_TX_QUEUE_CAB:
811                 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
812                           | AR_Q_MISC_FSP_DBA_GATED
813                           | AR_Q_MISC_CBR_INCR_DIS1
814                           | AR_Q_MISC_CBR_INCR_DIS0);
815                 value = (qi->tqi_readyTime -
816                          (ah->ah_config.sw_beacon_response_time -
817                           ah->ah_config.dma_beacon_response_time) -
818                          ah->ah_config.additional_swba_backoff) * 1024;
819                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
820                           value | AR_Q_RDYTIMECFG_EN);
821                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
822                           | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
823                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
824                 break;
825         case ATH9K_TX_QUEUE_PSPOLL:
826                 REG_WRITE(ah, AR_QMISC(q),
827                           REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
828                 break;
829         case ATH9K_TX_QUEUE_UAPSD:
830                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
831                           AR_D_MISC_POST_FR_BKOFF_DIS);
832                 break;
833         default:
834                 break;
835         }
836
837         if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
838                 REG_WRITE(ah, AR_DMISC(q),
839                           REG_READ(ah, AR_DMISC(q)) |
840                           SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
841                              AR_D_MISC_ARB_LOCKOUT_CNTRL) |
842                           AR_D_MISC_POST_FR_BKOFF_DIS);
843         }
844
845         if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
846                 ahp->ah_txOkInterruptMask |= 1 << q;
847         else
848                 ahp->ah_txOkInterruptMask &= ~(1 << q);
849         if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
850                 ahp->ah_txErrInterruptMask |= 1 << q;
851         else
852                 ahp->ah_txErrInterruptMask &= ~(1 << q);
853         if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
854                 ahp->ah_txDescInterruptMask |= 1 << q;
855         else
856                 ahp->ah_txDescInterruptMask &= ~(1 << q);
857         if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
858                 ahp->ah_txEolInterruptMask |= 1 << q;
859         else
860                 ahp->ah_txEolInterruptMask &= ~(1 << q);
861         if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
862                 ahp->ah_txUrnInterruptMask |= 1 << q;
863         else
864                 ahp->ah_txUrnInterruptMask &= ~(1 << q);
865         ath9k_hw_set_txq_interrupts(ah, qi);
866
867         return true;
868 }
869
870 int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
871                         u32 pa, struct ath_desc *nds, u64 tsf)
872 {
873         struct ar5416_desc ads;
874         struct ar5416_desc *adsp = AR5416DESC(ds);
875         u32 phyerr;
876
877         if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
878                 return -EINPROGRESS;
879
880         ads.u.rx = adsp->u.rx;
881
882         ds->ds_rxstat.rs_status = 0;
883         ds->ds_rxstat.rs_flags = 0;
884
885         ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
886         ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
887
888         ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
889         ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
890         ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
891         ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
892         ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
893         ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
894         ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
895         if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
896                 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
897         else
898                 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
899
900         ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
901         ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
902
903         ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
904         ds->ds_rxstat.rs_moreaggr =
905                 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
906         ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
907         ds->ds_rxstat.rs_flags =
908                 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
909         ds->ds_rxstat.rs_flags |=
910                 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
911
912         if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
913                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
914         if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
915                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
916         if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
917                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
918
919         if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
920                 if (ads.ds_rxstatus8 & AR_CRCErr)
921                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
922                 else if (ads.ds_rxstatus8 & AR_PHYErr) {
923                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
924                         phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
925                         ds->ds_rxstat.rs_phyerr = phyerr;
926                 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
927                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
928                 else if (ads.ds_rxstatus8 & AR_MichaelErr)
929                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
930         }
931
932         return 0;
933 }
934
935 bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
936                           u32 size, u32 flags)
937 {
938         struct ar5416_desc *ads = AR5416DESC(ds);
939         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
940
941         ads->ds_ctl1 = size & AR_BufLen;
942         if (flags & ATH9K_RXDESC_INTREQ)
943                 ads->ds_ctl1 |= AR_RxIntrReq;
944
945         ads->ds_rxstatus8 &= ~AR_RxDone;
946         if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
947                 memset(&(ads->u), 0, sizeof(ads->u));
948
949         return true;
950 }
951
952 bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
953 {
954         u32 reg;
955
956         if (set) {
957                 REG_SET_BIT(ah, AR_DIAG_SW,
958                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
959
960                 if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
961                         REG_CLR_BIT(ah, AR_DIAG_SW,
962                                     (AR_DIAG_RX_DIS |
963                                      AR_DIAG_RX_ABORT));
964
965                         reg = REG_READ(ah, AR_OBS_BUS_1);
966                         DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
967                                 "rx failed to go idle in 10 ms RXSM=0x%x\n", reg);
968
969                         return false;
970                 }
971         } else {
972                 REG_CLR_BIT(ah, AR_DIAG_SW,
973                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
974         }
975
976         return true;
977 }
978
979 void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
980 {
981         REG_WRITE(ah, AR_RXDP, rxdp);
982 }
983
984 void ath9k_hw_rxena(struct ath_hal *ah)
985 {
986         REG_WRITE(ah, AR_CR, AR_CR_RXE);
987 }
988
989 void ath9k_hw_startpcureceive(struct ath_hal *ah)
990 {
991         REG_CLR_BIT(ah, AR_DIAG_SW,
992                     (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
993
994         ath9k_enable_mib_counters(ah);
995
996         ath9k_ani_reset(ah);
997 }
998
999 void ath9k_hw_stoppcurecv(struct ath_hal *ah)
1000 {
1001         REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
1002
1003         ath9k_hw_disable_mib_counters(ah);
1004 }
1005
1006 bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
1007 {
1008         REG_WRITE(ah, AR_CR, AR_CR_RXD);
1009
1010         if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
1011                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
1012                         "dma failed to stop in 10ms\n"
1013                         "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
1014                         REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
1015                 return false;
1016         } else {
1017                 return true;
1018         }
1019 }