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
diff --git a/package/madwifi/patches/116-adhoc_beacon_PR_1033.patch b/package/madwifi/patches/116-adhoc_beacon_PR_1033.patch
new file mode 100644 (file)
index 0000000..92a147c
--- /dev/null
@@ -0,0 +1,196 @@
+diff -urN madwifi-ng-refcount-r2313-20070505.old/ath/if_ath.c madwifi-ng-refcount-r2313-20070505.dev/ath/if_ath.c
+--- madwifi-ng-refcount-r2313-20070505.old/ath/if_ath.c        2007-05-13 18:17:55.862076712 +0200
++++ madwifi-ng-refcount-r2313-20070505.dev/ath/if_ath.c        2007-05-13 18:17:56.119037648 +0200
+@@ -4411,16 +4411,31 @@
+       struct ieee80211com *ic = &sc->sc_ic;
+       struct ath_hal *ah = sc->sc_ah;
+       struct ieee80211_node *ni;
+-      u_int32_t nexttbtt, intval;
++      u_int32_t nexttbtt = 0;
++      u_int32_t intval;
++      u_int64_t tsf, hw_tsf;
++      u_int32_t tsftu, hw_tsftu;
++      int should_reset_tsf = 0;
+       if (vap == NULL)
+               vap = TAILQ_FIRST(&ic->ic_vaps);   /* XXX */
+       ni = vap->iv_bss;
+-      /* extract tstamp from last beacon and convert to TU */
+-      nexttbtt = TSF_TO_TU(LE_READ_4(ni->ni_tstamp.data + 4),
+-                           LE_READ_4(ni->ni_tstamp.data));
++      hw_tsf = ath_hal_gettsf64(ah);
++      tsf = le64_to_cpu(ni->ni_tstamp.tsf);
++      hw_tsftu = hw_tsf >> 10;
++      tsftu = tsf >> 10;
++
++      /* we should reset hw TSF only once, so we increment
++         ni_tstamp.tsf to avoid resetting the hw TSF multiple
++         times */
++
++      if (tsf == 0) {
++              should_reset_tsf = 1;
++              ni->ni_tstamp.tsf = cpu_to_le64(1);
++      }
++
+       /* XXX conditionalize multi-bss support? */
+       if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+               /*
+@@ -4434,20 +4449,61 @@
+               if (sc->sc_stagbeacons)
+                       intval /= ATH_BCBUF;    /* for staggered beacons */
+               if ((sc->sc_nostabeacons) &&
+-                  (vap->iv_opmode == IEEE80211_M_HOSTAP))
+-                      nexttbtt = 0;
++                      (vap->iv_opmode == IEEE80211_M_HOSTAP))
++                      should_reset_tsf = 1;
+       } else
+               intval = ni->ni_intval & HAL_BEACON_PERIOD;
+-      if (nexttbtt == 0)              /* e.g. for ap mode */
++
++#define       FUDGE   2
++      sc->sc_syncbeacon = 0;
++      if (should_reset_tsf) {
++
++              /* We just created the interface and TSF will be reset to
++                 zero, so next beacon will be sent at the next intval
++                 time */
++
+               nexttbtt = intval;
+-      else if (intval)                /* NB: can be 0 for monitor mode */
+-              nexttbtt = roundup(nexttbtt, intval);
+-      DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
+-              __func__, nexttbtt, intval, ni->ni_intval);
++      } else if (intval) {    /* NB: can be 0 for monitor mode */
++              if (tsf == 1) {
++      
++                      /* We do not receive any beacons or probe response. Since
++                         a beacon should be sent every 'intval' ms, we compute
++                         the next beacon timestamp using the hardware TSF. We
++                         ensure that it is at least FUDGE ms ahead of the
++                         current TSF. Otherwise, we use the next beacon
++                         timestamp again */
++
++                      nexttbtt = roundup(hw_tsftu +1, intval);
++                      while (nexttbtt <= hw_tsftu + FUDGE) {
++                              nexttbtt += intval;
++                      }
++              } else {
++                      if (tsf > hw_tsf) {
++
++                      /* We do receive a beacon from someone else in the past,
++                         but the hw TSF has not been updated (otherwise we
++                         would have tsf >= hw_tsf). Since we cannot use the
++                         hardware TSF, we will do nothing and wait for the
++                         next beacon. In order to do so, we set sc->syncbeacon
++                         again */
++
++                              sc->sc_syncbeacon = 1;
++                              goto ath_beacon_config_debug;
++                      } else {
++                              /* We do receive a beacon in the past, normal case. We
++                                 make sure that the timestamp is at least FUDGE ms
++                                 ahead of the hardware TSF */
++
++                              nexttbtt = tsftu + intval;
++                              while (nexttbtt <= hw_tsftu + FUDGE) {
++                                      nexttbtt += intval;
++                              }
++                      }
++              }
++      }
++
+       if (ic->ic_opmode == IEEE80211_M_STA && !(sc->sc_nostabeacons)) {
+               HAL_BEACON_STATE bs;
+-              u_int64_t tsf;
+-              u_int32_t tsftu;
+               int dtimperiod, dtimcount;
+               int cfpperiod, cfpcount;
+@@ -4463,13 +4519,13 @@
+                       dtimcount = 0;          /* XXX? */
+               cfpperiod = 1;                  /* NB: no PCF support yet */
+               cfpcount = 0;
+-#define       FUDGE   2
+               /*
+                * Pull nexttbtt forward to reflect the current
+                * TSF and calculate dtim+cfp state for the result.
+                */
+-              tsf = ath_hal_gettsf64(ah);
+-              tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
++              nexttbtt = tsftu;
++              if (nexttbtt == 0)              /* e.g. for ap mode */
++                      nexttbtt = intval;
+               do {
+                       nexttbtt += intval;
+                       if (--dtimcount < 0) {
+@@ -4477,7 +4533,7 @@
+                               if (--cfpcount < 0)
+                                       cfpcount = cfpperiod - 1;
+                       }
+-              } while (nexttbtt < tsftu);
++              } while (nexttbtt < hw_tsftu + FUDGE);
+ #undef FUDGE
+               memset(&bs, 0, sizeof(bs));
+               bs.bs_intval = intval;
+@@ -4529,7 +4585,7 @@
+               DPRINTF(sc, ATH_DEBUG_BEACON, 
+                       "%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",
+                       __func__,
+-                      (long long) tsf, tsftu,
++                      (long long) hw_tsf, hw_tsftu,
+                       bs.bs_intval,
+                       bs.bs_nexttbtt,
+                       bs.bs_dtimperiod,
+@@ -4548,7 +4604,7 @@
+               ath_hal_intrset(ah, sc->sc_imask);
+       } else {
+               ath_hal_intrset(ah, 0);
+-              if (nexttbtt == intval)
++              if (should_reset_tsf)
+                       intval |= HAL_BEACON_RESET_TSF;
+               if (ic->ic_opmode == IEEE80211_M_IBSS) {
+                       /*
+@@ -4585,8 +4641,40 @@
+               if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_hasveol)
+                       ath_beacon_start_adhoc(sc, vap);
+       }
+-      sc->sc_syncbeacon = 0;
+ #undef TSF_TO_TU
++
++      ath_beacon_config_debug:
++
++      /* we print all debug messages here, in order to preserve the
++         time critical aspect of this function */
++
++      DPRINTF(sc, ATH_DEBUG_BEACON,
++              "%s: ni=%p tsf=%llu hw_tsf=%llu tsftu=%u hw_tsftu=%u\n",
++              __func__, ni, tsf, hw_tsf, tsftu, hw_tsftu);
++
++      if (should_reset_tsf) {
++              /* we just created the interface */
++              DPRINTF(sc, ATH_DEBUG_BEACON, "%s: first beacon\n",__func__);
++      } else {
++              if (tsf == 1) {
++                      /* we do not receive any beacons or probe response */
++                      DPRINTF(sc, ATH_DEBUG_BEACON,
++                              "%s: no beacon received...\n",__func__);
++              } else {
++                      if (tsf > hw_tsf) {
++                              /* we do receive a beacon and the hw TSF has not been updated */
++                              DPRINTF(sc, ATH_DEBUG_BEACON,
++                                      "%s: beacon received, but TSF is incorrect\n",__func__);
++                      } else {
++                              /* we do receive a beacon in the past, normal case */
++                              DPRINTF(sc, ATH_DEBUG_BEACON,
++                                      "%s: beacon received, TSF is correct\n",__func__);
++                      }
++              }
++      }
++
++      DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt=%u intval=%u\n",
++              __func__,nexttbtt, intval & HAL_BEACON_PERIOD);
+ }
+ static int
This page took 0.023001 seconds and 4 git commands to generate.