From owner-svn-src-all@freebsd.org Sun Oct 18 00:27:22 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 5F869445ED5; Sun, 18 Oct 2020 00:27:22 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CDLLf1RJ3z3XTX; Sun, 18 Oct 2020 00:27:22 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 0DF0A9FD3; Sun, 18 Oct 2020 00:27:22 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 09I0RLvQ043604; Sun, 18 Oct 2020 00:27:21 GMT (envelope-from bz@FreeBSD.org) Received: (from bz@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 09I0RKPL043599; Sun, 18 Oct 2020 00:27:20 GMT (envelope-from bz@FreeBSD.org) Message-Id: <202010180027.09I0RKPL043599@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bz set sender to bz@FreeBSD.org using -f From: "Bjoern A. Zeeb" Date: Sun, 18 Oct 2020 00:27:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r366800 - in head: sbin/ifconfig sys/net80211 X-SVN-Group: head X-SVN-Commit-Author: bz X-SVN-Commit-Paths: in head: sbin/ifconfig sys/net80211 X-SVN-Commit-Revision: 366800 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 18 Oct 2020 00:27:22 -0000 Author: bz Date: Sun Oct 18 00:27:20 2020 New Revision: 366800 URL: https://svnweb.freebsd.org/changeset/base/366800 Log: net80211: update for (more) VHT160 support Implement two macros IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160MHZ() and its 80+80 counter part to check in vhtcaps for appropriate levels of support and use the macros throughout the code. Add vht160_chan_ranges/is_vht160_valid_freq and handle analogue to vht80 in various parts of the code. Add ieee80211_add_channel_cbw() which also takes the CBW flag fields and make the former ieee80211_add_channel() a wrapper to it. With the CBW flags we can add HT/VHT channels passing them to getflags() for the 2/5ghz functions. In ifconfig(8) add the regdomain_addchans() support for VHT160 and VHT80P80. With this (+ regdoain.xml updates) VHT160 channels can be configured, listed, and pass regdomain where appropriate. Tested with: iwlwifi Reviewed by: adrian MFC after: 10 days Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D26712 Modified: head/sbin/ifconfig/ifieee80211.c head/sys/net80211/ieee80211.c head/sys/net80211/ieee80211.h head/sys/net80211/ieee80211_regdomain.c head/sys/net80211/ieee80211_var.h head/sys/net80211/ieee80211_vht.c Modified: head/sbin/ifconfig/ifieee80211.c ============================================================================== --- head/sbin/ifconfig/ifieee80211.c Sat Oct 17 23:42:33 2020 (r366799) +++ head/sbin/ifconfig/ifieee80211.c Sun Oct 18 00:27:20 2020 (r366800) @@ -2405,7 +2405,31 @@ regdomain_makechannels( &dc->dc_chaninfo); } - /* XXX TODO: VHT80P80, VHT160 */ + /* VHT160 */ + if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160MHZ( + dc->dc_vhtcaps)) { + regdomain_addchans(ci, &rd->bands_11ac, reg, + IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U | + IEEE80211_CHAN_VHT160, + &dc->dc_chaninfo); + regdomain_addchans(ci, &rd->bands_11ac, reg, + IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D | + IEEE80211_CHAN_VHT160, + &dc->dc_chaninfo); + } + + /* VHT80P80 */ + if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160_80P80MHZ( + dc->dc_vhtcaps)) { + regdomain_addchans(ci, &rd->bands_11ac, reg, + IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U | + IEEE80211_CHAN_VHT80P80, + &dc->dc_chaninfo); + regdomain_addchans(ci, &rd->bands_11ac, reg, + IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D | + IEEE80211_CHAN_VHT80P80, + &dc->dc_chaninfo); + } } if (!LIST_EMPTY(&rd->bands_11ng) && dc->dc_htcaps != 0) { Modified: head/sys/net80211/ieee80211.c ============================================================================== --- head/sys/net80211/ieee80211.c Sat Oct 17 23:42:33 2020 (r366799) +++ head/sys/net80211/ieee80211.c Sun Oct 18 00:27:20 2020 (r366800) @@ -1163,6 +1163,12 @@ struct vht_chan_range vht80_chan_ranges[] = { { 0, 0 } }; +struct vht_chan_range vht160_chan_ranges[] = { + { 5170, 5330 }, + { 5490, 5650 }, + { 0, 0 } +}; + static int set_vht_extchan(struct ieee80211_channel *c) { @@ -1177,8 +1183,24 @@ set_vht_extchan(struct ieee80211_channel *c) } if (IEEE80211_IS_CHAN_VHT160(c)) { - printf("%s: TODO VHT160 channel (ieee=%d, flags=0x%08x)\n", - __func__, c->ic_ieee, c->ic_flags); + for (i = 0; vht160_chan_ranges[i].freq_start != 0; i++) { + if (c->ic_freq >= vht160_chan_ranges[i].freq_start && + c->ic_freq < vht160_chan_ranges[i].freq_end) { + int midpoint; + + midpoint = vht160_chan_ranges[i].freq_start + 80; + c->ic_vht_ch_freq1 = + ieee80211_mhz2ieee(midpoint, c->ic_flags); + c->ic_vht_ch_freq2 = 0; +#if 0 + printf("%s: %d, freq=%d, midpoint=%d, freq1=%d, freq2=%d\n", + __func__, c->ic_ieee, c->ic_freq, midpoint, + c->ic_vht_ch_freq1, c->ic_vht_ch_freq2); +#endif + return (1); + } + } + return (0); } if (IEEE80211_IS_CHAN_VHT80(c)) { @@ -1225,11 +1247,24 @@ set_vht_extchan(struct ieee80211_channel *c) /* * Return whether the current channel could possibly be a part of - * a VHT80 channel. + * a VHT80/VHT160 channel. * * This doesn't check that the whole range is in the allowed list * according to regulatory. */ +static bool +is_vht160_valid_freq(uint16_t freq) +{ + int i; + + for (i = 0; vht160_chan_ranges[i].freq_start != 0; i++) { + if (freq >= vht160_chan_ranges[i].freq_start && + freq < vht160_chan_ranges[i].freq_end) + return (true); + } + return (false); +} + static int is_vht80_valid_freq(uint16_t freq) { @@ -1410,18 +1445,17 @@ getflags(const uint8_t bands[], uint32_t flags[], int * Add one 20 MHz channel into specified channel list. * You MUST NOT mix bands when calling this. It will not add 5ghz * channels if you have any B/G/N band bit set. - * This also does not support 40/80/160/80+80. + * The _cbw() variant does also support HT40/VHT80/160/80+80. */ -/* XXX VHT */ int -ieee80211_add_channel(struct ieee80211_channel chans[], int maxchans, +ieee80211_add_channel_cbw(struct ieee80211_channel chans[], int maxchans, int *nchans, uint8_t ieee, uint16_t freq, int8_t maxregpower, - uint32_t chan_flags, const uint8_t bands[]) + uint32_t chan_flags, const uint8_t bands[], int cbw_flags) { uint32_t flags[IEEE80211_MODE_MAX]; int i, error; - getflags(bands, flags, 0); + getflags(bands, flags, cbw_flags); KASSERT(flags[0] != 0, ("%s: no correct mode provided\n", __func__)); error = addchan(chans, maxchans, nchans, ieee, freq, maxregpower, @@ -1434,6 +1468,16 @@ ieee80211_add_channel(struct ieee80211_channel chans[] return (error); } +int +ieee80211_add_channel(struct ieee80211_channel chans[], int maxchans, + int *nchans, uint8_t ieee, uint16_t freq, int8_t maxregpower, + uint32_t chan_flags, const uint8_t bands[]) +{ + + return (ieee80211_add_channel_cbw(chans, maxchans, nchans, ieee, freq, + maxregpower, chan_flags, bands, 0)); +} + static struct ieee80211_channel * findchannel(struct ieee80211_channel chans[], int nchans, uint16_t freq, uint32_t flags) @@ -1573,7 +1617,11 @@ add_chanlist(struct ieee80211_channel chans[], int max is_vht = !! (flags[j] & IEEE80211_CHAN_VHT); /* XXX TODO FIXME VHT80P80. */ - /* XXX TODO FIXME VHT160. */ + + /* Test for VHT160 analogue to the VHT80 below. */ + if (is_vht && flags[j] & IEEE80211_CHAN_VHT160) + if (! is_vht160_valid_freq(freq)) + continue; /* * Test for VHT80. Modified: head/sys/net80211/ieee80211.h ============================================================================== --- head/sys/net80211/ieee80211.h Sat Oct 17 23:42:33 2020 (r366799) +++ head/sys/net80211/ieee80211.h Sun Oct 18 00:27:20 2020 (r366800) @@ -815,6 +815,13 @@ struct ieee80211_ie_vht_operation { #define IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160_80P80MHZ 2 #define IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_RESERVED 3 +#define IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160MHZ(_vhtcaps) \ + (_IEEE80211_MASKSHIFT(_vhtcaps, IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK) >= \ + IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160MHZ) +#define IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160_80P80MHZ(_vhtcaps) \ + (_IEEE80211_MASKSHIFT(_vhtcaps, IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK) == \ + IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160_80P80MHZ) + #define IEEE80211_VHTCAP_RXLDPC 0x00000010 #define IEEE80211_VHTCAP_RXLDPC_S 4 Modified: head/sys/net80211/ieee80211_regdomain.c ============================================================================== --- head/sys/net80211/ieee80211_regdomain.c Sat Oct 17 23:42:33 2020 (r366799) +++ head/sys/net80211/ieee80211_regdomain.c Sun Oct 18 00:27:20 2020 (r366800) @@ -151,11 +151,10 @@ ieee80211_init_channels(struct ieee80211com *ic, if (isset(bands, IEEE80211_MODE_VHT_5GHZ)) { cbw_flags |= NET80211_CBW_FLAG_HT40; /* Make sure this is set; or assert? */ cbw_flags |= NET80211_CBW_FLAG_VHT80; - if (_IEEE80211_MASKSHIFT(ic->ic_vhtcaps, - IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK) >= 1) + if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160MHZ(ic->ic_vhtcaps)) cbw_flags |= NET80211_CBW_FLAG_VHT160; - if (_IEEE80211_MASKSHIFT(ic->ic_vhtcaps, - IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK) == 2) + if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160_80P80MHZ( + ic->ic_vhtcaps)) cbw_flags |= NET80211_CBW_FLAG_VHT80P80; ieee80211_add_channel_list_5ghz(chans, IEEE80211_CHAN_MAX, nchans, def_chan_5ghz_band1, nitems(def_chan_5ghz_band1), Modified: head/sys/net80211/ieee80211_var.h ============================================================================== --- head/sys/net80211/ieee80211_var.h Sat Oct 17 23:42:33 2020 (r366799) +++ head/sys/net80211/ieee80211_var.h Sun Oct 18 00:27:20 2020 (r366800) @@ -772,6 +772,8 @@ int ieee80211_mhz2ieee(u_int, u_int); int ieee80211_chan2ieee(struct ieee80211com *, const struct ieee80211_channel *); u_int ieee80211_ieee2mhz(u_int, u_int); +int ieee80211_add_channel_cbw(struct ieee80211_channel[], int, int *, + uint8_t, uint16_t, int8_t, uint32_t, const uint8_t[], int); int ieee80211_add_channel(struct ieee80211_channel[], int, int *, uint8_t, uint16_t, int8_t, uint32_t, const uint8_t[]); int ieee80211_add_channel_ht40(struct ieee80211_channel[], int, int *, Modified: head/sys/net80211/ieee80211_vht.c ============================================================================== --- head/sys/net80211/ieee80211_vht.c Sat Oct 17 23:42:33 2020 (r366799) +++ head/sys/net80211/ieee80211_vht.c Sun Oct 18 00:27:20 2020 (r366800) @@ -153,13 +153,10 @@ ieee80211_vht_vattach(struct ieee80211vap *vap) IEEE80211_FVHT_VHT | IEEE80211_FVHT_USEVHT40 | IEEE80211_FVHT_USEVHT80; -#if 0 - /* XXX TODO: enable VHT80+80, VHT160 capabilities */ - if (XXX TODO FIXME) + if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160MHZ(vap->iv_vhtcaps)) vap->iv_flags_vht |= IEEE80211_FVHT_USEVHT160; - if (XXX TODO FIXME) + if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160_80P80MHZ(vap->iv_vhtcaps)) vap->iv_flags_vht |= IEEE80211_FVHT_USEVHT80P80; -#endif memcpy(&vap->iv_vht_mcsinfo, &ic->ic_vht_mcsinfo, sizeof(struct ieee80211_vht_mcs_info)); @@ -202,15 +199,11 @@ ieee80211_vht_announce(struct ieee80211com *ic) return; /* Channel width */ - ic_printf(ic, "[VHT] Channel Widths: 20MHz, 40MHz, 80MHz"); - if (_IEEE80211_MASKSHIFT(ic->ic_vhtcaps, - IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK) >= 1) - printf(" 160MHz"); - if (_IEEE80211_MASKSHIFT(ic->ic_vhtcaps, - IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK) == 2) - printf(" 80+80MHz"); - printf("\n"); - + ic_printf(ic, "[VHT] Channel Widths: 20MHz, 40MHz, 80MHz%s%s\n", + (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160MHZ(ic->ic_vhtcaps)) ? + ", 160MHz" : "", + (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160_80P80MHZ(ic->ic_vhtcaps)) ? + ", 80+80MHz" : ""); /* Features */ ic_printf(ic, "[VHT] Features: %b\n", ic->ic_vhtcaps, IEEE80211_VHTCAP_BITS);