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