update madwifi to latest rev - works around some crashiness
[openwrt.git] / package / madwifi / patches / 116-adhoc_beacon_PR_1033.patch
1 Index: madwifi-ng-r2834-20071106/ath/if_ath.c
2 ===================================================================
3 --- madwifi-ng-r2834-20071106.orig/ath/if_ath.c 2007-11-07 14:02:01.785472625 +0100
4 +++ madwifi-ng-r2834-20071106/ath/if_ath.c      2007-11-07 14:02:02.637521177 +0100
5 @@ -4559,16 +4559,31 @@
6         struct ieee80211com *ic = &sc->sc_ic;
7         struct ath_hal *ah = sc->sc_ah;
8         struct ieee80211_node *ni;
9 -       u_int32_t nexttbtt, intval;
10 +       u_int32_t nexttbtt = 0;
11 +       u_int32_t intval;
12 +       u_int64_t tsf, hw_tsf;
13 +       u_int32_t tsftu, hw_tsftu;
14 +       int should_reset_tsf = 0;
15  
16         if (vap == NULL)
17                 vap = TAILQ_FIRST(&ic->ic_vaps);   /* XXX */
18  
19         ni = vap->iv_bss;
20  
21 -       /* extract tstamp from last beacon and convert to TU */
22 -       nexttbtt = TSF_TO_TU(LE_READ_4(ni->ni_tstamp.data + 4),
23 -                            LE_READ_4(ni->ni_tstamp.data));
24 +       hw_tsf = ath_hal_gettsf64(ah);
25 +       tsf = le64_to_cpu(ni->ni_tstamp.tsf);
26 +       hw_tsftu = hw_tsf >> 10;
27 +       tsftu = tsf >> 10;
28 +
29 +       /* we should reset hw TSF only once, so we increment
30 +          ni_tstamp.tsf to avoid resetting the hw TSF multiple
31 +          times */
32 +
33 +       if (tsf == 0) {
34 +               should_reset_tsf = 1;
35 +               ni->ni_tstamp.tsf = cpu_to_le64(1);
36 +       }
37 +
38         /* XXX conditionalize multi-bss support? */
39         if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
40                 /*
41 @@ -4582,20 +4597,61 @@
42                 if (sc->sc_stagbeacons)
43                         intval /= ATH_BCBUF;    /* for staggered beacons */
44                 if ((sc->sc_nostabeacons) &&
45 -                   (vap->iv_opmode == IEEE80211_M_HOSTAP))
46 -                       nexttbtt = 0;
47 +                       (vap->iv_opmode == IEEE80211_M_HOSTAP))
48 +                       should_reset_tsf = 1;
49         } else
50                 intval = ni->ni_intval & HAL_BEACON_PERIOD;
51 -       if (nexttbtt == 0)              /* e.g. for ap mode */
52 +
53 +#define        FUDGE   2
54 +       sc->sc_syncbeacon = 0;
55 +       if (should_reset_tsf) {
56 +
57 +               /* We just created the interface and TSF will be reset to
58 +                  zero, so next beacon will be sent at the next intval
59 +                  time */
60 +
61                 nexttbtt = intval;
62 -       else if (intval)                /* NB: can be 0 for monitor mode */
63 -               nexttbtt = roundup(nexttbtt, intval);
64 -       DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
65 -               __func__, nexttbtt, intval, ni->ni_intval);
66 +       } else if (intval) {    /* NB: can be 0 for monitor mode */
67 +               if (tsf == 1) {
68 +       
69 +                       /* We do not receive any beacons or probe response. Since
70 +                          a beacon should be sent every 'intval' ms, we compute
71 +                          the next beacon timestamp using the hardware TSF. We
72 +                          ensure that it is at least FUDGE ms ahead of the
73 +                          current TSF. Otherwise, we use the next beacon
74 +                          timestamp again */
75 +
76 +                       nexttbtt = roundup(hw_tsftu +1, intval);
77 +                       while (nexttbtt <= hw_tsftu + FUDGE) {
78 +                               nexttbtt += intval;
79 +                       }
80 +               } else {
81 +                       if (tsf > hw_tsf) {
82 +
83 +                       /* We do receive a beacon from someone else in the past,
84 +                          but the hw TSF has not been updated (otherwise we
85 +                          would have tsf >= hw_tsf). Since we cannot use the
86 +                          hardware TSF, we will do nothing and wait for the
87 +                          next beacon. In order to do so, we set sc->syncbeacon
88 +                          again */
89 +
90 +                               sc->sc_syncbeacon = 1;
91 +                               goto ath_beacon_config_debug;
92 +                       } else {
93 +                               /* We do receive a beacon in the past, normal case. We
94 +                                  make sure that the timestamp is at least FUDGE ms
95 +                                  ahead of the hardware TSF */
96 +
97 +                               nexttbtt = tsftu + intval;
98 +                               while (nexttbtt <= hw_tsftu + FUDGE) {
99 +                                       nexttbtt += intval;
100 +                               }
101 +                       }
102 +               }
103 +       }
104 +
105         if (ic->ic_opmode == IEEE80211_M_STA && !(sc->sc_nostabeacons)) {
106                 HAL_BEACON_STATE bs;
107 -               u_int64_t tsf;
108 -               u_int32_t tsftu;
109                 int dtimperiod, dtimcount;
110                 int cfpperiod, cfpcount;
111  
112 @@ -4611,13 +4667,13 @@
113                         dtimcount = 0;          /* XXX? */
114                 cfpperiod = 1;                  /* NB: no PCF support yet */
115                 cfpcount = 0;
116 -#define        FUDGE   2
117                 /*
118                  * Pull nexttbtt forward to reflect the current
119                  * TSF and calculate dtim+cfp state for the result.
120                  */
121 -               tsf = ath_hal_gettsf64(ah);
122 -               tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
123 +               nexttbtt = tsftu;
124 +               if (nexttbtt == 0)              /* e.g. for ap mode */
125 +                       nexttbtt = intval;
126                 do {
127                         nexttbtt += intval;
128                         if (--dtimcount < 0) {
129 @@ -4625,7 +4681,7 @@
130                                 if (--cfpcount < 0)
131                                         cfpcount = cfpperiod - 1;
132                         }
133 -               } while (nexttbtt < tsftu);
134 +               } while (nexttbtt < hw_tsftu + FUDGE);
135  #undef FUDGE
136                 memset(&bs, 0, sizeof(bs));
137                 bs.bs_intval = intval;
138 @@ -4677,7 +4733,7 @@
139                 DPRINTF(sc, ATH_DEBUG_BEACON,
140                         "%s: tsf %llu tsf:tu %u intval %u nexttbtt %u dtim %u nextdtim %u bmiss %u sleep %u cfp:period %u maxdur %u next %u timoffset %u\n",
141                         __func__,
142 -                       (unsigned long long) tsf, tsftu,
143 +                       (unsigned long long) hw_tsf, hw_tsftu,
144                         bs.bs_intval,
145                         bs.bs_nexttbtt,
146                         bs.bs_dtimperiod,
147 @@ -4699,7 +4755,7 @@
148                 ath_hal_intrset(ah, sc->sc_imask);
149         } else {
150                 ath_hal_intrset(ah, 0);
151 -               if (nexttbtt == intval)
152 +               if (should_reset_tsf)
153                         intval |= HAL_BEACON_RESET_TSF;
154                 if (ic->ic_opmode == IEEE80211_M_IBSS) {
155                         /*
156 @@ -4736,8 +4792,40 @@
157                 if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_hasveol)
158                         ath_beacon_start_adhoc(sc, vap);
159         }
160 -       sc->sc_syncbeacon = 0;
161  #undef TSF_TO_TU
162 +
163 +       ath_beacon_config_debug:
164 +
165 +       /* we print all debug messages here, in order to preserve the
166 +          time critical aspect of this function */
167 +
168 +       DPRINTF(sc, ATH_DEBUG_BEACON,
169 +               "%s: ni=%p tsf=%llu hw_tsf=%llu tsftu=%u hw_tsftu=%u\n",
170 +               __func__, ni, tsf, hw_tsf, tsftu, hw_tsftu);
171 +
172 +       if (should_reset_tsf) {
173 +               /* we just created the interface */
174 +               DPRINTF(sc, ATH_DEBUG_BEACON, "%s: first beacon\n",__func__);
175 +       } else {
176 +               if (tsf == 1) {
177 +                       /* we do not receive any beacons or probe response */
178 +                       DPRINTF(sc, ATH_DEBUG_BEACON,
179 +                               "%s: no beacon received...\n",__func__);
180 +               } else {
181 +                       if (tsf > hw_tsf) {
182 +                               /* we do receive a beacon and the hw TSF has not been updated */
183 +                               DPRINTF(sc, ATH_DEBUG_BEACON,
184 +                                       "%s: beacon received, but TSF is incorrect\n",__func__);
185 +                       } else {
186 +                               /* we do receive a beacon in the past, normal case */
187 +                               DPRINTF(sc, ATH_DEBUG_BEACON,
188 +                                       "%s: beacon received, TSF is correct\n",__func__);
189 +                       }
190 +               }
191 +       }
192 +
193 +       DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt=%u intval=%u\n",
194 +               __func__,nexttbtt, intval & HAL_BEACON_PERIOD);
195  }
196  
197  static int