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.c416
1 files changed, 190 insertions, 226 deletions
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index e955bb9d98cb..c2091f1f4096 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
@@ -20,11 +20,11 @@
20static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, 20static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
21 struct ath9k_tx_queue_info *qi) 21 struct ath9k_tx_queue_info *qi)
22{ 22{
23 ath_print(ath9k_hw_common(ah), ATH_DBG_INTERRUPT, 23 ath_dbg(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", 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, 25 ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
26 ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask, 26 ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
27 ah->txurn_interrupt_mask); 27 ah->txurn_interrupt_mask);
28 28
29 ENABLE_REGWRITE_BUFFER(ah); 29 ENABLE_REGWRITE_BUFFER(ah);
30 30
@@ -40,7 +40,6 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
40 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); 40 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
41 41
42 REGWRITE_BUFFER_FLUSH(ah); 42 REGWRITE_BUFFER_FLUSH(ah);
43 DISABLE_REGWRITE_BUFFER(ah);
44} 43}
45 44
46u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) 45u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
@@ -57,8 +56,8 @@ EXPORT_SYMBOL(ath9k_hw_puttxbuf);
57 56
58void ath9k_hw_txstart(struct ath_hw *ah, u32 q) 57void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
59{ 58{
60 ath_print(ath9k_hw_common(ah), ATH_DBG_QUEUE, 59 ath_dbg(ath9k_hw_common(ah), ATH_DBG_QUEUE,
61 "Enable TXE on queue: %u\n", q); 60 "Enable TXE on queue: %u\n", q);
62 REG_WRITE(ah, AR_Q_TXE, 1 << q); 61 REG_WRITE(ah, AR_Q_TXE, 1 << q);
63} 62}
64EXPORT_SYMBOL(ath9k_hw_txstart); 63EXPORT_SYMBOL(ath9k_hw_txstart);
@@ -118,12 +117,11 @@ EXPORT_SYMBOL(ath9k_hw_numtxpending);
118bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel) 117bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
119{ 118{
120 u32 txcfg, curLevel, newLevel; 119 u32 txcfg, curLevel, newLevel;
121 enum ath9k_int omask;
122 120
123 if (ah->tx_trig_level >= ah->config.max_txtrig_level) 121 if (ah->tx_trig_level >= ah->config.max_txtrig_level)
124 return false; 122 return false;
125 123
126 omask = ath9k_hw_set_interrupts(ah, ah->imask & ~ATH9K_INT_GLOBAL); 124 ath9k_hw_disable_interrupts(ah);
127 125
128 txcfg = REG_READ(ah, AR_TXCFG); 126 txcfg = REG_READ(ah, AR_TXCFG);
129 curLevel = MS(txcfg, AR_FTRIG); 127 curLevel = MS(txcfg, AR_FTRIG);
@@ -137,7 +135,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
137 REG_WRITE(ah, AR_TXCFG, 135 REG_WRITE(ah, AR_TXCFG,
138 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG)); 136 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
139 137
140 ath9k_hw_set_interrupts(ah, omask); 138 ath9k_hw_enable_interrupts(ah);
141 139
142 ah->tx_trig_level = newLevel; 140 ah->tx_trig_level = newLevel;
143 141
@@ -145,85 +143,59 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
145} 143}
146EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel); 144EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel);
147 145
148bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) 146void ath9k_hw_abort_tx_dma(struct ath_hw *ah)
149{ 147{
150#define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */ 148 int i, q;
151#define ATH9K_TIME_QUANTUM 100 /* usec */
152 struct ath_common *common = ath9k_hw_common(ah);
153 struct ath9k_hw_capabilities *pCap = &ah->caps;
154 struct ath9k_tx_queue_info *qi;
155 u32 tsfLow, j, wait;
156 u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
157 149
158 if (q >= pCap->total_queues) { 150 REG_WRITE(ah, AR_Q_TXD, AR_Q_TXD_M);
159 ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
160 "invalid queue: %u\n", q);
161 return false;
162 }
163 151
164 qi = &ah->txq[q]; 152 REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
165 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 153 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
166 ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, " 154 REG_SET_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
167 "inactive queue: %u\n", q);
168 return false;
169 }
170 155
171 REG_WRITE(ah, AR_Q_TXD, 1 << q); 156 for (q = 0; q < AR_NUM_QCU; q++) {
157 for (i = 0; i < 1000; i++) {
158 if (i)
159 udelay(5);
172 160
173 for (wait = wait_time; wait != 0; wait--) { 161 if (!ath9k_hw_numtxpending(ah, q))
174 if (ath9k_hw_numtxpending(ah, q) == 0) 162 break;
175 break; 163 }
176 udelay(ATH9K_TIME_QUANTUM);
177 } 164 }
178 165
179 if (ath9k_hw_numtxpending(ah, q)) { 166 REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
180 ath_print(common, ATH_DBG_QUEUE, 167 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
181 "%s: Num of pending TX Frames %d on Q %d\n", 168 REG_CLR_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
182 __func__, ath9k_hw_numtxpending(ah, q), q);
183
184 for (j = 0; j < 2; j++) {
185 tsfLow = REG_READ(ah, AR_TSF_L32);
186 REG_WRITE(ah, AR_QUIET2,
187 SM(10, AR_QUIET2_QUIET_DUR));
188 REG_WRITE(ah, AR_QUIET_PERIOD, 100);
189 REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
190 REG_SET_BIT(ah, AR_TIMER_MODE,
191 AR_QUIET_TIMER_EN);
192
193 if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
194 break;
195 169
196 ath_print(common, ATH_DBG_QUEUE, 170 REG_WRITE(ah, AR_Q_TXD, 0);
197 "TSF has moved while trying to set " 171}
198 "quiet time TSF: 0x%08x\n", tsfLow); 172EXPORT_SYMBOL(ath9k_hw_abort_tx_dma);
199 }
200 173
201 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); 174bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q)
175{
176#define ATH9K_TX_STOP_DMA_TIMEOUT 1000 /* usec */
177#define ATH9K_TIME_QUANTUM 100 /* usec */
178 int wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
179 int wait;
202 180
203 udelay(200); 181 REG_WRITE(ah, AR_Q_TXD, 1 << q);
204 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
205 182
206 wait = wait_time; 183 for (wait = wait_time; wait != 0; wait--) {
207 while (ath9k_hw_numtxpending(ah, q)) { 184 if (wait != wait_time)
208 if ((--wait) == 0) {
209 ath_print(common, ATH_DBG_FATAL,
210 "Failed to stop TX DMA in 100 "
211 "msec after killing last frame\n");
212 break;
213 }
214 udelay(ATH9K_TIME_QUANTUM); 185 udelay(ATH9K_TIME_QUANTUM);
215 }
216 186
217 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); 187 if (ath9k_hw_numtxpending(ah, q) == 0)
188 break;
218 } 189 }
219 190
220 REG_WRITE(ah, AR_Q_TXD, 0); 191 REG_WRITE(ah, AR_Q_TXD, 0);
192
221 return wait != 0; 193 return wait != 0;
222 194
223#undef ATH9K_TX_STOP_DMA_TIMEOUT 195#undef ATH9K_TX_STOP_DMA_TIMEOUT
224#undef ATH9K_TIME_QUANTUM 196#undef ATH9K_TIME_QUANTUM
225} 197}
226EXPORT_SYMBOL(ath9k_hw_stoptxdma); 198EXPORT_SYMBOL(ath9k_hw_stop_dma_queue);
227 199
228void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs) 200void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
229{ 201{
@@ -237,23 +209,16 @@ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
237{ 209{
238 u32 cw; 210 u32 cw;
239 struct ath_common *common = ath9k_hw_common(ah); 211 struct ath_common *common = ath9k_hw_common(ah);
240 struct ath9k_hw_capabilities *pCap = &ah->caps;
241 struct ath9k_tx_queue_info *qi; 212 struct ath9k_tx_queue_info *qi;
242 213
243 if (q >= pCap->total_queues) {
244 ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, "
245 "invalid queue: %u\n", q);
246 return false;
247 }
248
249 qi = &ah->txq[q]; 214 qi = &ah->txq[q];
250 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 215 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
251 ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, " 216 ath_dbg(common, ATH_DBG_QUEUE,
252 "inactive queue: %u\n", q); 217 "Set TXQ properties, inactive queue: %u\n", q);
253 return false; 218 return false;
254 } 219 }
255 220
256 ath_print(common, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q); 221 ath_dbg(common, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q);
257 222
258 qi->tqi_ver = qinfo->tqi_ver; 223 qi->tqi_ver = qinfo->tqi_ver;
259 qi->tqi_subtype = qinfo->tqi_subtype; 224 qi->tqi_subtype = qinfo->tqi_subtype;
@@ -308,19 +273,12 @@ bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
308 struct ath9k_tx_queue_info *qinfo) 273 struct ath9k_tx_queue_info *qinfo)
309{ 274{
310 struct ath_common *common = ath9k_hw_common(ah); 275 struct ath_common *common = ath9k_hw_common(ah);
311 struct ath9k_hw_capabilities *pCap = &ah->caps;
312 struct ath9k_tx_queue_info *qi; 276 struct ath9k_tx_queue_info *qi;
313 277
314 if (q >= pCap->total_queues) {
315 ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, "
316 "invalid queue: %u\n", q);
317 return false;
318 }
319
320 qi = &ah->txq[q]; 278 qi = &ah->txq[q];
321 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 279 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
322 ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, " 280 ath_dbg(common, ATH_DBG_QUEUE,
323 "inactive queue: %u\n", q); 281 "Get TXQ properties, inactive queue: %u\n", q);
324 return false; 282 return false;
325 } 283 }
326 284
@@ -348,45 +306,41 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
348{ 306{
349 struct ath_common *common = ath9k_hw_common(ah); 307 struct ath_common *common = ath9k_hw_common(ah);
350 struct ath9k_tx_queue_info *qi; 308 struct ath9k_tx_queue_info *qi;
351 struct ath9k_hw_capabilities *pCap = &ah->caps;
352 int q; 309 int q;
353 310
354 switch (type) { 311 switch (type) {
355 case ATH9K_TX_QUEUE_BEACON: 312 case ATH9K_TX_QUEUE_BEACON:
356 q = pCap->total_queues - 1; 313 q = ATH9K_NUM_TX_QUEUES - 1;
357 break; 314 break;
358 case ATH9K_TX_QUEUE_CAB: 315 case ATH9K_TX_QUEUE_CAB:
359 q = pCap->total_queues - 2; 316 q = ATH9K_NUM_TX_QUEUES - 2;
360 break; 317 break;
361 case ATH9K_TX_QUEUE_PSPOLL: 318 case ATH9K_TX_QUEUE_PSPOLL:
362 q = 1; 319 q = 1;
363 break; 320 break;
364 case ATH9K_TX_QUEUE_UAPSD: 321 case ATH9K_TX_QUEUE_UAPSD:
365 q = pCap->total_queues - 3; 322 q = ATH9K_NUM_TX_QUEUES - 3;
366 break; 323 break;
367 case ATH9K_TX_QUEUE_DATA: 324 case ATH9K_TX_QUEUE_DATA:
368 for (q = 0; q < pCap->total_queues; q++) 325 for (q = 0; q < ATH9K_NUM_TX_QUEUES; q++)
369 if (ah->txq[q].tqi_type == 326 if (ah->txq[q].tqi_type ==
370 ATH9K_TX_QUEUE_INACTIVE) 327 ATH9K_TX_QUEUE_INACTIVE)
371 break; 328 break;
372 if (q == pCap->total_queues) { 329 if (q == ATH9K_NUM_TX_QUEUES) {
373 ath_print(common, ATH_DBG_FATAL, 330 ath_err(common, "No available TX queue\n");
374 "No available TX queue\n");
375 return -1; 331 return -1;
376 } 332 }
377 break; 333 break;
378 default: 334 default:
379 ath_print(common, ATH_DBG_FATAL, 335 ath_err(common, "Invalid TX queue type: %u\n", type);
380 "Invalid TX queue type: %u\n", type);
381 return -1; 336 return -1;
382 } 337 }
383 338
384 ath_print(common, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q); 339 ath_dbg(common, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q);
385 340
386 qi = &ah->txq[q]; 341 qi = &ah->txq[q];
387 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) { 342 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
388 ath_print(common, ATH_DBG_FATAL, 343 ath_err(common, "TX queue: %u already active\n", q);
389 "TX queue: %u already active\n", q);
390 return -1; 344 return -1;
391 } 345 }
392 memset(qi, 0, sizeof(struct ath9k_tx_queue_info)); 346 memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
@@ -413,23 +367,17 @@ EXPORT_SYMBOL(ath9k_hw_setuptxqueue);
413 367
414bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) 368bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
415{ 369{
416 struct ath9k_hw_capabilities *pCap = &ah->caps;
417 struct ath_common *common = ath9k_hw_common(ah); 370 struct ath_common *common = ath9k_hw_common(ah);
418 struct ath9k_tx_queue_info *qi; 371 struct ath9k_tx_queue_info *qi;
419 372
420 if (q >= pCap->total_queues) {
421 ath_print(common, ATH_DBG_QUEUE, "Release TXQ, "
422 "invalid queue: %u\n", q);
423 return false;
424 }
425 qi = &ah->txq[q]; 373 qi = &ah->txq[q];
426 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 374 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
427 ath_print(common, ATH_DBG_QUEUE, "Release TXQ, " 375 ath_dbg(common, ATH_DBG_QUEUE,
428 "inactive queue: %u\n", q); 376 "Release TXQ, inactive queue: %u\n", q);
429 return false; 377 return false;
430 } 378 }
431 379
432 ath_print(common, ATH_DBG_QUEUE, "Release TX queue: %u\n", q); 380 ath_dbg(common, ATH_DBG_QUEUE, "Release TX queue: %u\n", q);
433 381
434 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; 382 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
435 ah->txok_interrupt_mask &= ~(1 << q); 383 ah->txok_interrupt_mask &= ~(1 << q);
@@ -445,26 +393,19 @@ EXPORT_SYMBOL(ath9k_hw_releasetxqueue);
445 393
446bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) 394bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
447{ 395{
448 struct ath9k_hw_capabilities *pCap = &ah->caps;
449 struct ath_common *common = ath9k_hw_common(ah); 396 struct ath_common *common = ath9k_hw_common(ah);
450 struct ath9k_channel *chan = ah->curchan; 397 struct ath9k_channel *chan = ah->curchan;
451 struct ath9k_tx_queue_info *qi; 398 struct ath9k_tx_queue_info *qi;
452 u32 cwMin, chanCwMin, value; 399 u32 cwMin, chanCwMin, value;
453 400
454 if (q >= pCap->total_queues) {
455 ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, "
456 "invalid queue: %u\n", q);
457 return false;
458 }
459
460 qi = &ah->txq[q]; 401 qi = &ah->txq[q];
461 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 402 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
462 ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, " 403 ath_dbg(common, ATH_DBG_QUEUE,
463 "inactive queue: %u\n", q); 404 "Reset TXQ, inactive queue: %u\n", q);
464 return true; 405 return true;
465 } 406 }
466 407
467 ath_print(common, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q); 408 ath_dbg(common, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q);
468 409
469 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) { 410 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
470 if (chan && IS_CHAN_B(chan)) 411 if (chan && IS_CHAN_B(chan))
@@ -489,19 +430,21 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
489 SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)); 430 SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
490 431
491 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ); 432 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
492 REG_WRITE(ah, AR_DMISC(q),
493 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
494 433
495 REGWRITE_BUFFER_FLUSH(ah); 434 if (AR_SREV_9340(ah))
435 REG_WRITE(ah, AR_DMISC(q),
436 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1);
437 else
438 REG_WRITE(ah, AR_DMISC(q),
439 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
496 440
497 if (qi->tqi_cbrPeriod) { 441 if (qi->tqi_cbrPeriod) {
498 REG_WRITE(ah, AR_QCBRCFG(q), 442 REG_WRITE(ah, AR_QCBRCFG(q),
499 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) | 443 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
500 SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH)); 444 SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
501 REG_WRITE(ah, AR_QMISC(q), 445 REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_FSP_CBR |
502 REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | 446 (qi->tqi_cbrOverflowLimit ?
503 (qi->tqi_cbrOverflowLimit ? 447 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
504 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
505 } 448 }
506 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) { 449 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
507 REG_WRITE(ah, AR_QRDYTIMECFG(q), 450 REG_WRITE(ah, AR_QRDYTIMECFG(q),
@@ -509,51 +452,38 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
509 AR_Q_RDYTIMECFG_EN); 452 AR_Q_RDYTIMECFG_EN);
510 } 453 }
511 454
512 REGWRITE_BUFFER_FLUSH(ah);
513
514 REG_WRITE(ah, AR_DCHNTIME(q), 455 REG_WRITE(ah, AR_DCHNTIME(q),
515 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) | 456 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
516 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0)); 457 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
517 458
518 if (qi->tqi_burstTime 459 if (qi->tqi_burstTime
519 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) { 460 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE))
520 REG_WRITE(ah, AR_QMISC(q), 461 REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_RDYTIME_EXP_POLICY);
521 REG_READ(ah, AR_QMISC(q)) |
522 AR_Q_MISC_RDYTIME_EXP_POLICY);
523 462
524 } 463 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE)
525 464 REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS);
526 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
527 REG_WRITE(ah, AR_DMISC(q),
528 REG_READ(ah, AR_DMISC(q)) |
529 AR_D_MISC_POST_FR_BKOFF_DIS);
530 }
531 465
532 REGWRITE_BUFFER_FLUSH(ah); 466 REGWRITE_BUFFER_FLUSH(ah);
533 DISABLE_REGWRITE_BUFFER(ah);
534 467
535 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) { 468 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
536 REG_WRITE(ah, AR_DMISC(q), 469 REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_FRAG_BKOFF_EN);
537 REG_READ(ah, AR_DMISC(q)) | 470
538 AR_D_MISC_FRAG_BKOFF_EN);
539 }
540 switch (qi->tqi_type) { 471 switch (qi->tqi_type) {
541 case ATH9K_TX_QUEUE_BEACON: 472 case ATH9K_TX_QUEUE_BEACON:
542 ENABLE_REGWRITE_BUFFER(ah); 473 ENABLE_REGWRITE_BUFFER(ah);
543 474
544 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) 475 REG_SET_BIT(ah, AR_QMISC(q),
545 | AR_Q_MISC_FSP_DBA_GATED 476 AR_Q_MISC_FSP_DBA_GATED
546 | AR_Q_MISC_BEACON_USE 477 | AR_Q_MISC_BEACON_USE
547 | AR_Q_MISC_CBR_INCR_DIS1); 478 | AR_Q_MISC_CBR_INCR_DIS1);
548 479
549 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) 480 REG_SET_BIT(ah, AR_DMISC(q),
550 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << 481 (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
551 AR_D_MISC_ARB_LOCKOUT_CNTRL_S) 482 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
552 | AR_D_MISC_BEACON_USE 483 | AR_D_MISC_BEACON_USE
553 | AR_D_MISC_POST_FR_BKOFF_DIS); 484 | AR_D_MISC_POST_FR_BKOFF_DIS);
554 485
555 REGWRITE_BUFFER_FLUSH(ah); 486 REGWRITE_BUFFER_FLUSH(ah);
556 DISABLE_REGWRITE_BUFFER(ah);
557 487
558 /* 488 /*
559 * cwmin and cwmax should be 0 for beacon queue 489 * cwmin and cwmax should be 0 for beacon queue
@@ -570,42 +500,38 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
570 case ATH9K_TX_QUEUE_CAB: 500 case ATH9K_TX_QUEUE_CAB:
571 ENABLE_REGWRITE_BUFFER(ah); 501 ENABLE_REGWRITE_BUFFER(ah);
572 502
573 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) 503 REG_SET_BIT(ah, AR_QMISC(q),
574 | AR_Q_MISC_FSP_DBA_GATED 504 AR_Q_MISC_FSP_DBA_GATED
575 | AR_Q_MISC_CBR_INCR_DIS1 505 | AR_Q_MISC_CBR_INCR_DIS1
576 | AR_Q_MISC_CBR_INCR_DIS0); 506 | AR_Q_MISC_CBR_INCR_DIS0);
577 value = (qi->tqi_readyTime - 507 value = (qi->tqi_readyTime -
578 (ah->config.sw_beacon_response_time - 508 (ah->config.sw_beacon_response_time -
579 ah->config.dma_beacon_response_time) - 509 ah->config.dma_beacon_response_time) -
580 ah->config.additional_swba_backoff) * 1024; 510 ah->config.additional_swba_backoff) * 1024;
581 REG_WRITE(ah, AR_QRDYTIMECFG(q), 511 REG_WRITE(ah, AR_QRDYTIMECFG(q),
582 value | AR_Q_RDYTIMECFG_EN); 512 value | AR_Q_RDYTIMECFG_EN);
583 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) 513 REG_SET_BIT(ah, AR_DMISC(q),
584 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << 514 (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
585 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)); 515 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
586 516
587 REGWRITE_BUFFER_FLUSH(ah); 517 REGWRITE_BUFFER_FLUSH(ah);
588 DISABLE_REGWRITE_BUFFER(ah);
589 518
590 break; 519 break;
591 case ATH9K_TX_QUEUE_PSPOLL: 520 case ATH9K_TX_QUEUE_PSPOLL:
592 REG_WRITE(ah, AR_QMISC(q), 521 REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_CBR_INCR_DIS1);
593 REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
594 break; 522 break;
595 case ATH9K_TX_QUEUE_UAPSD: 523 case ATH9K_TX_QUEUE_UAPSD:
596 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) | 524 REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS);
597 AR_D_MISC_POST_FR_BKOFF_DIS);
598 break; 525 break;
599 default: 526 default:
600 break; 527 break;
601 } 528 }
602 529
603 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) { 530 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
604 REG_WRITE(ah, AR_DMISC(q), 531 REG_SET_BIT(ah, AR_DMISC(q),
605 REG_READ(ah, AR_DMISC(q)) | 532 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
606 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, 533 AR_D_MISC_ARB_LOCKOUT_CNTRL) |
607 AR_D_MISC_ARB_LOCKOUT_CNTRL) | 534 AR_D_MISC_POST_FR_BKOFF_DIS);
608 AR_D_MISC_POST_FR_BKOFF_DIS);
609 } 535 }
610 536
611 if (AR_SREV_9300_20_OR_LATER(ah)) 537 if (AR_SREV_9300_20_OR_LATER(ah))
@@ -703,6 +629,12 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
703 rs->rs_flags |= ATH9K_RX_DECRYPT_BUSY; 629 rs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
704 630
705 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) { 631 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
632 /*
633 * Treat these errors as mutually exclusive to avoid spurious
634 * extra error reports from the hardware. If a CRC error is
635 * reported, then decryption and MIC errors are irrelevant,
636 * the frame is going to be dropped either way
637 */
706 if (ads.ds_rxstatus8 & AR_CRCErr) 638 if (ads.ds_rxstatus8 & AR_CRCErr)
707 rs->rs_status |= ATH9K_RXERR_CRC; 639 rs->rs_status |= ATH9K_RXERR_CRC;
708 else if (ads.ds_rxstatus8 & AR_PHYErr) { 640 else if (ads.ds_rxstatus8 & AR_PHYErr) {
@@ -713,6 +645,9 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
713 rs->rs_status |= ATH9K_RXERR_DECRYPT; 645 rs->rs_status |= ATH9K_RXERR_DECRYPT;
714 else if (ads.ds_rxstatus8 & AR_MichaelErr) 646 else if (ads.ds_rxstatus8 & AR_MichaelErr)
715 rs->rs_status |= ATH9K_RXERR_MIC; 647 rs->rs_status |= ATH9K_RXERR_MIC;
648
649 if (ads.ds_rxstatus8 & AR_KeyMiss)
650 rs->rs_status |= ATH9K_RXERR_DECRYPT;
716 } 651 }
717 652
718 return 0; 653 return 0;
@@ -741,9 +676,9 @@ bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
741 AR_DIAG_RX_ABORT)); 676 AR_DIAG_RX_ABORT));
742 677
743 reg = REG_READ(ah, AR_OBS_BUS_1); 678 reg = REG_READ(ah, AR_OBS_BUS_1);
744 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, 679 ath_err(ath9k_hw_common(ah),
745 "RX failed to go idle in 10 ms RXSM=0x%x\n", 680 "RX failed to go idle in 10 ms RXSM=0x%x\n",
746 reg); 681 reg);
747 682
748 return false; 683 return false;
749 } 684 }
@@ -772,14 +707,6 @@ void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning)
772} 707}
773EXPORT_SYMBOL(ath9k_hw_startpcureceive); 708EXPORT_SYMBOL(ath9k_hw_startpcureceive);
774 709
775void ath9k_hw_stoppcurecv(struct ath_hw *ah)
776{
777 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
778
779 ath9k_hw_disable_mib_counters(ah);
780}
781EXPORT_SYMBOL(ath9k_hw_stoppcurecv);
782
783void ath9k_hw_abortpcurecv(struct ath_hw *ah) 710void ath9k_hw_abortpcurecv(struct ath_hw *ah)
784{ 711{
785 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS); 712 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
@@ -788,35 +715,51 @@ void ath9k_hw_abortpcurecv(struct ath_hw *ah)
788} 715}
789EXPORT_SYMBOL(ath9k_hw_abortpcurecv); 716EXPORT_SYMBOL(ath9k_hw_abortpcurecv);
790 717
791bool ath9k_hw_stopdmarecv(struct ath_hw *ah) 718bool ath9k_hw_stopdmarecv(struct ath_hw *ah, bool *reset)
792{ 719{
793#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ 720#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */
794#define AH_RX_TIME_QUANTUM 100 /* usec */
795 struct ath_common *common = ath9k_hw_common(ah); 721 struct ath_common *common = ath9k_hw_common(ah);
722 u32 mac_status, last_mac_status = 0;
796 int i; 723 int i;
797 724
725 /* Enable access to the DMA observation bus */
726 REG_WRITE(ah, AR_MACMISC,
727 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
728 (AR_MACMISC_MISC_OBS_BUS_1 <<
729 AR_MACMISC_MISC_OBS_BUS_MSB_S)));
730
798 REG_WRITE(ah, AR_CR, AR_CR_RXD); 731 REG_WRITE(ah, AR_CR, AR_CR_RXD);
799 732
800 /* Wait for rx enable bit to go low */ 733 /* Wait for rx enable bit to go low */
801 for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) { 734 for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) {
802 if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0) 735 if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0)
803 break; 736 break;
737
738 if (!AR_SREV_9300_20_OR_LATER(ah)) {
739 mac_status = REG_READ(ah, AR_DMADBG_7) & 0x7f0;
740 if (mac_status == 0x1c0 && mac_status == last_mac_status) {
741 *reset = true;
742 break;
743 }
744
745 last_mac_status = mac_status;
746 }
747
804 udelay(AH_TIME_QUANTUM); 748 udelay(AH_TIME_QUANTUM);
805 } 749 }
806 750
807 if (i == 0) { 751 if (i == 0) {
808 ath_print(common, ATH_DBG_FATAL, 752 ath_err(common,
809 "DMA failed to stop in %d ms " 753 "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x DMADBG_7=0x%08x\n",
810 "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n", 754 AH_RX_STOP_DMA_TIMEOUT / 1000,
811 AH_RX_STOP_DMA_TIMEOUT / 1000, 755 REG_READ(ah, AR_CR),
812 REG_READ(ah, AR_CR), 756 REG_READ(ah, AR_DIAG_SW),
813 REG_READ(ah, AR_DIAG_SW)); 757 REG_READ(ah, AR_DMADBG_7));
814 return false; 758 return false;
815 } else { 759 } else {
816 return true; 760 return true;
817 } 761 }
818 762
819#undef AH_RX_TIME_QUANTUM
820#undef AH_RX_STOP_DMA_TIMEOUT 763#undef AH_RX_STOP_DMA_TIMEOUT
821} 764}
822EXPORT_SYMBOL(ath9k_hw_stopdmarecv); 765EXPORT_SYMBOL(ath9k_hw_stopdmarecv);
@@ -854,28 +797,61 @@ bool ath9k_hw_intrpend(struct ath_hw *ah)
854} 797}
855EXPORT_SYMBOL(ath9k_hw_intrpend); 798EXPORT_SYMBOL(ath9k_hw_intrpend);
856 799
857enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, 800void ath9k_hw_disable_interrupts(struct ath_hw *ah)
858 enum ath9k_int ints) 801{
802 struct ath_common *common = ath9k_hw_common(ah);
803
804 ath_dbg(common, ATH_DBG_INTERRUPT, "disable IER\n");
805 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
806 (void) REG_READ(ah, AR_IER);
807 if (!AR_SREV_9100(ah)) {
808 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
809 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
810
811 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
812 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
813 }
814}
815EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
816
817void ath9k_hw_enable_interrupts(struct ath_hw *ah)
818{
819 struct ath_common *common = ath9k_hw_common(ah);
820 u32 sync_default = AR_INTR_SYNC_DEFAULT;
821
822 if (!(ah->imask & ATH9K_INT_GLOBAL))
823 return;
824
825 if (AR_SREV_9340(ah))
826 sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
827
828 ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n");
829 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
830 if (!AR_SREV_9100(ah)) {
831 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
832 AR_INTR_MAC_IRQ);
833 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
834
835
836 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
837 REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default);
838 }
839 ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
840 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
841}
842EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
843
844void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
859{ 845{
860 enum ath9k_int omask = ah->imask; 846 enum ath9k_int omask = ah->imask;
861 u32 mask, mask2; 847 u32 mask, mask2;
862 struct ath9k_hw_capabilities *pCap = &ah->caps; 848 struct ath9k_hw_capabilities *pCap = &ah->caps;
863 struct ath_common *common = ath9k_hw_common(ah); 849 struct ath_common *common = ath9k_hw_common(ah);
864 850
865 ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); 851 if (!(ints & ATH9K_INT_GLOBAL))
866 852 ath9k_hw_disable_interrupts(ah);
867 if (omask & ATH9K_INT_GLOBAL) {
868 ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
869 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
870 (void) REG_READ(ah, AR_IER);
871 if (!AR_SREV_9100(ah)) {
872 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
873 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
874 853
875 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); 854 ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
876 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
877 }
878 }
879 855
880 /* TODO: global int Ref count */ 856 /* TODO: global int Ref count */
881 mask = ints & ATH9K_INT_COMMON; 857 mask = ints & ATH9K_INT_COMMON;
@@ -914,6 +890,9 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
914 mask |= AR_IMR_GENTMR; 890 mask |= AR_IMR_GENTMR;
915 } 891 }
916 892
893 if (ints & ATH9K_INT_GENTIMER)
894 mask |= AR_IMR_GENTMR;
895
917 if (ints & (ATH9K_INT_BMISC)) { 896 if (ints & (ATH9K_INT_BMISC)) {
918 mask |= AR_IMR_BCNMISC; 897 mask |= AR_IMR_BCNMISC;
919 if (ints & ATH9K_INT_TIM) 898 if (ints & ATH9K_INT_TIM)
@@ -936,7 +915,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
936 mask2 |= AR_IMR_S2_CST; 915 mask2 |= AR_IMR_S2_CST;
937 } 916 }
938 917
939 ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); 918 ath_dbg(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
940 REG_WRITE(ah, AR_IMR, mask); 919 REG_WRITE(ah, AR_IMR, mask);
941 ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC | 920 ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
942 AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | 921 AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
@@ -951,24 +930,9 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
951 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); 930 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
952 } 931 }
953 932
954 if (ints & ATH9K_INT_GLOBAL) { 933 if (ints & ATH9K_INT_GLOBAL)
955 ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n"); 934 ath9k_hw_enable_interrupts(ah);
956 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
957 if (!AR_SREV_9100(ah)) {
958 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
959 AR_INTR_MAC_IRQ);
960 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
961
962
963 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
964 AR_INTR_SYNC_DEFAULT);
965 REG_WRITE(ah, AR_INTR_SYNC_MASK,
966 AR_INTR_SYNC_DEFAULT);
967 }
968 ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
969 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
970 }
971 935
972 return omask; 936 return;
973} 937}
974EXPORT_SYMBOL(ath9k_hw_set_interrupts); 938EXPORT_SYMBOL(ath9k_hw_set_interrupts);