PERFORCE change 80453 for review
Sam Leffler
sam at FreeBSD.org
Mon Jul 18 16:56:39 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=80453
Change 80453 by sam at 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<<i)) &&
+ findrate(ic, i, rate) != -1)
+ return 1;
+ }
+ return 0;
+ } else {
+ /*
+ * Mode is fixed, check for rate.
+ */
+ return (findrate(ic, mode, rate) != -1);
+ }
+}
+
+/*
* Handle a media change request.
*/
int
@@ -534,7 +571,7 @@
struct ifmedia_entry *ime;
enum ieee80211_opmode newopmode;
enum ieee80211_phymode newphymode;
- int i, j, newrate, error = 0;
+ int j, newrate, error = 0;
ic = ieee80211_find_instance(ifp);
if (!ic) {
@@ -579,40 +616,16 @@
/*
* Next, the fixed/variable rate.
*/
- i = -1;
newrate = ic->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<<j)) == 0)
- continue;
- i = findrate(ic, j, newrate);
- if (i != -1) {
- /* lock mode too */
- newphymode = j;
- break;
- }
- }
- } else {
- i = findrate(ic, newphymode, newrate);
- }
- if (i == -1) /* mode/rate mismatch */
- return EINVAL;
- }
- /* NB: defer rate setting to later */
+ } else
+ newrate = IEEE80211_FIXED_RATE_NONE;
/*
* Deduce new operating mode but don't install it just yet.
@@ -647,10 +660,8 @@
/*
* Handle phy mode change.
*/
- if (ic->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 <net80211/ieee80211_var.h>
#include <net80211/ieee80211_ioctl.h>
-#include <dev/wi/if_wavelan_ieee.h>
-
#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) <<<
More information about the p4-projects
mailing list