madwifi: add some beacon setup/update related fixes (based on Bruno Randolf's patchset)
[openwrt/openwrt.git] / package / madwifi / patches / 375-atim_tsf_update.patch
1 --- a/ath/if_ath.c
2 +++ b/ath/if_ath.c
3 @@ -2785,6 +2785,44 @@
4 return 1;
5 }
6
7 +/* Fix up the ATIM window after TSF resync */
8 +static int
9 +ath_hw_check_atim(struct ath_softc *sc, int window)
10 +{
11 +#define AR5K_TIMER0_5210 0x802c /* Next beacon time register */
12 +#define AR5K_TIMER0_5211 0x8028
13 +#define AR5K_TIMER3_5210 0x8038 /* End of ATIM window time register */
14 +#define AR5K_TIMER3_5211 0x8034
15 + struct ath_hal *ah = sc->sc_ah;
16 + unsigned int nbtt, atim;
17 + int dev = ar_device(sc->devid);
18 +
19 + switch(dev) {
20 + case 5210:
21 + nbtt = OS_REG_READ(ah, AR5K_TIMER0_5210);
22 + atim = OS_REG_READ(ah, AR5K_TIMER3_5210);
23 + if (atim - nbtt != window) {
24 + OS_REG_WRITE(ah, AR5K_TIMER3_5210, nbtt + window );
25 + return atim - nbtt;
26 + }
27 + break;
28 + case 5211:
29 + case 5212:
30 + nbtt = OS_REG_READ(ah, AR5K_TIMER0_5211);
31 + atim = OS_REG_READ(ah, AR5K_TIMER3_5211);
32 + if (atim - nbtt != window) {
33 + OS_REG_WRITE(ah, AR5K_TIMER3_5211, nbtt + window );
34 + return atim - nbtt;
35 + }
36 + break;
37 + /* NB: 5416+ doesn't do ATIM in hw */
38 + default:
39 + break;
40 + }
41 + return 0;
42 +}
43 +
44 +
45 /*
46 * Reset the hardware w/o losing operational state. This is
47 * basically a more efficient way of doing ath_stop, ath_init,
48 @@ -6391,6 +6429,11 @@
49 DPRINTF(sc, ATH_DEBUG_BEACON,
50 "Updated beacon timers\n");
51 }
52 + if ((sc->sc_opmode == IEEE80211_M_IBSS) &&
53 + IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid) &&
54 + ath_hw_check_atim(sc, 1)) {
55 + DPRINTF(sc, ATH_DEBUG_ANY, "Fixed ATIM window after beacon recv\n");
56 + }
57 /* NB: Fall Through */
58 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
59 if (vap->iv_opmode == IEEE80211_M_IBSS &&