Ticket #1033: madwifi-ibss-merge-clean.diff
| File madwifi-ibss-merge-clean.diff, 9.6 kB (added by benoit.papillault@free.fr, 1 year ago) |
|---|
-
net80211/ieee80211_node.c
old new 517 517 struct ieee80211com *ic = ni->ni_ic; 518 518 #endif 519 519 520 if (ni == vap->iv_bss || 521 IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid)) { 520 if (ni == vap->iv_bss) { 522 521 /* unchanged, nothing to do */ 523 522 return 0; 524 523 } … … 1195 1194 struct ieee80211com *ic = vap->iv_ic; 1196 1195 struct ieee80211_node *ni; 1197 1196 1198 ni = ieee80211_dup_bss(vap, wh->i_addr2, 1);1197 ni = ieee80211_dup_bss(vap, wh->i_addr2, 0); 1199 1198 if (ni != NULL) { 1200 1199 ni->ni_esslen = sp->ssid[1]; 1201 1200 memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]); -
net80211/ieee80211_linux.c
old new 360 360 361 361 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 362 362 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 363 struct timespec t; 363 364 /* Assume each node needs 500 bytes */ 364 365 if (buf + space < p + 500) 365 366 break; 366 367 /* 367 368 if (ni->ni_vap == vap && 368 369 0 != memcmp(vap->iv_myaddr, ni->ni_macaddr, IEEE80211_ADDR_LEN)) { 369 struct timespec t;370 */ 370 371 jiffies_to_timespec(jiffies - ni->ni_last_rx, &t); 371 p += sprintf(p, "macaddr: <%s>\n", ether_sprintf(ni->ni_macaddr)); 372 p += sprintf(p, "ni: %p%s vap: %p macaddr: <%s>\n", 373 ni, ni == ni->ni_vap->iv_bss ? "*" : " ", 374 ni->ni_vap, ether_sprintf(ni->ni_macaddr)); 372 375 p += sprintf(p, " rssi %d\n", ni->ni_rssi); 373 376 374 377 p += sprintf(p, " last_rx %ld.%06ld\n", 375 378 t.tv_sec, t.tv_nsec / 1000); 376 379 p += sprintf(p, " ni_tstamp %10llu ni_rtsf %10llu\n", 380 le64_to_cpu(ni->ni_tstamp.tsf), ni->ni_rtsf); 381 /* 377 382 } 383 */ 378 384 } 379 385 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 380 386 return (p - buf); -
ath/if_ath.c
old new 4540 4540 * the beacon miss handling so we'll receive a BMISS 4541 4541 * interrupt when we stop seeing beacons from the AP 4542 4542 * we've associated with. 4543 * 4544 * Note : TBTT is Target Beacon Transmission Time (see IEEE 802.11-1999) 4543 4545 */ 4544 4546 static void 4545 4547 ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap) … … 4549 4551 struct ieee80211com *ic = &sc->sc_ic; 4550 4552 struct ath_hal *ah = sc->sc_ah; 4551 4553 struct ieee80211_node *ni; 4552 u_int32_t nexttbtt, intval; 4554 u_int32_t nexttbtt = 0; 4555 u_int32_t intval; 4556 u_int64_t tsf, hw_tsf; 4557 u_int32_t tsftu, hw_tsftu; 4558 int should_reset_tsf = 0; 4553 4559 4554 4560 if (vap == NULL) 4555 4561 vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */ 4556 4562 4557 4563 ni = vap->iv_bss; 4558 4564 4559 /* extract tstamp from last beacon and convert to TU */ 4560 nexttbtt = TSF_TO_TU(LE_READ_4(ni->ni_tstamp.data + 4), 4561 LE_READ_4(ni->ni_tstamp.data)); 4565 hw_tsf = ath_hal_gettsf64(ah); 4566 tsf = le64_to_cpu(ni->ni_tstamp.tsf); 4567 hw_tsftu = hw_tsf >> 10; 4568 tsftu = tsf >> 10; 4569 4570 /* we should reset hw TSF only once, so we increment 4571 ni_tstamp.tsf to avoid resetting the hw TSF multiple 4572 times */ 4573 4574 if (tsf == 0) { 4575 should_reset_tsf = 1; 4576 ni->ni_tstamp.tsf = cpu_to_le64(1); 4577 } 4578 4562 4579 /* XXX conditionalize multi-bss support? */ 4563 4580 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 4564 4581 /* … … 4572 4589 if (sc->sc_stagbeacons) 4573 4590 intval /= ATH_BCBUF; /* for staggered beacons */ 4574 4591 if ((sc->sc_nostabeacons) && 4575 (vap->iv_opmode == IEEE80211_M_HOSTAP))4576 nexttbtt = 0;4592 (vap->iv_opmode == IEEE80211_M_HOSTAP)) 4593 should_reset_tsf = 1; 4577 4594 } else 4578 4595 intval = ni->ni_intval & HAL_BEACON_PERIOD; 4579 if (nexttbtt == 0) /* e.g. for ap mode */ 4596 4597 #define FUDGE 2 4598 sc->sc_syncbeacon = 0; 4599 4600 if (should_reset_tsf) { 4601 4602 /* We just created the interface and TSF will be reset to 4603 zero, so next beacon will be sent at the next intval 4604 time */ 4605 4580 4606 nexttbtt = intval; 4581 else if (intval) /* NB: can be 0 for monitor mode */ 4582 nexttbtt = roundup(nexttbtt, intval); 4583 DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt %u intval %u (%u)\n", 4584 __func__, nexttbtt, intval, ni->ni_intval); 4607 } else if (intval) { /* NB: can be 0 for monitor mode */ 4608 if (tsf == 1) { 4609 4610 /* We do not receive any beacons or probe response. Since 4611 a beacon should be sent every 'intval' ms, we compute 4612 the next beacon timestamp using the hardware TSF. We 4613 ensure that it is at least FUDGE ms ahead of the 4614 current TSF. Otherwise, we use the next beacon 4615 timestamp again */ 4616 4617 nexttbtt = roundup(hw_tsftu +1, intval); 4618 while (nexttbtt <= hw_tsftu + FUDGE) { 4619 nexttbtt += intval; 4620 } 4621 } else { 4622 if (tsf > hw_tsf) { 4623 4624 /* We do receive a beacon from someone else in the past, 4625 but the hw TSF has not been updated (otherwise we 4626 would have tsf >= hw_tsf). Since we cannot use the 4627 hardware TSF, we will do nothing and wait for the 4628 next beacon. In order to do so, we set sc->syncbeacon 4629 again */ 4630 4631 sc->sc_syncbeacon = 1; 4632 goto ath_beacon_config_debug; 4633 } else { 4634 /* We do receive a beacon in the past, normal case. We 4635 make sure that the timestamp is at least FUDGE ms 4636 ahead of the hardware TSF */ 4637 4638 nexttbtt = tsftu + intval; 4639 while (nexttbtt <= hw_tsftu + FUDGE) { 4640 nexttbtt += intval; 4641 } 4642 } 4643 } 4644 } 4645 4585 4646 if (ic->ic_opmode == IEEE80211_M_STA && !(sc->sc_nostabeacons)) { 4586 4647 HAL_BEACON_STATE bs; 4587 u_int64_t tsf;4588 u_int32_t tsftu;4589 4648 int dtimperiod, dtimcount; 4590 4649 int cfpperiod, cfpcount; 4591 4650 … … 4601 4660 dtimcount = 0; /* XXX? */ 4602 4661 cfpperiod = 1; /* NB: no PCF support yet */ 4603 4662 cfpcount = 0; 4604 #define FUDGE 24605 4663 /* 4606 4664 * Pull nexttbtt forward to reflect the current 4607 4665 * TSF and calculate dtim+cfp state for the result. 4608 4666 */ 4609 tsf = ath_hal_gettsf64(ah); 4610 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE; 4667 nexttbtt = tsftu; 4668 if (nexttbtt == 0) /* e.g. for ap mode */ 4669 nexttbtt = intval; 4611 4670 do { 4612 4671 nexttbtt += intval; 4613 4672 if (--dtimcount < 0) { … … 4615 4674 if (--cfpcount < 0) 4616 4675 cfpcount = cfpperiod - 1; 4617 4676 } 4618 } while (nexttbtt < tsftu);4677 } while (nexttbtt < hw_tsftu + FUDGE); 4619 4678 #undef FUDGE 4620 4679 memset(&bs, 0, sizeof(bs)); 4621 4680 bs.bs_intval = intval; … … 4689 4748 ath_hal_intrset(ah, sc->sc_imask); 4690 4749 } else { 4691 4750 ath_hal_intrset(ah, 0); 4692 if ( nexttbtt == intval)4751 if (should_reset_tsf) 4693 4752 intval |= HAL_BEACON_RESET_TSF; 4694 4753 if (ic->ic_opmode == IEEE80211_M_IBSS) { 4695 4754 /* … … 4726 4785 if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_hasveol) 4727 4786 ath_beacon_start_adhoc(sc, vap); 4728 4787 } 4729 sc->sc_syncbeacon = 0;4730 4788 #undef TSF_TO_TU 4789 4790 ath_beacon_config_debug: 4791 4792 /* we print all debug messages here, in order to preserve the 4793 time critical aspect of this function */ 4794 4795 DPRINTF(sc, ATH_DEBUG_BEACON, 4796 "%s: ni=%p tsf=%llu hw_tsf=%llu tsftu=%u hw_tsftu=%u\n", 4797 __func__, ni, tsf, hw_tsf, tsftu, hw_tsftu); 4798 4799 if (should_reset_tsf) { 4800 /* we just created the interface */ 4801 DPRINTF(sc, ATH_DEBUG_BEACON, "%s: first beacon\n",__func__); 4802 } else { 4803 if (tsf == 1) { 4804 /* we do not receive any beacons or probe response */ 4805 DPRINTF(sc, ATH_DEBUG_BEACON, 4806 "%s: no beacon received...\n",__func__); 4807 } else { 4808 if (tsf > hw_tsf) { 4809 /* we do receive a beacon and the hw TSF has not been updated */ 4810 DPRINTF(sc, ATH_DEBUG_BEACON, 4811 "%s: beacon received, but TSF is incorrect\n",__func__); 4812 } else { 4813 /* we do receive a beacon in the past, normal case */ 4814 DPRINTF(sc, ATH_DEBUG_BEACON, 4815 "%s: beacon received, TSF is correct\n",__func__); 4816 } 4817 } 4818 } 4819 4820 DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt=%u intval=%u\n", 4821 __func__,nexttbtt, intval & HAL_BEACON_PERIOD); 4731 4822 } 4732 4823 4733 4824 static int … … 5595 5686 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 5596 5687 if (vap->iv_opmode == IEEE80211_M_IBSS && 5597 5688 vap->iv_state == IEEE80211_S_RUN) { 5689 5690 /* jal: added: don't merge if we have a desired 5691 BSSID */ 5692 5693 if (vap->iv_flags & IEEE80211_F_DESBSSID) { 5694 break; 5695 } 5696 5697 /* To handle IBSS merge, we need the struct 5698 ieee80211_node which has been updated with the 5699 BSSID and TSF from the last beacon */ 5700 5701 ni = ieee80211_find_rxnode(ni->ni_ic, 5702 (const struct ieee80211_frame_min *) skb->data); 5703 if (ni == NULL) { 5704 break; 5705 } 5706 5598 5707 /* 5599 5708 * Handle IBSS merge as needed; check the TSF on the 5600 5709 * frame before attempting the merge. The 802.11 spec … … 5605 5714 * ath_newstate as the state machine will go from 5606 5715 * RUN -> RUN when this happens. 5607 5716 */ 5608 /* jal: added: don't merge if we have a desired 5609 BSSID */ 5610 if (!(vap->iv_flags & IEEE80211_F_DESBSSID) && 5611 le64_to_cpu(ni->ni_tstamp.tsf) >= rtsf) { 5612 DPRINTF(sc, ATH_DEBUG_STATE, 5613 "ibss merge, rtsf %10llu local tsf %10llu\n", 5614 rtsf, 5615 (unsigned long long) le64_to_cpu(ni->ni_tstamp.tsf)); 5616 (void) ieee80211_ibss_merge(ni); 5617 } 5717 5718 DPRINTF(sc, ATH_DEBUG_BEACON, 5719 "check for ibss merge for ni=%p TSF1(t4)=%10llu TSF2(t3)=%10llu\n", 5720 ni, rtsf, le64_to_cpu(ni->ni_tstamp.tsf)); 5721 5722 if (rtsf < le64_to_cpu(ni->ni_tstamp.tsf)) { 5723 DPRINTF(sc, ATH_DEBUG_BEACON, 5724 "ibss merge, rtsf %10llu local tsf %10llu\n", 5725 rtsf, le64_to_cpu(ni->ni_tstamp.tsf)); 5726 ieee80211_ibss_merge(ni); 5727 } 5618 5728 } 5619 5729 break; 5620 5730 }
