From dda5d9e315afb925b18cf0084b9fb205d0c10773 Mon Sep 17 00:00:00 2001 From: Alexei Avshalom Lazar Date: Tue, 10 Sep 2019 10:26:01 +0300 Subject: [PATCH] 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 --- src/drivers/driver.h | 30 ++++++++++++++++++++++++++++++ src/drivers/driver_nl80211.c | 21 +++++++++++++++++++++ src/drivers/driver_nl80211_capa.c | 24 +++++++++++++++++++++++- 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index e9d0e4728..7b0522d38 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -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; }; /** diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index b8aa0a0e6..56810a7f1 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -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); diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c index 8318b10ab..cd9693c90 100644 --- a/src/drivers/driver_nl80211_capa.c +++ b/src/drivers/driver_nl80211_capa.c @@ -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) {