svn commit: r227331 - head/sys/net80211
Adrian Chadd
adrian at FreeBSD.org
Tue Nov 8 04:00:25 UTC 2011
Author: adrian
Date: Tue Nov 8 04:00:24 2011
New Revision: 227331
URL: http://svn.freebsd.org/changeset/base/227331
Log:
Add 802.11h quiet time element support into net80211.
This supports both station and hostap modes:
* Station mode quiet time element support listens to quiet time
IE's and modifies the local quiet time configuration as appropriate;
* Hostap mode both obeys the locally configured quiet time period
and includes it in beacon frames so stations also can obey as needed.
Submitted by: Himali Patel <himali.patel at sibridgetech.com>
Sponsored by: Sibridge Technologies
Modified:
head/sys/net80211/ieee80211.h
head/sys/net80211/ieee80211_dfs.c
head/sys/net80211/ieee80211_input.c
head/sys/net80211/ieee80211_ioctl.c
head/sys/net80211/ieee80211_ioctl.h
head/sys/net80211/ieee80211_output.c
head/sys/net80211/ieee80211_proto.h
head/sys/net80211/ieee80211_scan.h
head/sys/net80211/ieee80211_sta.c
head/sys/net80211/ieee80211_var.h
Modified: head/sys/net80211/ieee80211.h
==============================================================================
--- head/sys/net80211/ieee80211.h Tue Nov 8 02:54:08 2011 (r227330)
+++ head/sys/net80211/ieee80211.h Tue Nov 8 04:00:24 2011 (r227331)
@@ -759,6 +759,18 @@ struct ieee80211_country_ie {
/*
* 802.11h Channel Switch Announcement (CSA).
*/
+struct ieee80211_quiet_ie {
+ uint8_t quiet_ie; /* IEEE80211_ELEMID_QUIET */
+ uint8_t len;
+ uint8_t tbttcount; /* quiet start */
+ uint8_t period; /* beacon intervals between quiets */
+ uint16_t duration; /* TUs of each quiet*/
+ uint16_t offset; /* TUs of from TBTT of quiet start */
+} __packed;
+
+/*
+ * 802.11h Channel Switch Announcement (CSA).
+ */
struct ieee80211_csa_ie {
uint8_t csa_ie; /* IEEE80211_ELEMID_CHANSWITCHANN */
uint8_t csa_len;
Modified: head/sys/net80211/ieee80211_dfs.c
==============================================================================
--- head/sys/net80211/ieee80211_dfs.c Tue Nov 8 02:54:08 2011 (r227330)
+++ head/sys/net80211/ieee80211_dfs.c Tue Nov 8 04:00:24 2011 (r227331)
@@ -64,6 +64,12 @@ SYSCTL_INT(_net_wlan, OID_AUTO, cac_time
&ieee80211_cac_timeout, 0, "CAC timeout (secs)");
#define CAC_TIMEOUT msecs_to_ticks(ieee80211_cac_timeout*1000)
+static int
+null_set_quiet(struct ieee80211_node *ni, u_int8_t *quiet_elm)
+{
+ return ENOSYS;
+}
+
void
ieee80211_dfs_attach(struct ieee80211com *ic)
{
@@ -71,6 +77,8 @@ ieee80211_dfs_attach(struct ieee80211com
callout_init_mtx(&dfs->nol_timer, IEEE80211_LOCK_OBJ(ic), 0);
callout_init_mtx(&dfs->cac_timer, IEEE80211_LOCK_OBJ(ic), 0);
+
+ ic->ic_set_quiet = null_set_quiet;
}
void
Modified: head/sys/net80211/ieee80211_input.c
==============================================================================
--- head/sys/net80211/ieee80211_input.c Tue Nov 8 02:54:08 2011 (r227330)
+++ head/sys/net80211/ieee80211_input.c Tue Nov 8 04:00:24 2011 (r227331)
@@ -522,6 +522,9 @@ ieee80211_parse_beacon(struct ieee80211_
case IEEE80211_ELEMID_CSA:
scan->csa = frm;
break;
+ case IEEE80211_ELEMID_QUIET:
+ scan->quiet = frm;
+ break;
case IEEE80211_ELEMID_FHPARMS:
if (ic->ic_phytype == IEEE80211_T_FH) {
scan->fhdwell = LE_READ_2(&frm[2]);
Modified: head/sys/net80211/ieee80211_ioctl.c
==============================================================================
--- head/sys/net80211/ieee80211_ioctl.c Tue Nov 8 02:54:08 2011 (r227330)
+++ head/sys/net80211/ieee80211_ioctl.c Tue Nov 8 04:00:24 2011 (r227331)
@@ -972,6 +972,21 @@ ieee80211_ioctl_get80211(struct ieee8021
case IEEE80211_IOC_PUREG:
ireq->i_val = (vap->iv_flags & IEEE80211_F_PUREG) != 0;
break;
+ case IEEE80211_IOC_QUIET:
+ ireq->i_val = vap->iv_quiet;
+ break;
+ case IEEE80211_IOC_QUIET_COUNT:
+ ireq->i_val = vap->iv_quiet_count;
+ break;
+ case IEEE80211_IOC_QUIET_PERIOD:
+ ireq->i_val = vap->iv_quiet_period;
+ break;
+ case IEEE80211_IOC_QUIET_DUR:
+ ireq->i_val = vap->iv_quiet_duration;
+ break;
+ case IEEE80211_IOC_QUIET_OFFSET:
+ ireq->i_val = vap->iv_quiet_offset;
+ break;
case IEEE80211_IOC_BGSCAN:
ireq->i_val = (vap->iv_flags & IEEE80211_F_BGSCAN) != 0;
break;
@@ -2939,6 +2954,24 @@ ieee80211_ioctl_set80211(struct ieee8021
if (isvap11g(vap))
error = ENETRESET;
break;
+ case IEEE80211_IOC_QUIET:
+ vap->iv_quiet= ireq->i_val;
+ break;
+ case IEEE80211_IOC_QUIET_COUNT:
+ vap->iv_quiet_count=ireq->i_val;
+ break;
+ case IEEE80211_IOC_QUIET_PERIOD:
+ vap->iv_quiet_period=ireq->i_val;
+ break;
+ case IEEE80211_IOC_QUIET_OFFSET:
+ vap->iv_quiet_offset=ireq->i_val;
+ break;
+ case IEEE80211_IOC_QUIET_DUR:
+ if(ireq->i_val < vap->iv_bss->ni_intval)
+ vap->iv_quiet_duration = ireq->i_val;
+ else
+ error = EINVAL;
+ break;
case IEEE80211_IOC_BGSCAN:
if (ireq->i_val) {
if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0)
Modified: head/sys/net80211/ieee80211_ioctl.h
==============================================================================
--- head/sys/net80211/ieee80211_ioctl.h Tue Nov 8 02:54:08 2011 (r227330)
+++ head/sys/net80211/ieee80211_ioctl.h Tue Nov 8 04:00:24 2011 (r227331)
@@ -715,6 +715,11 @@ struct ieee80211req {
#define IEEE80211_IOC_TDMA_SLOTLEN 203 /* TDMA: slot length (usecs) */
#define IEEE80211_IOC_TDMA_BINTERVAL 204 /* TDMA: beacon intvl (slots) */
+#define IEEE80211_IOC_QUIET 205 /* Quiet Enable/Disable */
+#define IEEE80211_IOC_QUIET_PERIOD 206 /* Quiet Period */
+#define IEEE80211_IOC_QUIET_OFFSET 207 /* Quiet Offset */
+#define IEEE80211_IOC_QUIET_DUR 208 /* Quiet Duration */
+#define IEEE80211_IOC_QUIET_COUNT 209 /* Quiet Count */
/*
* Parameters for controlling a scan requested with
* IEEE80211_IOC_SCAN_REQ.
Modified: head/sys/net80211/ieee80211_output.c
==============================================================================
--- head/sys/net80211/ieee80211_output.c Tue Nov 8 02:54:08 2011 (r227330)
+++ head/sys/net80211/ieee80211_output.c Tue Nov 8 04:00:24 2011 (r227331)
@@ -1661,6 +1661,33 @@ ieee80211_add_supportedchannels(uint8_t
}
/*
+ * Add an 11h Quiet time element to a frame.
+ */
+static uint8_t *
+ieee80211_add_quiet(uint8_t *frm, struct ieee80211vap *vap)
+{
+ struct ieee80211_quiet_ie *quiet = (struct ieee80211_quiet_ie *) frm;
+
+ quiet->quiet_ie = IEEE80211_ELEMID_QUIET;
+ quiet->len = 6;
+ if (vap->iv_quiet_count_value == 1)
+ vap->iv_quiet_count_value = vap->iv_quiet_count;
+ else if (vap->iv_quiet_count_value > 1)
+ vap->iv_quiet_count_value--;
+
+ if (vap->iv_quiet_count_value == 0) {
+ /* value 0 is reserved as per 802.11h standerd */
+ vap->iv_quiet_count_value = 1;
+ }
+
+ quiet->tbttcount = vap->iv_quiet_count_value;
+ quiet->period = vap->iv_quiet_period;
+ quiet->duration = htole16(vap->iv_quiet_duration);
+ quiet->offset = htole16(vap->iv_quiet_offset);
+ return frm + sizeof(*quiet);
+}
+
+/*
* Add an 11h Channel Switch Announcement element to a frame.
* Note that we use the per-vap CSA count to adjust the global
* counter so we can use this routine to form probe response
@@ -2253,6 +2280,7 @@ ieee80211_alloc_proberesp(struct ieee802
+ IEEE80211_COUNTRY_MAX_SIZE
+ 3
+ sizeof(struct ieee80211_csa_ie)
+ + sizeof(struct ieee80211_quiet_ie)
+ 3
+ 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
+ sizeof(struct ieee80211_ie_wpa)
@@ -2319,6 +2347,13 @@ ieee80211_alloc_proberesp(struct ieee802
if (ic->ic_flags & IEEE80211_F_CSAPENDING)
frm = ieee80211_add_csa(frm, vap);
}
+ if (vap->iv_flags & IEEE80211_F_DOTH) {
+ if (IEEE80211_IS_CHAN_DFS(ic->ic_bsschan) &&
+ (vap->iv_flags_ext & IEEE80211_FEXT_DFS)) {
+ if (vap->iv_quiet)
+ frm = ieee80211_add_quiet(frm, vap);
+ }
+ }
if (IEEE80211_IS_CHAN_ANYG(bss->ni_chan))
frm = ieee80211_add_erp(frm, ic);
frm = ieee80211_add_xrates(frm, rs);
@@ -2617,9 +2652,20 @@ ieee80211_beacon_construct(struct mbuf *
frm = ieee80211_add_powerconstraint(frm, vap);
bo->bo_csa = frm;
if (ic->ic_flags & IEEE80211_F_CSAPENDING)
- frm = ieee80211_add_csa(frm, vap);
+ frm = ieee80211_add_csa(frm, vap);
} else
bo->bo_csa = frm;
+
+ if (vap->iv_flags & IEEE80211_F_DOTH) {
+ bo->bo_quiet = frm;
+ if (IEEE80211_IS_CHAN_DFS(ic->ic_bsschan) &&
+ (vap->iv_flags_ext & IEEE80211_FEXT_DFS)) {
+ if (vap->iv_quiet)
+ frm = ieee80211_add_quiet(frm,vap);
+ }
+ } else
+ bo->bo_quiet = frm;
+
if (IEEE80211_IS_CHAN_ANYG(ni->ni_chan)) {
bo->bo_erp = frm;
frm = ieee80211_add_erp(frm, ic);
@@ -2733,7 +2779,8 @@ ieee80211_beacon_alloc(struct ieee80211_
+ 2 + 4 + vap->iv_tim_len /* DTIM/IBSSPARMS */
+ IEEE80211_COUNTRY_MAX_SIZE /* country */
+ 2 + 1 /* power control */
- + sizeof(struct ieee80211_csa_ie) /* CSA */
+ + sizeof(struct ieee80211_csa_ie) /* CSA */
+ + sizeof(struct ieee80211_quiet_ie) /* Quiet */
+ 2 + 1 /* ERP */
+ 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
+ (vap->iv_caps & IEEE80211_C_WPA ? /* WPA 1+2 */
@@ -2953,6 +3000,7 @@ ieee80211_beacon_update(struct ieee80211
bo->bo_appie += adjust;
bo->bo_wme += adjust;
bo->bo_csa += adjust;
+ bo->bo_quiet += adjust;
bo->bo_tim_len = timlen;
/* update information element */
@@ -3006,6 +3054,7 @@ ieee80211_beacon_update(struct ieee80211
#endif
bo->bo_appie += sizeof(*csa);
bo->bo_csa_trailer_len += sizeof(*csa);
+ bo->bo_quiet += sizeof(*csa);
bo->bo_tim_trailer_len += sizeof(*csa);
m->m_len += sizeof(*csa);
m->m_pkthdr.len += sizeof(*csa);
@@ -3016,6 +3065,11 @@ ieee80211_beacon_update(struct ieee80211
vap->iv_csa_count++;
/* NB: don't clear IEEE80211_BEACON_CSA */
}
+ if (IEEE80211_IS_CHAN_DFS(ic->ic_bsschan) &&
+ (vap->iv_flags_ext & IEEE80211_FEXT_DFS) ){
+ if (vap->iv_quiet)
+ ieee80211_add_quiet(bo->bo_quiet, vap);
+ }
if (isset(bo->bo_flags, IEEE80211_BEACON_ERP)) {
/*
* ERP element needs updating.
Modified: head/sys/net80211/ieee80211_proto.h
==============================================================================
--- head/sys/net80211/ieee80211_proto.h Tue Nov 8 02:54:08 2011 (r227330)
+++ head/sys/net80211/ieee80211_proto.h Tue Nov 8 04:00:24 2011 (r227331)
@@ -344,6 +344,7 @@ struct ieee80211_beacon_offsets {
uint16_t bo_appie_len; /* AppIE length in bytes */
uint16_t bo_csa_trailer_len;
uint8_t *bo_csa; /* start of CSA element */
+ uint8_t *bo_quiet; /* start of Quiet element */
uint8_t *bo_meshconf; /* start of MESHCONF element */
uint8_t *bo_spare[3];
};
Modified: head/sys/net80211/ieee80211_scan.h
==============================================================================
--- head/sys/net80211/ieee80211_scan.h Tue Nov 8 02:54:08 2011 (r227330)
+++ head/sys/net80211/ieee80211_scan.h Tue Nov 8 04:00:24 2011 (r227331)
@@ -213,6 +213,7 @@ struct ieee80211_scanparams {
uint8_t *ath;
uint8_t *tdma;
uint8_t *csa;
+ uint8_t *quiet;
uint8_t *meshid;
uint8_t *meshconf;
uint8_t *spare[3];
Modified: head/sys/net80211/ieee80211_sta.c
==============================================================================
--- head/sys/net80211/ieee80211_sta.c Tue Nov 8 02:54:08 2011 (r227330)
+++ head/sys/net80211/ieee80211_sta.c Tue Nov 8 04:00:24 2011 (r227331)
@@ -1347,6 +1347,8 @@ sta_recv_mgmt(struct ieee80211_node *ni,
scan.htcap, scan.htinfo);
/* XXX state changes? */
}
+ if (scan.quiet)
+ ic->ic_set_quiet(ni, scan.quiet);
if (scan.tim != NULL) {
struct ieee80211_tim_ie *tim =
(struct ieee80211_tim_ie *) scan.tim;
Modified: head/sys/net80211/ieee80211_var.h
==============================================================================
--- head/sys/net80211/ieee80211_var.h Tue Nov 8 02:54:08 2011 (r227330)
+++ head/sys/net80211/ieee80211_var.h Tue Nov 8 04:00:24 2011 (r227331)
@@ -242,6 +242,10 @@ struct ieee80211com {
int (*ic_setregdomain)(struct ieee80211com *,
struct ieee80211_regdomain *,
int, struct ieee80211_channel []);
+
+ int (*ic_set_quiet)(struct ieee80211_node *,
+ u_int8_t *quiet_elm);
+
/* send/recv 802.11 management frame */
int (*ic_send_mgmt)(struct ieee80211_node *,
int, int);
@@ -403,6 +407,12 @@ struct ieee80211vap {
uint8_t iv_dtim_period; /* DTIM period */
uint8_t iv_dtim_count; /* DTIM count from last bcn */
/* set/unset aid pwrsav state */
+ uint8_t iv_quiet; /* Quiet Element */
+ uint8_t iv_quiet_count; /* constant count for Quiet Element */
+ uint8_t iv_quiet_count_value; /* variable count for Quiet Element */
+ uint8_t iv_quiet_period; /* period for Quiet Element */
+ uint16_t iv_quiet_duration; /* duration for Quiet Element */
+ uint16_t iv_quiet_offset; /* offset for Quiet Element */
int iv_csa_count; /* count for doing CSA */
struct ieee80211_node *iv_bss; /* information for this node */
More information about the svn-src-all
mailing list