Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 8 Nov 2011 04:00:25 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r227331 - head/sys/net80211
Message-ID:  <201111080400.pA840PMj012100@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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@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 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201111080400.pA840PMj012100>