aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Kossifidis <mickflemm@gmail.com>2011-11-25 13:40:22 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-28 14:44:13 -0500
commit34ce644aa8342f95eb1e187178f83febade4af37 (patch)
tree03483c0c1b4c3d3b49b91dabeb645164ed452760
parentfea9480786c0fc41901bddb9819dd036527a9e10 (diff)
ath5k: Cleanups v1
No functional changes, just a few comments/documentation/cleanup Signed-off-by: Nick Kossifidis <mickflemm@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c112
-rw-r--r--drivers/net/wireless/ath/ath5k/dma.c17
2 files changed, 96 insertions, 33 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index c18d31008978..47194a4e3652 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2149,69 +2149,110 @@ ath5k_intr(int irq, void *dev_id)
2149 enum ath5k_int status; 2149 enum ath5k_int status;
2150 unsigned int counter = 1000; 2150 unsigned int counter = 1000;
2151 2151
2152
2153 /*
2154 * If hw is not ready (or detached) and we get an
2155 * interrupt, or if we have no interrupts pending
2156 * (that means it's not for us) skip it.
2157 *
2158 * NOTE: Group 0/1 PCI interface registers are not
2159 * supported on WiSOCs, so we can't check for pending
2160 * interrupts (ISR belongs to another register group
2161 * so we are ok).
2162 */
2152 if (unlikely(test_bit(ATH_STAT_INVALID, ah->status) || 2163 if (unlikely(test_bit(ATH_STAT_INVALID, ah->status) ||
2153 ((ath5k_get_bus_type(ah) != ATH_AHB) && 2164 ((ath5k_get_bus_type(ah) != ATH_AHB) &&
2154 !ath5k_hw_is_intr_pending(ah)))) 2165 !ath5k_hw_is_intr_pending(ah))))
2155 return IRQ_NONE; 2166 return IRQ_NONE;
2156 2167
2168 /** Main loop **/
2157 do { 2169 do {
2158 ath5k_hw_get_isr(ah, &status); /* NB: clears IRQ too */ 2170 ath5k_hw_get_isr(ah, &status); /* NB: clears IRQ too */
2171
2159 ATH5K_DBG(ah, ATH5K_DEBUG_INTR, "status 0x%x/0x%x\n", 2172 ATH5K_DBG(ah, ATH5K_DEBUG_INTR, "status 0x%x/0x%x\n",
2160 status, ah->imask); 2173 status, ah->imask);
2174
2175 /*
2176 * Fatal hw error -> Log and reset
2177 *
2178 * Fatal errors are unrecoverable so we have to
2179 * reset the card. These errors include bus and
2180 * dma errors.
2181 */
2161 if (unlikely(status & AR5K_INT_FATAL)) { 2182 if (unlikely(status & AR5K_INT_FATAL)) {
2162 /* 2183
2163 * Fatal errors are unrecoverable.
2164 * Typically these are caused by DMA errors.
2165 */
2166 ATH5K_DBG(ah, ATH5K_DEBUG_RESET, 2184 ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
2167 "fatal int, resetting\n"); 2185 "fatal int, resetting\n");
2168 ieee80211_queue_work(ah->hw, &ah->reset_work); 2186 ieee80211_queue_work(ah->hw, &ah->reset_work);
2187
2188 /*
2189 * RX Overrun -> Count and reset if needed
2190 *
2191 * Receive buffers are full. Either the bus is busy or
2192 * the CPU is not fast enough to process all received
2193 * frames.
2194 */
2169 } else if (unlikely(status & AR5K_INT_RXORN)) { 2195 } else if (unlikely(status & AR5K_INT_RXORN)) {
2196
2170 /* 2197 /*
2171 * Receive buffers are full. Either the bus is busy or
2172 * the CPU is not fast enough to process all received
2173 * frames.
2174 * Older chipsets need a reset to come out of this 2198 * Older chipsets need a reset to come out of this
2175 * condition, but we treat it as RX for newer chips. 2199 * condition, but we treat it as RX for newer chips.
2176 * We don't know exactly which versions need a reset - 2200 * We don't know exactly which versions need a reset
2177 * this guess is copied from the HAL. 2201 * this guess is copied from the HAL.
2178 */ 2202 */
2179 ah->stats.rxorn_intr++; 2203 ah->stats.rxorn_intr++;
2204
2180 if (ah->ah_mac_srev < AR5K_SREV_AR5212) { 2205 if (ah->ah_mac_srev < AR5K_SREV_AR5212) {
2181 ATH5K_DBG(ah, ATH5K_DEBUG_RESET, 2206 ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
2182 "rx overrun, resetting\n"); 2207 "rx overrun, resetting\n");
2183 ieee80211_queue_work(ah->hw, &ah->reset_work); 2208 ieee80211_queue_work(ah->hw, &ah->reset_work);
2184 } else 2209 } else
2185 ath5k_schedule_rx(ah); 2210 ath5k_schedule_rx(ah);
2211
2186 } else { 2212 } else {
2213
2214 /* Software Beacon Alert -> Schedule beacon tasklet */
2187 if (status & AR5K_INT_SWBA) 2215 if (status & AR5K_INT_SWBA)
2188 tasklet_hi_schedule(&ah->beacontq); 2216 tasklet_hi_schedule(&ah->beacontq);
2189 2217
2190 if (status & AR5K_INT_RXEOL) { 2218 /*
2191 /* 2219 * No more RX descriptors -> Just count
2192 * NB: the hardware should re-read the link when 2220 *
2193 * RXE bit is written, but it doesn't work at 2221 * NB: the hardware should re-read the link when
2194 * least on older hardware revs. 2222 * RXE bit is written, but it doesn't work at
2195 */ 2223 * least on older hardware revs.
2224 */
2225 if (status & AR5K_INT_RXEOL)
2196 ah->stats.rxeol_intr++; 2226 ah->stats.rxeol_intr++;
2197 } 2227
2198 if (status & AR5K_INT_TXURN) { 2228
2199 /* bump tx trigger level */ 2229 /* TX Underrun -> Bump tx trigger level */
2230 if (status & AR5K_INT_TXURN)
2200 ath5k_hw_update_tx_triglevel(ah, true); 2231 ath5k_hw_update_tx_triglevel(ah, true);
2201 } 2232
2233 /* RX -> Schedule rx tasklet */
2202 if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) 2234 if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR))
2203 ath5k_schedule_rx(ah); 2235 ath5k_schedule_rx(ah);
2204 if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC 2236
2205 | AR5K_INT_TXERR | AR5K_INT_TXEOL)) 2237 /* TX -> Schedule tx tasklet */
2238 if (status & (AR5K_INT_TXOK
2239 | AR5K_INT_TXDESC
2240 | AR5K_INT_TXERR
2241 | AR5K_INT_TXEOL))
2206 ath5k_schedule_tx(ah); 2242 ath5k_schedule_tx(ah);
2207 if (status & AR5K_INT_BMISS) { 2243
2208 /* TODO */ 2244 /* Missed beacon -> TODO
2209 } 2245 if (status & AR5K_INT_BMISS)
2246 */
2247
2248 /* MIB event -> Update counters and notify ANI */
2210 if (status & AR5K_INT_MIB) { 2249 if (status & AR5K_INT_MIB) {
2211 ah->stats.mib_intr++; 2250 ah->stats.mib_intr++;
2212 ath5k_hw_update_mib_counters(ah); 2251 ath5k_hw_update_mib_counters(ah);
2213 ath5k_ani_mib_intr(ah); 2252 ath5k_ani_mib_intr(ah);
2214 } 2253 }
2254
2255 /* GPIO -> Notify RFKill layer */
2215 if (status & AR5K_INT_GPIO) 2256 if (status & AR5K_INT_GPIO)
2216 tasklet_schedule(&ah->rf_kill.toggleq); 2257 tasklet_schedule(&ah->rf_kill.toggleq);
2217 2258
@@ -2222,12 +2263,19 @@ ath5k_intr(int irq, void *dev_id)
2222 2263
2223 } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); 2264 } while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
2224 2265
2266 /*
2267 * Until we handle rx/tx interrupts mask them on IMR
2268 *
2269 * NOTE: ah->(rx/tx)_pending are set when scheduling the tasklets
2270 * and unset after we 've handled the interrupts.
2271 */
2225 if (ah->rx_pending || ah->tx_pending) 2272 if (ah->rx_pending || ah->tx_pending)
2226 ath5k_set_current_imask(ah); 2273 ath5k_set_current_imask(ah);
2227 2274
2228 if (unlikely(!counter)) 2275 if (unlikely(!counter))
2229 ATH5K_WARN(ah, "too many interrupts, giving up for now\n"); 2276 ATH5K_WARN(ah, "too many interrupts, giving up for now\n");
2230 2277
2278 /* Fire up calibration poll */
2231 ath5k_intr_calibration_poll(ah); 2279 ath5k_intr_calibration_poll(ah);
2232 2280
2233 return IRQ_HANDLED; 2281 return IRQ_HANDLED;
@@ -2544,9 +2592,15 @@ int ath5k_start(struct ieee80211_hw *hw)
2544 * and then setup of the interrupt mask. 2592 * and then setup of the interrupt mask.
2545 */ 2593 */
2546 ah->curchan = ah->hw->conf.channel; 2594 ah->curchan = ah->hw->conf.channel;
2547 ah->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | 2595 ah->imask = AR5K_INT_RXOK
2548 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | 2596 | AR5K_INT_RXERR
2549 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB; 2597 | AR5K_INT_RXEOL
2598 | AR5K_INT_RXORN
2599 | AR5K_INT_TXDESC
2600 | AR5K_INT_TXEOL
2601 | AR5K_INT_FATAL
2602 | AR5K_INT_GLOBAL
2603 | AR5K_INT_MIB;
2550 2604
2551 ret = ath5k_reset(ah, NULL, false); 2605 ret = ath5k_reset(ah, NULL, false);
2552 if (ret) 2606 if (ret)
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c
index b5db6e78f88e..97864d88d181 100644
--- a/drivers/net/wireless/ath/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -701,21 +701,25 @@ int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
701 if (unlikely(pisr & (AR5K_ISR_BNR))) 701 if (unlikely(pisr & (AR5K_ISR_BNR)))
702 *interrupt_mask |= AR5K_INT_BNR; 702 *interrupt_mask |= AR5K_INT_BNR;
703 703
704 /* Doppler chirp received */
704 if (unlikely(pisr & (AR5K_ISR_RXDOPPLER))) 705 if (unlikely(pisr & (AR5K_ISR_RXDOPPLER)))
705 *interrupt_mask |= AR5K_INT_RX_DOPPLER; 706 *interrupt_mask |= AR5K_INT_RX_DOPPLER;
706 707
708 /* A queue got CBR overrun */
707 if (unlikely(pisr & (AR5K_ISR_QCBRORN))) { 709 if (unlikely(pisr & (AR5K_ISR_QCBRORN))) {
708 *interrupt_mask |= AR5K_INT_QCBRORN; 710 *interrupt_mask |= AR5K_INT_QCBRORN;
709 ah->ah_txq_isr_qcborn |= AR5K_REG_MS(sisr3, 711 ah->ah_txq_isr_qcborn |= AR5K_REG_MS(sisr3,
710 AR5K_SISR3_QCBRORN); 712 AR5K_SISR3_QCBRORN);
711 } 713 }
712 714
715 /* A queue got CBR underrun */
713 if (unlikely(pisr & (AR5K_ISR_QCBRURN))) { 716 if (unlikely(pisr & (AR5K_ISR_QCBRURN))) {
714 *interrupt_mask |= AR5K_INT_QCBRURN; 717 *interrupt_mask |= AR5K_INT_QCBRURN;
715 ah->ah_txq_isr_qcburn |= AR5K_REG_MS(sisr3, 718 ah->ah_txq_isr_qcburn |= AR5K_REG_MS(sisr3,
716 AR5K_SISR3_QCBRURN); 719 AR5K_SISR3_QCBRURN);
717 } 720 }
718 721
722 /* A queue got triggered */
719 if (unlikely(pisr & (AR5K_ISR_QTRIG))) { 723 if (unlikely(pisr & (AR5K_ISR_QTRIG))) {
720 *interrupt_mask |= AR5K_INT_QTRIG; 724 *interrupt_mask |= AR5K_INT_QTRIG;
721 ah->ah_txq_isr_qtrig |= AR5K_REG_MS(sisr4, 725 ah->ah_txq_isr_qtrig |= AR5K_REG_MS(sisr4,
@@ -772,16 +776,14 @@ enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
772 u32 simr2 = ath5k_hw_reg_read(ah, AR5K_SIMR2) 776 u32 simr2 = ath5k_hw_reg_read(ah, AR5K_SIMR2)
773 & AR5K_SIMR2_QCU_TXURN; 777 & AR5K_SIMR2_QCU_TXURN;
774 778
779 /* Fatal interrupt abstraction for 5211+ */
775 if (new_mask & AR5K_INT_FATAL) { 780 if (new_mask & AR5K_INT_FATAL) {
776 int_mask |= AR5K_IMR_HIUERR; 781 int_mask |= AR5K_IMR_HIUERR;
777 simr2 |= (AR5K_SIMR2_MCABT | AR5K_SIMR2_SSERR 782 simr2 |= (AR5K_SIMR2_MCABT | AR5K_SIMR2_SSERR
778 | AR5K_SIMR2_DPERR); 783 | AR5K_SIMR2_DPERR);
779 } 784 }
780 785
781 /*Beacon Not Ready*/ 786 /* Misc beacon related interrupts */
782 if (new_mask & AR5K_INT_BNR)
783 int_mask |= AR5K_INT_BNR;
784
785 if (new_mask & AR5K_INT_TIM) 787 if (new_mask & AR5K_INT_TIM)
786 int_mask |= AR5K_IMR_TIM; 788 int_mask |= AR5K_IMR_TIM;
787 789
@@ -796,6 +798,11 @@ enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
796 if (new_mask & AR5K_INT_CAB_TIMEOUT) 798 if (new_mask & AR5K_INT_CAB_TIMEOUT)
797 simr2 |= AR5K_SISR2_CAB_TIMEOUT; 799 simr2 |= AR5K_SISR2_CAB_TIMEOUT;
798 800
801 /*Beacon Not Ready*/
802 if (new_mask & AR5K_INT_BNR)
803 int_mask |= AR5K_INT_BNR;
804
805 /* RX doppler chirp */
799 if (new_mask & AR5K_INT_RX_DOPPLER) 806 if (new_mask & AR5K_INT_RX_DOPPLER)
800 int_mask |= AR5K_IMR_RXDOPPLER; 807 int_mask |= AR5K_IMR_RXDOPPLER;
801 808
@@ -805,10 +812,12 @@ enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
805 ath5k_hw_reg_write(ah, simr2, AR5K_SIMR2); 812 ath5k_hw_reg_write(ah, simr2, AR5K_SIMR2);
806 813
807 } else { 814 } else {
815 /* Fatal interrupt abstraction for 5210 */
808 if (new_mask & AR5K_INT_FATAL) 816 if (new_mask & AR5K_INT_FATAL)
809 int_mask |= (AR5K_IMR_SSERR | AR5K_IMR_MCABT 817 int_mask |= (AR5K_IMR_SSERR | AR5K_IMR_MCABT
810 | AR5K_IMR_HIUERR | AR5K_IMR_DPERR); 818 | AR5K_IMR_HIUERR | AR5K_IMR_DPERR);
811 819
820 /* Only common interrupts left for 5210 (no SIMRs) */
812 ath5k_hw_reg_write(ah, int_mask, AR5K_IMR); 821 ath5k_hw_reg_write(ah, int_mask, AR5K_IMR);
813 } 822 }
814 823