diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2006-08-29 17:56:33 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2006-08-29 17:56:33 +0000 |
commit | 1113059f93396744170bfc8d0b3599691bb14993 (patch) | |
tree | d96767bfdbfbcc2e7a800cdbae25ed888a311c7b /sys/net80211/ieee80211_proto.c | |
parent | 917da5642b0e18d3e064f75d0fcef3aba833a77c (diff) |
Change the way ieee80211_fix_rate() handles the IEEE80211_F_DOFRATE flag.
Instead of removing the rates from the node's rate set, just check that
the fixed rate is present in the rate set. Otherwise, the node will be
marked non-ERP which will force the use of protection mode (either
CTS-to-self or RTS/CTS) in an 802.11g network and degrade performance.
This fixes HostAP mode for 11g with a fixed rate.
Problem originally reported by Sam Fourman Jr.
Code from FreeBSD.
ok reyk@, "no objections here" jsg@
Diffstat (limited to 'sys/net80211/ieee80211_proto.c')
-rw-r--r-- | sys/net80211/ieee80211_proto.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index 771dfe9019e..b88c0d0675e 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_proto.c,v 1.11 2006/08/19 12:38:16 damien Exp $ */ +/* $OpenBSD: ieee80211_proto.c,v 1.12 2006/08/29 17:56:32 damien Exp $ */ /* $NetBSD: ieee80211_proto.c,v 1.8 2004/04/30 23:58:20 dyoung Exp $ */ /*- @@ -209,12 +209,19 @@ ieee80211_fix_rate(struct ieee80211com *ic, struct ieee80211_node *ni, { #define RV(v) ((v) & IEEE80211_RATE_VAL) int i, j, ignore, error; - int okrate, badrate; + int okrate, badrate, fixedrate; struct ieee80211_rateset *srs, *nrs; u_int8_t r; + /* + * If the fixed rate check was requested but no fixed rate has been + * defined then just remove the check. + */ + if ((flags & IEEE80211_F_DOFRATE) && ic->ic_fixed_rate == -1) + flags &= ~IEEE80211_F_DOFRATE; + error = 0; - okrate = badrate = 0; + okrate = badrate = fixedrate = 0; srs = &ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)]; nrs = &ni->ni_rates; for (i = 0; i < nrs->rs_nrates; ) { @@ -236,17 +243,10 @@ ieee80211_fix_rate(struct ieee80211com *ic, struct ieee80211_node *ni, badrate = r; if (flags & IEEE80211_F_DOFRATE) { /* - * Apply fixed rate constraint. Note that we do - * not apply the constraint to basic rates as - * otherwise we may not be able to associate if - * the rate set we submit to the AP is invalid - * (e.g. fix rate at 36Mb/s which is not a basic - * rate for 11a operation). + * Check fixed rate is included. */ - if ((nrs->rs_rates[i] & IEEE80211_RATE_BASIC) == 0 && - ic->ic_fixed_rate >= 0 && - r != RV(srs->rs_rates[ic->ic_fixed_rate])) - ignore++; + if (r == RV(srs->rs_rates[ic->ic_fixed_rate])) + fixedrate = r; } if (flags & IEEE80211_F_DONEGO) { /* @@ -296,7 +296,8 @@ ieee80211_fix_rate(struct ieee80211com *ic, struct ieee80211_node *ni, okrate = nrs->rs_rates[i]; i++; } - if (okrate == 0 || error != 0) + if (okrate == 0 || error != 0 || + ((flags & IEEE80211_F_DOFRATE) && fixedrate == 0)) return badrate | IEEE80211_RATE_BASIC; else return RV(okrate); |