PERFORCE change 113229 for review
Sam Leffler
sam at FreeBSD.org
Sun Jan 21 00:01:10 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=113229
Change 113229 by sam at sam_ebb on 2007/01/21 00:01:05
IFC @ 113228
Affected files ...
.. //depot/projects/wifi/sys/net80211/_ieee80211.h#13 integrate
.. //depot/projects/wifi/sys/net80211/ieee80211.c#37 integrate
.. //depot/projects/wifi/sys/net80211/ieee80211_freebsd.c#23 integrate
.. //depot/projects/wifi/sys/net80211/ieee80211_freebsd.h#21 integrate
.. //depot/projects/wifi/sys/net80211/ieee80211_input.c#78 integrate
.. //depot/projects/wifi/sys/net80211/ieee80211_node.c#76 integrate
.. //depot/projects/wifi/sys/net80211/ieee80211_proto.c#46 integrate
.. //depot/projects/wifi/sys/net80211/ieee80211_proto.h#28 integrate
.. //depot/projects/wifi/sys/net80211/ieee80211_var.h#44 integrate
Differences ...
==== //depot/projects/wifi/sys/net80211/_ieee80211.h#13 (text+ko) ====
@@ -29,7 +29,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: src/sys/net80211/_ieee80211.h,v 1.5 2006/12/27 18:46:18 sam Exp $
+ * $FreeBSD: src/sys/net80211/_ieee80211.h,v 1.6 2007/01/15 01:12:28 sam Exp $
*/
#ifndef _NET80211__IEEE80211_H_
#define _NET80211__IEEE80211_H_
@@ -129,6 +129,7 @@
#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */
#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */
+#define IEEE80211_CHAN_GSM 0x1000 /* 900 MHz spectrum channel */
#define IEEE80211_CHAN_STURBO 0x2000 /* 11a static turbo channel only */
#define IEEE80211_CHAN_HALF 0x4000 /* Half rate channel */
#define IEEE80211_CHAN_QUARTER 0x8000 /* Quarter rate channel */
@@ -199,6 +200,10 @@
(((_c)->ic_flags & IEEE80211_CHAN_HALF) != 0)
#define IEEE80211_IS_CHAN_QUARTER(_c) \
(((_c)->ic_flags & IEEE80211_CHAN_QUARTER) != 0)
+#define IEEE80211_IS_CHAN_FULL(_c) \
+ (((_c)->ic_flags & (IEEE80211_CHAN_QUARTER | IEEE80211_CHAN_HALF)) == 0)
+#define IEEE80211_IS_CHAN_GSM(_c) \
+ (((_c)->ic_flags & IEEE80211_CHAN_GSM) != 0)
/* ni_chan encoding for FH phy */
#define IEEE80211_FH_CHANMOD 80
==== //depot/projects/wifi/sys/net80211/ieee80211.c#37 (text+ko) ====
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/net80211/ieee80211.c,v 1.33 2006/12/28 01:31:26 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/net80211/ieee80211.c,v 1.35 2007/01/15 01:12:28 sam Exp $");
/*
* IEEE 802.11 generic handler
@@ -274,6 +274,7 @@
ieee80211_sysctl_detach(ic);
ieee80211_scan_detach(ic);
+ /* NB: must be called before ieee80211_node_detach */
ieee80211_proto_detach(ic);
ieee80211_crypto_detach(ic);
ieee80211_power_detach(ic);
@@ -287,12 +288,34 @@
ether_ifdetach(ifp);
}
+static __inline int
+mapgsm(u_int freq, u_int flags)
+{
+ freq *= 10;
+ if (flags & IEEE80211_CHAN_QUARTER)
+ freq += 5;
+ else if (flags & IEEE80211_CHAN_HALF)
+ freq += 10;
+ else
+ freq += 20;
+ /* NB: there is no 907/20 wide but leave room */
+ return (freq - 906*10) / 5;
+}
+
+static __inline int
+mappsb(u_int freq, u_int flags)
+{
+ return 37 + ((freq * 10) + ((freq % 5) == 2 ? 5 : 0) - 49400) / 5;
+}
+
/*
* Convert MHz frequency to IEEE channel number.
*/
int
ieee80211_mhz2ieee(u_int freq, u_int flags)
{
+ if (flags & IEEE80211_CHAN_GSM)
+ return mapgsm(freq, flags);
if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */
if (freq == 2484)
return 14;
@@ -303,20 +326,21 @@
} else if (flags & IEEE80211_CHAN_5GHZ) { /* 5Ghz band */
if (freq <= 5000) {
if (flags &(IEEE80211_CHAN_HALF|IEEE80211_CHAN_QUARTER))
- return 37 + ((freq * 10) +
- ((freq % 5) == 2 ? 5 : 0) - 49400) / 5;
+ return mappsb(freq, flags);
return (freq - 4000) / 5;
} else
return (freq - 5000) / 5;
} else { /* either, guess */
if (freq == 2484)
return 14;
- if (freq < 2484)
+ if (freq < 2484) {
+ if (907 <= freq && freq <= 922)
+ return mapgsm(freq, flags);
return ((int) freq - 2407) / 5;
+ }
if (freq < 5000) {
if (flags &(IEEE80211_CHAN_HALF|IEEE80211_CHAN_QUARTER))
- return 37 + ((freq * 10) +
- ((freq % 5) == 2 ? 5 : 0) - 49400) / 5;
+ return mappsb(freq, flags);
else if (freq > 4900)
return (freq - 4000) / 5;
else
@@ -345,6 +369,8 @@
u_int
ieee80211_ieee2mhz(u_int chan, u_int flags)
{
+ if (flags & IEEE80211_CHAN_GSM)
+ return 907 + 5 * (chan / 10);
if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */
if (chan == 14)
return 2484;
@@ -359,13 +385,13 @@
}
return 5000 + (chan*5);
} else { /* either, guess */
+ /* XXX can't distinguish PSB+GSM channels */
if (chan == 14)
return 2484;
if (chan < 14) /* 0-13 */
return 2407 + chan*5;
if (chan < 27) /* 15-26 */
return 2512 + ((chan-15)*20);
- /* XXX can't distinguish PSB channels */
return 5000 + (chan*5);
}
}
@@ -523,12 +549,10 @@
{
enum ieee80211_phymode mode = ieee80211_chan2mode(c);
- if (mode == IEEE80211_MODE_11A) {
- if (IEEE80211_IS_CHAN_HALF(c))
- return &ieee80211_rateset_half;
- if (IEEE80211_IS_CHAN_QUARTER(c))
- return &ieee80211_rateset_quarter;
- }
+ if (IEEE80211_IS_CHAN_HALF(c))
+ return &ieee80211_rateset_half;
+ if (IEEE80211_IS_CHAN_QUARTER(c))
+ return &ieee80211_rateset_quarter;
return &ic->ic_sup_rates[mode];
}
@@ -910,21 +934,13 @@
ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode)
{
/*
- * Do mode-specific rate setup.
+ * Adjust basic rates in 11b/11g supported rate set.
+ * Note that if operating on a hal/quarter rate channel
+ * this is a noop as those rates sets are different
+ * and used instead.
*/
- if (mode == IEEE80211_MODE_11G) {
- /*
- * Use a mixed 11b/11g rate set.
- */
- ieee80211_set11gbasicrates(&ic->ic_sup_rates[mode],
- IEEE80211_MODE_11G);
- } else if (mode == IEEE80211_MODE_11B) {
- /*
- * Force pure 11b rate set.
- */
- ieee80211_set11gbasicrates(&ic->ic_sup_rates[mode],
- IEEE80211_MODE_11B);
- }
+ if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11B)
+ ieee80211_set11gbasicrates(&ic->ic_sup_rates[mode], mode);
ic->ic_curmode = mode;
ieee80211_reset_erp(ic); /* reset ERP state */
==== //depot/projects/wifi/sys/net80211/ieee80211_freebsd.c#23 (text+ko) ====
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_freebsd.c,v 1.12 2006/06/24 18:00:17 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_freebsd.c,v 1.13 2007/01/08 18:23:43 sam Exp $");
/*
* IEEE 802.11 support (FreeBSD-specific code)
@@ -150,6 +150,26 @@
return atomic_cmpset_int(&ni->ni_refcnt, 0, 1);
}
+void
+ieee80211_drain_ifq(struct ifqueue *ifq)
+{
+ struct ieee80211_node *ni;
+ struct mbuf *m;
+
+ for (;;) {
+ IF_DEQUEUE(ifq, m);
+ if (m == NULL)
+ break;
+
+ ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+ KASSERT(ni != NULL, ("frame w/o node"));
+ ieee80211_free_node(ni);
+ m->m_pkthdr.rcvif = NULL;
+
+ m_freem(m);
+ }
+}
+
/*
* Allocate and setup a management frame of the specified
* size. We return the mbuf and a pointer to the start
==== //depot/projects/wifi/sys/net80211/ieee80211_freebsd.h#21 (text+ko) ====
@@ -24,11 +24,12 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: src/sys/net80211/ieee80211_freebsd.h,v 1.7 2006/07/26 03:15:15 sam Exp $
+ * $FreeBSD: src/sys/net80211/ieee80211_freebsd.h,v 1.10 2007/01/09 04:37:05 sam Exp $
*/
#ifndef _NET80211_IEEE80211_FREEBSD_H_
#define _NET80211_IEEE80211_FREEBSD_H_
+#ifdef _KERNEL
/*
* Common state locking definitions.
*/
@@ -160,6 +161,9 @@
int ieee80211_node_dectestref(struct ieee80211_node *ni);
#define ieee80211_node_refcnt(_ni) (_ni)->ni_refcnt
+struct ifqueue;
+void ieee80211_drain_ifq(struct ifqueue *);
+
#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)
@@ -215,6 +219,7 @@
void ieee80211_sysctl_detach(struct ieee80211com *);
void ieee80211_load_module(const char *);
+#endif /* _KERNEL */
/* XXX this stuff belongs elsewhere */
/*
==== //depot/projects/wifi/sys/net80211/ieee80211_input.c#78 (text+ko) ====
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.97 2006/12/01 17:58:33 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.98 2007/01/08 17:24:51 sam Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -2764,6 +2764,7 @@
IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
rate = ieee80211_setup_rates(ni, rates, xrates,
+ IEEE80211_F_JOIN |
IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
if (rate & IEEE80211_RATE_BASIC) {
==== //depot/projects/wifi/sys/net80211/ieee80211_node.c#76 (text+ko) ====
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_node.c,v 1.76 2006/12/27 18:46:18 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_node.c,v 1.78 2007/01/15 01:12:28 sam Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -320,16 +320,20 @@
/*
* Do mode-specific rate setup.
*/
- if (IEEE80211_IS_CHAN_ANYG(chan)) {
- /*
- * Use a mixed 11b/11g rate set.
- */
- ieee80211_set11gbasicrates(&ni->ni_rates, IEEE80211_MODE_11G);
- } else if (IEEE80211_IS_CHAN_B(chan)) {
- /*
- * Force pure 11b rate set.
- */
- ieee80211_set11gbasicrates(&ni->ni_rates, IEEE80211_MODE_11B);
+ if (IEEE80211_IS_CHAN_FULL(chan)) {
+ if (IEEE80211_IS_CHAN_ANYG(chan)) {
+ /*
+ * Use a mixed 11b/11g rate set.
+ */
+ ieee80211_set11gbasicrates(&ni->ni_rates,
+ IEEE80211_MODE_11G);
+ } else if (IEEE80211_IS_CHAN_B(chan)) {
+ /*
+ * Force pure 11b rate set.
+ */
+ ieee80211_set11gbasicrates(&ni->ni_rates,
+ IEEE80211_MODE_11B);
+ }
}
(void) ieee80211_sta_join1(ieee80211_ref_node(ni));
@@ -440,7 +444,8 @@
if (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY)
fail |= 0x04;
}
- rate = ieee80211_fix_rate(ni, IEEE80211_F_DONEGO | IEEE80211_F_DOFRATE);
+ rate = ieee80211_fix_rate(ni,
+ IEEE80211_F_JOIN | IEEE80211_F_DONEGO | IEEE80211_F_DOFRATE);
if (rate & IEEE80211_RATE_BASIC)
fail |= 0x08;
if (ic->ic_des_nssid != 0 &&
@@ -534,11 +539,6 @@
if (ic->ic_opmode == IEEE80211_M_IBSS) {
struct ieee80211_node_table *nt;
/*
- * Delete unusable rates; we've already checked
- * that the negotiated rate set is acceptable.
- */
- ieee80211_fix_rate(selbs, IEEE80211_F_DODEL);
- /*
* Fillin the neighbor table; it will already
* exist if we are simply switching mastership.
* XXX ic_sta always setup so this is unnecessary?
@@ -565,6 +565,13 @@
copy_bss(selbs, obss);
ieee80211_free_node(obss);
}
+
+ /*
+ * Delete unusable rates; we've already checked
+ * that the negotiated rate set is acceptable.
+ */
+ ieee80211_fix_rate(ic->ic_bss, IEEE80211_F_DODEL | IEEE80211_F_JOIN);
+
ic->ic_bsschan = selbs->ni_chan;
ic->ic_curchan = ic->ic_bsschan;
ic->ic_curmode = ieee80211_chan2mode(ic->ic_curchan);
@@ -987,7 +994,9 @@
ieee80211_saveath(ni, sp->ath);
/* NB: must be after ni_chan is setup */
- ieee80211_setup_rates(ni, sp->rates, sp->xrates, IEEE80211_F_DOSORT);
+ ieee80211_setup_rates(ni, sp->rates, sp->xrates,
+ IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
+ IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
}
/*
@@ -1695,7 +1704,8 @@
IEEE80211_AID_SET(ni->ni_associd, ic->ic_aid_bitmap);
ic->ic_sta_assoc++;
newassoc = 1;
- if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
+ if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan) &&
+ IEEE80211_IS_CHAN_FULL(ni->ni_chan))
ieee80211_node_join_11g(ic, ni);
} else
newassoc = 0;
@@ -1822,7 +1832,8 @@
ni->ni_associd = 0;
ic->ic_sta_assoc--;
- if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
+ if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan) &&
+ IEEE80211_IS_CHAN_FULL(ni->ni_chan))
ieee80211_node_leave_11g(ic, ni);
/*
* Cleanup station state. In particular clear various
==== //depot/projects/wifi/sys/net80211/ieee80211_proto.c#46 (text+ko) ====
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_proto.c,v 1.32 2006/12/27 18:46:18 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_proto.c,v 1.34 2007/01/08 18:23:43 sam Exp $");
/*
* IEEE 802.11 protocol support.
@@ -130,7 +130,7 @@
if (ic->ic_auth->ia_detach)
ic->ic_auth->ia_detach(ic);
- IF_DRAIN(&ic->ic_mgtq);
+ ieee80211_drain_ifq(&ic->ic_mgtq);
mtx_destroy(&ic->ic_mgtq.ifq_mtx);
/*
@@ -334,12 +334,23 @@
}
}
+static __inline int
+findrix(const struct ieee80211_rateset *rs, int r)
+{
+ int i;
+
+ for (i = 0; i < rs->rs_nrates; i++)
+ if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == r)
+ return i;
+ return -1;
+}
+
int
ieee80211_fix_rate(struct ieee80211_node *ni, int flags)
{
#define RV(v) ((v) & IEEE80211_RATE_VAL)
struct ieee80211com *ic = ni->ni_ic;
- int i, j, ignore, error;
+ int i, j, rix, error;
int okrate, badrate, fixedrate;
const struct ieee80211_rateset *srs;
struct ieee80211_rateset *nrs;
@@ -351,7 +362,6 @@
srs = ieee80211_get_suprates(ic, ni->ni_chan);
nrs = &ni->ni_rates;
for (i = 0; i < nrs->rs_nrates; ) {
- ignore = 0;
if (flags & IEEE80211_F_DOSORT) {
/*
* Sort rates.
@@ -371,51 +381,40 @@
*/
if (r == ic->ic_fixed_rate)
fixedrate = r;
+ /*
+ * Check against supported rates.
+ */
+ rix = findrix(srs, r);
if (flags & IEEE80211_F_DONEGO) {
- /*
- * Check against supported rates.
- */
- for (j = 0; j < srs->rs_nrates; j++) {
- if (r == RV(srs->rs_rates[j])) {
- /*
- * Overwrite with the supported rate
- * value so any basic rate bit is set.
- * This insures that response we send
- * to stations have the necessary basic
- * rate bit set.
- */
- nrs->rs_rates[i] = srs->rs_rates[j];
- break;
- }
- }
- if (j == srs->rs_nrates) {
+ if (rix < 0) {
/*
* A rate in the node's rate set is not
* supported. If this is a basic rate and we
- * are operating as an AP then this is an error.
+ * are operating as a STA then this is an error.
* Otherwise we just discard/ignore the rate.
- * Note that this is important for 11b stations
- * when they want to associate with an 11g AP.
*/
- if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
+ if ((flags & IEEE80211_F_JOIN) &&
(nrs->rs_rates[i] & IEEE80211_RATE_BASIC))
error++;
- ignore++;
+ } else if ((flags & IEEE80211_F_JOIN) == 0) {
+ /*
+ * Overwrite with the supported rate
+ * value so any basic rate bit is set.
+ */
+ nrs->rs_rates[i] = srs->rs_rates[rix];
}
}
- if (flags & IEEE80211_F_DODEL) {
+ if ((flags & IEEE80211_F_DODEL) && rix < 0) {
/*
* Delete unacceptable rates.
*/
- if (ignore) {
- nrs->rs_nrates--;
- for (j = i; j < nrs->rs_nrates; j++)
- nrs->rs_rates[j] = nrs->rs_rates[j + 1];
- nrs->rs_rates[j] = 0;
- continue;
- }
+ nrs->rs_nrates--;
+ for (j = i; j < nrs->rs_nrates; j++)
+ nrs->rs_rates[j] = nrs->rs_rates[j + 1];
+ nrs->rs_rates[j] = 0;
+ continue;
}
- if (!ignore)
+ if (rix >= 0)
okrate = nrs->rs_rates[i];
i++;
}
@@ -1088,7 +1087,7 @@
default:
break;
}
- goto reset;
+ break;
case IEEE80211_S_ASSOC:
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
@@ -1103,16 +1102,18 @@
default:
break;
}
- goto reset;
+ break;
case IEEE80211_S_SCAN:
ieee80211_cancel_scan(ic);
- goto reset;
+ break;
case IEEE80211_S_AUTH:
- reset:
- IF_DRAIN(&ic->ic_mgtq);
+ break;
+ }
+ if (ostate != IEEE80211_S_INIT) {
+ /* NB: optimize INIT -> INIT case */
+ ieee80211_drain_ifq(&ic->ic_mgtq);
ieee80211_reset_bss(ic);
ieee80211_scan_flush(ic);
- break;
}
if (ic->ic_auth->ia_detach != NULL)
ic->ic_auth->ia_detach(ic);
==== //depot/projects/wifi/sys/net80211/ieee80211_proto.h#28 (text+ko) ====
@@ -29,7 +29,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: src/sys/net80211/ieee80211_proto.h,v 1.19 2006/07/26 03:15:15 sam Exp $
+ * $FreeBSD: src/sys/net80211/ieee80211_proto.h,v 1.20 2007/01/08 17:24:51 sam Exp $
*/
#ifndef _NET80211_IEEE80211_PROTO_H_
#define _NET80211_IEEE80211_PROTO_H_
@@ -179,6 +179,7 @@
#define IEEE80211_F_DOFRATE 0x00000002 /* use fixed rate */
#define IEEE80211_F_DONEGO 0x00000004 /* calc negotiated rate */
#define IEEE80211_F_DODEL 0x00000008 /* delete ignore rate */
+#define IEEE80211_F_JOIN 0x00000010 /* sta joining our bss */
int ieee80211_fix_rate(struct ieee80211_node *, int);
/*
==== //depot/projects/wifi/sys/net80211/ieee80211_var.h#44 (text+ko) ====
@@ -29,7 +29,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: src/sys/net80211/ieee80211_var.h,v 1.44 2006/12/27 18:46:18 sam Exp $
+ * $FreeBSD: src/sys/net80211/ieee80211_var.h,v 1.45 2007/01/06 02:56:41 kmacy Exp $
*/
#ifndef _NET80211_IEEE80211_VAR_H_
#define _NET80211_IEEE80211_VAR_H_
More information about the p4-projects
mailing list