Ticket #1033: adhoc-beacon-5.diff
| File adhoc-beacon-5.diff, 5.8 kB (added by tjalling.hattink@ti-wmc.nl, 2 years ago) |
|---|
-
ath/if_ath.c
old new 4416 4416 struct ieee80211com *ic = &sc->sc_ic; 4417 4417 struct ath_hal *ah = sc->sc_ah; 4418 4418 struct ieee80211_node *ni; 4419 u_int32_t nexttbtt, intval; 4419 u_int32_t nexttbtt = 0; 4420 u_int32_t intval; 4421 u_int64_t tsf, hw_tsf; 4422 u_int32_t tsftu, hw_tsftu; 4423 int should_reset_tsf = 0; 4420 4424 4421 4425 if (vap == NULL) 4422 4426 vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */ 4423 4427 4424 4428 ni = vap->iv_bss; 4425 4429 4426 /* extract tstamp from last beacon and convert to TU */ 4427 nexttbtt = TSF_TO_TU(LE_READ_4(ni->ni_tstamp.data + 4), 4428 LE_READ_4(ni->ni_tstamp.data)); 4430 hw_tsf = ath_hal_gettsf64(ah); 4431 tsf = le64_to_cpu(ni->ni_tstamp.tsf); 4432 hw_tsftu = hw_tsf >> 10; 4433 tsftu = tsf >> 10; 4434 4435 /* we should reset hw TSF only once, so we increment 4436 ni_tstamp.tsf to avoid resetting the hw TSF multiple 4437 times */ 4438 4439 if (tsf == 0) { 4440 should_reset_tsf = 1; 4441 ni->ni_tstamp.tsf = cpu_to_le64(1); 4442 } 4443 4429 4444 /* XXX conditionalize multi-bss support? */ 4430 4445 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 4431 4446 /* … … 4439 4454 if (sc->sc_stagbeacons) 4440 4455 intval /= ATH_BCBUF; /* for staggered beacons */ 4441 4456 if ((sc->sc_nostabeacons) && 4442 (vap->iv_opmode == IEEE80211_M_HOSTAP))4443 nexttbtt = 0;4457 (vap->iv_opmode == IEEE80211_M_HOSTAP)) 4458 should_reset_tsf = 1; 4444 4459 } else 4445 4460 intval = ni->ni_intval & HAL_BEACON_PERIOD; 4446 if (nexttbtt == 0) /* e.g. for ap mode */ 4461 4462 #define FUDGE 2 4463 sc->sc_syncbeacon = 0; 4464 if (should_reset_tsf) { 4465 4466 /* We just created the interface and TSF will be reset to 4467 zero, so next beacon will be sent at the next intval 4468 time */ 4469 4447 4470 nexttbtt = intval; 4448 else if (intval) /* NB: can be 0 for monitor mode */ 4449 nexttbtt = roundup(nexttbtt, intval); 4450 DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt %u intval %u (%u)\n", 4451 __func__, nexttbtt, intval, ni->ni_intval); 4471 } else if (intval) { /* NB: can be 0 for monitor mode */ 4472 if (tsf == 1) { 4473 4474 /* We do not receive any beacons or probe response. Since 4475 a beacon should be sent every 'intval' ms, we compute 4476 the next beacon timestamp using the hardware TSF. We 4477 ensure that it is at least FUDGE ms ahead of the 4478 current TSF. Otherwise, we use the next beacon 4479 timestamp again */ 4480 4481 nexttbtt = roundup(hw_tsftu +1, intval); 4482 while (nexttbtt <= hw_tsftu + FUDGE) { 4483 nexttbtt += intval; 4484 } 4485 } else { 4486 if (tsf > hw_tsf) { 4487 4488 /* We do receive a beacon from someone else in the past, 4489 but the hw TSF has not been updated (otherwise we 4490 would have tsf >= hw_tsf). Since we cannot use the 4491 hardware TSF, we will do nothing and wait for the 4492 next beacon. In order to do so, we set sc->syncbeacon 4493 again */ 4494 4495 sc->sc_syncbeacon = 1; 4496 goto ath_beacon_config_debug; 4497 } else { 4498 /* We do receive a beacon in the past, normal case. We 4499 make sure that the timestamp is at least FUDGE ms 4500 ahead of the hardware TSF */ 4501 4502 nexttbtt = tsftu + intval; 4503 while (nexttbtt <= hw_tsftu + FUDGE) { 4504 nexttbtt += intval; 4505 } 4506 } 4507 } 4508 } 4509 4452 4510 if (ic->ic_opmode == IEEE80211_M_STA && !(sc->sc_nostabeacons)) { 4453 4511 HAL_BEACON_STATE bs; 4454 u_int64_t tsf;4455 u_int32_t tsftu;4456 4512 int dtimperiod, dtimcount; 4457 4513 int cfpperiod, cfpcount; 4458 4514 … … 4468 4524 dtimcount = 0; /* XXX? */ 4469 4525 cfpperiod = 1; /* NB: no PCF support yet */ 4470 4526 cfpcount = 0; 4471 #define FUDGE 24472 4527 /* 4473 4528 * Pull nexttbtt forward to reflect the current 4474 4529 * TSF and calculate dtim+cfp state for the result. 4475 4530 */ 4476 tsf = ath_hal_gettsf64(ah); 4477 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE; 4531 nexttbtt = tsftu; 4532 if (nexttbtt == 0) /* e.g. for ap mode */ 4533 nexttbtt = intval; 4478 4534 do { 4479 4535 nexttbtt += intval; 4480 4536 if (--dtimcount < 0) { … … 4482 4538 if (--cfpcount < 0) 4483 4539 cfpcount = cfpperiod - 1; 4484 4540 } 4485 } while (nexttbtt < tsftu);4541 } while (nexttbtt < hw_tsftu + FUDGE); 4486 4542 #undef FUDGE 4487 4543 memset(&bs, 0, sizeof(bs)); 4488 4544 bs.bs_intval = intval; … … 4534 4590 DPRINTF(sc, ATH_DEBUG_BEACON, 4535 4591 "%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", 4536 4592 __func__, 4537 (long long) tsf,tsftu,4593 (long long) hw_tsf, hw_tsftu, 4538 4594 bs.bs_intval, 4539 4595 bs.bs_nexttbtt, 4540 4596 bs.bs_dtimperiod, … … 4553 4609 ath_hal_intrset(ah, sc->sc_imask); 4554 4610 } else { 4555 4611 ath_hal_intrset(ah, 0); 4556 if ( nexttbtt == intval)4612 if (should_reset_tsf) 4557 4613 intval |= HAL_BEACON_RESET_TSF; 4558 4614 if (ic->ic_opmode == IEEE80211_M_IBSS) { 4559 4615 /* … … 4590 4646 if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_hasveol) 4591 4647 ath_beacon_start_adhoc(sc, vap); 4592 4648 } 4593 sc->sc_syncbeacon = 0;4594 4649 #undef TSF_TO_TU 4650 4651 ath_beacon_config_debug: 4652 4653 /* we print all debug messages here, in order to preserve the 4654 time critical aspect of this function */ 4655 4656 DPRINTF(sc, ATH_DEBUG_BEACON, 4657 "%s: ni=%p tsf=%llu hw_tsf=%llu tsftu=%u hw_tsftu=%u\n", 4658 __func__, ni, tsf, hw_tsf, tsftu, hw_tsftu); 4659 4660 if (should_reset_tsf) { 4661 /* we just created the interface */ 4662 DPRINTF(sc, ATH_DEBUG_BEACON, "%s: first beacon\n",__func__); 4663 } else { 4664 if (tsf == 1) { 4665 /* we do not receive any beacons or probe response */ 4666 DPRINTF(sc, ATH_DEBUG_BEACON, 4667 "%s: no beacon received...\n",__func__); 4668 } else { 4669 if (tsf > hw_tsf) { 4670 /* we do receive a beacon and the hw TSF has not been updated */ 4671 DPRINTF(sc, ATH_DEBUG_BEACON, 4672 "%s: beacon received, but TSF is incorrect\n",__func__); 4673 } else { 4674 /* we do receive a beacon in the past, normal case */ 4675 DPRINTF(sc, ATH_DEBUG_BEACON, 4676 "%s: beacon received, TSF is correct\n",__func__); 4677 } 4678 } 4679 } 4680 4681 DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt=%u intval=%u\n", 4682 __func__,nexttbtt, intval & HAL_BEACON_PERIOD); 4595 4683 } 4596 4684 4597 4685 static int
