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 */ |
96 | |