Changeset 2632

Show
Ignore:
Timestamp:
08/03/07 11:03:35 (1 year ago)
Author:
nbd
Message:

Work around a reported CPU soft lockup caused by an interrupt storm
in the HAL_INT_MIB interrupt triggered by an excessive amount of PHY errors.
(Fixes #1239, #1445)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ath/if_ath.c

    r2591 r2632  
    204204static void ath_chan_change(struct ath_softc *, struct ieee80211_channel *); 
    205205static void ath_calibrate(unsigned long); 
     206static void ath_mib_enable(unsigned long); 
    206207static int ath_newstate(struct ieee80211vap *, enum ieee80211_state, int); 
    207208 
     
    662663        sc->sc_cal_ch.function = ath_calibrate; 
    663664        sc->sc_cal_ch.data = (unsigned long) dev; 
     665 
     666        init_timer(&sc->sc_mib_enable); 
     667        sc->sc_mib_enable.function = ath_mib_enable; 
     668        sc->sc_mib_enable.data = (unsigned long) sc; 
    664669 
    665670#ifdef ATH_SUPERG_DYNTURBO 
     
    17481753                        sc->sc_stats.ast_mib++; 
    17491754                        /* 
    1750                          * Disable interrupts until we service the MIB 
    1751                          * interrupt; otherwise it will continue to fire. 
     1755                         * When the card receives lots of PHY errors, the MIB 
     1756                         * interrupt will fire at a very rapid rate. We will use 
     1757                         * a timer to enforce at least 1 jiffy delay between 
     1758                         * MIB interrupts. This should be unproblematic, since 
     1759                         * the hardware will continue to update the counters in the 
     1760                         * mean time. 
    17521761                         */ 
    1753                         ath_hal_intrset(ah, 0)
    1754                         /* 
    1755                         * Let the HAL handle the event.  We assume it will 
    1756                          * clear whatever condition caused the interrupt. 
    1757                         */ 
     1762                        sc->sc_imask &= ~HAL_INT_MIB
     1763                        ath_hal_intrset(ah, sc->sc_imask); 
     1764                        mod_timer(&sc->sc_mib_enable, jiffies + 1); 
     1765 
     1766                        /* Let the HAL handle the event. */ 
    17581767                        ath_hal_mibevent(ah, &sc->sc_halstats); 
    1759                         ath_hal_intrset(ah, sc->sc_imask); 
    17601768                } 
    17611769        } 
     
    78547862        } 
    78557863        return 0; 
     7864} 
     7865 
     7866/* 
     7867 * Enable MIB interrupts again, after the ISR disabled them 
     7868 * to slow down the rate of PHY error reporting. 
     7869 */ 
     7870static void 
     7871ath_mib_enable(unsigned long arg) 
     7872{ 
     7873        struct ath_softc *sc = (struct ath_softc *) arg; 
     7874 
     7875        sc->sc_imask |= HAL_INT_MIB; 
     7876        ath_hal_intrset(sc->sc_ah, sc->sc_imask); 
    78567877} 
    78577878 
  • trunk/ath/if_athvar.h

    r2583 r2632  
    676676 
    677677        u_int16_t sc_reapcount;                 /* # of tx buffers reaped after net dev stopped */ 
     678        struct timer_list sc_mib_enable; 
    678679 
    679680#ifdef ATH_REVERSE_ENGINEERING