]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Add support for EDMG channels
authorAlexei Avshalom Lazar <ailizaro@codeaurora.org>
Tue, 10 Sep 2019 07:26:01 +0000 (10:26 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 7 Oct 2019 13:06:04 +0000 (16:06 +0300)
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>
src/drivers/driver.h
src/drivers/driver_nl80211.c
src/drivers/driver_nl80211_capa.c

index e9d0e47282306070822d4f560d6bceb5b4a3b08c..7b0522d385fe9b7e8616942ffff7eefcb1aad234 100644 (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;
 };
 
 /**
index b8aa0a0e624bab70caa7f8d8a10d48dfe4e5706c..56810a7f13326b4f718360c94cbd6867f2e1d94f 100644 (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);
index 8318b10ab9e7846e7f36996a5a9b9865ec671238..cd9693c908d221ee7a207051039eefcdaaa2c2e8 100644 (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) {