Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[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                 ath9k_hw_updatetxtriglevel(ah, true);
299         }
300         if (ads->ds_txstatus9 & AR_TxOpExceeded)
301                 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
302         if (ads->ds_txstatus1 & AR_TxTimerExpired)
303                 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
304
305         if (ads->ds_txstatus1 & AR_DescCfgErr)
306                 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
307         if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
308                 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
309                 ath9k_hw_updatetxtriglevel(ah, true);
310         }
311         if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
312                 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
313                 ath9k_hw_updatetxtriglevel(ah, true);
314         }
315         if (ads->ds_txstatus0 & AR_TxBaStatus) {
316                 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
317                 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
318                 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
319         }
320
321         ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
322         switch (ds->ds_txstat.ts_rateindex) {
323         case 0:
324                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
325                 break;
326         case 1:
327                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
328                 break;
329         case 2:
330                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
331                 break;
332         case 3:
333                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
334                 break;
335         }
336
337         ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
338         ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
339         ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
340         ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
341         ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
342         ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
343         ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
344         ds->ds_txstat.evm0 = ads->AR_TxEVM0;
345         ds->ds_txstat.evm1 = ads->AR_TxEVM1;
346         ds->ds_txstat.evm2 = ads->AR_TxEVM2;
347         ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
348         ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
349         ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
350         ds->ds_txstat.ts_antenna = 1;
351
352         return 0;
353 }
354
355 void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
356                             u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
357                             u32 keyIx, enum ath9k_key_type keyType, u32 flags)
358 {
359         struct ar5416_desc *ads = AR5416DESC(ds);
360         struct ath_hal_5416 *ahp = AH5416(ah);
361
362         txPower += ahp->ah_txPowerIndexOffset;
363         if (txPower > 63)
364                 txPower = 63;
365
366         ads->ds_ctl0 = (pktLen & AR_FrameLen)
367                 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
368                 | SM(txPower, AR_XmitPower)
369                 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
370                 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
371                 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
372                 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
373
374         ads->ds_ctl1 =
375                 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
376                 | SM(type, AR_FrameType)
377                 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
378                 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
379                 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
380
381         ads->ds_ctl6 = SM(keyType, AR_EncrType);
382
383         if (AR_SREV_9285(ah)) {
384                 ads->ds_ctl8 = 0;
385                 ads->ds_ctl9 = 0;
386                 ads->ds_ctl10 = 0;
387                 ads->ds_ctl11 = 0;
388         }
389 }
390
391 void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
392                                   struct ath_desc *lastds,
393                                   u32 durUpdateEn, u32 rtsctsRate,
394                                   u32 rtsctsDuration,
395                                   struct ath9k_11n_rate_series series[],
396                                   u32 nseries, u32 flags)
397 {
398         struct ar5416_desc *ads = AR5416DESC(ds);
399         struct ar5416_desc *last_ads = AR5416DESC(lastds);
400         u32 ds_ctl0;
401
402         (void) nseries;
403         (void) rtsctsDuration;
404
405         if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
406                 ds_ctl0 = ads->ds_ctl0;
407
408                 if (flags & ATH9K_TXDESC_RTSENA) {
409                         ds_ctl0 &= ~AR_CTSEnable;
410                         ds_ctl0 |= AR_RTSEnable;
411                 } else {
412                         ds_ctl0 &= ~AR_RTSEnable;
413                         ds_ctl0 |= AR_CTSEnable;
414                 }
415
416                 ads->ds_ctl0 = ds_ctl0;
417         } else {
418                 ads->ds_ctl0 =
419                         (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
420         }
421
422         ads->ds_ctl2 = set11nTries(series, 0)
423                 | set11nTries(series, 1)
424                 | set11nTries(series, 2)
425                 | set11nTries(series, 3)
426                 | (durUpdateEn ? AR_DurUpdateEna : 0)
427                 | SM(0, AR_BurstDur);
428
429         ads->ds_ctl3 = set11nRate(series, 0)
430                 | set11nRate(series, 1)
431                 | set11nRate(series, 2)
432                 | set11nRate(series, 3);
433
434         ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
435                 | set11nPktDurRTSCTS(series, 1);
436
437         ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
438                 | set11nPktDurRTSCTS(series, 3);
439
440         ads->ds_ctl7 = set11nRateFlags(series, 0)
441                 | set11nRateFlags(series, 1)
442                 | set11nRateFlags(series, 2)
443                 | set11nRateFlags(series, 3)
444                 | SM(rtsctsRate, AR_RTSCTSRate);
445         last_ads->ds_ctl2 = ads->ds_ctl2;
446         last_ads->ds_ctl3 = ads->ds_ctl3;
447 }
448
449 void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
450                                 u32 aggrLen)
451 {
452         struct ar5416_desc *ads = AR5416DESC(ds);
453
454         ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
455         ads->ds_ctl6 &= ~AR_AggrLen;
456         ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
457 }
458
459 void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
460                                  u32 numDelims)
461 {
462         struct ar5416_desc *ads = AR5416DESC(ds);
463         unsigned int ctl6;
464
465         ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
466
467         ctl6 = ads->ds_ctl6;
468         ctl6 &= ~AR_PadDelim;
469         ctl6 |= SM(numDelims, AR_PadDelim);
470         ads->ds_ctl6 = ctl6;
471 }
472
473 void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
474 {
475         struct ar5416_desc *ads = AR5416DESC(ds);
476
477         ads->ds_ctl1 |= AR_IsAggr;
478         ads->ds_ctl1 &= ~AR_MoreAggr;
479         ads->ds_ctl6 &= ~AR_PadDelim;
480 }
481
482 void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
483 {
484         struct ar5416_desc *ads = AR5416DESC(ds);
485
486         ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
487 }
488
489 void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
490                                    u32 burstDuration)
491 {
492         struct ar5416_desc *ads = AR5416DESC(ds);
493
494         ads->ds_ctl2 &= ~AR_BurstDur;
495         ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
496 }
497
498 void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
499                                      u32 vmf)
500 {
501         struct ar5416_desc *ads = AR5416DESC(ds);
502
503         if (vmf)
504                 ads->ds_ctl0 |= AR_VirtMoreFrag;
505         else
506                 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
507 }
508
509 void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
510 {
511         struct ath_hal_5416 *ahp = AH5416(ah);
512
513         *txqs &= ahp->ah_intrTxqs;
514         ahp->ah_intrTxqs &= ~(*txqs);
515 }
516
517 bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
518                             const struct ath9k_tx_queue_info *qinfo)
519 {
520         u32 cw;
521         struct ath_hal_5416 *ahp = AH5416(ah);
522         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
523         struct ath9k_tx_queue_info *qi;
524
525         if (q >= pCap->total_queues) {
526                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
527                          __func__, q);
528                 return false;
529         }
530
531         qi = &ahp->ah_txq[q];
532         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
533                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
534                          __func__);
535                 return false;
536         }
537
538         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
539
540         qi->tqi_ver = qinfo->tqi_ver;
541         qi->tqi_subtype = qinfo->tqi_subtype;
542         qi->tqi_qflags = qinfo->tqi_qflags;
543         qi->tqi_priority = qinfo->tqi_priority;
544         if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
545                 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
546         else
547                 qi->tqi_aifs = INIT_AIFS;
548         if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
549                 cw = min(qinfo->tqi_cwmin, 1024U);
550                 qi->tqi_cwmin = 1;
551                 while (qi->tqi_cwmin < cw)
552                         qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
553         } else
554                 qi->tqi_cwmin = qinfo->tqi_cwmin;
555         if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
556                 cw = min(qinfo->tqi_cwmax, 1024U);
557                 qi->tqi_cwmax = 1;
558                 while (qi->tqi_cwmax < cw)
559                         qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
560         } else
561                 qi->tqi_cwmax = INIT_CWMAX;
562
563         if (qinfo->tqi_shretry != 0)
564                 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
565         else
566                 qi->tqi_shretry = INIT_SH_RETRY;
567         if (qinfo->tqi_lgretry != 0)
568                 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
569         else
570                 qi->tqi_lgretry = INIT_LG_RETRY;
571         qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
572         qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
573         qi->tqi_burstTime = qinfo->tqi_burstTime;
574         qi->tqi_readyTime = qinfo->tqi_readyTime;
575
576         switch (qinfo->tqi_subtype) {
577         case ATH9K_WME_UPSD:
578                 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
579                         qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
580                 break;
581         default:
582                 break;
583         }
584
585         return true;
586 }
587
588 bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
589                             struct ath9k_tx_queue_info *qinfo)
590 {
591         struct ath_hal_5416 *ahp = AH5416(ah);
592         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
593         struct ath9k_tx_queue_info *qi;
594
595         if (q >= pCap->total_queues) {
596                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
597                          __func__, q);
598                 return false;
599         }
600
601         qi = &ahp->ah_txq[q];
602         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
603                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
604                          __func__);
605                 return false;
606         }
607
608         qinfo->tqi_qflags = qi->tqi_qflags;
609         qinfo->tqi_ver = qi->tqi_ver;
610         qinfo->tqi_subtype = qi->tqi_subtype;
611         qinfo->tqi_qflags = qi->tqi_qflags;
612         qinfo->tqi_priority = qi->tqi_priority;
613         qinfo->tqi_aifs = qi->tqi_aifs;
614         qinfo->tqi_cwmin = qi->tqi_cwmin;
615         qinfo->tqi_cwmax = qi->tqi_cwmax;
616         qinfo->tqi_shretry = qi->tqi_shretry;
617         qinfo->tqi_lgretry = qi->tqi_lgretry;
618         qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
619         qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
620         qinfo->tqi_burstTime = qi->tqi_burstTime;
621         qinfo->tqi_readyTime = qi->tqi_readyTime;
622
623         return true;
624 }
625
626 int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
627                           const struct ath9k_tx_queue_info *qinfo)
628 {
629         struct ath_hal_5416 *ahp = AH5416(ah);
630         struct ath9k_tx_queue_info *qi;
631         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
632         int q;
633
634         switch (type) {
635         case ATH9K_TX_QUEUE_BEACON:
636                 q = pCap->total_queues - 1;
637                 break;
638         case ATH9K_TX_QUEUE_CAB:
639                 q = pCap->total_queues - 2;
640                 break;
641         case ATH9K_TX_QUEUE_PSPOLL:
642                 q = 1;
643                 break;
644         case ATH9K_TX_QUEUE_UAPSD:
645                 q = pCap->total_queues - 3;
646                 break;
647         case ATH9K_TX_QUEUE_DATA:
648                 for (q = 0; q < pCap->total_queues; q++)
649                         if (ahp->ah_txq[q].tqi_type ==
650                             ATH9K_TX_QUEUE_INACTIVE)
651                                 break;
652                 if (q == pCap->total_queues) {
653                         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
654                                 "%s: no available tx queue\n", __func__);
655                         return -1;
656                 }
657                 break;
658         default:
659                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
660                         __func__, type);
661                 return -1;
662         }
663
664         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
665
666         qi = &ahp->ah_txq[q];
667         if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
668                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
669                         "%s: tx queue %u already active\n", __func__, q);
670                 return -1;
671         }
672         memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
673         qi->tqi_type = type;
674         if (qinfo == NULL) {
675                 qi->tqi_qflags =
676                         TXQ_FLAG_TXOKINT_ENABLE
677                         | TXQ_FLAG_TXERRINT_ENABLE
678                         | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
679                 qi->tqi_aifs = INIT_AIFS;
680                 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
681                 qi->tqi_cwmax = INIT_CWMAX;
682                 qi->tqi_shretry = INIT_SH_RETRY;
683                 qi->tqi_lgretry = INIT_LG_RETRY;
684                 qi->tqi_physCompBuf = 0;
685         } else {
686                 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
687                 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
688         }
689
690         return q;
691 }
692
693 bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
694 {
695         struct ath_hal_5416 *ahp = AH5416(ah);
696         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
697         struct ath9k_tx_queue_info *qi;
698
699         if (q >= pCap->total_queues) {
700                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
701                          __func__, q);
702                 return false;
703         }
704         qi = &ahp->ah_txq[q];
705         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
706                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
707                          __func__, q);
708                 return false;
709         }
710
711         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
712                 __func__, q);
713
714         qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
715         ahp->ah_txOkInterruptMask &= ~(1 << q);
716         ahp->ah_txErrInterruptMask &= ~(1 << q);
717         ahp->ah_txDescInterruptMask &= ~(1 << q);
718         ahp->ah_txEolInterruptMask &= ~(1 << q);
719         ahp->ah_txUrnInterruptMask &= ~(1 << q);
720         ath9k_hw_set_txq_interrupts(ah, qi);
721
722         return true;
723 }
724
725 bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
726 {
727         struct ath_hal_5416 *ahp = AH5416(ah);
728         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
729         struct ath9k_channel *chan = ah->ah_curchan;
730         struct ath9k_tx_queue_info *qi;
731         u32 cwMin, chanCwMin, value;
732
733         if (q >= pCap->total_queues) {
734                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
735                          __func__, q);
736                 return false;
737         }
738
739         qi = &ahp->ah_txq[q];
740         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
741                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
742                          __func__, q);
743                 return true;
744         }
745
746         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
747
748         if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
749                 if (chan && IS_CHAN_B(chan))
750                         chanCwMin = INIT_CWMIN_11B;
751                 else
752                         chanCwMin = INIT_CWMIN;
753
754                 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
755         } else
756                 cwMin = qi->tqi_cwmin;
757
758         REG_WRITE(ah, AR_DLCL_IFS(q),
759                   SM(cwMin, AR_D_LCL_IFS_CWMIN) |
760                   SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
761                   SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
762
763         REG_WRITE(ah, AR_DRETRY_LIMIT(q),
764                   SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) |
765                   SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) |
766                   SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
767
768         REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
769         REG_WRITE(ah, AR_DMISC(q),
770                   AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
771
772         if (qi->tqi_cbrPeriod) {
773                 REG_WRITE(ah, AR_QCBRCFG(q),
774                           SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
775                           SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
776                 REG_WRITE(ah, AR_QMISC(q),
777                           REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR |
778                           (qi->tqi_cbrOverflowLimit ?
779                            AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
780         }
781         if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
782                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
783                           SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
784                           AR_Q_RDYTIMECFG_EN);
785         }
786
787         REG_WRITE(ah, AR_DCHNTIME(q),
788                   SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
789                   (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
790
791         if (qi->tqi_burstTime
792             && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
793                 REG_WRITE(ah, AR_QMISC(q),
794                           REG_READ(ah, AR_QMISC(q)) |
795                           AR_Q_MISC_RDYTIME_EXP_POLICY);
796
797         }
798
799         if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
800                 REG_WRITE(ah, AR_DMISC(q),
801                           REG_READ(ah, AR_DMISC(q)) |
802                           AR_D_MISC_POST_FR_BKOFF_DIS);
803         }
804         if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
805                 REG_WRITE(ah, AR_DMISC(q),
806                           REG_READ(ah, AR_DMISC(q)) |
807                           AR_D_MISC_FRAG_BKOFF_EN);
808         }
809         switch (qi->tqi_type) {
810         case ATH9K_TX_QUEUE_BEACON:
811                 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
812                           | AR_Q_MISC_FSP_DBA_GATED
813                           | AR_Q_MISC_BEACON_USE
814                           | AR_Q_MISC_CBR_INCR_DIS1);
815
816                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
817                           | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
818                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
819                           | AR_D_MISC_BEACON_USE
820                           | AR_D_MISC_POST_FR_BKOFF_DIS);
821                 break;
822         case ATH9K_TX_QUEUE_CAB:
823                 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
824                           | AR_Q_MISC_FSP_DBA_GATED
825                           | AR_Q_MISC_CBR_INCR_DIS1
826                           | AR_Q_MISC_CBR_INCR_DIS0);
827                 value = (qi->tqi_readyTime -
828                          (ah->ah_config.sw_beacon_response_time -
829                           ah->ah_config.dma_beacon_response_time) -
830                          ah->ah_config.additional_swba_backoff) * 1024;
831                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
832                           value | AR_Q_RDYTIMECFG_EN);
833                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
834                           | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
835                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
836                 break;
837         case ATH9K_TX_QUEUE_PSPOLL:
838                 REG_WRITE(ah, AR_QMISC(q),
839                           REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
840                 break;
841         case ATH9K_TX_QUEUE_UAPSD:
842                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
843                           AR_D_MISC_POST_FR_BKOFF_DIS);
844                 break;
845         default:
846                 break;
847         }
848
849         if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
850                 REG_WRITE(ah, AR_DMISC(q),
851                           REG_READ(ah, AR_DMISC(q)) |
852                           SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
853                              AR_D_MISC_ARB_LOCKOUT_CNTRL) |
854                           AR_D_MISC_POST_FR_BKOFF_DIS);
855         }
856
857         if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
858                 ahp->ah_txOkInterruptMask |= 1 << q;
859         else
860                 ahp->ah_txOkInterruptMask &= ~(1 << q);
861         if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
862                 ahp->ah_txErrInterruptMask |= 1 << q;
863         else
864                 ahp->ah_txErrInterruptMask &= ~(1 << q);
865         if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
866                 ahp->ah_txDescInterruptMask |= 1 << q;
867         else
868                 ahp->ah_txDescInterruptMask &= ~(1 << q);
869         if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
870                 ahp->ah_txEolInterruptMask |= 1 << q;
871         else
872                 ahp->ah_txEolInterruptMask &= ~(1 << q);
873         if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
874                 ahp->ah_txUrnInterruptMask |= 1 << q;
875         else
876                 ahp->ah_txUrnInterruptMask &= ~(1 << q);
877         ath9k_hw_set_txq_interrupts(ah, qi);
878
879         return true;
880 }
881
882 int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
883                         u32 pa, struct ath_desc *nds, u64 tsf)
884 {
885         struct ar5416_desc ads;
886         struct ar5416_desc *adsp = AR5416DESC(ds);
887         u32 phyerr;
888
889         if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
890                 return -EINPROGRESS;
891
892         ads.u.rx = adsp->u.rx;
893
894         ds->ds_rxstat.rs_status = 0;
895         ds->ds_rxstat.rs_flags = 0;
896
897         ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
898         ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
899
900         ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
901         ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
902         ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
903         ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
904         ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
905         ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
906         ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
907         if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
908                 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
909         else
910                 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
911
912         ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
913         ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
914
915         ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
916         ds->ds_rxstat.rs_moreaggr =
917                 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
918         ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
919         ds->ds_rxstat.rs_flags =
920                 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
921         ds->ds_rxstat.rs_flags |=
922                 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
923
924         if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
925                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
926         if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
927                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
928         if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
929                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
930
931         if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
932                 if (ads.ds_rxstatus8 & AR_CRCErr)
933                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
934                 else if (ads.ds_rxstatus8 & AR_PHYErr) {
935                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
936                         phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
937                         ds->ds_rxstat.rs_phyerr = phyerr;
938                 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
939                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
940                 else if (ads.ds_rxstatus8 & AR_MichaelErr)
941                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
942         }
943
944         return 0;
945 }
946
947 bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
948                           u32 size, u32 flags)
949 {
950         struct ar5416_desc *ads = AR5416DESC(ds);
951         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
952
953         ads->ds_ctl1 = size & AR_BufLen;
954         if (flags & ATH9K_RXDESC_INTREQ)
955                 ads->ds_ctl1 |= AR_RxIntrReq;
956
957         ads->ds_rxstatus8 &= ~AR_RxDone;
958         if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
959                 memset(&(ads->u), 0, sizeof(ads->u));
960
961         return true;
962 }
963
964 bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
965 {
966         u32 reg;
967
968         if (set) {
969                 REG_SET_BIT(ah, AR_DIAG_SW,
970                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
971
972                 if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
973                         REG_CLR_BIT(ah, AR_DIAG_SW,
974                                     (AR_DIAG_RX_DIS |
975                                      AR_DIAG_RX_ABORT));
976
977                         reg = REG_READ(ah, AR_OBS_BUS_1);
978                         DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
979                                 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
980                                 __func__, reg);
981
982                         return false;
983                 }
984         } else {
985                 REG_CLR_BIT(ah, AR_DIAG_SW,
986                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
987         }
988
989         return true;
990 }
991
992 void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
993 {
994         REG_WRITE(ah, AR_RXDP, rxdp);
995 }
996
997 void ath9k_hw_rxena(struct ath_hal *ah)
998 {
999         REG_WRITE(ah, AR_CR, AR_CR_RXE);
1000 }
1001
1002 void ath9k_hw_startpcureceive(struct ath_hal *ah)
1003 {
1004         REG_CLR_BIT(ah, AR_DIAG_SW,
1005                     (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
1006
1007         ath9k_enable_mib_counters(ah);
1008
1009         ath9k_ani_reset(ah);
1010 }
1011
1012 void ath9k_hw_stoppcurecv(struct ath_hal *ah)
1013 {
1014         REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
1015
1016         ath9k_hw_disable_mib_counters(ah);
1017 }
1018
1019 bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
1020 {
1021         REG_WRITE(ah, AR_CR, AR_CR_RXD);
1022
1023         if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
1024                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
1025                         "%s: dma failed to stop in 10ms\n"
1026                         "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
1027                         __func__,
1028                         REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
1029                 return false;
1030         } else {
1031                 return true;
1032         }
1033 }