svn commit: r313462 - head/sys/net80211

Adrian Chadd adrian at FreeBSD.org
Thu Feb 9 04:07:31 UTC 2017


Author: adrian
Date: Thu Feb  9 04:07:30 2017
New Revision: 313462
URL: https://svnweb.freebsd.org/changeset/base/313462

Log:
  [net80211] quiet IE handling improvements
  
  * on the station side, only call the quiet time IE method if we have a
    quiet IE - otherwise call the NULL method once, and then don't waste
    time calling NULL
  
  * on the beacon generation side - force a beacon regeneration each time
    quiet time is enabled/disabled.  Without this, enabling/disabling quiet
    time IE would cause the beacon contents to be corrupted since none of
    the "move contents around" logic (like for CSA and TIM handling) is implemented.
  
  This changes the size of ieee80211_node so it requires a kernel recompile,
  but no userland recompile.
  
  Tested:
  
  * AR9380, AP mode, enabling/disabling quiet time IE
  * AR9380, STA mode, with upcoming driver changes.

Modified:
  head/sys/net80211/ieee80211_node.h
  head/sys/net80211/ieee80211_output.c
  head/sys/net80211/ieee80211_proto.h
  head/sys/net80211/ieee80211_sta.c
  head/sys/net80211/ieee80211_var.h

Modified: head/sys/net80211/ieee80211_node.h
==============================================================================
--- head/sys/net80211/ieee80211_node.h	Thu Feb  9 02:08:42 2017	(r313461)
+++ head/sys/net80211/ieee80211_node.h	Thu Feb  9 04:07:30 2017	(r313462)
@@ -249,6 +249,11 @@ struct ieee80211_node {
 
 	struct ieee80211vap	*ni_wdsvap;	/* associated WDS vap */
 	void			*ni_rctls;	/* private ratectl state */
+
+	/* quiet time IE state for the given node */
+	uint32_t		ni_quiet_ie_set;	/* Quiet time IE was seen */
+	struct			ieee80211_quiet_ie ni_quiet_ie;	/* last seen quiet IE */
+
 	uint64_t		ni_spare[3];
 };
 MALLOC_DECLARE(M_80211_NODE);

