aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/net80211/ieee80211_input.c9
-rw-r--r--sys/net80211/ieee80211_ioctl.c12
-rw-r--r--sys/net80211/ieee80211_ioctl.h1
-rw-r--r--sys/net80211/ieee80211_var.h3
4 files changed, 23 insertions, 2 deletions
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index 106615bcf6c1..7eac99b82b0e 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -2305,7 +2305,14 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
rate = ieee80211_setup_rates(ic, ni, rates, xrates,
IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
- if (rate & IEEE80211_RATE_BASIC) {
+ /*
+ * If constrained to 11g-only stations reject an
+ * 11b-only station. We cheat a bit here by looking
+ * at the max negotiated xmit rate and assuming anyone
+ * with a best rate <24Mb/s is an 11b station.
+ */
+ if ((rate & IEEE80211_RATE_BASIC) ||
+ ((ic->ic_flags & IEEE80211_F_PUREG) && rate < 48)) {
IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
"[%s] deny %s request, rate set mismatch\n",
ether_sprintf(wh->i_addr2),
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index 490b56755844..83ac126cf33a 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -1451,6 +1451,9 @@ ieee80211_ioctl_get80211(struct ieee80211com *ic, u_long cmd, struct ieee80211re
/* NB: get from ic_bss for station mode */
ireq->i_val = ic->ic_bss->ni_intval;
break;
+ case IEEE80211_IOC_PUREG:
+ ireq->i_val = (ic->ic_flags & IEEE80211_F_PUREG) != 0;
+ break;
default:
error = EINVAL;
break;
@@ -2316,6 +2319,15 @@ ieee80211_ioctl_set80211(struct ieee80211com *ic, u_long cmd, struct ieee80211re
} else
error = EINVAL;
break;
+ case IEEE80211_IOC_PUREG:
+ if (ireq->i_val)
+ ic->ic_flags |= IEEE80211_F_PUREG;
+ else
+ ic->ic_flags &= ~IEEE80211_F_PUREG;
+ /* NB: reset only if we're operating on an 11g channel */
+ if (ic->ic_curmode == IEEE80211_MODE_11G)
+ error = ENETRESET;
+ break;
default:
error = EINVAL;
break;
diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h
index b561b15c029c..658bd56b04c1 100644
--- a/sys/net80211/ieee80211_ioctl.h
+++ b/sys/net80211/ieee80211_ioctl.h
@@ -426,6 +426,7 @@ struct ieee80211req {
#define IEEE80211_IOC_BEACON_INTERVAL 53 /* beacon interval (ms) */
#define IEEE80211_IOC_ADDMAC 54 /* add sta to MAC ACL table */
#define IEEE80211_IOC_DELMAC 55 /* del sta from MAC ACL table */
+#define IEEE80211_IOC_PUREG 56 /* pure 11g (no 11b stations) */
/*
* Scan result data returned for IEEE80211_IOC_SCAN_RESULTS.
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index f4cfb3e9593e..b20b2b776398 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -196,9 +196,10 @@ struct ieee80211com {
#define IEEE80211_ADDR_COPY(dst,src) memcpy(dst,src,IEEE80211_ADDR_LEN)
/* ic_flags */
-/* NB: bits 0x6f available */
+/* NB: bits 0x4f available */
/* NB: this is intentionally setup to be IEEE80211_CAPINFO_PRIVACY */
#define IEEE80211_F_PRIVACY 0x00000010 /* CONF: privacy enabled */
+#define IEEE80211_F_PUREG 0x00000020 /* CONF: 11g w/o 11b sta's */
#define IEEE80211_F_SCAN 0x00000080 /* STATUS: scanning */
#define IEEE80211_F_ASCAN 0x00000100 /* STATUS: active scan */
#define IEEE80211_F_SIBSS 0x00000200 /* STATUS: start IBSS */