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.c571
1 files changed, 236 insertions, 335 deletions
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index efc420cd42b..0e425cb4bbb 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -25,14 +25,21 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
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 ENABLE_REGWRITE_BUFFER(ah);
29
28 REG_WRITE(ah, AR_IMR_S0, 30 REG_WRITE(ah, AR_IMR_S0,
29 SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK) 31 SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
30 | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC)); 32 | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
31 REG_WRITE(ah, AR_IMR_S1, 33 REG_WRITE(ah, AR_IMR_S1,
32 SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR) 34 SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
33 | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL)); 35 | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
34 REG_RMW_FIELD(ah, AR_IMR_S2, 36
35 AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask); 37 ah->imrs2_reg &= ~AR_IMR_S2_QCU_TXURN;
38 ah->imrs2_reg |= (ah->txurn_interrupt_mask & AR_IMR_S2_QCU_TXURN);
39 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
40
41 REGWRITE_BUFFER_FLUSH(ah);
42 DISABLE_REGWRITE_BUFFER(ah);
36} 43}
37 44
38u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) 45u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
@@ -55,6 +62,18 @@ void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
55} 62}
56EXPORT_SYMBOL(ath9k_hw_txstart); 63EXPORT_SYMBOL(ath9k_hw_txstart);
57 64
65void 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}
75EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
76
58u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q) 77u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
59{ 78{
60 u32 npend; 79 u32 npend;
@@ -103,7 +122,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
103 if (ah->tx_trig_level >= ah->config.max_txtrig_level) 122 if (ah->tx_trig_level >= ah->config.max_txtrig_level)
104 return false; 123 return false;
105 124
106 omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL); 125 omask = ath9k_hw_set_interrupts(ah, ah->imask & ~ATH9K_INT_GLOBAL);
107 126
108 txcfg = REG_READ(ah, AR_TXCFG); 127 txcfg = REG_READ(ah, AR_TXCFG);
109 curLevel = MS(txcfg, AR_FTRIG); 128 curLevel = MS(txcfg, AR_FTRIG);
@@ -205,280 +224,6 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
205} 224}
206EXPORT_SYMBOL(ath9k_hw_stoptxdma); 225EXPORT_SYMBOL(ath9k_hw_stoptxdma);
207 226
208void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
209 u32 segLen, bool firstSeg,
210 bool lastSeg, const struct ath_desc *ds0)
211{
212 struct ar5416_desc *ads = AR5416DESC(ds);
213
214 if (firstSeg) {
215 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
216 } else if (lastSeg) {
217 ads->ds_ctl0 = 0;
218 ads->ds_ctl1 = segLen;
219 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
220 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
221 } else {
222 ads->ds_ctl0 = 0;
223 ads->ds_ctl1 = segLen | AR_TxMore;
224 ads->ds_ctl2 = 0;
225 ads->ds_ctl3 = 0;
226 }
227 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
228 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
229 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
230 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
231 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
232}
233EXPORT_SYMBOL(ath9k_hw_filltxdesc);
234
235void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
236{
237 struct ar5416_desc *ads = AR5416DESC(ds);
238
239 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
240 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
241 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
242 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
243 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
244}
245EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
246
247int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
248{
249 struct ar5416_desc *ads = AR5416DESC(ds);
250
251 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
252 return -EINPROGRESS;
253
254 ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
255 ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
256 ds->ds_txstat.ts_status = 0;
257 ds->ds_txstat.ts_flags = 0;
258
259 if (ads->ds_txstatus1 & AR_FrmXmitOK)
260 ds->ds_txstat.ts_status |= ATH9K_TX_ACKED;
261 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
262 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
263 if (ads->ds_txstatus1 & AR_Filtered)
264 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
265 if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
266 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
267 ath9k_hw_updatetxtriglevel(ah, true);
268 }
269 if (ads->ds_txstatus9 & AR_TxOpExceeded)
270 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
271 if (ads->ds_txstatus1 & AR_TxTimerExpired)
272 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
273
274 if (ads->ds_txstatus1 & AR_DescCfgErr)
275 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
276 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
277 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
278 ath9k_hw_updatetxtriglevel(ah, true);
279 }
280 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
281 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
282 ath9k_hw_updatetxtriglevel(ah, true);
283 }
284 if (ads->ds_txstatus0 & AR_TxBaStatus) {
285 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
286 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
287 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
288 }
289
290 ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
291 switch (ds->ds_txstat.ts_rateindex) {
292 case 0:
293 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
294 break;
295 case 1:
296 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
297 break;
298 case 2:
299 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
300 break;
301 case 3:
302 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
303 break;
304 }
305
306 ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
307 ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
308 ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
309 ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
310 ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
311 ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
312 ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
313 ds->ds_txstat.evm0 = ads->AR_TxEVM0;
314 ds->ds_txstat.evm1 = ads->AR_TxEVM1;
315 ds->ds_txstat.evm2 = ads->AR_TxEVM2;
316 ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
317 ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
318 ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
319 ds->ds_txstat.ts_antenna = 0;
320
321 return 0;
322}
323EXPORT_SYMBOL(ath9k_hw_txprocdesc);
324
325void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
326 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
327 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
328{
329 struct ar5416_desc *ads = AR5416DESC(ds);
330
331 txPower += ah->txpower_indexoffset;
332 if (txPower > 63)
333 txPower = 63;
334
335 ads->ds_ctl0 = (pktLen & AR_FrameLen)
336 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
337 | SM(txPower, AR_XmitPower)
338 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
339 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
340 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
341 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
342
343 ads->ds_ctl1 =
344 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
345 | SM(type, AR_FrameType)
346 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
347 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
348 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
349
350 ads->ds_ctl6 = SM(keyType, AR_EncrType);
351
352 if (AR_SREV_9285(ah)) {
353 ads->ds_ctl8 = 0;
354 ads->ds_ctl9 = 0;
355 ads->ds_ctl10 = 0;
356 ads->ds_ctl11 = 0;
357 }
358}
359EXPORT_SYMBOL(ath9k_hw_set11n_txdesc);
360
361void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
362 struct ath_desc *lastds,
363 u32 durUpdateEn, u32 rtsctsRate,
364 u32 rtsctsDuration,
365 struct ath9k_11n_rate_series series[],
366 u32 nseries, u32 flags)
367{
368 struct ar5416_desc *ads = AR5416DESC(ds);
369 struct ar5416_desc *last_ads = AR5416DESC(lastds);
370 u32 ds_ctl0;
371
372 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
373 ds_ctl0 = ads->ds_ctl0;
374
375 if (flags & ATH9K_TXDESC_RTSENA) {
376 ds_ctl0 &= ~AR_CTSEnable;
377 ds_ctl0 |= AR_RTSEnable;
378 } else {
379 ds_ctl0 &= ~AR_RTSEnable;
380 ds_ctl0 |= AR_CTSEnable;
381 }
382
383 ads->ds_ctl0 = ds_ctl0;
384 } else {
385 ads->ds_ctl0 =
386 (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
387 }
388
389 ads->ds_ctl2 = set11nTries(series, 0)
390 | set11nTries(series, 1)
391 | set11nTries(series, 2)
392 | set11nTries(series, 3)
393 | (durUpdateEn ? AR_DurUpdateEna : 0)
394 | SM(0, AR_BurstDur);
395
396 ads->ds_ctl3 = set11nRate(series, 0)
397 | set11nRate(series, 1)
398 | set11nRate(series, 2)
399 | set11nRate(series, 3);
400
401 ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
402 | set11nPktDurRTSCTS(series, 1);
403
404 ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
405 | set11nPktDurRTSCTS(series, 3);
406
407 ads->ds_ctl7 = set11nRateFlags(series, 0)
408 | set11nRateFlags(series, 1)
409 | set11nRateFlags(series, 2)
410 | set11nRateFlags(series, 3)
411 | SM(rtsctsRate, AR_RTSCTSRate);
412 last_ads->ds_ctl2 = ads->ds_ctl2;
413 last_ads->ds_ctl3 = ads->ds_ctl3;
414}
415EXPORT_SYMBOL(ath9k_hw_set11n_ratescenario);
416
417void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
418 u32 aggrLen)
419{
420 struct ar5416_desc *ads = AR5416DESC(ds);
421
422 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
423 ads->ds_ctl6 &= ~AR_AggrLen;
424 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
425}
426EXPORT_SYMBOL(ath9k_hw_set11n_aggr_first);
427
428void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
429 u32 numDelims)
430{
431 struct ar5416_desc *ads = AR5416DESC(ds);
432 unsigned int ctl6;
433
434 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
435
436 ctl6 = ads->ds_ctl6;
437 ctl6 &= ~AR_PadDelim;
438 ctl6 |= SM(numDelims, AR_PadDelim);
439 ads->ds_ctl6 = ctl6;
440}
441EXPORT_SYMBOL(ath9k_hw_set11n_aggr_middle);
442
443void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
444{
445 struct ar5416_desc *ads = AR5416DESC(ds);
446
447 ads->ds_ctl1 |= AR_IsAggr;
448 ads->ds_ctl1 &= ~AR_MoreAggr;
449 ads->ds_ctl6 &= ~AR_PadDelim;
450}
451EXPORT_SYMBOL(ath9k_hw_set11n_aggr_last);
452
453void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
454{
455 struct ar5416_desc *ads = AR5416DESC(ds);
456
457 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
458}
459EXPORT_SYMBOL(ath9k_hw_clr11n_aggr);
460
461void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
462 u32 burstDuration)
463{
464 struct ar5416_desc *ads = AR5416DESC(ds);
465
466 ads->ds_ctl2 &= ~AR_BurstDur;
467 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
468}
469EXPORT_SYMBOL(ath9k_hw_set11n_burstduration);
470
471void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
472 u32 vmf)
473{
474 struct ar5416_desc *ads = AR5416DESC(ds);
475
476 if (vmf)
477 ads->ds_ctl0 |= AR_VirtMoreFrag;
478 else
479 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
480}
481
482void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs) 227void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
483{ 228{
484 *txqs &= ah->intr_txqs; 229 *txqs &= ah->intr_txqs;
@@ -730,6 +475,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
730 } else 475 } else
731 cwMin = qi->tqi_cwmin; 476 cwMin = qi->tqi_cwmin;
732 477
478 ENABLE_REGWRITE_BUFFER(ah);
479
733 REG_WRITE(ah, AR_DLCL_IFS(q), 480 REG_WRITE(ah, AR_DLCL_IFS(q),
734 SM(cwMin, AR_D_LCL_IFS_CWMIN) | 481 SM(cwMin, AR_D_LCL_IFS_CWMIN) |
735 SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) | 482 SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
@@ -744,6 +491,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
744 REG_WRITE(ah, AR_DMISC(q), 491 REG_WRITE(ah, AR_DMISC(q),
745 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2); 492 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
746 493
494 REGWRITE_BUFFER_FLUSH(ah);
495
747 if (qi->tqi_cbrPeriod) { 496 if (qi->tqi_cbrPeriod) {
748 REG_WRITE(ah, AR_QCBRCFG(q), 497 REG_WRITE(ah, AR_QCBRCFG(q),
749 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) | 498 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
@@ -759,6 +508,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
759 AR_Q_RDYTIMECFG_EN); 508 AR_Q_RDYTIMECFG_EN);
760 } 509 }
761 510
511 REGWRITE_BUFFER_FLUSH(ah);
512
762 REG_WRITE(ah, AR_DCHNTIME(q), 513 REG_WRITE(ah, AR_DCHNTIME(q),
763 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) | 514 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
764 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0)); 515 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
@@ -776,6 +527,10 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
776 REG_READ(ah, AR_DMISC(q)) | 527 REG_READ(ah, AR_DMISC(q)) |
777 AR_D_MISC_POST_FR_BKOFF_DIS); 528 AR_D_MISC_POST_FR_BKOFF_DIS);
778 } 529 }
530
531 REGWRITE_BUFFER_FLUSH(ah);
532 DISABLE_REGWRITE_BUFFER(ah);
533
779 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) { 534 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
780 REG_WRITE(ah, AR_DMISC(q), 535 REG_WRITE(ah, AR_DMISC(q),
781 REG_READ(ah, AR_DMISC(q)) | 536 REG_READ(ah, AR_DMISC(q)) |
@@ -783,6 +538,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
783 } 538 }
784 switch (qi->tqi_type) { 539 switch (qi->tqi_type) {
785 case ATH9K_TX_QUEUE_BEACON: 540 case ATH9K_TX_QUEUE_BEACON:
541 ENABLE_REGWRITE_BUFFER(ah);
542
786 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) 543 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
787 | AR_Q_MISC_FSP_DBA_GATED 544 | AR_Q_MISC_FSP_DBA_GATED
788 | AR_Q_MISC_BEACON_USE 545 | AR_Q_MISC_BEACON_USE
@@ -793,8 +550,20 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
793 AR_D_MISC_ARB_LOCKOUT_CNTRL_S) 550 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
794 | AR_D_MISC_BEACON_USE 551 | AR_D_MISC_BEACON_USE
795 | AR_D_MISC_POST_FR_BKOFF_DIS); 552 | AR_D_MISC_POST_FR_BKOFF_DIS);
553
554 REGWRITE_BUFFER_FLUSH(ah);
555 DISABLE_REGWRITE_BUFFER(ah);
556
557 /* cwmin and cwmax should be 0 for beacon queue */
558 if (AR_SREV_9300_20_OR_LATER(ah)) {
559 REG_WRITE(ah, AR_DLCL_IFS(q), SM(0, AR_D_LCL_IFS_CWMIN)
560 | SM(0, AR_D_LCL_IFS_CWMAX)
561 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
562 }
796 break; 563 break;
797 case ATH9K_TX_QUEUE_CAB: 564 case ATH9K_TX_QUEUE_CAB:
565 ENABLE_REGWRITE_BUFFER(ah);
566
798 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) 567 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
799 | AR_Q_MISC_FSP_DBA_GATED 568 | AR_Q_MISC_FSP_DBA_GATED
800 | AR_Q_MISC_CBR_INCR_DIS1 569 | AR_Q_MISC_CBR_INCR_DIS1
@@ -808,6 +577,10 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
808 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) 577 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
809 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << 578 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
810 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)); 579 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
580
581 REGWRITE_BUFFER_FLUSH(ah);
582 DISABLE_REGWRITE_BUFFER(ah);
583
811 break; 584 break;
812 case ATH9K_TX_QUEUE_PSPOLL: 585 case ATH9K_TX_QUEUE_PSPOLL:
813 REG_WRITE(ah, AR_QMISC(q), 586 REG_WRITE(ah, AR_QMISC(q),
@@ -829,6 +602,9 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
829 AR_D_MISC_POST_FR_BKOFF_DIS); 602 AR_D_MISC_POST_FR_BKOFF_DIS);
830 } 603 }
831 604
605 if (AR_SREV_9300_20_OR_LATER(ah))
606 REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN);
607
832 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE) 608 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
833 ah->txok_interrupt_mask |= 1 << q; 609 ah->txok_interrupt_mask |= 1 << q;
834 else 610 else
@@ -856,7 +632,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
856EXPORT_SYMBOL(ath9k_hw_resettxqueue); 632EXPORT_SYMBOL(ath9k_hw_resettxqueue);
857 633
858int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, 634int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
859 u32 pa, struct ath_desc *nds, u64 tsf) 635 struct ath_rx_status *rs, u64 tsf)
860{ 636{
861 struct ar5416_desc ads; 637 struct ar5416_desc ads;
862 struct ar5416_desc *adsp = AR5416DESC(ds); 638 struct ar5416_desc *adsp = AR5416DESC(ds);
@@ -867,92 +643,76 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
867 643
868 ads.u.rx = adsp->u.rx; 644 ads.u.rx = adsp->u.rx;
869 645
870 ds->ds_rxstat.rs_status = 0; 646 rs->rs_status = 0;
871 ds->ds_rxstat.rs_flags = 0; 647 rs->rs_flags = 0;
872 648
873 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen; 649 rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
874 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp; 650 rs->rs_tstamp = ads.AR_RcvTimestamp;
875 651
876 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) { 652 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
877 ds->ds_rxstat.rs_rssi = ATH9K_RSSI_BAD; 653 rs->rs_rssi = ATH9K_RSSI_BAD;
878 ds->ds_rxstat.rs_rssi_ctl0 = ATH9K_RSSI_BAD; 654 rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD;
879 ds->ds_rxstat.rs_rssi_ctl1 = ATH9K_RSSI_BAD; 655 rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD;
880 ds->ds_rxstat.rs_rssi_ctl2 = ATH9K_RSSI_BAD; 656 rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD;
881 ds->ds_rxstat.rs_rssi_ext0 = ATH9K_RSSI_BAD; 657 rs->rs_rssi_ext0 = ATH9K_RSSI_BAD;
882 ds->ds_rxstat.rs_rssi_ext1 = ATH9K_RSSI_BAD; 658 rs->rs_rssi_ext1 = ATH9K_RSSI_BAD;
883 ds->ds_rxstat.rs_rssi_ext2 = ATH9K_RSSI_BAD; 659 rs->rs_rssi_ext2 = ATH9K_RSSI_BAD;
884 } else { 660 } else {
885 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined); 661 rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
886 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, 662 rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
887 AR_RxRSSIAnt00); 663 AR_RxRSSIAnt00);
888 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, 664 rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
889 AR_RxRSSIAnt01); 665 AR_RxRSSIAnt01);
890 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, 666 rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
891 AR_RxRSSIAnt02); 667 AR_RxRSSIAnt02);
892 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, 668 rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4,
893 AR_RxRSSIAnt10); 669 AR_RxRSSIAnt10);
894 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, 670 rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4,
895 AR_RxRSSIAnt11); 671 AR_RxRSSIAnt11);
896 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, 672 rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4,
897 AR_RxRSSIAnt12); 673 AR_RxRSSIAnt12);
898 } 674 }
899 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid) 675 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
900 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx); 676 rs->rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
901 else 677 else
902 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID; 678 rs->rs_keyix = ATH9K_RXKEYIX_INVALID;
903 679
904 ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads)); 680 rs->rs_rate = RXSTATUS_RATE(ah, (&ads));
905 ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0; 681 rs->rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
906 682
907 ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0; 683 rs->rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
908 ds->ds_rxstat.rs_moreaggr = 684 rs->rs_moreaggr =
909 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0; 685 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
910 ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna); 686 rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
911 ds->ds_rxstat.rs_flags = 687 rs->rs_flags =
912 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0; 688 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
913 ds->ds_rxstat.rs_flags |= 689 rs->rs_flags |=
914 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0; 690 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
915 691
916 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr) 692 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
917 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE; 693 rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
918 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) 694 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
919 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST; 695 rs->rs_flags |= ATH9K_RX_DELIM_CRC_POST;
920 if (ads.ds_rxstatus8 & AR_DecryptBusyErr) 696 if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
921 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY; 697 rs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
922 698
923 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) { 699 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
924 if (ads.ds_rxstatus8 & AR_CRCErr) 700 if (ads.ds_rxstatus8 & AR_CRCErr)
925 ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC; 701 rs->rs_status |= ATH9K_RXERR_CRC;
926 else if (ads.ds_rxstatus8 & AR_PHYErr) { 702 else if (ads.ds_rxstatus8 & AR_PHYErr) {
927 ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY; 703 rs->rs_status |= ATH9K_RXERR_PHY;
928 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode); 704 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
929 ds->ds_rxstat.rs_phyerr = phyerr; 705 rs->rs_phyerr = phyerr;
930 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) 706 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
931 ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT; 707 rs->rs_status |= ATH9K_RXERR_DECRYPT;
932 else if (ads.ds_rxstatus8 & AR_MichaelErr) 708 else if (ads.ds_rxstatus8 & AR_MichaelErr)
933 ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC; 709 rs->rs_status |= ATH9K_RXERR_MIC;
934 } 710 }
935 711
936 return 0; 712 return 0;
937} 713}
938EXPORT_SYMBOL(ath9k_hw_rxprocdesc); 714EXPORT_SYMBOL(ath9k_hw_rxprocdesc);
939 715
940void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
941 u32 size, u32 flags)
942{
943 struct ar5416_desc *ads = AR5416DESC(ds);
944 struct ath9k_hw_capabilities *pCap = &ah->caps;
945
946 ads->ds_ctl1 = size & AR_BufLen;
947 if (flags & ATH9K_RXDESC_INTREQ)
948 ads->ds_ctl1 |= AR_RxIntrReq;
949
950 ads->ds_rxstatus8 &= ~AR_RxDone;
951 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
952 memset(&(ads->u), 0, sizeof(ads->u));
953}
954EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
955
956/* 716/*
957 * This can stop or re-enables RX. 717 * This can stop or re-enables RX.
958 * 718 *
@@ -996,12 +756,6 @@ void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
996} 756}
997EXPORT_SYMBOL(ath9k_hw_putrxbuf); 757EXPORT_SYMBOL(ath9k_hw_putrxbuf);
998 758
999void ath9k_hw_rxena(struct ath_hw *ah)
1000{
1001 REG_WRITE(ah, AR_CR, AR_CR_RXE);
1002}
1003EXPORT_SYMBOL(ath9k_hw_rxena);
1004
1005void ath9k_hw_startpcureceive(struct ath_hw *ah) 759void ath9k_hw_startpcureceive(struct ath_hw *ah)
1006{ 760{
1007 ath9k_enable_mib_counters(ah); 761 ath9k_enable_mib_counters(ah);
@@ -1020,6 +774,14 @@ void ath9k_hw_stoppcurecv(struct ath_hw *ah)
1020} 774}
1021EXPORT_SYMBOL(ath9k_hw_stoppcurecv); 775EXPORT_SYMBOL(ath9k_hw_stoppcurecv);
1022 776
777void 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}
783EXPORT_SYMBOL(ath9k_hw_abortpcurecv);
784
1023bool ath9k_hw_stopdmarecv(struct ath_hw *ah) 785bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
1024{ 786{
1025#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ 787#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */
@@ -1065,3 +827,142 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah)
1065 return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); 827 return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
1066} 828}
1067EXPORT_SYMBOL(ath9k_hw_beaconq_setup); 829EXPORT_SYMBOL(ath9k_hw_beaconq_setup);
830
831bool 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}
849EXPORT_SYMBOL(ath9k_hw_intrpend);
850
851enum 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}
968EXPORT_SYMBOL(ath9k_hw_set_interrupts);