Modified: head/sys/net80211/ieee80211_output.c
==============================================================================
--- head/sys/net80211/ieee80211_output.c	Thu Feb  9 02:08:42 2017	(r313461)
+++ head/sys/net80211/ieee80211_output.c	Thu Feb  9 04:07:30 2017	(r313462)
@@ -2128,7 +2128,6 @@ ieee80211_add_qos(uint8_t *frm, const st
  * Send a probe request frame with the specified ssid
  * and any optional information element data.
  */
-/* XXX VHT? */
 int
 ieee80211_send_probereq(struct ieee80211_node *ni,
 	const uint8_t sa[IEEE80211_ADDR_LEN],
@@ -2438,7 +2437,6 @@ ieee80211_send_mgmt(struct ieee80211_nod
 
 	case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
 	case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
-		/* XXX VHT? */
 		/*
 		 * asreq frame format
 		 *	[2] capability information
@@ -2700,7 +2698,6 @@ bad:
  * Space is left to prepend and 802.11 header at the
  * front but it's left to the caller to fill in.
  */
-/* XXX VHT? */
 struct mbuf *
 ieee80211_alloc_proberesp(struct ieee80211_node *bss, int legacy)
 {
@@ -3035,7 +3032,6 @@ ieee80211_tx_mgt_cb(struct ieee80211_nod
 	}
 }
 
-/* XXX VHT? */
 static void
 ieee80211_beacon_construct(struct mbuf *m, uint8_t *frm,
 	struct ieee80211_node *ni)
@@ -3163,15 +3159,23 @@ ieee80211_beacon_construct(struct mbuf *
 	} else
 		bo->bo_csa = frm;
 
+	bo->bo_quiet = NULL;
 	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)
+		    (vap->iv_flags_ext & IEEE80211_FEXT_DFS) &&
+		    (vap->iv_quiet == 1)) {
+			/*
+			 * We only insert the quiet IE offset if
+			 * the quiet IE is enabled.  Otherwise don't
+			 * put it here or we'll just overwrite
+			 * some other beacon contents.
+			 */
+			if (vap->iv_quiet) {
+				bo->bo_quiet = frm;
 				frm = ieee80211_add_quiet(frm,vap, 0);
+			}
 		}
-	} else
-		bo->bo_quiet = frm;
+	}
 
 	if (IEEE80211_IS_CHAN_ANYG(ni->ni_chan)) {
 		bo->bo_erp = frm;
@@ -3239,7 +3243,6 @@ ieee80211_beacon_construct(struct mbuf *
 /*
  * Allocate a beacon frame and fillin the appropriate bits.
  */
-/* XXX VHT? */
 struct mbuf *
 ieee80211_beacon_alloc(struct ieee80211_node *ni)
 {
@@ -3252,6 +3255,14 @@ ieee80211_beacon_alloc(struct ieee80211_
 	uint8_t *frm;
 
 	/*
+	 * Update the "We're putting the quiet IE in the beacon" state.
+	 */
+	if (vap->iv_quiet == 1)
+		vap->iv_flags_ext |= IEEE80211_FEXT_QUIET_IE;
+	else if (vap->iv_quiet == 0)
+		vap->iv_flags_ext &= ~IEEE80211_FEXT_QUIET_IE;
+
+	/*
 	 * beacon frame format
 	 *
 	 * Note: This needs updating for 802.11-2012.
@@ -3286,7 +3297,6 @@ ieee80211_beacon_alloc(struct ieee80211_
 	 * NB: we allocate the max space required for the TIM bitmap.
 	 * XXX how big is this?
 	 */
-	/* XXX VHT? */
 	pktlen =   8					/* time stamp */
 		 + sizeof(uint16_t)			/* beacon interval */
 		 + sizeof(uint16_t)			/* capabilities */
@@ -3392,6 +3402,42 @@ ieee80211_beacon_update(struct ieee80211
 		return 1;		/* just assume length changed */
 	}
 
+	/*
+	 * Handle the quiet time element being added and removed.
+	 * Again, for now we just cheat and reconstruct the whole
+	 * beacon - that way the gap is provided as appropriate.
+	 *
+	 * So, track whether we have already added the IE versus
+	 * whether we want to be adding the IE.
+	 */
+	if ((vap->iv_flags_ext & IEEE80211_FEXT_QUIET_IE) &&
+	    (vap->iv_quiet == 0)) {
+		/*
+		 * Quiet time beacon IE enabled, but it's disabled;
+		 * recalc
+		 */
+		vap->iv_flags_ext &= ~IEEE80211_FEXT_QUIET_IE;
+		ieee80211_beacon_construct(m,
+		    mtod(m, uint8_t*) + sizeof(struct ieee80211_frame), ni);
+		/* XXX do WME aggressive mode processing? */
+		IEEE80211_UNLOCK(ic);
+		return 1;		/* just assume length changed */
+	}
+
+	if (((vap->iv_flags_ext & IEEE80211_FEXT_QUIET_IE) == 0) &&
+	    (vap->iv_quiet == 1)) {
+		/*
+		 * Quiet time beacon IE disabled, but it's now enabled;
+		 * recalc
+		 */
+		vap->iv_flags_ext |= IEEE80211_FEXT_QUIET_IE;
+		ieee80211_beacon_construct(m,
+		    mtod(m, uint8_t*) + sizeof(struct ieee80211_frame), ni);
+		/* XXX do WME aggressive mode processing? */
+		IEEE80211_UNLOCK(ic);
+		return 1;		/* just assume length changed */
+	}
+
 	wh = mtod(m, struct ieee80211_frame *);
 
 	/*
@@ -3600,10 +3646,17 @@ ieee80211_beacon_update(struct ieee80211
 			vap->iv_csa_count++;
 			/* NB: don't clear IEEE80211_BEACON_CSA */
 		}
+
+		/*
+		 * Only add the quiet time IE if we've enabled it
+		 * as appropriate.
+		 */
 		if (IEEE80211_IS_CHAN_DFS(ic->ic_bsschan) &&
-		    (vap->iv_flags_ext & IEEE80211_FEXT_DFS) ){
-			if (vap->iv_quiet)
+		    (vap->iv_flags_ext & IEEE80211_FEXT_DFS)) {
+			if (vap->iv_quiet &&
+			    (vap->iv_flags_ext & IEEE80211_FEXT_QUIET_IE)) {
 				ieee80211_add_quiet(bo->bo_quiet, vap, 1);
+			}
 		}
 		if (isset(bo->bo_flags, IEEE80211_BEACON_ERP)) {
 			/*

Modified: head/sys/net80211/ieee80211_proto.h
==============================================================================
--- head/sys/net80211/ieee80211_proto.h	Thu Feb  9 02:08:42 2017	(r313461)
+++ head/sys/net80211/ieee80211_proto.h	Thu Feb  9 04:07:30 2017	(r313462)
@@ -391,6 +391,8 @@ enum {
 	IEEE80211_BEACON_TDMA	= 9,	/* TDMA Info */
 	IEEE80211_BEACON_ATH	= 10,	/* ATH parameters */
 	IEEE80211_BEACON_MESHCONF = 11,	/* Mesh Configuration */
+	IEEE80211_BEACON_QUIET	= 12,	/* Quiet time IE */
+	IEEE80211_BEACON_VHTINFO	= 13,	/* VHT information */
 };
 int	ieee80211_beacon_update(struct ieee80211_node *,
 		struct mbuf *, int mcast);

Modified: head/sys/net80211/ieee80211_sta.c
==============================================================================
--- head/sys/net80211/ieee80211_sta.c	Thu Feb  9 02:08:42 2017	(r313461)
+++ head/sys/net80211/ieee80211_sta.c	Thu Feb  9 04:07:30 2017	(r313462)
@@ -1319,6 +1319,27 @@ startbgscan(struct ieee80211vap *vap)
 	     ieee80211_time_after(ticks, ic->ic_lastdata + vap->iv_bgscanidle)));
 }
 
