aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/mac.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c200
1 files changed, 142 insertions, 58 deletions
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 800bfab94635..efc420cd42bf 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -14,16 +14,16 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include "ath9k.h" 17#include "hw.h"
18 18
19static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, 19static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
20 struct ath9k_tx_queue_info *qi) 20 struct ath9k_tx_queue_info *qi)
21{ 21{
22 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, 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", 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, 24 ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
25 ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask, 25 ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
26 ah->txurn_interrupt_mask); 26 ah->txurn_interrupt_mask);
27 27
28 REG_WRITE(ah, AR_IMR_S0, 28 REG_WRITE(ah, AR_IMR_S0,
29 SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK) 29 SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
@@ -39,17 +39,21 @@ u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
39{ 39{
40 return REG_READ(ah, AR_QTXDP(q)); 40 return REG_READ(ah, AR_QTXDP(q));
41} 41}
42EXPORT_SYMBOL(ath9k_hw_gettxbuf);
42 43
43void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp) 44void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
44{ 45{
45 REG_WRITE(ah, AR_QTXDP(q), txdp); 46 REG_WRITE(ah, AR_QTXDP(q), txdp);
46} 47}
48EXPORT_SYMBOL(ath9k_hw_puttxbuf);
47 49
48void ath9k_hw_txstart(struct ath_hw *ah, u32 q) 50void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
49{ 51{
50 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q); 52 ath_print(ath9k_hw_common(ah), ATH_DBG_QUEUE,
53 "Enable TXE on queue: %u\n", q);
51 REG_WRITE(ah, AR_Q_TXE, 1 << q); 54 REG_WRITE(ah, AR_Q_TXE, 1 << q);
52} 55}
56EXPORT_SYMBOL(ath9k_hw_txstart);
53 57
54u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q) 58u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
55{ 59{
@@ -64,13 +68,39 @@ u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
64 68
65 return npend; 69 return npend;
66} 70}
71EXPORT_SYMBOL(ath9k_hw_numtxpending);
67 72
73/**
74 * ath9k_hw_updatetxtriglevel - adjusts the frame trigger level
75 *
76 * @ah: atheros hardware struct
77 * @bIncTrigLevel: whether or not the frame trigger level should be updated
78 *
79 * The frame trigger level specifies the minimum number of bytes,
80 * in units of 64 bytes, that must be DMA'ed into the PCU TX FIFO
81 * before the PCU will initiate sending the frame on the air. This can
82 * mean we initiate transmit before a full frame is on the PCU TX FIFO.
83 * Resets to 0x1 (meaning 64 bytes or a full frame, whichever occurs
84 * first)
85 *
86 * Caution must be taken to ensure to set the frame trigger level based
87 * on the DMA request size. For example if the DMA request size is set to
88 * 128 bytes the trigger level cannot exceed 6 * 64 = 384. This is because
89 * there need to be enough space in the tx FIFO for the requested transfer
90 * size. Hence the tx FIFO will stop with 512 - 128 = 384 bytes. If we set
91 * the threshold to a value beyond 6, then the transmit will hang.
92 *
93 * Current dual stream devices have a PCU TX FIFO size of 8 KB.
94 * Current single stream devices have a PCU TX FIFO size of 4 KB, however,
95 * there is a hardware issue which forces us to use 2 KB instead so the
96 * frame trigger level must not exceed 2 KB for these chipsets.
97 */
68bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel) 98bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
69{ 99{
70 u32 txcfg, curLevel, newLevel; 100 u32 txcfg, curLevel, newLevel;
71 enum ath9k_int omask; 101 enum ath9k_int omask;
72 102
73 if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD) 103 if (ah->tx_trig_level >= ah->config.max_txtrig_level)
74 return false; 104 return false;
75 105
76 omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL); 106 omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL);
@@ -79,7 +109,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
79 curLevel = MS(txcfg, AR_FTRIG); 109 curLevel = MS(txcfg, AR_FTRIG);
80 newLevel = curLevel; 110 newLevel = curLevel;
81 if (bIncTrigLevel) { 111 if (bIncTrigLevel) {
82 if (curLevel < MAX_TX_FIFO_THRESHOLD) 112 if (curLevel < ah->config.max_txtrig_level)
83 newLevel++; 113 newLevel++;
84 } else if (curLevel > MIN_TX_FIFO_THRESHOLD) 114 } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
85 newLevel--; 115 newLevel--;
@@ -93,27 +123,28 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
93 123
94 return newLevel != curLevel; 124 return newLevel != curLevel;
95} 125}
126EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel);
96 127
97bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) 128bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
98{ 129{
99#define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */ 130#define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */
100#define ATH9K_TIME_QUANTUM 100 /* usec */ 131#define ATH9K_TIME_QUANTUM 100 /* usec */
101 132 struct ath_common *common = ath9k_hw_common(ah);
102 struct ath9k_hw_capabilities *pCap = &ah->caps; 133 struct ath9k_hw_capabilities *pCap = &ah->caps;
103 struct ath9k_tx_queue_info *qi; 134 struct ath9k_tx_queue_info *qi;
104 u32 tsfLow, j, wait; 135 u32 tsfLow, j, wait;
105 u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM; 136 u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
106 137
107 if (q >= pCap->total_queues) { 138 if (q >= pCap->total_queues) {
108 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, " 139 ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
109 "invalid queue: %u\n", q); 140 "invalid queue: %u\n", q);
110 return false; 141 return false;
111 } 142 }
112 143
113 qi = &ah->txq[q]; 144 qi = &ah->txq[q];
114 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 145 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
115 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, " 146 ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
116 "inactive queue: %u\n", q); 147 "inactive queue: %u\n", q);
117 return false; 148 return false;
118 } 149 }
119 150
@@ -126,9 +157,9 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
126 } 157 }
127 158
128 if (ath9k_hw_numtxpending(ah, q)) { 159 if (ath9k_hw_numtxpending(ah, q)) {
129 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, 160 ath_print(common, ATH_DBG_QUEUE,
130 "%s: Num of pending TX Frames %d on Q %d\n", 161 "%s: Num of pending TX Frames %d on Q %d\n",
131 __func__, ath9k_hw_numtxpending(ah, q), q); 162 __func__, ath9k_hw_numtxpending(ah, q), q);
132 163
133 for (j = 0; j < 2; j++) { 164 for (j = 0; j < 2; j++) {
134 tsfLow = REG_READ(ah, AR_TSF_L32); 165 tsfLow = REG_READ(ah, AR_TSF_L32);
@@ -142,9 +173,9 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
142 if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10)) 173 if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
143 break; 174 break;
144 175
145 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, 176 ath_print(common, ATH_DBG_QUEUE,
146 "TSF has moved while trying to set " 177 "TSF has moved while trying to set "
147 "quiet time TSF: 0x%08x\n", tsfLow); 178 "quiet time TSF: 0x%08x\n", tsfLow);
148 } 179 }
149 180
150 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); 181 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
@@ -155,9 +186,9 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
155 wait = wait_time; 186 wait = wait_time;
156 while (ath9k_hw_numtxpending(ah, q)) { 187 while (ath9k_hw_numtxpending(ah, q)) {
157 if ((--wait) == 0) { 188 if ((--wait) == 0) {
158 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, 189 ath_print(common, ATH_DBG_FATAL,
159 "Failed to stop TX DMA in 100 " 190 "Failed to stop TX DMA in 100 "
160 "msec after killing last frame\n"); 191 "msec after killing last frame\n");
161 break; 192 break;
162 } 193 }
163 udelay(ATH9K_TIME_QUANTUM); 194 udelay(ATH9K_TIME_QUANTUM);
@@ -172,6 +203,7 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
172#undef ATH9K_TX_STOP_DMA_TIMEOUT 203#undef ATH9K_TX_STOP_DMA_TIMEOUT
173#undef ATH9K_TIME_QUANTUM 204#undef ATH9K_TIME_QUANTUM
174} 205}
206EXPORT_SYMBOL(ath9k_hw_stoptxdma);
175 207
176void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds, 208void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
177 u32 segLen, bool firstSeg, 209 u32 segLen, bool firstSeg,
@@ -198,6 +230,7 @@ void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
198 ads->ds_txstatus6 = ads->ds_txstatus7 = 0; 230 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
199 ads->ds_txstatus8 = ads->ds_txstatus9 = 0; 231 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
200} 232}
233EXPORT_SYMBOL(ath9k_hw_filltxdesc);
201 234
202void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds) 235void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
203{ 236{
@@ -209,6 +242,7 @@ void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
209 ads->ds_txstatus6 = ads->ds_txstatus7 = 0; 242 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
210 ads->ds_txstatus8 = ads->ds_txstatus9 = 0; 243 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
211} 244}
245EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
212 246
213int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds) 247int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
214{ 248{
@@ -222,6 +256,8 @@ int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
222 ds->ds_txstat.ts_status = 0; 256 ds->ds_txstat.ts_status = 0;
223 ds->ds_txstat.ts_flags = 0; 257 ds->ds_txstat.ts_flags = 0;
224 258
259 if (ads->ds_txstatus1 & AR_FrmXmitOK)
260 ds->ds_txstat.ts_status |= ATH9K_TX_ACKED;
225 if (ads->ds_txstatus1 & AR_ExcessiveRetries) 261 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
226 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY; 262 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
227 if (ads->ds_txstatus1 & AR_Filtered) 263 if (ads->ds_txstatus1 & AR_Filtered)
@@ -284,6 +320,7 @@ int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
284 320
285 return 0; 321 return 0;
286} 322}
323EXPORT_SYMBOL(ath9k_hw_txprocdesc);
287 324
288void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds, 325void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
289 u32 pktLen, enum ath9k_pkt_type type, u32 txPower, 326 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
@@ -319,6 +356,7 @@ void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
319 ads->ds_ctl11 = 0; 356 ads->ds_ctl11 = 0;
320 } 357 }
321} 358}
359EXPORT_SYMBOL(ath9k_hw_set11n_txdesc);
322 360
323void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds, 361void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
324 struct ath_desc *lastds, 362 struct ath_desc *lastds,
@@ -374,6 +412,7 @@ void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
374 last_ads->ds_ctl2 = ads->ds_ctl2; 412 last_ads->ds_ctl2 = ads->ds_ctl2;
375 last_ads->ds_ctl3 = ads->ds_ctl3; 413 last_ads->ds_ctl3 = ads->ds_ctl3;
376} 414}
415EXPORT_SYMBOL(ath9k_hw_set11n_ratescenario);
377 416
378void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds, 417void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
379 u32 aggrLen) 418 u32 aggrLen)
@@ -384,6 +423,7 @@ void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
384 ads->ds_ctl6 &= ~AR_AggrLen; 423 ads->ds_ctl6 &= ~AR_AggrLen;
385 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen); 424 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
386} 425}
426EXPORT_SYMBOL(ath9k_hw_set11n_aggr_first);
387 427
388void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds, 428void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
389 u32 numDelims) 429 u32 numDelims)
@@ -398,6 +438,7 @@ void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
398 ctl6 |= SM(numDelims, AR_PadDelim); 438 ctl6 |= SM(numDelims, AR_PadDelim);
399 ads->ds_ctl6 = ctl6; 439 ads->ds_ctl6 = ctl6;
400} 440}
441EXPORT_SYMBOL(ath9k_hw_set11n_aggr_middle);
401 442
402void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds) 443void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
403{ 444{
@@ -407,6 +448,7 @@ void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
407 ads->ds_ctl1 &= ~AR_MoreAggr; 448 ads->ds_ctl1 &= ~AR_MoreAggr;
408 ads->ds_ctl6 &= ~AR_PadDelim; 449 ads->ds_ctl6 &= ~AR_PadDelim;
409} 450}
451EXPORT_SYMBOL(ath9k_hw_set11n_aggr_last);
410 452
411void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds) 453void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
412{ 454{
@@ -414,6 +456,7 @@ void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
414 456
415 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr); 457 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
416} 458}
459EXPORT_SYMBOL(ath9k_hw_clr11n_aggr);
417 460
418void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds, 461void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
419 u32 burstDuration) 462 u32 burstDuration)
@@ -423,6 +466,7 @@ void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
423 ads->ds_ctl2 &= ~AR_BurstDur; 466 ads->ds_ctl2 &= ~AR_BurstDur;
424 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur); 467 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
425} 468}
469EXPORT_SYMBOL(ath9k_hw_set11n_burstduration);
426 470
427void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds, 471void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
428 u32 vmf) 472 u32 vmf)
@@ -440,28 +484,30 @@ void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
440 *txqs &= ah->intr_txqs; 484 *txqs &= ah->intr_txqs;
441 ah->intr_txqs &= ~(*txqs); 485 ah->intr_txqs &= ~(*txqs);
442} 486}
487EXPORT_SYMBOL(ath9k_hw_gettxintrtxqs);
443 488
444bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, 489bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
445 const struct ath9k_tx_queue_info *qinfo) 490 const struct ath9k_tx_queue_info *qinfo)
446{ 491{
447 u32 cw; 492 u32 cw;
493 struct ath_common *common = ath9k_hw_common(ah);
448 struct ath9k_hw_capabilities *pCap = &ah->caps; 494 struct ath9k_hw_capabilities *pCap = &ah->caps;
449 struct ath9k_tx_queue_info *qi; 495 struct ath9k_tx_queue_info *qi;
450 496
451 if (q >= pCap->total_queues) { 497 if (q >= pCap->total_queues) {
452 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, " 498 ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, "
453 "invalid queue: %u\n", q); 499 "invalid queue: %u\n", q);
454 return false; 500 return false;
455 } 501 }
456 502
457 qi = &ah->txq[q]; 503 qi = &ah->txq[q];
458 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 504 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
459 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, " 505 ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, "
460 "inactive queue: %u\n", q); 506 "inactive queue: %u\n", q);
461 return false; 507 return false;
462 } 508 }
463 509
464 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q); 510 ath_print(common, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q);
465 511
466 qi->tqi_ver = qinfo->tqi_ver; 512 qi->tqi_ver = qinfo->tqi_ver;
467 qi->tqi_subtype = qinfo->tqi_subtype; 513 qi->tqi_subtype = qinfo->tqi_subtype;
@@ -510,23 +556,25 @@ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
510 556
511 return true; 557 return true;
512} 558}
559EXPORT_SYMBOL(ath9k_hw_set_txq_props);
513 560
514bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q, 561bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
515 struct ath9k_tx_queue_info *qinfo) 562 struct ath9k_tx_queue_info *qinfo)
516{ 563{
564 struct ath_common *common = ath9k_hw_common(ah);
517 struct ath9k_hw_capabilities *pCap = &ah->caps; 565 struct ath9k_hw_capabilities *pCap = &ah->caps;
518 struct ath9k_tx_queue_info *qi; 566 struct ath9k_tx_queue_info *qi;
519 567
520 if (q >= pCap->total_queues) { 568 if (q >= pCap->total_queues) {
521 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, " 569 ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, "
522 "invalid queue: %u\n", q); 570 "invalid queue: %u\n", q);
523 return false; 571 return false;
524 } 572 }
525 573
526 qi = &ah->txq[q]; 574 qi = &ah->txq[q];
527 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 575 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
528 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, " 576 ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, "
529 "inactive queue: %u\n", q); 577 "inactive queue: %u\n", q);
530 return false; 578 return false;
531 } 579 }
532 580
@@ -547,10 +595,12 @@ bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
547 595
548 return true; 596 return true;
549} 597}
598EXPORT_SYMBOL(ath9k_hw_get_txq_props);
550 599
551int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, 600int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
552 const struct ath9k_tx_queue_info *qinfo) 601 const struct ath9k_tx_queue_info *qinfo)
553{ 602{
603 struct ath_common *common = ath9k_hw_common(ah);
554 struct ath9k_tx_queue_info *qi; 604 struct ath9k_tx_queue_info *qi;
555 struct ath9k_hw_capabilities *pCap = &ah->caps; 605 struct ath9k_hw_capabilities *pCap = &ah->caps;
556 int q; 606 int q;
@@ -574,23 +624,23 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
574 ATH9K_TX_QUEUE_INACTIVE) 624 ATH9K_TX_QUEUE_INACTIVE)
575 break; 625 break;
576 if (q == pCap->total_queues) { 626 if (q == pCap->total_queues) {
577 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 627 ath_print(common, ATH_DBG_FATAL,
578 "No available TX queue\n"); 628 "No available TX queue\n");
579 return -1; 629 return -1;
580 } 630 }
581 break; 631 break;
582 default: 632 default:
583 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Invalid TX queue type: %u\n", 633 ath_print(common, ATH_DBG_FATAL,
584 type); 634 "Invalid TX queue type: %u\n", type);
585 return -1; 635 return -1;
586 } 636 }
587 637
588 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q); 638 ath_print(common, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q);
589 639
590 qi = &ah->txq[q]; 640 qi = &ah->txq[q];
591 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) { 641 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
592 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 642 ath_print(common, ATH_DBG_FATAL,
593 "TX queue: %u already active\n", q); 643 "TX queue: %u already active\n", q);
594 return -1; 644 return -1;
595 } 645 }
596 memset(qi, 0, sizeof(struct ath9k_tx_queue_info)); 646 memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
@@ -613,25 +663,27 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
613 663
614 return q; 664 return q;
615} 665}
666EXPORT_SYMBOL(ath9k_hw_setuptxqueue);
616 667
617bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) 668bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
618{ 669{
619 struct ath9k_hw_capabilities *pCap = &ah->caps; 670 struct ath9k_hw_capabilities *pCap = &ah->caps;
671 struct ath_common *common = ath9k_hw_common(ah);
620 struct ath9k_tx_queue_info *qi; 672 struct ath9k_tx_queue_info *qi;
621 673
622 if (q >= pCap->total_queues) { 674 if (q >= pCap->total_queues) {
623 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, " 675 ath_print(common, ATH_DBG_QUEUE, "Release TXQ, "
624 "invalid queue: %u\n", q); 676 "invalid queue: %u\n", q);
625 return false; 677 return false;
626 } 678 }
627 qi = &ah->txq[q]; 679 qi = &ah->txq[q];
628 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 680 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
629 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, " 681 ath_print(common, ATH_DBG_QUEUE, "Release TXQ, "
630 "inactive queue: %u\n", q); 682 "inactive queue: %u\n", q);
631 return false; 683 return false;
632 } 684 }
633 685
634 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TX queue: %u\n", q); 686 ath_print(common, ATH_DBG_QUEUE, "Release TX queue: %u\n", q);
635 687
636 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; 688 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
637 ah->txok_interrupt_mask &= ~(1 << q); 689 ah->txok_interrupt_mask &= ~(1 << q);
@@ -643,28 +695,30 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
643 695
644 return true; 696 return true;
645} 697}
698EXPORT_SYMBOL(ath9k_hw_releasetxqueue);
646 699
647bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) 700bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
648{ 701{
649 struct ath9k_hw_capabilities *pCap = &ah->caps; 702 struct ath9k_hw_capabilities *pCap = &ah->caps;
703 struct ath_common *common = ath9k_hw_common(ah);
650 struct ath9k_channel *chan = ah->curchan; 704 struct ath9k_channel *chan = ah->curchan;
651 struct ath9k_tx_queue_info *qi; 705 struct ath9k_tx_queue_info *qi;
652 u32 cwMin, chanCwMin, value; 706 u32 cwMin, chanCwMin, value;
653 707
654 if (q >= pCap->total_queues) { 708 if (q >= pCap->total_queues) {
655 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, " 709 ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, "
656 "invalid queue: %u\n", q); 710 "invalid queue: %u\n", q);
657 return false; 711 return false;
658 } 712 }
659 713
660 qi = &ah->txq[q]; 714 qi = &ah->txq[q];
661 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 715 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
662 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, " 716 ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, "
663 "inactive queue: %u\n", q); 717 "inactive queue: %u\n", q);
664 return true; 718 return true;
665 } 719 }
666 720
667 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q); 721 ath_print(common, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q);
668 722
669 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) { 723 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
670 if (chan && IS_CHAN_B(chan)) 724 if (chan && IS_CHAN_B(chan))
@@ -799,6 +853,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
799 853
800 return true; 854 return true;
801} 855}
856EXPORT_SYMBOL(ath9k_hw_resettxqueue);
802 857
803int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, 858int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
804 u32 pa, struct ath_desc *nds, u64 tsf) 859 u32 pa, struct ath_desc *nds, u64 tsf)
@@ -880,6 +935,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
880 935
881 return 0; 936 return 0;
882} 937}
938EXPORT_SYMBOL(ath9k_hw_rxprocdesc);
883 939
884void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, 940void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
885 u32 size, u32 flags) 941 u32 size, u32 flags)
@@ -895,7 +951,15 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
895 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) 951 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
896 memset(&(ads->u), 0, sizeof(ads->u)); 952 memset(&(ads->u), 0, sizeof(ads->u));
897} 953}
954EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
898 955
956/*
957 * This can stop or re-enables RX.
958 *
959 * If bool is set this will kill any frame which is currently being
960 * transferred between the MAC and baseband and also prevent any new
961 * frames from getting started.
962 */
899bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set) 963bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
900{ 964{
901 u32 reg; 965 u32 reg;
@@ -911,8 +975,9 @@ bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
911 AR_DIAG_RX_ABORT)); 975 AR_DIAG_RX_ABORT));
912 976
913 reg = REG_READ(ah, AR_OBS_BUS_1); 977 reg = REG_READ(ah, AR_OBS_BUS_1);
914 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 978 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
915 "RX failed to go idle in 10 ms RXSM=0x%x\n", reg); 979 "RX failed to go idle in 10 ms RXSM=0x%x\n",
980 reg);
916 981
917 return false; 982 return false;
918 } 983 }
@@ -923,16 +988,19 @@ bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
923 988
924 return true; 989 return true;
925} 990}
991EXPORT_SYMBOL(ath9k_hw_setrxabort);
926 992
927void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp) 993void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
928{ 994{
929 REG_WRITE(ah, AR_RXDP, rxdp); 995 REG_WRITE(ah, AR_RXDP, rxdp);
930} 996}
997EXPORT_SYMBOL(ath9k_hw_putrxbuf);
931 998
932void ath9k_hw_rxena(struct ath_hw *ah) 999void ath9k_hw_rxena(struct ath_hw *ah)
933{ 1000{
934 REG_WRITE(ah, AR_CR, AR_CR_RXE); 1001 REG_WRITE(ah, AR_CR, AR_CR_RXE);
935} 1002}
1003EXPORT_SYMBOL(ath9k_hw_rxena);
936 1004
937void ath9k_hw_startpcureceive(struct ath_hw *ah) 1005void ath9k_hw_startpcureceive(struct ath_hw *ah)
938{ 1006{
@@ -942,6 +1010,7 @@ void ath9k_hw_startpcureceive(struct ath_hw *ah)
942 1010
943 REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 1011 REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
944} 1012}
1013EXPORT_SYMBOL(ath9k_hw_startpcureceive);
945 1014
946void ath9k_hw_stoppcurecv(struct ath_hw *ah) 1015void ath9k_hw_stoppcurecv(struct ath_hw *ah)
947{ 1016{
@@ -949,12 +1018,13 @@ void ath9k_hw_stoppcurecv(struct ath_hw *ah)
949 1018
950 ath9k_hw_disable_mib_counters(ah); 1019 ath9k_hw_disable_mib_counters(ah);
951} 1020}
1021EXPORT_SYMBOL(ath9k_hw_stoppcurecv);
952 1022
953bool ath9k_hw_stopdmarecv(struct ath_hw *ah) 1023bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
954{ 1024{
955#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ 1025#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */
956#define AH_RX_TIME_QUANTUM 100 /* usec */ 1026#define AH_RX_TIME_QUANTUM 100 /* usec */
957 1027 struct ath_common *common = ath9k_hw_common(ah);
958 int i; 1028 int i;
959 1029
960 REG_WRITE(ah, AR_CR, AR_CR_RXD); 1030 REG_WRITE(ah, AR_CR, AR_CR_RXD);
@@ -967,12 +1037,12 @@ bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
967 } 1037 }
968 1038
969 if (i == 0) { 1039 if (i == 0) {
970 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 1040 ath_print(common, ATH_DBG_FATAL,
971 "DMA failed to stop in %d ms " 1041 "DMA failed to stop in %d ms "
972 "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n", 1042 "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
973 AH_RX_STOP_DMA_TIMEOUT / 1000, 1043 AH_RX_STOP_DMA_TIMEOUT / 1000,
974 REG_READ(ah, AR_CR), 1044 REG_READ(ah, AR_CR),
975 REG_READ(ah, AR_DIAG_SW)); 1045 REG_READ(ah, AR_DIAG_SW));
976 return false; 1046 return false;
977 } else { 1047 } else {
978 return true; 1048 return true;
@@ -981,3 +1051,17 @@ bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
981#undef AH_RX_TIME_QUANTUM 1051#undef AH_RX_TIME_QUANTUM
982#undef AH_RX_STOP_DMA_TIMEOUT 1052#undef AH_RX_STOP_DMA_TIMEOUT
983} 1053}
1054EXPORT_SYMBOL(ath9k_hw_stopdmarecv);
1055
1056int ath9k_hw_beaconq_setup(struct ath_hw *ah)
1057{
1058 struct ath9k_tx_queue_info qi;
1059
1060 memset(&qi, 0, sizeof(qi));
1061 qi.tqi_aifs = 1;
1062 qi.tqi_cwmin = 0;
1063 qi.tqi_cwmax = 0;
1064 /* NB: don't enable any interrupts */
1065 return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
1066}
1067EXPORT_SYMBOL(ath9k_hw_beaconq_setup);