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:
parent
a19913c170
commit
dda5d9e315
3 changed files with 74 additions and 1 deletions
|
@ -212,6 +212,24 @@ enum ieee80211_op_mode {
|
||||||
IEEE80211_MODE_NUM
|
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
|
* struct hostapd_hw_modes - Supported hardware mode information
|
||||||
*/
|
*/
|
||||||
|
@ -272,6 +290,12 @@ struct hostapd_hw_modes {
|
||||||
* he_capab - HE (IEEE 802.11ax) capabilities
|
* he_capab - HE (IEEE 802.11ax) capabilities
|
||||||
*/
|
*/
|
||||||
struct he_capabilities he_capab[IEEE80211_MODE_NUM];
|
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)
|
* bandwidth - Channel bandwidth in MHz (20, 40, 80, 160)
|
||||||
*/
|
*/
|
||||||
int bandwidth;
|
int bandwidth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure describes the most essential parameters needed
|
||||||
|
* for IEEE 802.11ay EDMG configuration.
|
||||||
|
*/
|
||||||
|
struct ieee80211_edmg_config edmg;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4454,6 +4454,15 @@ static int nl80211_put_freq_params(struct nl_msg *msg,
|
||||||
wpa_printf(MSG_DEBUG, " * channel_type=%d", ct);
|
wpa_printf(MSG_DEBUG, " * channel_type=%d", ct);
|
||||||
if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, ct))
|
if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, ct))
|
||||||
return -ENOBUFS;
|
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 {
|
} else {
|
||||||
wpa_printf(MSG_DEBUG, " * channel_type=%d",
|
wpa_printf(MSG_DEBUG, " * channel_type=%d",
|
||||||
NL80211_CHAN_NO_HT);
|
NL80211_CHAN_NO_HT);
|
||||||
|
@ -5533,6 +5542,18 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
|
||||||
return -1;
|
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) {
|
if (params->bg_scan_period >= 0) {
|
||||||
wpa_printf(MSG_DEBUG, " * bg scan period=%d",
|
wpa_printf(MSG_DEBUG, " * bg scan period=%d",
|
||||||
params->bg_scan_period);
|
params->bg_scan_period);
|
||||||
|
|
|
@ -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,
|
static void phy_info_freq(struct hostapd_hw_modes *mode,
|
||||||
struct hostapd_channel_data *chan,
|
struct hostapd_channel_data *chan,
|
||||||
struct nlattr *tb_freq[])
|
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]);
|
tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
|
||||||
phy_info_vht_capa(mode, tb_band[NL80211_BAND_ATTR_VHT_CAPA],
|
phy_info_vht_capa(mode, tb_band[NL80211_BAND_ATTR_VHT_CAPA],
|
||||||
tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]);
|
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)
|
if (ret == NL_OK)
|
||||||
ret = phy_info_rates(mode, tb_band[NL80211_BAND_ATTR_RATES]);
|
ret = phy_info_rates(mode, tb_band[NL80211_BAND_ATTR_RATES]);
|
||||||
if (ret != NL_OK) {
|
if (ret != NL_OK) {
|
||||||
|
|
Loading…
Reference in a new issue