summaryrefslogtreecommitdiffstats
path: root/package/madwifi/patches/116-adhoc_beacon_PR_1033.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/madwifi/patches/116-adhoc_beacon_PR_1033.patch')
-rw-r--r--package/madwifi/patches/116-adhoc_beacon_PR_1033.patch196
1 files changed, 196 insertions, 0 deletions
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
index 0000000000..92a147c1b3
--- /dev/null
+++ b/package/madwifi/patches/116-adhoc_beacon_PR_1033.patch
@@ -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