diff options
author | Nick Kossifidis <mick@madwifi.org> | 2008-10-26 14:40:25 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-10-31 19:02:32 -0400 |
commit | 4c674c60bd567597f1224973712b352f4f474890 (patch) | |
tree | 0838978d789d120c3109a1b14a948a7ad4ff9cd8 /drivers/net/wireless/ath5k/qcu.c | |
parent | 84fa4f43c418d2eaad06734ea780a74c869f79c3 (diff) |
ath5k: Update interrupt masking code
*Properly get/set all available ISR/IMR values and review common/uncommon bits
*Better handling of per-txq interrupts (we can now resolve what q is generating
each interrupt -this will help in debuging wme later)
*Some minor updates from legacy-hal
*Properly handle RXNOFRM and TXNOFRM interrupt masking (even when we don't set
them on IMR they keep showing up, so we disable them by zeroing AR5K_RXNOFRM
and AR5K_TXNOFRM registers). This doesn't exist on legacy-hal but i've tested
it on various cards and it works fine.
Changes-Licensed-under: ISC
Signed-Off-by: Nick Kossifidis <mickflemm@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath5k/qcu.c')
-rw-r--r-- | drivers/net/wireless/ath5k/qcu.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath5k/qcu.c b/drivers/net/wireless/ath5k/qcu.c index 01bf09176d23..1b7bc50ea8eb 100644 --- a/drivers/net/wireless/ath5k/qcu.c +++ b/drivers/net/wireless/ath5k/qcu.c | |||
@@ -432,13 +432,30 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
432 | if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE) | 432 | if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE) |
433 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue); | 433 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue); |
434 | 434 | ||
435 | if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE) | ||
436 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue); | ||
437 | |||
438 | if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE) | ||
439 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue); | ||
440 | |||
441 | if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE) | ||
442 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue); | ||
443 | |||
444 | if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE) | ||
445 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue); | ||
435 | 446 | ||
436 | /* Update secondary interrupt mask registers */ | 447 | /* Update secondary interrupt mask registers */ |
448 | |||
449 | /* Filter out inactive queues */ | ||
437 | ah->ah_txq_imr_txok &= ah->ah_txq_status; | 450 | ah->ah_txq_imr_txok &= ah->ah_txq_status; |
438 | ah->ah_txq_imr_txerr &= ah->ah_txq_status; | 451 | ah->ah_txq_imr_txerr &= ah->ah_txq_status; |
439 | ah->ah_txq_imr_txurn &= ah->ah_txq_status; | 452 | ah->ah_txq_imr_txurn &= ah->ah_txq_status; |
440 | ah->ah_txq_imr_txdesc &= ah->ah_txq_status; | 453 | ah->ah_txq_imr_txdesc &= ah->ah_txq_status; |
441 | ah->ah_txq_imr_txeol &= ah->ah_txq_status; | 454 | ah->ah_txq_imr_txeol &= ah->ah_txq_status; |
455 | ah->ah_txq_imr_cbrorn &= ah->ah_txq_status; | ||
456 | ah->ah_txq_imr_cbrurn &= ah->ah_txq_status; | ||
457 | ah->ah_txq_imr_qtrig &= ah->ah_txq_status; | ||
458 | ah->ah_txq_imr_nofrm &= ah->ah_txq_status; | ||
442 | 459 | ||
443 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok, | 460 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok, |
444 | AR5K_SIMR0_QCU_TXOK) | | 461 | AR5K_SIMR0_QCU_TXOK) | |
@@ -448,8 +465,24 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
448 | AR5K_SIMR1_QCU_TXERR) | | 465 | AR5K_SIMR1_QCU_TXERR) | |
449 | AR5K_REG_SM(ah->ah_txq_imr_txeol, | 466 | AR5K_REG_SM(ah->ah_txq_imr_txeol, |
450 | AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1); | 467 | AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1); |
451 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txurn, | 468 | /* Update simr2 but don't overwrite rest simr2 settings */ |
452 | AR5K_SIMR2_QCU_TXURN), AR5K_SIMR2); | 469 | AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN); |
470 | AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, | ||
471 | AR5K_REG_SM(ah->ah_txq_imr_txurn, | ||
472 | AR5K_SIMR2_QCU_TXURN)); | ||
473 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn, | ||
474 | AR5K_SIMR3_QCBRORN) | | ||
475 | AR5K_REG_SM(ah->ah_txq_imr_cbrurn, | ||
476 | AR5K_SIMR3_QCBRURN), AR5K_SIMR3); | ||
477 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig, | ||
478 | AR5K_SIMR4_QTRIG), AR5K_SIMR4); | ||
479 | /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */ | ||
480 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm, | ||
481 | AR5K_TXNOFRM_QCU), AR5K_TXNOFRM); | ||
482 | /* No queue has TXNOFRM enabled, disable the interrupt | ||
483 | * by setting AR5K_TXNOFRM to zero */ | ||
484 | if (ah->ah_txq_imr_nofrm == 0) | ||
485 | ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM); | ||
453 | } | 486 | } |
454 | 487 | ||
455 | return 0; | 488 | return 0; |