Ticket #1033: madwifi-ibss-merge-clean.3.diff
| File madwifi-ibss-merge-clean.3.diff, 11.0 kB (added by mentor, 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 } … … 1188 1187 struct ieee80211com *ic = vap->iv_ic; 1189 1188 struct ieee80211_node *ni; 1190 1189 1191 ni = ieee80211_dup_bss(vap, wh->i_addr2, 1);1190 ni = ieee80211_dup_bss(vap, wh->i_addr2, 0); 1192 1191 if (ni != NULL) { 1193 1192 ni->ni_esslen = sp->ssid[1]; 1194 1193 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; 364 363 365 /* Assume each node needs 500 bytes */ 364 366 if (buf + space < p + 500) 365 367 break; 366 367 if (ni->ni_vap == vap && 368 0 != memcmp(vap->iv_myaddr, ni->ni_macaddr, IEEE80211_ADDR_LEN)) { 369 struct timespec t; 368 if ((ni->ni_vap == vap) && (memcmp(vap->iv_myaddr, 369 ni->ni_macaddr, IEEE80211_ADDR_LEN) != 0)) { 370 370 jiffies_to_timespec(jiffies - ni->ni_last_rx, &t); 371 p += sprintf(p, "macaddr: <%s>\n", ether_sprintf(ni->ni_macaddr)); 371 p += sprintf(p, "ni: %p%s vap: %p macaddr: <%s>\n", 372 ni, ni == ni->ni_vap->iv_bss ? "*" : " ", 373 ni->ni_vap, ether_sprintf(ni->ni_macaddr)); 372 374 p += sprintf(p, " rssi %d\n", ni->ni_rssi); 373 375 374 376 p += sprintf(p, " last_rx %ld.%06ld\n", 375 377 t.tv_sec, t.tv_nsec / 1000); 376 378 p += sprintf(p, " ni_tstamp %10llu ni_rtsf %10llu\n", 379 le64_to_cpu(ni->ni_tstamp.tsf), ni->ni_rtsf); 377 380 } 378 381 } 379 382 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 383 380 384 return (p - buf); 381 385 } 382 386 -
ath/if_ath.c
old new 4416 4416 * the beacon miss handling so we'll receive a BMISS 4417 4417 * interrupt when we stop seeing beacons from the AP 4418 4418 * we've associated with. 4419 * 4420 * Note : TBTT is Target Beacon Transmission Time (see IEEE 4421 * 802.11-1999: 4 & 11.2.1.3). 4419 4422 */ 4420 4423 static void 4421 4424 ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap) … … 4425 4428 struct ieee80211com *ic = &sc->sc_ic; 4426 4429 struct ath_hal *ah = sc->sc_ah; 4427 4430 struct ieee80211_node *ni; 4428 u_int32_t nexttbtt, intval; 4431 u_int32_t nexttbtt = 0; 4432 u_int32_t intval; 4433 u_int64_t tsf, hw_tsf; 4434 u_int32_t tsftu, hw_tsftu; 4435 int reset_tsf = 0; 4429 4436 4430 4437 if (vap == NULL) 4431 4438 vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */ 4432 4439 4433 4440 ni = vap->iv_bss; 4434 4441 4435 /* extract tstamp from last beacon and convert to TU */ 4436 nexttbtt = TSF_TO_TU(LE_READ_4(ni->ni_tstamp.data + 4), 4437 LE_READ_4(ni->ni_tstamp.data)); 4438 /* XXX conditionalize multi-bss support? */ 4442 hw_tsf = ath_hal_gettsf64(ah); 4443 tsf = le64_to_cpu(ni->ni_tstamp.tsf); 4444 hw_tsftu = hw_tsf >> 10; 4445 tsftu = tsf >> 10; 4446 4447 /* We should reset hw TSF only once, so we increment 4448 * ni_tstamp.tsf to avoid resetting the hw TSF multiple 4449 * times */ 4450 4451 if (tsf == 0) { 4452 reset_tsf = 1; 4453 ni->ni_tstamp.tsf = cpu_to_le64(1); 4454 } 4455 4456 /* XXX: Conditionalize multi-bss support? */ 4439 4457 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 4440 /* 4441 * For multi-bss ap support beacons are either staggered 4458 /* For multi-bss ap support beacons are either staggered 4442 4459 * evenly over N slots or burst together. For the former 4443 4460 * arrange for the SWBA to be delivered for each slot. 4444 * Slots that are not occupied will generate nothing. 4445 */ 4461 * Slots that are not occupied will generate nothing. */ 4446 4462 /* NB: the beacon interval is kept internally in TUs */ 4447 4463 intval = ic->ic_lintval & HAL_BEACON_PERIOD; 4448 4464 if (sc->sc_stagbeacons) 4449 4465 intval /= ATH_BCBUF; /* for staggered beacons */ 4450 4466 if ((sc->sc_nostabeacons) && 4451 (vap->iv_opmode == IEEE80211_M_HOSTAP))4452 nexttbtt = 0;4467 (vap->iv_opmode == IEEE80211_M_HOSTAP)) 4468 reset_tsf = 1; 4453 4469 } else 4454 4470 intval = ni->ni_intval & HAL_BEACON_PERIOD; 4455 if (nexttbtt == 0) /* e.g. for ap mode */ 4471 4472 #define FUDGE 2 4473 sc->sc_syncbeacon = 0; 4474 4475 if (reset_tsf) { 4476 /* We just created the interface and TSF will be reset to 4477 * zero, so next beacon will be sent at the next intval 4478 * time */ 4456 4479 nexttbtt = intval; 4457 else if (intval) /* NB: can be 0 for monitor mode */ 4458 nexttbtt = roundup(nexttbtt, intval); 4459 DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt %u intval %u (%u)\n", 4460 __func__, nexttbtt, intval, ni->ni_intval); 4480 } else if (intval) { /* NB: can be 0 for monitor mode */ 4481 if (tsf == 1) { 4482 /* We have not received any beacons or probe responses. 4483 * The next TBTT must be at least FUDGE ms ahead of the 4484 * hw_tsftu. Also, TSF == 0 is a TBTT - IEEE802.11-1999 4485 * 11.1.2.2, although I'm not sure it applies here... */ 4486 nexttbtt = roundup(hw_tsftu + FUDGE, intval); 4487 } else { 4488 if (tsf > hw_tsf) { 4489 /* We received a beacon, but the HW TSF has 4490 * not been updated (otherwise hw_tsf > tsf). 4491 * We cannot use the hardware TSF, so we wait 4492 * to synchronise beacons again. */ 4493 sc->sc_syncbeacon = 1; 4494 goto ath_beacon_config_debug; 4495 } else { 4496 /* Normal case: we received a beacon to which 4497 * we have synchornised. Make sure that 4498 * nexttbtt is at least FUDGE ms ahead of 4499 * hw_tsf. */ 4500 nexttbtt = tsftu + roundup(hw_tsftu + 4501 FUDGE - tsftu, intval); 4502 } 4503 } 4504 } 4505 4461 4506 if (ic->ic_opmode == IEEE80211_M_STA && !(sc->sc_nostabeacons)) { 4462 4507 HAL_BEACON_STATE bs; 4463 u_int64_t tsf;4464 u_int32_t tsftu;4465 4508 int dtimperiod, dtimcount; 4466 4509 int cfpperiod, cfpcount; 4467 4510 4468 /* 4469 * Setup dtim and cfp parameters according to 4470 * last beacon we received (which may be none). 4471 */ 4511 /* Setup DTIM and CFP parameters according to the last beacon 4512 * we have received (which may not have happened). */ 4472 4513 dtimperiod = vap->iv_dtim_period; 4473 4514 if (dtimperiod <= 0) /* NB: 0 if not known */ 4474 4515 dtimperiod = 1; … … 4477 4518 dtimcount = 0; /* XXX? */ 4478 4519 cfpperiod = 1; /* NB: no PCF support yet */ 4479 4520 cfpcount = 0; 4480 #define FUDGE 24481 4521 /* 4482 4522 * Pull nexttbtt forward to reflect the current 4483 4523 * TSF and calculate dtim+cfp state for the result. 4484 4524 */ 4485 tsf = ath_hal_gettsf64(ah); 4486 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE; 4525 nexttbtt = tsftu; 4526 if (nexttbtt == 0) /* e.g. for ap mode */ 4527 nexttbtt = intval; 4487 4528 do { 4488 4529 nexttbtt += intval; 4489 4530 if (--dtimcount < 0) { … … 4491 4532 if (--cfpcount < 0) 4492 4533 cfpcount = cfpperiod - 1; 4493 4534 } 4494 } while (nexttbtt < tsftu);4535 } while (nexttbtt < hw_tsftu + FUDGE); 4495 4536 #undef FUDGE 4496 4537 memset(&bs, 0, sizeof(bs)); 4497 4538 bs.bs_intval = intval; … … 4565 4606 ath_hal_intrset(ah, sc->sc_imask); 4566 4607 } else { 4567 4608 ath_hal_intrset(ah, 0); 4568 if ( nexttbtt == intval)4609 if (reset_tsf) 4569 4610 intval |= HAL_BEACON_RESET_TSF; 4570 4611 if (ic->ic_opmode == IEEE80211_M_IBSS) { 4571 4612 /* … … 4602 4643 if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_hasveol) 4603 4644 ath_beacon_start_adhoc(sc, vap); 4604 4645 } 4605 sc->sc_syncbeacon = 0;4606 4646 #undef TSF_TO_TU 4647 4648 ath_beacon_config_debug: 4649 /* We print all debug messages here, in order to preserve the 4650 * time critical aspect of this function */ 4651 DPRINTF(sc, ATH_DEBUG_BEACON, 4652 "%s: ni=%p tsf=%llu hw_tsf=%llu tsftu=%u hw_tsftu=%u\n", 4653 __func__, ni, tsf, hw_tsf, tsftu, hw_tsftu); 4654 4655 if (reset_tsf) 4656 /* We just created the interface */ 4657 DPRINTF(sc, ATH_DEBUG_BEACON, "%s: first beacon\n", __func__); 4658 else if (tsf == 1) 4659 /* We do not receive any beacons or probe response */ 4660 DPRINTF(sc, ATH_DEBUG_BEACON, 4661 "%s: no beacon received...\n",__func__); 4662 else if (tsf > hw_tsf) 4663 /* We do receive a beacon and the hw TSF has not been updated */ 4664 DPRINTF(sc, ATH_DEBUG_BEACON, 4665 "%s: beacon received, but TSF is incorrect\n", 4666 __func__); 4667 else 4668 /* We do receive a beacon in the past, normal case */ 4669 DPRINTF(sc, ATH_DEBUG_BEACON, 4670 "%s: beacon received, TSF is correct\n", 4671 __func__); 4672 4673 DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt=%u intval=%u\n", 4674 __func__, nexttbtt, intval & HAL_BEACON_PERIOD); 4607 4675 } 4608 4676 4609 4677 static int … … 5446 5514 struct ath_softc *sc = ni->ni_ic->ic_dev->priv; 5447 5515 struct ieee80211vap *vap = ni->ni_vap; 5448 5516 5449 /* 5450 * Call up first so subsequent work can use information 5451 * potentially stored in the node (e.g. for ibss merge). 5452 */ 5517 /* Call up first so subsequent work can use information 5518 * potentially stored in the node (e.g. for ibss merge). */ 5453 5519 sc->sc_recv_mgmt(ni, skb, subtype, rssi, rtsf); 5454 5520 switch (subtype) { 5455 5521 case IEEE80211_FC0_SUBTYPE_BEACON: 5456 /* update rssistatistics for use by the HAL */5522 /* Update RSSI statistics for use by the HAL */ 5457 5523 ATH_RSSI_LPF(ATH_NODE(ni)->an_halstats.ns_avgbrssi, rssi); 5458 5524 if ((sc->sc_syncbeacon || (vap->iv_flags_ext & IEEE80211_FEXT_APPIE_UPDATE)) && 5459 5525 ni == vap->iv_bss && vap->iv_state == IEEE80211_S_RUN) { 5460 /* 5461 * Resync beacon timers using the tsf of the 5462 * beacon frame we just received. 5463 */ 5526 /* Resync beacon timers using the TSF of the 5527 * beacon frame we just received. */ 5464 5528 vap->iv_flags_ext &= ~IEEE80211_FEXT_APPIE_UPDATE; 5465 5529 ath_beacon_config(sc, vap); 5466 5530 } 5467 /* fall thru...*/5531 /* NB: Fall Through */ 5468 5532 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 5469 5533 if (vap->iv_opmode == IEEE80211_M_IBSS && 5470 vap->iv_state == IEEE80211_S_RUN) { 5471 /* 5472 * Handle IBSS merge as needed; check the TSF on the 5534 vap->iv_state == IEEE80211_S_RUN) { 5535 /* Don't merge if we have a desired BSSID */ 5536 if (vap->iv_flags & IEEE80211_F_DESBSSID) 5537 break; 5538 5539 /* To handle IBSS merge, we need the struct 5540 * ieee80211_node which has been updated with the 5541 * BSSID and TSF from the last beacon */ 5542 ni = ieee80211_find_rxnode(ni->ni_ic, 5543 (const struct ieee80211_frame_min *) skb->data); 5544 if (ni == NULL) 5545 break; 5546 5547 /* Handle IBSS merge as needed; check the TSF on the 5473 5548 * frame before attempting the merge. The 802.11 spec 5474 5549 * says the station should change its BSSID to match 5475 5550 * the oldest station with the same SSID, where oldest 5476 5551 * is determined by the TSF. Note that hardware 5477 5552 * reconfiguration happens through callback to 5478 5553 * ath_newstate as the state machine will go from 5479 * RUN -> RUN when this happens. 5480 */ 5481 /* jal: added: don't merge if we have a desired 5482 BSSID */ 5483 if (!(vap->iv_flags & IEEE80211_F_DESBSSID) && 5484 le64_to_cpu(ni->ni_tstamp.tsf) >= rtsf) { 5485 DPRINTF(sc, ATH_DEBUG_STATE, 5486 "ibss merge, rtsf %10llu local tsf %10llu\n", 5487 rtsf, 5488 (unsigned long long) le64_to_cpu(ni->ni_tstamp.tsf)); 5489 (void) ieee80211_ibss_merge(ni); 5554 * RUN -> RUN when this happens. */ 5555 DPRINTF(sc, ATH_DEBUG_BEACON, 5556 "check for ibss merge for ni=%p TSF1(t4)=%10llu TSF2(t3)=%10llu\n", 5557 ni, rtsf, le64_to_cpu(ni->ni_tstamp.tsf)); 5558 5559 if (rtsf < le64_to_cpu(ni->ni_tstamp.tsf)) { 5560 DPRINTF(sc, ATH_DEBUG_BEACON, 5561 "ibss merge, rtsf %10llu local tsf %10llu\n", 5562 rtsf, le64_to_cpu(ni->ni_tstamp.tsf)); 5563 ieee80211_ibss_merge(ni); 5490 5564 } 5491 5565 } 5492 5566 break;
