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