nl80211: Add support for EDMG channels

IEEE P802.11ay defines Enhanced Directional Multi-Gigabit (EDMG) STA and
AP which allow channel bonding of 2 channels and more.

nl80211 provides the driver's EDMG capabilities from the kernel
using two new attributes:
NL80211_BAND_ATTR_EDMG_CHANNELS - bitmap field that indicates the 2.16
GHz channel(s) that are supported by the driver.
NL80211_BAND_ATTR_EDMG_BW_CONFIG - represents the channel bandwidth
configurations supported by the driver.
The driver's EDMG capabilities are stored inside struct hostapd_hw_modes.

As part of the connect request and starting AP, EDMG parameters are
passed as part of struct hostapd_freq_params.

The EDMG parameters are sent to the kernel by using two new attributes:
NL80211_ATTR_WIPHY_EDMG_CHANNEL and NL80211_ATTR_WIPHY_EDMG_BW_CONFIG
which specify channel and bandwidth configuration for the driver to use.

This implementation is limited to CB2 (channel bonding of 2 channels)
and the bonded channels must be adjacent.

Signed-off-by: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
This commit is contained in:
Alexei Avshalom Lazar 2019-09-10 10:26:01 +03:00 committed by Jouni Malinen
parent a19913c170
commit dda5d9e315
3 changed files with 74 additions and 1 deletions

View file

@ -212,6 +212,24 @@ enum ieee80211_op_mode {
IEEE80211_MODE_NUM
};
/**
* struct ieee80211_edmg_config - EDMG configuration
*
* This structure describes most essential parameters needed
* for IEEE 802.11ay EDMG configuration
*
* @channels: Bitmap that indicates the 2.16 GHz channel(s)
* that are allowed to be used for transmissions.
* Bit 0 indicates channel 1, bit 1 indicates channel 2, etc.
* Set to 0 to indicate EDMG not supported.
* @bw_config: Channel BW Configuration subfield encodes
* the allowed channel bandwidth configurations
*/
struct ieee80211_edmg_config {
u8 channels;
enum edmg_bw_config bw_config;
};
/**
* struct hostapd_hw_modes - Supported hardware mode information
*/
@ -272,6 +290,12 @@ struct hostapd_hw_modes {
* he_capab - HE (IEEE 802.11ax) capabilities
*/
struct he_capabilities he_capab[IEEE80211_MODE_NUM];
/**
* This structure describes the most essential parameters needed
* for IEEE 802.11ay EDMG configuration.
*/
struct ieee80211_edmg_config edmg;
};
@ -744,6 +768,12 @@ struct hostapd_freq_params {
* bandwidth - Channel bandwidth in MHz (20, 40, 80, 160)
*/
int bandwidth;
/**
* This structure describes the most essential parameters needed
* for IEEE 802.11ay EDMG configuration.
*/
struct ieee80211_edmg_config edmg;
};
/**

View file

@ -4454,6 +4454,15 @@ static int nl80211_put_freq_params(struct nl_msg *msg,
wpa_printf(MSG_DEBUG, " * channel_type=%d", ct);
if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, ct))
return -ENOBUFS;
} else if (freq->edmg.channels && freq->edmg.bw_config) {
wpa_printf(MSG_DEBUG,
" * EDMG configuration: channels=0x%x bw_config=%d",
freq->edmg.channels, freq->edmg.bw_config);
if (nla_put_u8(msg, NL80211_ATTR_WIPHY_EDMG_CHANNELS,
freq->edmg.channels) ||
nla_put_u8(msg, NL80211_ATTR_WIPHY_EDMG_BW_CONFIG,
freq->edmg.bw_config))
return -1;
} else {
wpa_printf(MSG_DEBUG, " * channel_type=%d",
NL80211_CHAN_NO_HT);
@ -5533,6 +5542,18 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
return -1;
}
if (params->freq.edmg.channels && params->freq.edmg.bw_config) {
wpa_printf(MSG_DEBUG,
" * EDMG configuration: channels=0x%x bw_config=%d",
params->freq.edmg.channels,
params->freq.edmg.bw_config);
if (nla_put_u8(msg, NL80211_ATTR_WIPHY_EDMG_CHANNELS,
params->freq.edmg.channels) ||
nla_put_u8(msg, NL80211_ATTR_WIPHY_EDMG_BW_CONFIG,
params->freq.edmg.bw_config))
return -1;
}
if (params->bg_scan_period >= 0) {
wpa_printf(MSG_DEBUG, " * bg scan period=%d",
params->bg_scan_period);

View file

@ -1337,6 +1337,23 @@ static void phy_info_vht_capa(struct hostapd_hw_modes *mode,
}
static int phy_info_edmg_capa(struct hostapd_hw_modes *mode,
struct nlattr *bw_config,
struct nlattr *channels)
{
if (!bw_config || !channels)
return NL_OK;
mode->edmg.bw_config = nla_get_u8(bw_config);
mode->edmg.channels = nla_get_u8(channels);
if (!mode->edmg.channels || !mode->edmg.bw_config)
return NL_STOP;
return NL_OK;
}
static void phy_info_freq(struct hostapd_hw_modes *mode,
struct hostapd_channel_data *chan,
struct nlattr *tb_freq[])
@ -1694,7 +1711,12 @@ static int phy_info_band(struct phy_info_arg *phy_info, struct nlattr *nl_band)
tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
phy_info_vht_capa(mode, tb_band[NL80211_BAND_ATTR_VHT_CAPA],
tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]);
ret = phy_info_freqs(phy_info, mode, tb_band[NL80211_BAND_ATTR_FREQS]);
ret = phy_info_edmg_capa(mode,
tb_band[NL80211_BAND_ATTR_EDMG_BW_CONFIG],
tb_band[NL80211_BAND_ATTR_EDMG_CHANNELS]);
if (ret == NL_OK)
ret = phy_info_freqs(phy_info, mode,
tb_band[NL80211_BAND_ATTR_FREQS]);
if (ret == NL_OK)
ret = phy_info_rates(mode, tb_band[NL80211_BAND_ATTR_RATES]);
if (ret != NL_OK) {