fix multicast/authframe handling for wds ap with split sta interfaces
[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 &&