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
This commit is contained in:
parent
3d8a0ab61d
commit
04e7bb08a5
@ -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) {
|
||||
|
@ -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 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.
|
||||
* 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[], int maxchans,
|
||||
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 maxchans, int *nchans,
|
||||
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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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 *,
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user