Date: Thu, 9 Feb 2017 04:07:30 +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: r313462 - head/sys/net80211 Message-ID: <201702090407.v1947UFx040073@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201702090407.v1947UFx040073>