madwifi: add a watchdog for software beacon alert interrupts
[openwrt-10.03/.git] / package / madwifi / patches / 455-beacon_watchdog.patch
1 --- a/ath/if_ath.c
2 +++ b/ath/if_ath.c
3 @@ -379,6 +379,7 @@ static u_int32_t ath_get_clamped_maxtxpo
4  static u_int32_t ath_set_clamped_maxtxpower(struct ath_softc *sc, 
5                 u_int32_t new_clamped_maxtxpower);
6  
7 +static void ath_bcn_timer(unsigned long arg);
8  static void ath_poll_disable(struct net_device *dev);
9  static void ath_poll_enable(struct net_device *dev);
10  static void ath_fetch_idle_time(struct ath_softc *sc);
11 @@ -829,6 +830,10 @@ ath_attach(u_int16_t devid, struct net_d
12         sc->sc_cal_ch.function = ath_calibrate;
13         sc->sc_cal_ch.data = (unsigned long) dev;
14  
15 +       init_timer(&sc->sc_bcntimer);
16 +       sc->sc_bcntimer.function = ath_bcn_timer;
17 +       sc->sc_bcntimer.data = (unsigned long) dev;
18 +
19         /* initialize DFS related variables */
20         sc->sc_dfswait = 0;
21         sc->sc_dfs_cac = 0;
22 @@ -2704,6 +2709,7 @@ ath_stop_locked(struct net_device *dev)
23         DPRINTF(sc, ATH_DEBUG_RESET, "invalid=%u flags=0x%x\n",
24                 sc->sc_invalid, dev->flags);
25  
26 +       del_timer_sync(&sc->sc_bcntimer);
27         if (dev->flags & IFF_RUNNING) {
28                 /*
29                  * Shutdown the hardware and driver:
30 @@ -3006,6 +3012,7 @@ ath_reset(struct net_device *dev)
31         struct ieee80211_channel *c;
32         HAL_STATUS status;
33  
34 +       del_timer_sync(&sc->sc_bcntimer);
35         /*
36          * XXX: starting the calibration too early seems to lead to
37          * problems with the beacons.
38 @@ -5305,6 +5312,7 @@ ath_beacon_send(struct ath_softc *sc, in
39         if (ath_chan_unavail_dbgmsg(sc))
40                 return;
41  
42 +       mod_timer(&sc->sc_bcntimer, jiffies + sc->sc_bcntimer_reload);
43         /*
44          * Check if the previous beacon has gone out.  If
45          * not don't try to post another, skip this period
46 @@ -5487,6 +5495,18 @@ ath_beacon_free(struct ath_softc *sc)
47                 cleanup_ath_buf(sc, bf, BUS_DMA_TODEVICE);
48  }
49  
50 +static void ath_bcn_timer(unsigned long arg)
51 +{
52 +       struct net_device *dev = (struct net_device *)arg;
53 +       struct ath_softc *sc = netdev_priv(dev);
54 +       struct ath_hal *ah = sc->sc_ah;
55 +
56 +       if (!sc->sc_beacons)
57 +               return;
58 +
59 +       ath_reset(dev);
60 +}
61 +
62  /*
63   * Configure the beacon and sleep timers.
64   *
65 @@ -5523,6 +5543,7 @@ ath_beacon_config(struct ath_softc *sc, 
66         if (vap == NULL)
67                 vap = TAILQ_FIRST(&ic->ic_vaps);   /* XXX */
68  
69 +       del_timer_sync(&sc->sc_bcntimer);
70         ni = vap->iv_bss;
71  
72         /* TSF calculation is timing critical - we don't want to be interrupted here */
73 @@ -5699,6 +5720,9 @@ ath_beacon_config(struct ath_softc *sc, 
74                         sc->sc_imask |= HAL_INT_SWBA;
75                         ath_set_beacon_cal(sc, 1);
76                         ath_beaconq_config(sc);
77 +
78 +                       sc->sc_bcntimer_reload = msecs_to_jiffies(10 * (intval & HAL_BEACON_PERIOD));
79 +                       mod_timer(&sc->sc_bcntimer, jiffies + sc->sc_bcntimer_reload);
80                 } else
81                         ath_set_beacon_cal(sc, 0);
82  
83 --- a/ath/if_athvar.h
84 +++ b/ath/if_athvar.h
85 @@ -789,6 +789,10 @@ struct ath_softc {
86         u_int16_t sc_ledoff;                    /* off time for current blink */
87         struct timer_list sc_ledtimer;          /* led off timer */
88  
89 +       /* beacon watchdog timer */
90 +       u_int32_t sc_bcntimer_reload;
91 +       struct timer_list sc_bcntimer;
92 +
93         struct ATH_TQ_STRUCT sc_fataltq;        /* fatal error intr tasklet */
94  
95         int sc_rxbufsize;                       /* rx size based on mtu */