From owner-p4-projects@FreeBSD.ORG Mon Jul 18 16:56:39 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id CB96A16A420; Mon, 18 Jul 2005 16:56:38 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9A3FC16A41C for ; Mon, 18 Jul 2005 16:56:38 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 00CEB43D4C for ; Mon, 18 Jul 2005 16:56:38 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j6IGub07064242 for ; Mon, 18 Jul 2005 16:56:37 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j6IGubhj064239 for perforce@freebsd.org; Mon, 18 Jul 2005 16:56:37 GMT (envelope-from sam@freebsd.org) Date: Mon, 18 Jul 2005 16:56:37 GMT Message-Id: <200507181656.j6IGubhj064239@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 80453 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Jul 2005 16:56:39 -0000 http://perforce.freebsd.org/chv.cgi?CH=80453 Change 80453 by sam@sam_ebb on 2005/07/18 16:56:28 Checkpoint backmerge of new scanning+roaming+power save support. While here nuke wiconfig compatbility ioctls and update some api's to conform to vap work. Still more things to cleanup/fix but bg scan+roam works. Affected files ... .. //depot/projects/wifi/sys/net80211/_ieee80211.h#7 edit .. //depot/projects/wifi/sys/net80211/ieee80211.c#24 edit .. //depot/projects/wifi/sys/net80211/ieee80211_freebsd.h#17 edit .. //depot/projects/wifi/sys/net80211/ieee80211_input.c#53 edit .. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#40 edit .. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.h#25 edit .. //depot/projects/wifi/sys/net80211/ieee80211_node.c#54 edit .. //depot/projects/wifi/sys/net80211/ieee80211_node.h#25 edit .. //depot/projects/wifi/sys/net80211/ieee80211_output.c#44 edit .. //depot/projects/wifi/sys/net80211/ieee80211_power.c#1 add .. //depot/projects/wifi/sys/net80211/ieee80211_power.h#1 add .. //depot/projects/wifi/sys/net80211/ieee80211_proto.c#28 edit .. //depot/projects/wifi/sys/net80211/ieee80211_proto.h#18 edit .. //depot/projects/wifi/sys/net80211/ieee80211_scan.c#1 add .. //depot/projects/wifi/sys/net80211/ieee80211_scan.h#1 add .. //depot/projects/wifi/sys/net80211/ieee80211_scan_ap.c#1 add .. //depot/projects/wifi/sys/net80211/ieee80211_scan_sta.c#1 add .. //depot/projects/wifi/sys/net80211/ieee80211_var.h#28 edit Differences ... ==== //depot/projects/wifi/sys/net80211/_ieee80211.h#7 (text+ko) ==== @@ -216,4 +216,14 @@ u_int8_t rs_rates[IEEE80211_RATE_MAXSIZE]; }; +struct ieee80211_roam { + int8_t rssi11a; /* rssi thresh for 11a bss */ + int8_t rssi11b; /* for 11g sta in 11b bss */ + int8_t rssi11bOnly; /* for 11b sta */ + u_int8_t pad1; + u_int8_t rate11a; /* rate thresh for 11a bss */ + u_int8_t rate11b; /* for 11g sta in 11b bss */ + u_int8_t rate11bOnly; /* for 11b sta */ + u_int8_t pad2; +}; #endif /* _NET80211__IEEE80211_H_ */ ==== //depot/projects/wifi/sys/net80211/ieee80211.c#24 (text+ko) ==== @@ -129,8 +129,6 @@ bpfattach2(ifp, DLT_IEEE802_11, sizeof(struct ieee80211_frame_addr4), &ic->ic_rawbpf); - ieee80211_crypto_attach(ic); - /* * Fill in 802.11 available channel set, mark * all available channels as active, and pick @@ -187,12 +185,16 @@ ic->ic_lintval = IEEE80211_BINTVAL_DEFAULT; ic->ic_bmisstimeout = 7*ic->ic_lintval; /* default 7 beacons */ ic->ic_dtim_period = IEEE80211_DTIM_DEFAULT; + IEEE80211_LOCK_INIT(ic, "ieee80211com"); IEEE80211_BEACON_LOCK_INIT(ic, "beacon"); ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX; + ieee80211_crypto_attach(ic); ieee80211_node_attach(ic); + ieee80211_power_attach(ic); ieee80211_proto_attach(ic); + ieee80211_scan_attach(ic); ieee80211_add_vap(ic); @@ -214,11 +216,14 @@ ieee80211_remove_vap(ic); ieee80211_sysctl_detach(ic); + ieee80211_scan_detach(ic); ieee80211_proto_detach(ic); ieee80211_crypto_detach(ic); + ieee80211_power_detach(ic); ieee80211_node_detach(ic); ifmedia_removeall(&ic->ic_media); + IEEE80211_LOCK_DESTROY(ic); IEEE80211_BEACON_LOCK_DESTROY(ic); bpfdetach(ifp); @@ -339,6 +344,7 @@ * (i.e. driver) work such as overriding methods. */ ieee80211_node_lateattach(ic); + ieee80211_power_lateattach(ic); /* * Fill in media characteristics. @@ -483,19 +489,6 @@ } } -static int -findrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate) -{ -#define IEEERATE(_ic,_m,_i) \ - ((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL) - int i, nrates = ic->ic_sup_rates[mode].rs_nrates; - for (i = 0; i < nrates; i++) - if (IEEERATE(ic, mode, i) == rate) - return i; - return -1; -#undef IEEERATE -} - /* * Find an instance by it's mac address. */ @@ -524,7 +517,51 @@ return NULL; } +static int +findrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate) +{ +#define IEEERATE(_ic,_m,_i) \ + ((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL) + int i, nrates = ic->ic_sup_rates[mode].rs_nrates; + for (i = 0; i < nrates; i++) + if (IEEERATE(ic, mode, i) == rate) + return i; + return -1; +#undef IEEERATE +} + /* + * Convert a media specification to a rate index and possibly a mode + * (if the rate is fixed and the mode is specified as ``auto'' then + * we need to lock down the mode so the index is meanginful). + */ +static int +checkrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate) +{ + + /* + * Check the rate table for the specified/current phy. + */ + if (mode == IEEE80211_MODE_AUTO) { + int i; + /* + * In autoselect mode search for the rate. + */ + for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_MAX; i++) { + if ((ic->ic_modecaps & (1<ic_fixed_rate; if (IFM_SUBTYPE(ime->ifm_media) != IFM_AUTO) { /* * Convert media subtype to rate. */ newrate = ieee80211_media2rate(ime->ifm_media); - if (newrate == 0) + if (newrate == 0 || !checkrate(ic, newphymode, newrate)) return EINVAL; - /* - * Check the rate table for the specified/current phy. - */ - if (newphymode == IEEE80211_MODE_AUTO) { - /* - * In autoselect mode search for the rate. - */ - for (j = IEEE80211_MODE_11A; - j < IEEE80211_MODE_MAX; j++) { - if ((ic->ic_modecaps & (1<ic_curmode != newphymode) { /* change phy mode */ - error = ieee80211_setmode(ic, newphymode); - if (error != 0) - return error; + if (ic->ic_des_mode != newphymode) { /* change phy mode */ + ic->ic_des_mode = newphymode; error = ENETRESET; } @@ -787,26 +798,12 @@ void ieee80211_watchdog(struct ieee80211com *ic) { - struct ieee80211_node_table *nt; - int need_inact_timer = 0; if (ic->ic_state != IEEE80211_S_INIT) { if (ic->ic_mgt_timer && --ic->ic_mgt_timer == 0) ieee80211_new_state(ic, IEEE80211_S_SCAN, 0); - nt = &ic->ic_scan; - if (nt->nt_inact_timer) { - if (--nt->nt_inact_timer == 0) - nt->nt_timeout(nt); - need_inact_timer += nt->nt_inact_timer; - } - nt = &ic->ic_sta; - if (nt->nt_inact_timer) { - if (--nt->nt_inact_timer == 0) - nt->nt_timeout(nt); - need_inact_timer += nt->nt_inact_timer; - } } - if (ic->ic_mgt_timer != 0 || need_inact_timer) + if (ic->ic_mgt_timer != 0) ic->ic_ifp->if_timer = 1; } ==== //depot/projects/wifi/sys/net80211/ieee80211_freebsd.h#17 (text+ko) ==== @@ -30,6 +30,18 @@ #define _NET80211_IEEE80211_FREEBSD_H_ /* + * Common state locking definitions. + */ +typedef struct mtx ieee80211_com_lock_t; +#define IEEE80211_LOCK_INIT(_ic, _name) \ + mtx_init(&(_ic)->ic_comlock, _name, "802.11 com lock", MTX_DEF) +#define IEEE80211_LOCK_DESTROY(_ic) mtx_destroy(&(_ic)->ic_comlock) +#define IEEE80211_LOCK(_ic) mtx_lock(&(_ic)->ic_comlock) +#define IEEE80211_UNLOCK(_ic) mtx_unlock(&(_ic)->ic_comlock) +#define IEEE80211_LOCK_ASSERT(_ic) \ + mtx_assert(&(_ic)->ic_comlock, MA_OWNED) + +/* * Beacon locking definitions. */ typedef struct mtx ieee80211_beacon_lock_t; @@ -58,7 +70,7 @@ */ typedef struct mtx ieee80211_scan_lock_t; #define IEEE80211_SCAN_LOCK_INIT(_nt, _name) \ - mtx_init(&(_nt)->nt_scanlock, _name, "802.11 scangen", MTX_DEF) + mtx_init(&(_nt)->nt_scanlock, _name, "802.11 node scangen", MTX_DEF) #define IEEE80211_SCAN_LOCK_DESTROY(_nt) mtx_destroy(&(_nt)->nt_scanlock) #define IEEE80211_SCAN_LOCK(_nt) mtx_lock(&(_nt)->nt_scanlock) #define IEEE80211_SCAN_UNLOCK(_nt) mtx_unlock(&(_nt)->nt_scanlock) @@ -145,6 +157,12 @@ int ieee80211_node_dectestref(struct ieee80211_node *ni); #define ieee80211_node_refcnt(_ni) (_ni)->ni_refcnt +#define msecs_to_ticks(ms) ((ms)*1000/hz) +#define time_after(a,b) ((long)(b) - (long)(a) < 0) +#define time_before(a,b) time_after(b,a) +#define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0) +#define time_before_eq(a,b) time_after_eq(b,a) + struct mbuf *ieee80211_getmgtframe(u_int8_t **frm, u_int pktlen); #define M_LINK0 M_PROTO1 /* WEP requested */ #define M_PWR_SAV M_PROTO4 /* bypass PS handling */ ==== //depot/projects/wifi/sys/net80211/ieee80211_input.c#53 (text+ko) ==== @@ -116,7 +116,6 @@ struct ieee80211_node *, struct mbuf *); static struct mbuf *ieee80211_decap_fastframe(struct ieee80211com *, struct ieee80211_node *, struct mbuf *); -static void ieee80211_node_pwrsave(struct ieee80211_node *, int enable); static void ieee80211_recv_pspoll(struct ieee80211com *, struct ieee80211_node *, struct mbuf *); @@ -938,10 +937,11 @@ /* * Install received rate set information in the node's state block. */ -static int -ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni, - u_int8_t *rates, u_int8_t *xrates, int flags) +int +ieee80211_setup_rates(struct ieee80211_node *ni, + const u_int8_t *rates, const u_int8_t *xrates, int flags) { + struct ieee80211com *ic = ni->ni_ic; struct ieee80211_rateset *rs = &ni->ni_rates; memset(rs, 0, sizeof(*rs)); @@ -964,7 +964,7 @@ memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates); rs->rs_nrates += nxrates; } - return ieee80211_fix_rate(ic, ni, flags); + return ieee80211_fix_rate(ni, flags); } static void @@ -1027,7 +1027,7 @@ * authorized at this point so traffic can flow. */ if (ni->ni_authmode != IEEE80211_AUTH_8021X) - ieee80211_node_authorize(ic, ni); + ieee80211_node_authorize(ni); break; case IEEE80211_M_STA: @@ -1251,7 +1251,7 @@ IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, "[%s] station authenticated (shared key)\n", ether_sprintf(ni->ni_macaddr)); - ieee80211_node_authorize(ic, ni); + ieee80211_node_authorize(ni); break; default: IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, @@ -1832,7 +1832,7 @@ return 0; /* NB: no change */ } -static void +void ieee80211_saveie(u_int8_t **iep, const u_int8_t *ie) { u_int ielen = ie[1]+2; @@ -1849,37 +1849,33 @@ /* XXX note failure */ } -#ifdef IEEE80211_DEBUG -static void -dump_probe_beacon(u_int8_t subtype, int isnew, - const u_int8_t mac[IEEE80211_ADDR_LEN], - u_int8_t chan, u_int8_t bchan, u_int16_t capinfo, u_int16_t bintval, - u_int8_t erp, u_int8_t *ssid, u_int8_t *country) +void +ieee80211_saveath(struct ieee80211_node *ni, u_int8_t *ie) { - printf("[%s] %s%s on chan %u (bss chan %u) ", - ether_sprintf(mac), isnew ? "new " : "", - ieee80211_mgt_subtype_name[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT], - chan, bchan); - ieee80211_print_essid(ssid + 2, ssid[1]); - printf("\n"); +#if 0 + const struct ieee80211_ath_ie *ath = + (const struct ieee80211_ath_ie *) ie; - if (isnew) { - printf("[%s] caps 0x%x bintval %u erp 0x%x", - ether_sprintf(mac), capinfo, bintval, erp); - if (country) { -#ifdef __FreeBSD__ - printf(" country info %*D", country[1], country+2, " "); -#else - int i; - printf(" country info"); - for (i = 0; i < country[1]; i++) - printf(" %02x", country[i+2]); + ni->ni_ath_flags = ath->ath_capability; #endif - } - printf("\n"); - } + ieee80211_saveie(&ni->ni_ath_ie, ie); +} + +static __inline int +contbgscan(struct ieee80211com *ic) +{ + return ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) && + time_after(ticks, ic->ic_lastdata + ic->ic_bgscanidle)); +} + +static __inline int +startbgscan(struct ieee80211com *ic) +{ + return ((ic->ic_flags & IEEE80211_F_BGSCAN) && + !IEEE80211_IS_CHAN_DTURBO(ic->ic_curchan) && + time_after(ticks, ic->ic_lastscan + ic->ic_bgscanintvl) && + time_after(ticks, ic->ic_lastdata + ic->ic_bgscanidle)); } -#endif /* IEEE80211_DEBUG */ void ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, @@ -1900,10 +1896,7 @@ switch (subtype) { case IEEE80211_FC0_SUBTYPE_PROBE_RESP: case IEEE80211_FC0_SUBTYPE_BEACON: { - u_int8_t *tstamp, *country, *tim; - u_int8_t chan, bchan, fhindex, erp; - u_int16_t capinfo, bintval, timoff; - u_int16_t fhdwell; + struct ieee80211_scanparams scan; /* * We process beacon/probe response frames: @@ -1935,32 +1928,29 @@ * [tlv] Atheros capabilities */ IEEE80211_VERIFY_LENGTH(efrm - frm, 12); - tstamp = frm; frm += 8; - bintval = le16toh(*(u_int16_t *)frm); frm += 2; - capinfo = le16toh(*(u_int16_t *)frm); frm += 2; - ssid = rates = xrates = country = wpa = wme = tim = ath = NULL; - bchan = ieee80211_chan2ieee(ic, ic->ic_curchan); - chan = bchan; - fhdwell = 0; - fhindex = 0; - erp = 0; - timoff = 0; + memset(&scan, 0, sizeof(scan)); + scan.tstamp = frm; frm += 8; + scan.bintval = le16toh(*(u_int16_t *)frm); frm += 2; + scan.capinfo = le16toh(*(u_int16_t *)frm); frm += 2; + scan.bchan = ieee80211_chan2ieee(ic, ic->ic_curchan); + scan.chan = scan.bchan; + while (frm < efrm) { switch (*frm) { case IEEE80211_ELEMID_SSID: - ssid = frm; + scan.ssid = frm; break; case IEEE80211_ELEMID_RATES: - rates = frm; + scan.rates = frm; break; case IEEE80211_ELEMID_COUNTRY: - country = frm; + scan.country = frm; break; case IEEE80211_ELEMID_FHPARMS: if (ic->ic_phytype == IEEE80211_T_FH) { - fhdwell = LE_READ_2(&frm[2]); - chan = IEEE80211_FH_CHAN(frm[4], frm[5]); - fhindex = frm[6]; + scan.fhdwell = LE_READ_2(&frm[2]); + scan.chan = IEEE80211_FH_CHAN(frm[4], frm[5]); + scan.fhindex = frm[6]; } break; case IEEE80211_ELEMID_DSPARMS: @@ -1969,17 +1959,17 @@ * is problematic for multi-mode devices. */ if (ic->ic_phytype != IEEE80211_T_FH) - chan = frm[2]; + scan.chan = frm[2]; break; case IEEE80211_ELEMID_TIM: /* XXX ATIM? */ - tim = frm; - timoff = frm - mtod(m0, u_int8_t *); + scan.tim = frm; + scan.timoff = frm - mtod(m0, u_int8_t *); break; case IEEE80211_ELEMID_IBSSPARMS: break; case IEEE80211_ELEMID_XRATES: - xrates = frm; + scan.xrates = frm; break; case IEEE80211_ELEMID_ERP: if (frm[1] != 1) { @@ -1989,18 +1979,18 @@ ic->ic_stats.is_rx_elem_toobig++; break; } - erp = frm[2]; + scan.erp = frm[2]; break; case IEEE80211_ELEMID_RSN: - wpa = frm; + scan.wpa = frm; break; case IEEE80211_ELEMID_VENDOR: if (iswpaoui(frm)) - wpa = frm; + scan.wpa = frm; else if (iswmeparam(frm) || iswmeinfo(frm)) - wme = frm; + scan.wme = frm; else if (isatherosoui(frm)) - ath = frm; + scan.ath = frm; break; default: IEEE80211_DISCARD_IE(ic, IEEE80211_MSG_ELEMID, @@ -2011,10 +2001,10 @@ } frm += frm[1] + 2; } - IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); - IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); + IEEE80211_VERIFY_ELEMENT(scan.rates, IEEE80211_RATE_MAXSIZE); + IEEE80211_VERIFY_ELEMENT(scan.ssid, IEEE80211_NWID_LEN); #if IEEE80211_CHAN_MAX < 255 - if (chan > IEEE80211_CHAN_MAX) { + if (scan.chan > IEEE80211_CHAN_MAX) { IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, wh, ieee80211_mgt_subtype_name[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT], @@ -2023,7 +2013,8 @@ return; } #endif - if (chan != bchan && ic->ic_phytype != IEEE80211_T_FH) { + if (scan.chan != scan.bchan && + ic->ic_phytype != IEEE80211_T_FH) { /* * Frame was received on a channel different from the * one indicated in the DS params element id; @@ -2037,7 +2028,7 @@ IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, wh, ieee80211_mgt_subtype_name[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT], - "for off-channel %u", chan); + "for off-channel %u", scan.chan); ic->ic_stats.is_rx_chanmismatch++; return; } @@ -2061,27 +2052,27 @@ ((ic->ic_flags & IEEE80211_F_SCAN) == 0 || IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid))) { /* record tsf of last beacon */ - memcpy(ni->ni_tstamp.data, tstamp, + memcpy(ni->ni_tstamp.data, scan.tstamp, sizeof(ni->ni_tstamp)); - if (ni->ni_erp != erp) { + if (ni->ni_erp != scan.erp) { IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, "[%s] erp change: was 0x%x, now 0x%x\n", ether_sprintf(wh->i_addr2), - ni->ni_erp, erp); + ni->ni_erp, scan.erp); if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) && (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION)) ic->ic_flags |= IEEE80211_F_USEPROT; else ic->ic_flags &= ~IEEE80211_F_USEPROT; - ni->ni_erp = erp; + ni->ni_erp = scan.erp; /* XXX statistic */ } - if ((ni->ni_capinfo ^ capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) { + if ((ni->ni_capinfo ^ scan.capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) { IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, "[%s] capabilities change: before 0x%x," " now 0x%x\n", ether_sprintf(wh->i_addr2), - ni->ni_capinfo, capinfo); + ni->ni_capinfo, scan.capinfo); /* * NB: we assume short preamble doesn't * change dynamically @@ -2089,111 +2080,78 @@ ieee80211_set_shortslottime(ic, IEEE80211_IS_CHAN_A(ic->ic_bsschan) || (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)); - ni->ni_capinfo = capinfo; + ni->ni_capinfo = scan.capinfo; /* XXX statistic */ } - if (wme != NULL && + if (scan.wme != NULL && (ni->ni_flags & IEEE80211_NODE_QOS) && - ieee80211_parse_wmeparams(ic, wme, wh) > 0) + ieee80211_parse_wmeparams(ic, scan.wme, wh) > 0) ieee80211_wme_updateparams(ic); - if (tim != NULL) { - struct ieee80211_tim_ie *ie = - (struct ieee80211_tim_ie *) tim; - - ni->ni_dtim_count = ie->tim_count; - ni->ni_dtim_period = ie->tim_period; + if (scan.ath != NULL) + ieee80211_parse_athparams(ni, scan.ath, wh); + if (scan.tim != NULL) { + struct ieee80211_tim_ie *tim = + (struct ieee80211_tim_ie *) scan.tim; +#if 0 + int aid = IEEE80211_AID(ni->ni_associd); + int ix = aid / NBBY; + int min = tim->tim_bitctl &~ 1; + int max = tim->tim_len + min - 4; + if ((tim->tim_bitctl&1) || + (min <= ix && ix <= max && + isset(tim->tim_bitmap - min, aid))) + ieee80211_sta_pwrsave(ic, 0); +#endif + ni->ni_dtim_count = tim->tim_count; + ni->ni_dtim_period = tim->tim_period; } - if (ath != NULL) - ieee80211_parse_athparams(ni, ath, wh); - /* NB: don't need the rest of this */ - if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) - return; - } - - if (ni == ic->ic_bss && - !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) { -#ifdef IEEE80211_DEBUG - if (ieee80211_msg_scan(ic)) - dump_probe_beacon(subtype, 1, - wh->i_addr2, chan, bchan, capinfo, - bintval, erp, ssid, country); -#endif /* - * Create a new entry. If scanning the entry goes - * in the scan cache. Otherwise, be particular when - * operating in adhoc mode--only take nodes marked - * as ibss participants so we don't populate our - * neighbor table with unintersting sta's. + * If scanning, pass the info to the scan module. + * Otherwise, check if it's the right time to do + * a background scan. Background scanning must + * be enabled and we must not be operating in the + * turbo phase of dynamic turbo mode. Then, + * it's been a while since the last background + * scan and if no data frames have come through + * recently, kick off a scan. Note that this + * is the mechanism by which a background scan + * is started _and_ continued each time we + * return on-channel to receive a beacon from + * our ap. */ - if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { - if ((capinfo & IEEE80211_CAPINFO_IBSS) == 0) - return; - ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta, - wh->i_addr2); - } else - ni = ieee80211_dup_bss(&ic->ic_scan, wh->i_addr2); - if (ni == NULL) - return; - ni->ni_esslen = ssid[1]; - memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); - memcpy(ni->ni_essid, ssid + 2, ssid[1]); - } else if (ssid[1] != 0 && - (ISPROBE(subtype) || ni->ni_esslen == 0)) { - /* - * Update ESSID at probe response to adopt - * hidden AP by Lucent/Cisco, which announces - * null ESSID in beacon. - */ -#ifdef IEEE80211_DEBUG - if (ieee80211_msg_scan(ic) || - ieee80211_msg_debug(ic)) - dump_probe_beacon(subtype, 0, - wh->i_addr2, chan, bchan, capinfo, - bintval, erp, ssid, country); -#endif - ni->ni_esslen = ssid[1]; - memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); - memcpy(ni->ni_essid, ssid + 2, ssid[1]); - } - ni->ni_scangen = ic->ic_scan.nt_scangen; - IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); - ni->ni_rssi = rssi; - ni->ni_rstamp = rstamp; - memcpy(ni->ni_tstamp.data, tstamp, sizeof(ni->ni_tstamp)); - ni->ni_intval = bintval; - ni->ni_capinfo = capinfo; - ni->ni_chan = ic->ic_curchan; - ni->ni_fhdwell = fhdwell; - ni->ni_fhindex = fhindex; - ni->ni_erp = erp; - if (tim != NULL) { - struct ieee80211_tim_ie *ie = - (struct ieee80211_tim_ie *) tim; - - ni->ni_dtim_count = ie->tim_count; - ni->ni_dtim_period = ie->tim_period; + if (ic->ic_flags & IEEE80211_F_SCAN) + ieee80211_add_scan(ic, &scan, wh, + subtype, rssi, rstamp); + else if (contbgscan(ic) || startbgscan(ic)) + ieee80211_bg_scan(ic); + return; } /* - * Record the byte offset from the mac header to - * the start of the TIM information element for - * use by hardware and/or to speedup software - * processing of beacon frames. + * If scanning, just pass information to the scan module. */ - ni->ni_timoff = timoff; - /* - * Record optional information elements that might be - * used by applications or drivers. - */ - if (wme != NULL) - ieee80211_saveie(&ni->ni_wme_ie, wme); - if (wpa != NULL) - ieee80211_saveie(&ni->ni_wpa_ie, wpa); - if (ath != NULL) { - ieee80211_saveie(&ni->ni_ath_ie, ath); - (void) ieee80211_parse_athparams(ni, ath, wh); + if (ic->ic_flags & IEEE80211_F_SCAN) { + ieee80211_add_scan(ic, &scan, wh, + subtype, rssi, rstamp); + return; + } + if (scan.capinfo & IEEE80211_CAPINFO_IBSS) { + if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { + /* + * Create a new entry in the neighbor table. + */ + ni = ieee80211_add_neighbor(ic, wh, &scan); + } else { + /* + * Record tsf for potential resync. + */ + memcpy(ni->ni_tstamp.data, scan.tstamp, + sizeof(ni->ni_tstamp)); + } + if (ni != NULL) { + ni->ni_rssi = rssi; + ni->ni_rstamp = rstamp; + } } - /* NB: must be after ni_chan is setup */ - ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT); break; } @@ -2272,7 +2230,7 @@ ieee80211_saveie(&ni->ni_ath_ie, ath); (void) ieee80211_parse_athparams(ni, ath, wh); } - rate = ieee80211_setup_rates(ic, ni, rates, xrates, + rate = ieee80211_setup_rates(ni, rates, xrates, IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); if (rate & IEEE80211_RATE_BASIC) { @@ -2496,7 +2454,7 @@ ic->ic_stats.is_rx_assoc_capmismatch++; return; } - rate = ieee80211_setup_rates(ic, ni, rates, xrates, + rate = ieee80211_setup_rates(ni, rates, xrates, IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); /* @@ -2634,7 +2592,7 @@ } IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); - rate = ieee80211_setup_rates(ic, ni, rates, xrates, + rate = ieee80211_setup_rates(ni, rates, xrates, IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); if (rate & IEEE80211_RATE_BASIC) { @@ -2782,66 +2740,6 @@ #undef IEEE80211_VERIFY_ELEMENT /* - * Handle station power-save state change. - */ -static void -ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable) -{ - struct ieee80211com *ic = ni->ni_ic; - struct mbuf *m; - - if (enable) { - if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) - ic->ic_ps_sta++; - ni->ni_flags |= IEEE80211_NODE_PWR_MGT; - IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, - "[%s] power save mode on, %u sta's in ps mode\n", - ether_sprintf(ni->ni_macaddr), ic->ic_ps_sta); - return; - } - - if (ni->ni_flags & IEEE80211_NODE_PWR_MGT) - ic->ic_ps_sta--; - ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT; - IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, - "[%s] power save mode off, %u sta's in ps mode\n", - ether_sprintf(ni->ni_macaddr), ic->ic_ps_sta); - /* XXX if no stations in ps mode, flush mc frames */ - - /* - * Flush queued unicast frames. - */ - if (IEEE80211_NODE_SAVEQ_QLEN(ni) == 0) { - if (ic->ic_set_tim != NULL) - ic->ic_set_tim(ic, ni, 0); /* just in case */ - return; - } - IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, - "[%s] flush ps queue, %u packets queued\n", - ether_sprintf(ni->ni_macaddr), IEEE80211_NODE_SAVEQ_QLEN(ni)); - for (;;) { - int qlen; - - IEEE80211_NODE_SAVEQ_DEQUEUE(ni, m, qlen); - if (m == NULL) - break; - /* - * If this is the last packet, turn off the TIM bit. - * If there are more packets, set the more packets bit - * in the mbuf so ieee80211_encap will mark the 802.11 - * head to indicate more data frames will follow. - */ - if (qlen != 0) - m->m_flags |= M_MORE_DATA; - /* XXX need different driver interface */ - /* XXX bypasses q max */ - IF_ENQUEUE(&ic->ic_ifp->if_snd, m); - } - if (ic->ic_set_tim != NULL) - ic->ic_set_tim(ic, ni, 0); -} - -/* * Process a received ps-poll frame. */ static void @@ -2882,10 +2780,10 @@ IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, "[%s] recv ps-poll, but queue empty\n", ether_sprintf(wh->i_addr2)); - ieee80211_send_nulldata(ic, ni); + ieee80211_send_nulldata(ni); ic->ic_stats.is_ps_qempty++; /* XXX node stat */ if (ic->ic_set_tim != NULL) - ic->ic_set_tim(ic, ni, 0); /* just in case */ + ic->ic_set_tim(ni, 0); /* just in case */ return; } /* @@ -2903,7 +2801,7 @@ "[%s] recv ps-poll, send packet, queue empty\n", ether_sprintf(ni->ni_macaddr)); if (ic->ic_set_tim != NULL) - ic->ic_set_tim(ic, ni, 0); + ic->ic_set_tim(ni, 0); } m->m_flags |= M_PWR_SAV; /* bypass PS handling */ IF_ENQUEUE(&ic->ic_ifp->if_snd, m); @@ -2929,6 +2827,48 @@ return wh->i_addr3; } +void +ieee80211_note(struct ieee80211com *ic, const char *fmt, ...) +{ + char buf[128]; /* XXX */ + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + if_printf(ic->ic_ifp, "%s", buf); /* NB: no \n */ +} + +void +ieee80211_note_frame(struct ieee80211com *ic, + const struct ieee80211_frame *wh, + const char *fmt, ...) +{ + char buf[128]; /* XXX */ + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + if_printf(ic->ic_ifp, "[%s] %s\n", + ether_sprintf(ieee80211_getbssid(ic, wh)), buf); +} + +void +ieee80211_note_mac(struct ieee80211com *ic, + const u_int8_t mac[IEEE80211_ADDR_LEN], + const char *fmt, ...) +{ + char buf[128]; /* XXX */ + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + if_printf(ic->ic_ifp, "[%s] %s\n", ether_sprintf(mac), buf); +} + static void ieee80211_discard_frame(struct ieee80211com *ic, const struct ieee80211_frame *wh, @@ -2936,7 +2876,8 @@ { va_list ap; - printf("[%s] discard ", ether_sprintf(ieee80211_getbssid(ic, wh))); + printf("[%s:%s] discard ", ic->ic_ifp->if_xname, + ether_sprintf(ieee80211_getbssid(ic, wh))); if (type != NULL) printf(" %s frame, ", type); else @@ -2954,7 +2895,8 @@ { va_list ap; - printf("[%s] discard ", ether_sprintf(ieee80211_getbssid(ic, wh))); + printf("[%s:%s] discard ", ic->ic_ifp->if_xname, + ether_sprintf(ieee80211_getbssid(ic, wh))); if (type != NULL) printf(" %s information element, ", type); else @@ -2972,7 +2914,7 @@ { va_list ap; - printf("[%s] discard ", ether_sprintf(mac)); + printf("[%s:%s] discard ", ic->ic_ifp->if_xname, ether_sprintf(mac)); if (type != NULL) printf(" %s frame, ", type); else ==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#40 (text+ko) ==== @@ -65,8 +65,6 @@ #include #include -#include - #define IS_UP(_ic) \ (((_ic)->ic_ifp->if_flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP)) #define IS_UP_AUTO(_ic) \ @@ -76,370 +74,6 @@ int ieee, int mode); /* - * XXX - * Wireless LAN specific configuration interface, which is compatible - * with wicontrol(8). - */ - -struct wi_read_ap_args { - int i; /* result count */ - struct wi_apinfo *ap; /* current entry in result buffer */ - caddr_t max; /* result buffer bound */ -}; - -static void -wi_read_ap_result(void *arg, struct ieee80211_node *ni) -{ >>> TRUNCATED FOR MAIL (1000 lines) <<<