From owner-svn-src-all@freebsd.org Mon Aug 24 13:15:10 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 3BCDC3BF4BF; Mon, 24 Aug 2020 13:15:10 +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 4BZszy0vXNz4mcC; Mon, 24 Aug 2020 13:15:10 +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 DE16A19299; Mon, 24 Aug 2020 13:15:09 +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 07ODF9m5054925; Mon, 24 Aug 2020 13:15:09 GMT (envelope-from bz@FreeBSD.org) Received: (from bz@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 07ODF9BZ054921; Mon, 24 Aug 2020 13:15:09 GMT (envelope-from bz@FreeBSD.org) Message-Id: <202008241315.07ODF9BZ054921@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bz set sender to bz@FreeBSD.org using -f From: "Bjoern A. Zeeb" Date: Mon, 24 Aug 2020 13:15:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r364673 - in head/sys: dev/rtwn dev/usb/wlan net80211 X-SVN-Group: head X-SVN-Commit-Author: bz X-SVN-Commit-Paths: in head/sys: dev/rtwn dev/usb/wlan net80211 X-SVN-Commit-Revision: 364673 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: Mon, 24 Aug 2020 13:15:10 -0000 Author: bz Date: Mon Aug 24 13:15:08 2020 New Revision: 364673 URL: https://svnweb.freebsd.org/changeset/base/364673 Log: net80211: enhance getflags*() and ieee80211_add_channel*() For ieee80211_add_channel+*() we are passing in an int flag for ht40 and in some cases another int flag for vht80 where we'd only need two bits really. Convert these variables to a bitflag and fold them together into one. This also allows for VHT160 and VHT80P80 and whatever may come to be considered. Define the various options currently needed. Change the drivers (rtwn and rsu) which actually set this bit to non-0. For convenience the "1" currently used for HT40 is preserved. Enahnce getflags_5ghz() to handle the full set of VHT flags based on the input flags from the the driver. Update the regdomain implementation as well to make use of the new flags and deal with higher [V]HT bandwidths. ieee80211_add_channel() specifically did not take flags so it will not support naything beyond 20Mhz channels. Note: I am not entirely happy with the "cbw_flag[s]" name, but we do use chan_flags elsewhere already. MFC after: 2 weeks Reviewed by: adrian, gnn Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate") Differential revision: https://reviews.freebsd.org/D26091 Modified: head/sys/dev/rtwn/if_rtwn.c head/sys/dev/usb/wlan/if_rsu.c head/sys/net80211/ieee80211.c head/sys/net80211/ieee80211_regdomain.c head/sys/net80211/ieee80211_var.h Modified: head/sys/dev/rtwn/if_rtwn.c ============================================================================== --- head/sys/dev/rtwn/if_rtwn.c Mon Aug 24 13:14:38 2020 (r364672) +++ head/sys/dev/rtwn/if_rtwn.c Mon Aug 24 13:15:08 2020 (r364673) @@ -1525,25 +1525,29 @@ rtwn_getradiocaps(struct ieee80211com *ic, { struct rtwn_softc *sc = ic->ic_softc; uint8_t bands[IEEE80211_MODE_BYTES]; - int i; + int cbw_flags, i; + cbw_flags = (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) ? + NET80211_CBW_FLAG_HT40 : 0; + memset(bands, 0, sizeof(bands)); setbit(bands, IEEE80211_MODE_11B); setbit(bands, IEEE80211_MODE_11G); setbit(bands, IEEE80211_MODE_11NG); ieee80211_add_channels_default_2ghz(chans, maxchans, nchans, - bands, !!(ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40)); + bands, cbw_flags); /* XXX workaround add_channel_list() limitations */ setbit(bands, IEEE80211_MODE_11A); setbit(bands, IEEE80211_MODE_11NA); for (i = 0; i < nitems(sc->chan_num_5ghz); i++) { + if (sc->chan_num_5ghz[i] == 0) continue; ieee80211_add_channel_list_5ghz(chans, maxchans, nchans, sc->chan_list_5ghz[i], sc->chan_num_5ghz[i], bands, - !!(ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40)); + cbw_flags); } } Modified: head/sys/dev/usb/wlan/if_rsu.c ============================================================================== --- head/sys/dev/usb/wlan/if_rsu.c Mon Aug 24 13:14:38 2020 (r364672) +++ head/sys/dev/usb/wlan/if_rsu.c Mon Aug 24 13:15:08 2020 (r364673) @@ -779,7 +779,8 @@ rsu_getradiocaps(struct ieee80211com *ic, if (sc->sc_ht) setbit(bands, IEEE80211_MODE_11NG); ieee80211_add_channels_default_2ghz(chans, maxchans, nchans, - bands, (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) != 0); + bands, (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) ? + NET80211_CBW_FLAG_HT40 : 0); } static void Modified: head/sys/net80211/ieee80211.c ============================================================================== --- head/sys/net80211/ieee80211.c Mon Aug 24 13:14:38 2020 (r364672) +++ head/sys/net80211/ieee80211.c Mon Aug 24 13:15:08 2020 (r364673) @@ -1301,7 +1301,7 @@ copychan_prev(struct ieee80211_channel chans[], int ma * XXX VHT-2GHz */ static void -getflags_2ghz(const uint8_t bands[], uint32_t flags[], int ht40) +getflags_2ghz(const uint8_t bands[], uint32_t flags[], int cbw_flags) { int nmodes; @@ -1312,7 +1312,7 @@ getflags_2ghz(const uint8_t bands[], uint32_t flags[], flags[nmodes++] = IEEE80211_CHAN_G; if (isset(bands, IEEE80211_MODE_11NG)) flags[nmodes++] = IEEE80211_CHAN_G | IEEE80211_CHAN_HT20; - if (ht40) { + if (cbw_flags & NET80211_CBW_FLAG_HT40) { flags[nmodes++] = IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U; flags[nmodes++] = IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D; } @@ -1320,12 +1320,12 @@ getflags_2ghz(const uint8_t bands[], uint32_t flags[], } static void -getflags_5ghz(const uint8_t bands[], uint32_t flags[], int ht40, int vht80) +getflags_5ghz(const uint8_t bands[], uint32_t flags[], int cbw_flags) { int nmodes; /* - * the addchan_list function seems to expect the flags array to + * The addchan_list() function seems to expect the flags array to * be in channel width order, so the VHT bits are interspersed * as appropriate to maintain said order. * @@ -1344,36 +1344,51 @@ getflags_5ghz(const uint8_t bands[], uint32_t flags[], } /* 40MHz */ - if (ht40) { + if (cbw_flags & NET80211_CBW_FLAG_HT40) flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U; - } - if (ht40 && isset(bands, IEEE80211_MODE_VHT_5GHZ)) { - flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U - | IEEE80211_CHAN_VHT40U; - } - if (ht40) { + if ((cbw_flags & NET80211_CBW_FLAG_HT40) && + isset(bands, IEEE80211_MODE_VHT_5GHZ)) + flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U | + IEEE80211_CHAN_VHT40U; + if (cbw_flags & NET80211_CBW_FLAG_HT40) flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D; + if ((cbw_flags & NET80211_CBW_FLAG_HT40) && + isset(bands, IEEE80211_MODE_VHT_5GHZ)) + flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D | + IEEE80211_CHAN_VHT40D; + + /* 80MHz */ + if ((cbw_flags & NET80211_CBW_FLAG_VHT80) && + isset(bands, IEEE80211_MODE_VHT_5GHZ)) { + flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U | + IEEE80211_CHAN_VHT80; + flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D | + IEEE80211_CHAN_VHT80; } - if (ht40 && isset(bands, IEEE80211_MODE_VHT_5GHZ)) { - flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D - | IEEE80211_CHAN_VHT40D; + + /* VHT160 */ + if ((cbw_flags & NET80211_CBW_FLAG_VHT160) && + isset(bands, IEEE80211_MODE_VHT_5GHZ)) { + flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U | + IEEE80211_CHAN_VHT160; + flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D | + IEEE80211_CHAN_VHT160; } - /* 80MHz */ - if (vht80 && isset(bands, IEEE80211_MODE_VHT_5GHZ)) { - flags[nmodes++] = IEEE80211_CHAN_A | - IEEE80211_CHAN_HT40U | IEEE80211_CHAN_VHT80; - flags[nmodes++] = IEEE80211_CHAN_A | - IEEE80211_CHAN_HT40D | IEEE80211_CHAN_VHT80; + /* VHT80+80 */ + if ((cbw_flags & NET80211_CBW_FLAG_VHT80P80) && + isset(bands, IEEE80211_MODE_VHT_5GHZ)) { + flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U | + IEEE80211_CHAN_VHT80P80; + flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D | + IEEE80211_CHAN_VHT80P80; } - /* XXX VHT160 */ - /* XXX VHT80+80 */ flags[nmodes] = 0; } static void -getflags(const uint8_t bands[], uint32_t flags[], int ht40, int vht80) +getflags(const uint8_t bands[], uint32_t flags[], int cbw_flags) { flags[0] = 0; @@ -1386,15 +1401,16 @@ getflags(const uint8_t bands[], uint32_t flags[], int isset(bands, IEEE80211_MODE_VHT_2GHZ)) return; - getflags_5ghz(bands, flags, ht40, vht80); + getflags_5ghz(bands, flags, cbw_flags); } else - getflags_2ghz(bands, flags, ht40); + getflags_2ghz(bands, flags, cbw_flags); } /* * 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. */ /* XXX VHT */ int @@ -1405,7 +1421,7 @@ ieee80211_add_channel(struct ieee80211_channel chans[] uint32_t flags[IEEE80211_MODE_MAX]; int i, error; - getflags(bands, flags, 0, 0); + getflags(bands, flags, 0); KASSERT(flags[0] != 0, ("%s: no correct mode provided\n", __func__)); error = addchan(chans, maxchans, nchans, ieee, freq, maxregpower, @@ -1632,12 +1648,12 @@ add_chanlist(struct ieee80211_channel chans[], int max int ieee80211_add_channel_list_2ghz(struct ieee80211_channel chans[], int maxchans, int *nchans, const uint8_t ieee[], int nieee, const uint8_t bands[], - int ht40) + int cbw_flags) { uint32_t flags[IEEE80211_MODE_MAX]; /* XXX no VHT for now */ - getflags_2ghz(bands, flags, ht40); + getflags_2ghz(bands, flags, cbw_flags); KASSERT(flags[0] != 0, ("%s: no correct mode provided\n", __func__)); return (add_chanlist(chans, maxchans, nchans, ieee, nieee, flags)); @@ -1645,30 +1661,27 @@ ieee80211_add_channel_list_2ghz(struct ieee80211_chann int ieee80211_add_channels_default_2ghz(struct ieee80211_channel chans[], - int maxchans, int *nchans, const uint8_t bands[], int ht40) + int maxchans, int *nchans, const uint8_t bands[], int cbw_flags) { const uint8_t default_chan_list[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; return (ieee80211_add_channel_list_2ghz(chans, maxchans, nchans, - default_chan_list, nitems(default_chan_list), bands, ht40)); + default_chan_list, nitems(default_chan_list), bands, cbw_flags)); } int ieee80211_add_channel_list_5ghz(struct ieee80211_channel chans[], int maxchans, int *nchans, const uint8_t ieee[], int nieee, const uint8_t bands[], - int ht40) + int cbw_flags) { - uint32_t flags[IEEE80211_MODE_MAX]; - int vht80 = 0; - /* - * For now, assume VHT == VHT80 support as a minimum. + * XXX-BZ with HT and VHT there is no 1:1 mapping anymore. Review all + * uses of IEEE80211_MODE_MAX and add a new #define name for array size. */ - if (isset(bands, IEEE80211_MODE_VHT_5GHZ)) - vht80 = 1; + uint32_t flags[2 * IEEE80211_MODE_MAX]; - getflags_5ghz(bands, flags, ht40, vht80); + getflags_5ghz(bands, flags, cbw_flags); KASSERT(flags[0] != 0, ("%s: no correct mode provided\n", __func__)); return (add_chanlist(chans, maxchans, nchans, ieee, nieee, flags)); Modified: head/sys/net80211/ieee80211_regdomain.c ============================================================================== --- head/sys/net80211/ieee80211_regdomain.c Mon Aug 24 13:14:38 2020 (r364672) +++ head/sys/net80211/ieee80211_regdomain.c Mon Aug 24 13:15:08 2020 (r364673) @@ -118,10 +118,11 @@ ieee80211_init_channels(struct ieee80211com *ic, { struct ieee80211_channel *chans = ic->ic_channels; int *nchans = &ic->ic_nchans; - int ht40; + int cbw_flags; /* XXX just do something for now */ - ht40 = !!(ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40); + cbw_flags = (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) ? + NET80211_CBW_FLAG_HT40 : 0; *nchans = 0; if (isset(bands, IEEE80211_MODE_11B) || isset(bands, IEEE80211_MODE_11G) || @@ -131,19 +132,40 @@ ieee80211_init_channels(struct ieee80211com *ic, nchan -= 3; ieee80211_add_channel_list_2ghz(chans, IEEE80211_CHAN_MAX, - nchans, def_chan_2ghz, nchan, bands, ht40); + nchans, def_chan_2ghz, nchan, bands, cbw_flags); } + /* XXX IEEE80211_MODE_VHT_2GHZ if we really want to. */ + if (isset(bands, IEEE80211_MODE_11A) || isset(bands, IEEE80211_MODE_11NA)) { ieee80211_add_channel_list_5ghz(chans, IEEE80211_CHAN_MAX, nchans, def_chan_5ghz_band1, nitems(def_chan_5ghz_band1), - bands, ht40); + bands, cbw_flags); ieee80211_add_channel_list_5ghz(chans, IEEE80211_CHAN_MAX, nchans, def_chan_5ghz_band2, nitems(def_chan_5ghz_band2), - bands, ht40); + bands, cbw_flags); ieee80211_add_channel_list_5ghz(chans, IEEE80211_CHAN_MAX, nchans, def_chan_5ghz_band3, nitems(def_chan_5ghz_band3), - bands, ht40); + bands, cbw_flags); + } + 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; +#define MS(_v, _f) (((_v) & _f) >> _f##_S) + if (MS(ic->ic_vhtcaps, IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK) >= 1) + cbw_flags |= NET80211_CBW_FLAG_VHT160; + if (MS(ic->ic_vhtcaps, IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK) == 2) + cbw_flags |= NET80211_CBW_FLAG_VHT80P80; +#undef MS + ieee80211_add_channel_list_5ghz(chans, IEEE80211_CHAN_MAX, + nchans, def_chan_5ghz_band1, nitems(def_chan_5ghz_band1), + bands, cbw_flags); + ieee80211_add_channel_list_5ghz(chans, IEEE80211_CHAN_MAX, + nchans, def_chan_5ghz_band2, nitems(def_chan_5ghz_band2), + bands, cbw_flags); + ieee80211_add_channel_list_5ghz(chans, IEEE80211_CHAN_MAX, + nchans, def_chan_5ghz_band3, nitems(def_chan_5ghz_band3), + bands, cbw_flags); } if (rd != NULL) ic->ic_regdomain = *rd; Modified: head/sys/net80211/ieee80211_var.h ============================================================================== --- head/sys/net80211/ieee80211_var.h Mon Aug 24 13:14:38 2020 (r364672) +++ head/sys/net80211/ieee80211_var.h Mon Aug 24 13:15:08 2020 (r364673) @@ -779,6 +779,10 @@ int ieee80211_add_channel_ht40(struct ieee80211_channe uint32_t ieee80211_get_channel_center_freq(const struct ieee80211_channel *); uint32_t ieee80211_get_channel_center_freq1(const struct ieee80211_channel *); uint32_t ieee80211_get_channel_center_freq2(const struct ieee80211_channel *); +#define NET80211_CBW_FLAG_HT40 0x01 +#define NET80211_CBW_FLAG_VHT80 0x02 +#define NET80211_CBW_FLAG_VHT160 0x04 +#define NET80211_CBW_FLAG_VHT80P80 0x08 int ieee80211_add_channel_list_2ghz(struct ieee80211_channel[], int, int *, const uint8_t[], int, const uint8_t[], int); int ieee80211_add_channels_default_2ghz(struct ieee80211_channel[], int,