ath9k: correct warning about unintialized variable 'tid'
[linux-2.6] / 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                 "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
29                 __func__, ahp->ah_txOkInterruptMask,
30                 ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
31                 ahp->ah_txEolInterruptMask, 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, "%s: queue %u\n", __func__, 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                                 "%s: TSF have moved while trying to set "
211                                 "quiet time TSF: 0x%08x\n",
212                                 __func__, tsfLow);
213                 }
214
215                 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
216
217                 udelay(200);
218                 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
219
220                 wait = 1000;
221
222                 while (ath9k_hw_numtxpending(ah, q)) {
223                         if ((--wait) == 0) {
224                                 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
225                                         "%s: Failed to stop Tx DMA in 100 "
226                                         "msec after killing last frame\n",
227                                         __func__);
228                                 break;
229                         }
230                         udelay(100);
231                 }
232
233                 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
234         }
235
236         REG_WRITE(ah, AR_Q_TXD, 0);
237
238         return wait != 0;
239 }
240
241 bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
242                          u32 segLen, bool firstSeg,
243                          bool lastSeg, const struct ath_desc *ds0)
244 {
245         struct ar5416_desc *ads = AR5416DESC(ds);
246
247         if (firstSeg) {
248                 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
249         } else if (lastSeg) {
250                 ads->ds_ctl0 = 0;
251                 ads->ds_ctl1 = segLen;
252                 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
253                 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
254         } else {
255                 ads->ds_ctl0 = 0;
256                 ads->ds_ctl1 = segLen | AR_TxMore;
257                 ads->ds_ctl2 = 0;
258                 ads->ds_ctl3 = 0;
259         }
260         ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
261         ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
262         ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
263         ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
264         ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
265
266         return true;
267 }
268
269 void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
270 {
271         struct ar5416_desc *ads = AR5416DESC(ds);
272
273         ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
274         ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
275         ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
276         ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
277         ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
278 }
279
280 int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
281 {
282         struct ar5416_desc *ads = AR5416DESC(ds);
283
284         if ((ads->ds_txstatus9 & AR_TxDone) == 0)
285                 return -EINPROGRESS;
286
287         ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
288         ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
289         ds->ds_txstat.ts_status = 0;
290         ds->ds_txstat.ts_flags = 0;
291
292         if (ads->ds_txstatus1 & AR_ExcessiveRetries)
293                 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
294         if (ads->ds_txstatus1 & AR_Filtered)
295                 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
296         if (ads->ds_txstatus1 & AR_FIFOUnderrun)
297                 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
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, "%s: invalid queue num %u\n",
525                          __func__, q);
526                 return false;
527         }
528
529         qi = &ahp->ah_txq[q];
530         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
531                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
532                          __func__);
533                 return false;
534         }
535
536         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
537
538         qi->tqi_ver = qinfo->tqi_ver;
539         qi->tqi_subtype = qinfo->tqi_subtype;
540         qi->tqi_qflags = qinfo->tqi_qflags;
541         qi->tqi_priority = qinfo->tqi_priority;
542         if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
543                 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
544         else
545                 qi->tqi_aifs = INIT_AIFS;
546         if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
547                 cw = min(qinfo->tqi_cwmin, 1024U);
548                 qi->tqi_cwmin = 1;
549                 while (qi->tqi_cwmin < cw)
550                         qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
551         } else
552                 qi->tqi_cwmin = qinfo->tqi_cwmin;
553         if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
554                 cw = min(qinfo->tqi_cwmax, 1024U);
555                 qi->tqi_cwmax = 1;
556                 while (qi->tqi_cwmax < cw)
557                         qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
558         } else
559                 qi->tqi_cwmax = INIT_CWMAX;
560
561         if (qinfo->tqi_shretry != 0)
562                 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
563         else
564                 qi->tqi_shretry = INIT_SH_RETRY;
565         if (qinfo->tqi_lgretry != 0)
566                 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
567         else
568                 qi->tqi_lgretry = INIT_LG_RETRY;
569         qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
570         qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
571         qi->tqi_burstTime = qinfo->tqi_burstTime;
572         qi->tqi_readyTime = qinfo->tqi_readyTime;
573
574         switch (qinfo->tqi_subtype) {
575         case ATH9K_WME_UPSD:
576                 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
577                         qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
578                 break;
579         default:
580                 break;
581         }
582
583         return true;
584 }
585
586 bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
587                             struct ath9k_tx_queue_info *qinfo)
588 {
589         struct ath_hal_5416 *ahp = AH5416(ah);
590         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
591         struct ath9k_tx_queue_info *qi;
592
593         if (q >= pCap->total_queues) {
594                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
595                          __func__, q);
596                 return false;
597         }
598
599         qi = &ahp->ah_txq[q];
600         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
601                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
602                          __func__);
603                 return false;
604         }
605
606         qinfo->tqi_qflags = qi->tqi_qflags;
607         qinfo->tqi_ver = qi->tqi_ver;
608         qinfo->tqi_subtype = qi->tqi_subtype;
609         qinfo->tqi_qflags = qi->tqi_qflags;
610         qinfo->tqi_priority = qi->tqi_priority;
611         qinfo->tqi_aifs = qi->tqi_aifs;
612         qinfo->tqi_cwmin = qi->tqi_cwmin;
613         qinfo->tqi_cwmax = qi->tqi_cwmax;
614         qinfo->tqi_shretry = qi->tqi_shretry;
615         qinfo->tqi_lgretry = qi->tqi_lgretry;
616         qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
617         qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
618         qinfo->tqi_burstTime = qi->tqi_burstTime;
619         qinfo->tqi_readyTime = qi->tqi_readyTime;
620
621         return true;
622 }
623
624 int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
625                           const struct ath9k_tx_queue_info *qinfo)
626 {
627         struct ath_hal_5416 *ahp = AH5416(ah);
628         struct ath9k_tx_queue_info *qi;
629         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
630         int q;
631
632         switch (type) {
633         case ATH9K_TX_QUEUE_BEACON:
634                 q = pCap->total_queues - 1;
635                 break;
636         case ATH9K_TX_QUEUE_CAB:
637                 q = pCap->total_queues - 2;
638                 break;
639         case ATH9K_TX_QUEUE_PSPOLL:
640                 q = 1;
641                 break;
642         case ATH9K_TX_QUEUE_UAPSD:
643                 q = pCap->total_queues - 3;
644                 break;
645         case ATH9K_TX_QUEUE_DATA:
646                 for (q = 0; q < pCap->total_queues; q++)
647                         if (ahp->ah_txq[q].tqi_type ==
648                             ATH9K_TX_QUEUE_INACTIVE)
649                                 break;
650                 if (q == pCap->total_queues) {
651                         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
652                                 "%s: no available tx queue\n", __func__);
653                         return -1;
654                 }
655                 break;
656         default:
657                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
658                         __func__, type);
659                 return -1;
660         }
661
662         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
663
664         qi = &ahp->ah_txq[q];
665         if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
666                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
667                         "%s: tx queue %u already active\n", __func__, q);
668                 return -1;
669         }
670         memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
671         qi->tqi_type = type;
672         if (qinfo == NULL) {
673                 qi->tqi_qflags =
674                         TXQ_FLAG_TXOKINT_ENABLE
675                         | TXQ_FLAG_TXERRINT_ENABLE
676                         | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
677                 qi->tqi_aifs = INIT_AIFS;
678                 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
679                 qi->tqi_cwmax = INIT_CWMAX;
680                 qi->tqi_shretry = INIT_SH_RETRY;
681                 qi->tqi_lgretry = INIT_LG_RETRY;
682                 qi->tqi_physCompBuf = 0;
683         } else {
684                 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
685                 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
686         }
687
688         return q;
689 }
690
691 bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
692 {
693         struct ath_hal_5416 *ahp = AH5416(ah);
694         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
695         struct ath9k_tx_queue_info *qi;
696
697         if (q >= pCap->total_queues) {
698                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
699                          __func__, q);
700                 return false;
701         }
702         qi = &ahp->ah_txq[q];
703         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
704                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
705                          __func__, q);
706                 return false;
707         }
708
709         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
710                 __func__, q);
711
712         qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
713         ahp->ah_txOkInterruptMask &= ~(1 << q);
714         ahp->ah_txErrInterruptMask &= ~(1 << q);
715         ahp->ah_txDescInterruptMask &= ~(1 << q);
716         ahp->ah_txEolInterruptMask &= ~(1 << q);
717         ahp->ah_txUrnInterruptMask &= ~(1 << q);
718         ath9k_hw_set_txq_interrupts(ah, qi);
719
720         return true;
721 }
722
723 bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
724 {
725         struct ath_hal_5416 *ahp = AH5416(ah);
726         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
727         struct ath9k_channel *chan = ah->ah_curchan;
728         struct ath9k_tx_queue_info *qi;
729         u32 cwMin, chanCwMin, value;
730
731         if (q >= pCap->total_queues) {
732                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
733                          __func__, q);
734                 return false;
735         }
736
737         qi = &ahp->ah_txq[q];
738         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
739                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
740                          __func__, q);
741                 return true;
742         }
743
744         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
745
746         if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
747                 if (chan && IS_CHAN_B(chan))
748                         chanCwMin = INIT_CWMIN_11B;
749                 else
750                         chanCwMin = INIT_CWMIN;
751
752                 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
753         } else
754                 cwMin = qi->tqi_cwmin;
755
756         REG_WRITE(ah, AR_DLCL_IFS(q),
757                   SM(cwMin, AR_D_LCL_IFS_CWMIN) |
758                   SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
759                   SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
760
761         REG_WRITE(ah, AR_DRETRY_LIMIT(q),
762                   SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) |
763                   SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) |
764                   SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
765
766         REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
767         REG_WRITE(ah, AR_DMISC(q),
768                   AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
769
770         if (qi->tqi_cbrPeriod) {
771                 REG_WRITE(ah, AR_QCBRCFG(q),
772                           SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
773                           SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
774                 REG_WRITE(ah, AR_QMISC(q),
775                           REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR |
776                           (qi->tqi_cbrOverflowLimit ?
777                            AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
778         }
779         if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
780                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
781                           SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
782                           AR_Q_RDYTIMECFG_EN);
783         }
784
785         REG_WRITE(ah, AR_DCHNTIME(q),
786                   SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
787                   (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
788
789         if (qi->tqi_burstTime
790             && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
791                 REG_WRITE(ah, AR_QMISC(q),
792                           REG_READ(ah, AR_QMISC(q)) |
793                           AR_Q_MISC_RDYTIME_EXP_POLICY);
794
795         }
796
797         if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
798                 REG_WRITE(ah, AR_DMISC(q),
799                           REG_READ(ah, AR_DMISC(q)) |
800                           AR_D_MISC_POST_FR_BKOFF_DIS);
801         }
802         if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
803                 REG_WRITE(ah, AR_DMISC(q),
804                           REG_READ(ah, AR_DMISC(q)) |
805                           AR_D_MISC_FRAG_BKOFF_EN);
806         }
807         switch (qi->tqi_type) {
808         case ATH9K_TX_QUEUE_BEACON:
809                 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
810                           | AR_Q_MISC_FSP_DBA_GATED
811                           | AR_Q_MISC_BEACON_USE
812                           | AR_Q_MISC_CBR_INCR_DIS1);
813
814                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
815                           | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
816                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
817                           | AR_D_MISC_BEACON_USE
818                           | AR_D_MISC_POST_FR_BKOFF_DIS);
819                 break;
820         case ATH9K_TX_QUEUE_CAB:
821                 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
822                           | AR_Q_MISC_FSP_DBA_GATED
823                           | AR_Q_MISC_CBR_INCR_DIS1
824                           | AR_Q_MISC_CBR_INCR_DIS0);
825                 value = (qi->tqi_readyTime -
826                          (ah->ah_config.sw_beacon_response_time -
827                           ah->ah_config.dma_beacon_response_time) -
828                          ah->ah_config.additional_swba_backoff) * 1024;
829                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
830                           value | AR_Q_RDYTIMECFG_EN);
831                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
832                           | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
833                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
834                 break;
835         case ATH9K_TX_QUEUE_PSPOLL:
836                 REG_WRITE(ah, AR_QMISC(q),
837                           REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
838                 break;
839         case ATH9K_TX_QUEUE_UAPSD:
840                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
841                           AR_D_MISC_POST_FR_BKOFF_DIS);
842                 break;
843         default:
844                 break;
845         }
846
847         if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
848                 REG_WRITE(ah, AR_DMISC(q),
849                           REG_READ(ah, AR_DMISC(q)) |
850                           SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
851                              AR_D_MISC_ARB_LOCKOUT_CNTRL) |
852                           AR_D_MISC_POST_FR_BKOFF_DIS);
853         }
854
855         if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
856                 ahp->ah_txOkInterruptMask |= 1 << q;
857         else
858                 ahp->ah_txOkInterruptMask &= ~(1 << q);
859         if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
860                 ahp->ah_txErrInterruptMask |= 1 << q;
861         else
862                 ahp->ah_txErrInterruptMask &= ~(1 << q);
863         if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
864                 ahp->ah_txDescInterruptMask |= 1 << q;
865         else
866                 ahp->ah_txDescInterruptMask &= ~(1 << q);
867         if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
868                 ahp->ah_txEolInterruptMask |= 1 << q;
869         else
870                 ahp->ah_txEolInterruptMask &= ~(1 << q);
871         if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
872                 ahp->ah_txUrnInterruptMask |= 1 << q;
873         else
874                 ahp->ah_txUrnInterruptMask &= ~(1 << q);
875         ath9k_hw_set_txq_interrupts(ah, qi);
876
877         return true;
878 }
879
880 int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
881                         u32 pa, struct ath_desc *nds, u64 tsf)
882 {
883         struct ar5416_desc ads;
884         struct ar5416_desc *adsp = AR5416DESC(ds);
885         u32 phyerr;
886
887         if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
888                 return -EINPROGRESS;
889
890         ads.u.rx = adsp->u.rx;
891
892         ds->ds_rxstat.rs_status = 0;
893         ds->ds_rxstat.rs_flags = 0;
894
895         ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
896         ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
897
898         ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
899         ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
900         ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
901         ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
902         ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
903         ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
904         ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
905         if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
906                 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
907         else
908                 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
909
910         ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
911         ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
912
913         ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
914         ds->ds_rxstat.rs_moreaggr =
915                 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
916         ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
917         ds->ds_rxstat.rs_flags =
918                 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
919         ds->ds_rxstat.rs_flags |=
920                 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
921
922         if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
923                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
924         if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
925                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
926         if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
927                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
928
929         if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
930                 if (ads.ds_rxstatus8 & AR_CRCErr)
931                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
932                 else if (ads.ds_rxstatus8 & AR_PHYErr) {
933                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
934                         phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
935                         ds->ds_rxstat.rs_phyerr = phyerr;
936                 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
937                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
938                 else if (ads.ds_rxstatus8 & AR_MichaelErr)
939                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
940         }
941
942         return 0;
943 }
944
945 bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
946                           u32 size, u32 flags)
947 {
948         struct ar5416_desc *ads = AR5416DESC(ds);
949         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
950
951         ads->ds_ctl1 = size & AR_BufLen;
952         if (flags & ATH9K_RXDESC_INTREQ)
953                 ads->ds_ctl1 |= AR_RxIntrReq;
954
955         ads->ds_rxstatus8 &= ~AR_RxDone;
956         if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
957                 memset(&(ads->u), 0, sizeof(ads->u));
958
959         return true;
960 }
961
962 bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
963 {
964         u32 reg;
965
966         if (set) {
967                 REG_SET_BIT(ah, AR_DIAG_SW,
968                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
969
970                 if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
971                         REG_CLR_BIT(ah, AR_DIAG_SW,
972                                     (AR_DIAG_RX_DIS |
973                                      AR_DIAG_RX_ABORT));
974
975                         reg = REG_READ(ah, AR_OBS_BUS_1);
976                         DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
977                                 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
978                                 __func__, reg);
979
980                         return false;
981                 }
982         } else {
983                 REG_CLR_BIT(ah, AR_DIAG_SW,
984                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
985         }
986
987         return true;
988 }
989
990 void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
991 {
992         REG_WRITE(ah, AR_RXDP, rxdp);
993 }
994
995 void ath9k_hw_rxena(struct ath_hal *ah)
996 {
997         REG_WRITE(ah, AR_CR, AR_CR_RXE);
998 }
999
1000 void ath9k_hw_startpcureceive(struct ath_hal *ah)
1001 {
1002         REG_CLR_BIT(ah, AR_DIAG_SW,
1003                     (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
1004
1005         ath9k_enable_mib_counters(ah);
1006
1007         ath9k_ani_reset(ah);
1008 }
1009
1010 void ath9k_hw_stoppcurecv(struct ath_hal *ah)
1011 {
1012         REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
1013
1014         ath9k_hw_disable_mib_counters(ah);
1015 }
1016
1017 bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
1018 {
1019         REG_WRITE(ah, AR_CR, AR_CR_RXD);
1020
1021         if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
1022                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
1023                         "%s: dma failed to stop in 10ms\n"
1024                         "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
1025                         __func__,
1026                         REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
1027                 return false;
1028         } else {
1029                 return true;
1030         }
1031 }