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