From 1cc47aa694fbad766abef84974b911cb95559ca4 Mon Sep 17 00:00:00 2001 From: Stefan Sperling Date: Tue, 30 May 2017 11:00:39 +0000 Subject: Introduce ieee80211_min_basic_rate() and ieee80211_max_basic_rate(). These helpers can be used by drivers to improve compatibility with APs that disable some mandatory PHY rates in the basic rate set. For instance, many of our drivers hard-code 11b rates on 2 Ghz and run into problems when APs disable them. Since 11b rates are being disabled by default by some vendors, hardcoding them is not a good idea anymore. ok mpi@ phessler@ --- sys/net80211/ieee80211.c | 39 ++++++++++++++++++++++++++++++++++++++- sys/net80211/ieee80211_var.h | 4 +++- 2 files changed, 41 insertions(+), 2 deletions(-) (limited to 'sys/net80211') diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c index e330f8ec954..a5da6f1050b 100644 --- a/sys/net80211/ieee80211.c +++ b/sys/net80211/ieee80211.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211.c,v 1.58 2016/01/13 14:33:07 stsp Exp $ */ +/* $OpenBSD: ieee80211.c,v 1.59 2017/05/30 11:00:38 stsp Exp $ */ /* $NetBSD: ieee80211.c,v 1.19 2004/06/06 05:45:29 dyoung Exp $ */ /*- @@ -712,6 +712,43 @@ ieee80211_setbasicrates(struct ieee80211com *ic) } } +int +ieee80211_min_basic_rate(struct ieee80211com *ic) +{ + struct ieee80211_rateset *rs = &ic->ic_bss->ni_rates; + int i; + + for (i = 0; i < rs->rs_nrates; i++) { + if (rs->rs_rates[i] & IEEE80211_RATE_BASIC) + return i; + } + + return 0; +} + +int +ieee80211_max_basic_rate(struct ieee80211com *ic) +{ + struct ieee80211_rateset *rs = &ic->ic_bss->ni_rates; + int i, best, rval, best_rval; + + /* Defaults to 1 Mbit/s on 2GHz and 6 Mbit/s on 5GHz. */ + best = 0; + best_rval = (rs->rs_rates[best] & IEEE80211_RATE_VAL); + + for (i = 0; i < rs->rs_nrates; i++) { + if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) == 0) + continue; + rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL); + if (rval > best_rval) { + best_rval = rval; + best = i; + } + } + + return best; +} + /* * Set the current phy mode and recalculate the active channel * set based on the available channels for this mode. Also diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index 627eaebc8f9..7d6bb1bd85e 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_var.h,v 1.77 2017/02/02 16:47:53 stsp Exp $ */ +/* $OpenBSD: ieee80211_var.h,v 1.78 2017/05/30 11:00:38 stsp Exp $ */ /* $NetBSD: ieee80211_var.h,v 1.7 2004/05/06 03:07:10 dyoung Exp $ */ /*- @@ -402,6 +402,8 @@ u_int ieee80211_mhz2ieee(u_int, u_int); u_int ieee80211_chan2ieee(struct ieee80211com *, const struct ieee80211_channel *); u_int ieee80211_ieee2mhz(u_int, u_int); +int ieee80211_min_basic_rate(struct ieee80211com *); +int ieee80211_max_basic_rate(struct ieee80211com *); int ieee80211_setmode(struct ieee80211com *, enum ieee80211_phymode); enum ieee80211_phymode ieee80211_next_mode(struct ifnet *); enum ieee80211_phymode ieee80211_chan2mode(struct ieee80211com *, -- cgit v1.2.3