+#ifdef	notyet
+/*
+ * Compare two quiet IEs and return if they are equivalent.
+ *
+ * The tbttcount isnt checked - that's not part of the configuration.
+ */
+static int
+compare_quiet_ie(const struct ieee80211_quiet_ie *q1,
+    const struct ieee80211_quiet_ie *q2)
+{
+
+	if (q1->period != q2->period)
+		return (0);
+	if (le16dec(&q1->duration) != le16dec(&q2->duration))
+		return (0);
+	if (le16dec(&q1->offset) != le16dec(&q2->offset))
+		return (0);
+	return (1);
+}
+#endif
+
 static void
 sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
     const struct ieee80211_rx_stats *rxs,
@@ -1449,8 +1470,26 @@ sta_recv_mgmt(struct ieee80211_node *ni,
 					ht_state_change = 1;
 			}
 
-			if (scan.quiet)
+			/*
+			 * If we have a quiet time IE then report it up to
+			 * the driver.
+			 *
+			 * Otherwise, inform the driver that the quiet time
+			 * IE has disappeared - only do that once rather than
+			 * spamming it each time.
+			 */
+			if (scan.quiet) {
 				ic->ic_set_quiet(ni, scan.quiet);
+				ni->ni_quiet_ie_set = 1;
+				memcpy(&ni->ni_quiet_ie, scan.quiet,
+				    sizeof(struct ieee80211_quiet_ie));
+			} else {
+				if (ni->ni_quiet_ie_set == 1)
+					ic->ic_set_quiet(ni, NULL);
+				ni->ni_quiet_ie_set = 0;
+				bzero(&ni->ni_quiet_ie,
+				    sizeof(struct ieee80211_quiet_ie));
+			}
 
 			if (scan.tim != NULL) {
 				struct ieee80211_tim_ie *tim =

Modified: head/sys/net80211/ieee80211_var.h
==============================================================================
--- head/sys/net80211/ieee80211_var.h	Thu Feb  9 02:08:42 2017	(r313461)
+++ head/sys/net80211/ieee80211_var.h	Thu Feb  9 04:07:30 2017	(r313462)
@@ -636,12 +636,13 @@ MALLOC_DECLARE(M_80211_VAP);
 #define	IEEE80211_FEXT_SEQNO_OFFLOAD	0x00100000	/* CONF: driver does seqno insertion/allocation */
 #define	IEEE80211_FEXT_FRAG_OFFLOAD	0x00200000	/* CONF: hardware does 802.11 fragmentation + assignment */
 #define	IEEE80211_FEXT_VHT	0x00400000	/* CONF: VHT support */
+#define	IEEE80211_FEXT_QUIET_IE	0x00800000	/* STATUS: quiet IE in a beacon has been added */
 
 #define	IEEE80211_FEXT_BITS \
 	"\20\2INACT\3SCANWAIT\4BGSCAN\5WPS\6TSN\7SCANREQ\10RESUME" \
 	"\0114ADDR\12NONEPR_PR\13SWBMISS\14DFS\15DOTD\16STATEWAIT\17REINIT" \
 	"\20BPF\21WDSLEGACY\22PROBECHAN\23UNIQMAC\24SCAN_OFFLOAD\25SEQNO_OFFLOAD" \
-	"\26VHT"
+	"\26VHT\27QUIET_IE"
 
 /* ic_flags_ht/iv_flags_ht */
 #define	IEEE80211_FHT_NONHT_PR	 0x00000001	/* STATUS: non-HT sta present */


More information about the svn-src-head mailing list