]> Pileus Git - ~andy/linux/blob - drivers/net/wireless/ath/ath9k/mac.c
ath9k: never read from the AR_IMR_S2 register
[~andy/linux] / drivers / net / wireless / ath / ath9k / mac.c
1 /*
2  * Copyright (c) 2008-2009 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 "hw.h"
18
19 static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
20                                         struct ath9k_tx_queue_info *qi)
21 {
22         ath_print(ath9k_hw_common(ah), ATH_DBG_INTERRUPT,
23                   "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
24                   ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
25                   ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
26                   ah->txurn_interrupt_mask);
27
28         REG_WRITE(ah, AR_IMR_S0,
29                   SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
30                   | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
31         REG_WRITE(ah, AR_IMR_S1,
32                   SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
33                   | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
34
35         ah->imrs2_reg &= ~AR_IMR_S2_QCU_TXURN;
36         ah->imrs2_reg |= (ah->txurn_interrupt_mask & AR_IMR_S2_QCU_TXURN);
37         REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
38 }
39
40 u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
41 {
42         return REG_READ(ah, AR_QTXDP(q));
43 }
44 EXPORT_SYMBOL(ath9k_hw_gettxbuf);
45
46 void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
47 {
48         REG_WRITE(ah, AR_QTXDP(q), txdp);
49 }
50 EXPORT_SYMBOL(ath9k_hw_puttxbuf);
51
52 void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
53 {
54         ath_print(ath9k_hw_common(ah), ATH_DBG_QUEUE,
55                   "Enable TXE on queue: %u\n", q);
56         REG_WRITE(ah, AR_Q_TXE, 1 << q);
57 }
58 EXPORT_SYMBOL(ath9k_hw_txstart);
59
60 u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
61 {
62         u32 npend;
63
64         npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
65         if (npend == 0) {
66
67                 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
68                         npend = 1;
69         }
70
71         return npend;
72 }
73 EXPORT_SYMBOL(ath9k_hw_numtxpending);
74
75 /**
76  * ath9k_hw_updatetxtriglevel - adjusts the frame trigger level
77  *
78  * @ah: atheros hardware struct
79  * @bIncTrigLevel: whether or not the frame trigger level should be updated
80  *
81  * The frame trigger level specifies the minimum number of bytes,
82  * in units of 64 bytes, that must be DMA'ed into the PCU TX FIFO
83  * before the PCU will initiate sending the frame on the air. This can
84  * mean we initiate transmit before a full frame is on the PCU TX FIFO.
85  * Resets to 0x1 (meaning 64 bytes or a full frame, whichever occurs
86  * first)
87  *
88  * Caution must be taken to ensure to set the frame trigger level based
89  * on the DMA request size. For example if the DMA request size is set to
90  * 128 bytes the trigger level cannot exceed 6 * 64 = 384. This is because
91  * there need to be enough space in the tx FIFO for the requested transfer
92  * size. Hence the tx FIFO will stop with 512 - 128 = 384 bytes. If we set
93  * the threshold to a value beyond 6, then the transmit will hang.
94  *
95  * Current dual   stream devices have a PCU TX FIFO size of 8 KB.
96  * Current single stream devices have a PCU TX FIFO size of 4 KB, however,
97  * there is a hardware issue which forces us to use 2 KB instead so the
98  * frame trigger level must not exceed 2 KB for these chipsets.
99  */
100 bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
101 {
102         u32 txcfg, curLevel, newLevel;
103         enum ath9k_int omask;
104
105         if (ah->tx_trig_level >= ah->config.max_txtrig_level)
106                 return false;
107
108         omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL);
109
110         txcfg = REG_READ(ah, AR_TXCFG);
111         curLevel = MS(txcfg, AR_FTRIG);
112         newLevel = curLevel;
113         if (bIncTrigLevel) {
114                 if (curLevel < ah->config.max_txtrig_level)
115                         newLevel++;
116         } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
117                 newLevel--;
118         if (newLevel != curLevel)
119                 REG_WRITE(ah, AR_TXCFG,
120                           (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
121
122         ath9k_hw_set_interrupts(ah, omask);
123
124         ah->tx_trig_level = newLevel;
125
126         return newLevel != curLevel;
127 }
128 EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel);
129
130 bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
131 {
132 #define ATH9K_TX_STOP_DMA_TIMEOUT       4000    /* usec */
133 #define ATH9K_TIME_QUANTUM              100     /* usec */
134         struct ath_common *common = ath9k_hw_common(ah);
135         struct ath9k_hw_capabilities *pCap = &ah->caps;
136         struct ath9k_tx_queue_info *qi;
137         u32 tsfLow, j, wait;
138         u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
139
140         if (q >= pCap->total_queues) {
141                 ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
142                           "invalid queue: %u\n", q);
143                 return false;
144         }
145
146         qi = &ah->txq[q];
147         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
148                 ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
149                           "inactive queue: %u\n", q);
150                 return false;
151         }
152
153         REG_WRITE(ah, AR_Q_TXD, 1 << q);
154
155         for (wait = wait_time; wait != 0; wait--) {
156                 if (ath9k_hw_numtxpending(ah, q) == 0)
157                         break;
158                 udelay(ATH9K_TIME_QUANTUM);
159         }
160
161         if (ath9k_hw_numtxpending(ah, q)) {
162                 ath_print(common, ATH_DBG_QUEUE,
163                           "%s: Num of pending TX Frames %d on Q %d\n",
164                           __func__, ath9k_hw_numtxpending(ah, q), q);
165
166                 for (j = 0; j < 2; j++) {
167                         tsfLow = REG_READ(ah, AR_TSF_L32);
168                         REG_WRITE(ah, AR_QUIET2,
169                                   SM(10, AR_QUIET2_QUIET_DUR));
170                         REG_WRITE(ah, AR_QUIET_PERIOD, 100);
171                         REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
172                         REG_SET_BIT(ah, AR_TIMER_MODE,
173                                        AR_QUIET_TIMER_EN);
174
175                         if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
176                                 break;
177
178                         ath_print(common, ATH_DBG_QUEUE,
179                                   "TSF has moved while trying to set "
180                                   "quiet time TSF: 0x%08x\n", tsfLow);
181                 }
182
183                 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
184
185                 udelay(200);
186                 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
187
188                 wait = wait_time;
189                 while (ath9k_hw_numtxpending(ah, q)) {
190                         if ((--wait) == 0) {
191                                 ath_print(common, ATH_DBG_FATAL,
192                                           "Failed to stop TX DMA in 100 "
193                                           "msec after killing last frame\n");
194                                 break;
195                         }
196                         udelay(ATH9K_TIME_QUANTUM);
197                 }
198
199                 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
200         }
201
202         REG_WRITE(ah, AR_Q_TXD, 0);
203         return wait != 0;
204
205 #undef ATH9K_TX_STOP_DMA_TIMEOUT
206 #undef ATH9K_TIME_QUANTUM
207 }
208 EXPORT_SYMBOL(ath9k_hw_stoptxdma);
209
210 void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
211                          u32 segLen, bool firstSeg,
212                          bool lastSeg, const struct ath_desc *ds0)
213 {
214         struct ar5416_desc *ads = AR5416DESC(ds);
215
216         if (firstSeg) {
217                 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
218         } else if (lastSeg) {
219                 ads->ds_ctl0 = 0;
220                 ads->ds_ctl1 = segLen;
221                 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
222                 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
223         } else {
224                 ads->ds_ctl0 = 0;
225                 ads->ds_ctl1 = segLen | AR_TxMore;
226                 ads->ds_ctl2 = 0;
227                 ads->ds_ctl3 = 0;
228         }
229         ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
230         ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
231         ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
232         ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
233         ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
234 }
235 EXPORT_SYMBOL(ath9k_hw_filltxdesc);
236
237 void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
238 {
239         struct ar5416_desc *ads = AR5416DESC(ds);
240
241         ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
242         ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
243         ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
244         ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
245         ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
246 }
247 EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
248
249 int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
250 {
251         struct ar5416_desc *ads = AR5416DESC(ds);
252
253         if ((ads->ds_txstatus9 & AR_TxDone) == 0)
254                 return -EINPROGRESS;
255
256         ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
257         ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
258         ds->ds_txstat.ts_status = 0;
259         ds->ds_txstat.ts_flags = 0;
260
261         if (ads->ds_txstatus1 & AR_FrmXmitOK)
262                 ds->ds_txstat.ts_status |= ATH9K_TX_ACKED;
263         if (ads->ds_txstatus1 & AR_ExcessiveRetries)
264                 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
265         if (ads->ds_txstatus1 & AR_Filtered)
266                 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
267         if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
268                 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
269                 ath9k_hw_updatetxtriglevel(ah, true);
270         }
271         if (ads->ds_txstatus9 & AR_TxOpExceeded)
272                 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
273         if (ads->ds_txstatus1 & AR_TxTimerExpired)
274                 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
275
276         if (ads->ds_txstatus1 & AR_DescCfgErr)
277                 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
278         if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
279                 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
280                 ath9k_hw_updatetxtriglevel(ah, true);
281         }
282         if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
283                 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
284                 ath9k_hw_updatetxtriglevel(ah, true);
285         }
286         if (ads->ds_txstatus0 & AR_TxBaStatus) {
287                 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
288                 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
289                 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
290         }
291
292         ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
293         switch (ds->ds_txstat.ts_rateindex) {
294         case 0:
295                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
296                 break;
297         case 1:
298                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
299                 break;
300         case 2:
301                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
302                 break;
303         case 3:
304                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
305                 break;
306         }
307
308         ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
309         ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
310         ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
311         ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
312         ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
313         ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
314         ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
315         ds->ds_txstat.evm0 = ads->AR_TxEVM0;
316         ds->ds_txstat.evm1 = ads->AR_TxEVM1;
317         ds->ds_txstat.evm2 = ads->AR_TxEVM2;
318         ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
319         ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
320         ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
321         ds->ds_txstat.ts_antenna = 0;
322
323         return 0;
324 }
325 EXPORT_SYMBOL(ath9k_hw_txprocdesc);
326
327 void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
328                             u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
329                             u32 keyIx, enum ath9k_key_type keyType, u32 flags)
330 {
331         struct ar5416_desc *ads = AR5416DESC(ds);
332
333         txPower += ah->txpower_indexoffset;
334         if (txPower > 63)
335                 txPower = 63;
336
337         ads->ds_ctl0 = (pktLen & AR_FrameLen)
338                 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
339                 | SM(txPower, AR_XmitPower)
340                 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
341                 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
342                 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
343                 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
344
345         ads->ds_ctl1 =
346                 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
347                 | SM(type, AR_FrameType)
348                 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
349                 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
350                 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
351
352         ads->ds_ctl6 = SM(keyType, AR_EncrType);
353
354         if (AR_SREV_9285(ah)) {
355                 ads->ds_ctl8 = 0;
356                 ads->ds_ctl9 = 0;
357                 ads->ds_ctl10 = 0;
358                 ads->ds_ctl11 = 0;
359         }
360 }
361 EXPORT_SYMBOL(ath9k_hw_set11n_txdesc);
362
363 void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
364                                   struct ath_desc *lastds,
365                                   u32 durUpdateEn, u32 rtsctsRate,
366                                   u32 rtsctsDuration,
367                                   struct ath9k_11n_rate_series series[],
368                                   u32 nseries, u32 flags)
369 {
370         struct ar5416_desc *ads = AR5416DESC(ds);
371         struct ar5416_desc *last_ads = AR5416DESC(lastds);
372         u32 ds_ctl0;
373
374         if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
375                 ds_ctl0 = ads->ds_ctl0;
376
377                 if (flags & ATH9K_TXDESC_RTSENA) {
378                         ds_ctl0 &= ~AR_CTSEnable;
379                         ds_ctl0 |= AR_RTSEnable;
380                 } else {
381                         ds_ctl0 &= ~AR_RTSEnable;
382                         ds_ctl0 |= AR_CTSEnable;
383                 }
384
385                 ads->ds_ctl0 = ds_ctl0;
386         } else {
387                 ads->ds_ctl0 =
388                         (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
389         }
390
391         ads->ds_ctl2 = set11nTries(series, 0)
392                 | set11nTries(series, 1)
393                 | set11nTries(series, 2)
394                 | set11nTries(series, 3)
395                 | (durUpdateEn ? AR_DurUpdateEna : 0)
396                 | SM(0, AR_BurstDur);
397
398         ads->ds_ctl3 = set11nRate(series, 0)
399                 | set11nRate(series, 1)
400                 | set11nRate(series, 2)
401                 | set11nRate(series, 3);
402
403         ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
404                 | set11nPktDurRTSCTS(series, 1);
405
406         ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
407                 | set11nPktDurRTSCTS(series, 3);
408
409         ads->ds_ctl7 = set11nRateFlags(series, 0)
410                 | set11nRateFlags(series, 1)
411                 | set11nRateFlags(series, 2)
412                 | set11nRateFlags(series, 3)
413                 | SM(rtsctsRate, AR_RTSCTSRate);
414         last_ads->ds_ctl2 = ads->ds_ctl2;
415         last_ads->ds_ctl3 = ads->ds_ctl3;
416 }
417 EXPORT_SYMBOL(ath9k_hw_set11n_ratescenario);
418
419 void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
420                                 u32 aggrLen)
421 {
422         struct ar5416_desc *ads = AR5416DESC(ds);
423
424         ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
425         ads->ds_ctl6 &= ~AR_AggrLen;
426         ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
427 }
428 EXPORT_SYMBOL(ath9k_hw_set11n_aggr_first);
429
430 void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
431                                  u32 numDelims)
432 {
433         struct ar5416_desc *ads = AR5416DESC(ds);
434         unsigned int ctl6;
435
436         ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
437
438         ctl6 = ads->ds_ctl6;
439         ctl6 &= ~AR_PadDelim;
440         ctl6 |= SM(numDelims, AR_PadDelim);
441         ads->ds_ctl6 = ctl6;
442 }
443 EXPORT_SYMBOL(ath9k_hw_set11n_aggr_middle);
444
445 void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
446 {
447         struct ar5416_desc *ads = AR5416DESC(ds);
448
449         ads->ds_ctl1 |= AR_IsAggr;
450         ads->ds_ctl1 &= ~AR_MoreAggr;
451         ads->ds_ctl6 &= ~AR_PadDelim;
452 }
453 EXPORT_SYMBOL(ath9k_hw_set11n_aggr_last);
454
455 void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
456 {
457         struct ar5416_desc *ads = AR5416DESC(ds);
458
459         ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
460 }
461 EXPORT_SYMBOL(ath9k_hw_clr11n_aggr);
462
463 void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
464                                    u32 burstDuration)
465 {
466         struct ar5416_desc *ads = AR5416DESC(ds);
467
468         ads->ds_ctl2 &= ~AR_BurstDur;
469         ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
470 }
471 EXPORT_SYMBOL(ath9k_hw_set11n_burstduration);
472
473 void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
474                                      u32 vmf)
475 {
476         struct ar5416_desc *ads = AR5416DESC(ds);
477
478         if (vmf)
479                 ads->ds_ctl0 |= AR_VirtMoreFrag;
480         else
481                 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
482 }
483
484 void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
485 {
486         *txqs &= ah->intr_txqs;
487         ah->intr_txqs &= ~(*txqs);
488 }
489 EXPORT_SYMBOL(ath9k_hw_gettxintrtxqs);
490
491 bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
492                             const struct ath9k_tx_queue_info *qinfo)
493 {
494         u32 cw;
495         struct ath_common *common = ath9k_hw_common(ah);
496         struct ath9k_hw_capabilities *pCap = &ah->caps;
497         struct ath9k_tx_queue_info *qi;
498
499         if (q >= pCap->total_queues) {
500                 ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, "
501                           "invalid queue: %u\n", q);
502                 return false;
503         }
504
505         qi = &ah->txq[q];
506         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
507                 ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, "
508                           "inactive queue: %u\n", q);
509                 return false;
510         }
511
512         ath_print(common, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q);
513
514         qi->tqi_ver = qinfo->tqi_ver;
515         qi->tqi_subtype = qinfo->tqi_subtype;
516         qi->tqi_qflags = qinfo->tqi_qflags;
517         qi->tqi_priority = qinfo->tqi_priority;
518         if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
519                 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
520         else
521                 qi->tqi_aifs = INIT_AIFS;
522         if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
523                 cw = min(qinfo->tqi_cwmin, 1024U);
524                 qi->tqi_cwmin = 1;
525                 while (qi->tqi_cwmin < cw)
526                         qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
527         } else
528                 qi->tqi_cwmin = qinfo->tqi_cwmin;
529         if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
530                 cw = min(qinfo->tqi_cwmax, 1024U);
531                 qi->tqi_cwmax = 1;
532                 while (qi->tqi_cwmax < cw)
533                         qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
534         } else
535                 qi->tqi_cwmax = INIT_CWMAX;
536
537         if (qinfo->tqi_shretry != 0)
538                 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
539         else
540                 qi->tqi_shretry = INIT_SH_RETRY;
541         if (qinfo->tqi_lgretry != 0)
542                 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
543         else
544                 qi->tqi_lgretry = INIT_LG_RETRY;
545         qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
546         qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
547         qi->tqi_burstTime = qinfo->tqi_burstTime;
548         qi->tqi_readyTime = qinfo->tqi_readyTime;
549
550         switch (qinfo->tqi_subtype) {
551         case ATH9K_WME_UPSD:
552                 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
553                         qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
554                 break;
555         default:
556                 break;
557         }
558
559         return true;
560 }
561 EXPORT_SYMBOL(ath9k_hw_set_txq_props);
562
563 bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
564                             struct ath9k_tx_queue_info *qinfo)
565 {
566         struct ath_common *common = ath9k_hw_common(ah);
567         struct ath9k_hw_capabilities *pCap = &ah->caps;
568         struct ath9k_tx_queue_info *qi;
569
570         if (q >= pCap->total_queues) {
571                 ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, "
572                           "invalid queue: %u\n", q);
573                 return false;
574         }
575
576         qi = &ah->txq[q];
577         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
578                 ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, "
579                           "inactive queue: %u\n", q);
580                 return false;
581         }
582
583         qinfo->tqi_qflags = qi->tqi_qflags;
584         qinfo->tqi_ver = qi->tqi_ver;
585         qinfo->tqi_subtype = qi->tqi_subtype;
586         qinfo->tqi_qflags = qi->tqi_qflags;
587         qinfo->tqi_priority = qi->tqi_priority;
588         qinfo->tqi_aifs = qi->tqi_aifs;
589         qinfo->tqi_cwmin = qi->tqi_cwmin;
590         qinfo->tqi_cwmax = qi->tqi_cwmax;
591         qinfo->tqi_shretry = qi->tqi_shretry;
592         qinfo->tqi_lgretry = qi->tqi_lgretry;
593         qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
594         qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
595         qinfo->tqi_burstTime = qi->tqi_burstTime;
596         qinfo->tqi_readyTime = qi->tqi_readyTime;
597
598         return true;
599 }
600 EXPORT_SYMBOL(ath9k_hw_get_txq_props);
601
602 int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
603                           const struct ath9k_tx_queue_info *qinfo)
604 {
605         struct ath_common *common = ath9k_hw_common(ah);
606         struct ath9k_tx_queue_info *qi;
607         struct ath9k_hw_capabilities *pCap = &ah->caps;
608         int q;
609
610         switch (type) {
611         case ATH9K_TX_QUEUE_BEACON:
612                 q = pCap->total_queues - 1;
613                 break;
614         case ATH9K_TX_QUEUE_CAB:
615                 q = pCap->total_queues - 2;
616                 break;
617         case ATH9K_TX_QUEUE_PSPOLL:
618                 q = 1;
619                 break;
620         case ATH9K_TX_QUEUE_UAPSD:
621                 q = pCap->total_queues - 3;
622                 break;
623         case ATH9K_TX_QUEUE_DATA:
624                 for (q = 0; q < pCap->total_queues; q++)
625                         if (ah->txq[q].tqi_type ==
626                             ATH9K_TX_QUEUE_INACTIVE)
627                                 break;
628                 if (q == pCap->total_queues) {
629                         ath_print(common, ATH_DBG_FATAL,
630                                   "No available TX queue\n");
631                         return -1;
632                 }
633                 break;
634         default:
635                 ath_print(common, ATH_DBG_FATAL,
636                           "Invalid TX queue type: %u\n", type);
637                 return -1;
638         }
639
640         ath_print(common, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q);
641
642         qi = &ah->txq[q];
643         if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
644                 ath_print(common, ATH_DBG_FATAL,
645                           "TX queue: %u already active\n", q);
646                 return -1;
647         }
648         memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
649         qi->tqi_type = type;
650         if (qinfo == NULL) {
651                 qi->tqi_qflags =
652                         TXQ_FLAG_TXOKINT_ENABLE
653                         | TXQ_FLAG_TXERRINT_ENABLE
654                         | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
655                 qi->tqi_aifs = INIT_AIFS;
656                 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
657                 qi->tqi_cwmax = INIT_CWMAX;
658                 qi->tqi_shretry = INIT_SH_RETRY;
659                 qi->tqi_lgretry = INIT_LG_RETRY;
660                 qi->tqi_physCompBuf = 0;
661         } else {
662                 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
663                 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
664         }
665
666         return q;
667 }
668 EXPORT_SYMBOL(ath9k_hw_setuptxqueue);
669
670 bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
671 {
672         struct ath9k_hw_capabilities *pCap = &ah->caps;
673         struct ath_common *common = ath9k_hw_common(ah);
674         struct ath9k_tx_queue_info *qi;
675
676         if (q >= pCap->total_queues) {
677                 ath_print(common, ATH_DBG_QUEUE, "Release TXQ, "
678                           "invalid queue: %u\n", q);
679                 return false;
680         }
681         qi = &ah->txq[q];
682         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
683                 ath_print(common, ATH_DBG_QUEUE, "Release TXQ, "
684                           "inactive queue: %u\n", q);
685                 return false;
686         }
687
688         ath_print(common, ATH_DBG_QUEUE, "Release TX queue: %u\n", q);
689
690         qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
691         ah->txok_interrupt_mask &= ~(1 << q);
692         ah->txerr_interrupt_mask &= ~(1 << q);
693         ah->txdesc_interrupt_mask &= ~(1 << q);
694         ah->txeol_interrupt_mask &= ~(1 << q);
695         ah->txurn_interrupt_mask &= ~(1 << q);
696         ath9k_hw_set_txq_interrupts(ah, qi);
697
698         return true;
699 }
700 EXPORT_SYMBOL(ath9k_hw_releasetxqueue);
701
702 bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
703 {
704         struct ath9k_hw_capabilities *pCap = &ah->caps;
705         struct ath_common *common = ath9k_hw_common(ah);
706         struct ath9k_channel *chan = ah->curchan;
707         struct ath9k_tx_queue_info *qi;
708         u32 cwMin, chanCwMin, value;
709
710         if (q >= pCap->total_queues) {
711                 ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, "
712                           "invalid queue: %u\n", q);
713                 return false;
714         }
715
716         qi = &ah->txq[q];
717         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
718                 ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, "
719                           "inactive queue: %u\n", q);
720                 return true;
721         }
722
723         ath_print(common, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q);
724
725         if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
726                 if (chan && IS_CHAN_B(chan))
727                         chanCwMin = INIT_CWMIN_11B;
728                 else
729                         chanCwMin = INIT_CWMIN;
730
731                 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
732         } else
733                 cwMin = qi->tqi_cwmin;
734
735         REG_WRITE(ah, AR_DLCL_IFS(q),
736                   SM(cwMin, AR_D_LCL_IFS_CWMIN) |
737                   SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
738                   SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
739
740         REG_WRITE(ah, AR_DRETRY_LIMIT(q),
741                   SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) |
742                   SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) |
743                   SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
744
745         REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
746         REG_WRITE(ah, AR_DMISC(q),
747                   AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
748
749         if (qi->tqi_cbrPeriod) {
750                 REG_WRITE(ah, AR_QCBRCFG(q),
751                           SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
752                           SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
753                 REG_WRITE(ah, AR_QMISC(q),
754                           REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR |
755                           (qi->tqi_cbrOverflowLimit ?
756                            AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
757         }
758         if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
759                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
760                           SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
761                           AR_Q_RDYTIMECFG_EN);
762         }
763
764         REG_WRITE(ah, AR_DCHNTIME(q),
765                   SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
766                   (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
767
768         if (qi->tqi_burstTime
769             && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
770                 REG_WRITE(ah, AR_QMISC(q),
771                           REG_READ(ah, AR_QMISC(q)) |
772                           AR_Q_MISC_RDYTIME_EXP_POLICY);
773
774         }
775
776         if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
777                 REG_WRITE(ah, AR_DMISC(q),
778                           REG_READ(ah, AR_DMISC(q)) |
779                           AR_D_MISC_POST_FR_BKOFF_DIS);
780         }
781         if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
782                 REG_WRITE(ah, AR_DMISC(q),
783                           REG_READ(ah, AR_DMISC(q)) |
784                           AR_D_MISC_FRAG_BKOFF_EN);
785         }
786         switch (qi->tqi_type) {
787         case ATH9K_TX_QUEUE_BEACON:
788                 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
789                           | AR_Q_MISC_FSP_DBA_GATED
790                           | AR_Q_MISC_BEACON_USE
791                           | AR_Q_MISC_CBR_INCR_DIS1);
792
793                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
794                           | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
795                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
796                           | AR_D_MISC_BEACON_USE
797                           | AR_D_MISC_POST_FR_BKOFF_DIS);
798                 break;
799         case ATH9K_TX_QUEUE_CAB:
800                 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
801                           | AR_Q_MISC_FSP_DBA_GATED
802                           | AR_Q_MISC_CBR_INCR_DIS1
803                           | AR_Q_MISC_CBR_INCR_DIS0);
804                 value = (qi->tqi_readyTime -
805                          (ah->config.sw_beacon_response_time -
806                           ah->config.dma_beacon_response_time) -
807                          ah->config.additional_swba_backoff) * 1024;
808                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
809                           value | AR_Q_RDYTIMECFG_EN);
810                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
811                           | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
812                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
813                 break;
814         case ATH9K_TX_QUEUE_PSPOLL:
815                 REG_WRITE(ah, AR_QMISC(q),
816                           REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
817                 break;
818         case ATH9K_TX_QUEUE_UAPSD:
819                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
820                           AR_D_MISC_POST_FR_BKOFF_DIS);
821                 break;
822         default:
823                 break;
824         }
825
826         if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
827                 REG_WRITE(ah, AR_DMISC(q),
828                           REG_READ(ah, AR_DMISC(q)) |
829                           SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
830                              AR_D_MISC_ARB_LOCKOUT_CNTRL) |
831                           AR_D_MISC_POST_FR_BKOFF_DIS);
832         }
833
834         if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
835                 ah->txok_interrupt_mask |= 1 << q;
836         else
837                 ah->txok_interrupt_mask &= ~(1 << q);
838         if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
839                 ah->txerr_interrupt_mask |= 1 << q;
840         else
841                 ah->txerr_interrupt_mask &= ~(1 << q);
842         if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
843                 ah->txdesc_interrupt_mask |= 1 << q;
844         else
845                 ah->txdesc_interrupt_mask &= ~(1 << q);
846         if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
847                 ah->txeol_interrupt_mask |= 1 << q;
848         else
849                 ah->txeol_interrupt_mask &= ~(1 << q);
850         if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
851                 ah->txurn_interrupt_mask |= 1 << q;
852         else
853                 ah->txurn_interrupt_mask &= ~(1 << q);
854         ath9k_hw_set_txq_interrupts(ah, qi);
855
856         return true;
857 }
858 EXPORT_SYMBOL(ath9k_hw_resettxqueue);
859
860 int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
861                         u32 pa, struct ath_desc *nds, u64 tsf)
862 {
863         struct ar5416_desc ads;
864         struct ar5416_desc *adsp = AR5416DESC(ds);
865         u32 phyerr;
866
867         if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
868                 return -EINPROGRESS;
869
870         ads.u.rx = adsp->u.rx;
871
872         ds->ds_rxstat.rs_status = 0;
873         ds->ds_rxstat.rs_flags = 0;
874
875         ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
876         ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
877
878         if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
879                 ds->ds_rxstat.rs_rssi = ATH9K_RSSI_BAD;
880                 ds->ds_rxstat.rs_rssi_ctl0 = ATH9K_RSSI_BAD;
881                 ds->ds_rxstat.rs_rssi_ctl1 = ATH9K_RSSI_BAD;
882                 ds->ds_rxstat.rs_rssi_ctl2 = ATH9K_RSSI_BAD;
883                 ds->ds_rxstat.rs_rssi_ext0 = ATH9K_RSSI_BAD;
884                 ds->ds_rxstat.rs_rssi_ext1 = ATH9K_RSSI_BAD;
885                 ds->ds_rxstat.rs_rssi_ext2 = ATH9K_RSSI_BAD;
886         } else {
887                 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
888                 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
889                                                 AR_RxRSSIAnt00);
890                 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
891                                                 AR_RxRSSIAnt01);
892                 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
893                                                 AR_RxRSSIAnt02);
894                 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4,
895                                                 AR_RxRSSIAnt10);
896                 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4,
897                                                 AR_RxRSSIAnt11);
898                 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4,
899                                                 AR_RxRSSIAnt12);
900         }
901         if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
902                 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
903         else
904                 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
905
906         ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
907         ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
908
909         ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
910         ds->ds_rxstat.rs_moreaggr =
911                 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
912         ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
913         ds->ds_rxstat.rs_flags =
914                 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
915         ds->ds_rxstat.rs_flags |=
916                 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
917
918         if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
919                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
920         if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
921                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
922         if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
923                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
924
925         if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
926                 if (ads.ds_rxstatus8 & AR_CRCErr)
927                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
928                 else if (ads.ds_rxstatus8 & AR_PHYErr) {
929                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
930                         phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
931                         ds->ds_rxstat.rs_phyerr = phyerr;
932                 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
933                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
934                 else if (ads.ds_rxstatus8 & AR_MichaelErr)
935                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
936         }
937
938         return 0;
939 }
940 EXPORT_SYMBOL(ath9k_hw_rxprocdesc);
941
942 void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
943                           u32 size, u32 flags)
944 {
945         struct ar5416_desc *ads = AR5416DESC(ds);
946         struct ath9k_hw_capabilities *pCap = &ah->caps;
947
948         ads->ds_ctl1 = size & AR_BufLen;
949         if (flags & ATH9K_RXDESC_INTREQ)
950                 ads->ds_ctl1 |= AR_RxIntrReq;
951
952         ads->ds_rxstatus8 &= ~AR_RxDone;
953         if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
954                 memset(&(ads->u), 0, sizeof(ads->u));
955 }
956 EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
957
958 /*
959  * This can stop or re-enables RX.
960  *
961  * If bool is set this will kill any frame which is currently being
962  * transferred between the MAC and baseband and also prevent any new
963  * frames from getting started.
964  */
965 bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
966 {
967         u32 reg;
968
969         if (set) {
970                 REG_SET_BIT(ah, AR_DIAG_SW,
971                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
972
973                 if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE,
974                                    0, AH_WAIT_TIMEOUT)) {
975                         REG_CLR_BIT(ah, AR_DIAG_SW,
976                                     (AR_DIAG_RX_DIS |
977                                      AR_DIAG_RX_ABORT));
978
979                         reg = REG_READ(ah, AR_OBS_BUS_1);
980                         ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
981                                   "RX failed to go idle in 10 ms RXSM=0x%x\n",
982                                   reg);
983
984                         return false;
985                 }
986         } else {
987                 REG_CLR_BIT(ah, AR_DIAG_SW,
988                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
989         }
990
991         return true;
992 }
993 EXPORT_SYMBOL(ath9k_hw_setrxabort);
994
995 void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
996 {
997         REG_WRITE(ah, AR_RXDP, rxdp);
998 }
999 EXPORT_SYMBOL(ath9k_hw_putrxbuf);
1000
1001 void ath9k_hw_rxena(struct ath_hw *ah)
1002 {
1003         REG_WRITE(ah, AR_CR, AR_CR_RXE);
1004 }
1005 EXPORT_SYMBOL(ath9k_hw_rxena);
1006
1007 void ath9k_hw_startpcureceive(struct ath_hw *ah)
1008 {
1009         ath9k_enable_mib_counters(ah);
1010
1011         ath9k_ani_reset(ah);
1012
1013         REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
1014 }
1015 EXPORT_SYMBOL(ath9k_hw_startpcureceive);
1016
1017 void ath9k_hw_stoppcurecv(struct ath_hw *ah)
1018 {
1019         REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
1020
1021         ath9k_hw_disable_mib_counters(ah);
1022 }
1023 EXPORT_SYMBOL(ath9k_hw_stoppcurecv);
1024
1025 bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
1026 {
1027 #define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
1028 #define AH_RX_TIME_QUANTUM     100     /* usec */
1029         struct ath_common *common = ath9k_hw_common(ah);
1030         int i;
1031
1032         REG_WRITE(ah, AR_CR, AR_CR_RXD);
1033
1034         /* Wait for rx enable bit to go low */
1035         for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) {
1036                 if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0)
1037                         break;
1038                 udelay(AH_TIME_QUANTUM);
1039         }
1040
1041         if (i == 0) {
1042                 ath_print(common, ATH_DBG_FATAL,
1043                           "DMA failed to stop in %d ms "
1044                           "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
1045                           AH_RX_STOP_DMA_TIMEOUT / 1000,
1046                           REG_READ(ah, AR_CR),
1047                           REG_READ(ah, AR_DIAG_SW));
1048                 return false;
1049         } else {
1050                 return true;
1051         }
1052
1053 #undef AH_RX_TIME_QUANTUM
1054 #undef AH_RX_STOP_DMA_TIMEOUT
1055 }
1056 EXPORT_SYMBOL(ath9k_hw_stopdmarecv);
1057
1058 int ath9k_hw_beaconq_setup(struct ath_hw *ah)
1059 {
1060         struct ath9k_tx_queue_info qi;
1061
1062         memset(&qi, 0, sizeof(qi));
1063         qi.tqi_aifs = 1;
1064         qi.tqi_cwmin = 0;
1065         qi.tqi_cwmax = 0;
1066         /* NB: don't enable any interrupts */
1067         return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
1068 }
1069 EXPORT_SYMBOL(ath9k_hw_beaconq_setup);