summaryrefslogtreecommitdiffstats
path: root/sys/net80211/ieee80211_proto.c
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2007-01-08 17:24:51 +0000
committersam <sam@FreeBSD.org>2007-01-08 17:24:51 +0000
commitfae048c8598d2452ea294b97092f230431c7d37c (patch)
treedb2e192b629326cfac5f0245ca3a5e0ed3326978 /sys/net80211/ieee80211_proto.c
parent6d67972dc50a1f716abce17b6a0a3c60b8df2449 (diff)
downloadFreeBSD-src-fae048c8598d2452ea294b97092f230431c7d37c.zip
FreeBSD-src-fae048c8598d2452ea294b97092f230431c7d37c.tar.gz
Correct several issues with rate set negotiation:
o add IEEE80211_F_JOIN flag to ieee80211_fix_rate to indicate a station is joining a BSS; this is used to control whether or not we over-write the basic rate bit in the calculated rate set o fix ieee80211_fix_rate to honor IEEE80211_F_DODEL when IEEE80211_F_DONEGO is not specified (e.g. when joining an ibss network) o on sta join always delete unusable rates from the negotiated rate set, this was being done only ibss networks but is also needed for 11g bss with mixed stations o on sta join delete unusable rates from the bss node's rate set, not the scan table entry's rate set o when calculating a rate set for new neighbors in an ibss caculate a negotiated rate set so drivers are not presented with rates they should not use Submitted by: Sepherosa Ziehau (w/ modifications) Obtained from: DragonFly MFC after: 1 month
Diffstat (limited to 'sys/net80211/ieee80211_proto.c')
-rw-r--r--sys/net80211/ieee80211_proto.c65
1 files changed, 32 insertions, 33 deletions
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index e11fb70..590522f 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -322,12 +322,23 @@ ieee80211_dump_pkt(const u_int8_t *buf, int len, int rate, int rssi)
}
}
+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;
@@ -345,7 +356,6 @@ ieee80211_fix_rate(struct ieee80211_node *ni, int flags)
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.
@@ -367,51 +377,40 @@ ieee80211_fix_rate(struct ieee80211_node *ni, int flags)
if (r == RV(srs->rs_rates[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++;
}
OpenPOWER on IntegriCloud