[PATCH 06/50] driver_nl80211: Support setting up an AP on a specified link
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Wed Feb 15 15:08:20 PST 2023
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
src/drivers/driver_nl80211.c | 258 ++++++++++++++++++++---------------
1 file changed, 147 insertions(+), 111 deletions(-)
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index ea7d8bdf44..282b61b673 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -4711,11 +4711,118 @@ static int nl80211_mbssid(struct nl_msg *msg,
#endif /* CONFIG_IEEE80211AX */
+static int nl80211_put_freq_params(struct nl_msg *msg,
+ const struct hostapd_freq_params *freq)
+{
+ enum hostapd_hw_mode hw_mode;
+ int is_24ghz;
+ u8 channel;
+
+ wpa_printf(MSG_DEBUG, " * freq=%d", freq->freq);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq))
+ return -ENOBUFS;
+
+ wpa_printf(MSG_DEBUG, " * eht_enabled=%d", freq->eht_enabled);
+ wpa_printf(MSG_DEBUG, " * he_enabled=%d", freq->he_enabled);
+ wpa_printf(MSG_DEBUG, " * vht_enabled=%d", freq->vht_enabled);
+ wpa_printf(MSG_DEBUG, " * ht_enabled=%d", freq->ht_enabled);
+ wpa_printf(MSG_DEBUG, " * radar_background=%d",
+ freq->radar_background);
+
+ hw_mode = ieee80211_freq_to_chan(freq->freq, &channel);
+ is_24ghz = hw_mode == HOSTAPD_MODE_IEEE80211G ||
+ hw_mode == HOSTAPD_MODE_IEEE80211B;
+
+ if (freq->vht_enabled ||
+ ((freq->he_enabled || freq->eht_enabled) && !is_24ghz)) {
+ enum nl80211_chan_width cw;
+
+ wpa_printf(MSG_DEBUG, " * bandwidth=%d", freq->bandwidth);
+ switch (freq->bandwidth) {
+ case 20:
+ cw = NL80211_CHAN_WIDTH_20;
+ break;
+ case 40:
+ cw = NL80211_CHAN_WIDTH_40;
+ break;
+ case 80:
+ if (freq->center_freq2)
+ cw = NL80211_CHAN_WIDTH_80P80;
+ else
+ cw = NL80211_CHAN_WIDTH_80;
+ break;
+ case 160:
+ cw = NL80211_CHAN_WIDTH_160;
+ break;
+ case 320:
+ cw = NL80211_CHAN_WIDTH_320;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ wpa_printf(MSG_DEBUG, " * channel_width=%d", cw);
+ wpa_printf(MSG_DEBUG, " * center_freq1=%d",
+ freq->center_freq1);
+ wpa_printf(MSG_DEBUG, " * center_freq2=%d",
+ freq->center_freq2);
+ if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, cw) ||
+ nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1,
+ freq->center_freq1) ||
+ (freq->center_freq2 &&
+ nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2,
+ freq->center_freq2)))
+ return -ENOBUFS;
+ } else if (freq->ht_enabled) {
+ enum nl80211_channel_type ct;
+
+ wpa_printf(MSG_DEBUG, " * sec_channel_offset=%d",
+ freq->sec_channel_offset);
+ switch (freq->sec_channel_offset) {
+ case -1:
+ ct = NL80211_CHAN_HT40MINUS;
+ break;
+ case 1:
+ ct = NL80211_CHAN_HT40PLUS;
+ break;
+ default:
+ ct = NL80211_CHAN_HT20;
+ break;
+ }
+
+ 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);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
+ NL80211_CHAN_NO_HT))
+ return -ENOBUFS;
+ }
+ if (freq->radar_background &&
+ nla_put_flag(msg, NL80211_ATTR_RADAR_BACKGROUND))
+ return -ENOBUFS;
+
+ return 0;
+}
+
+
static int wpa_driver_nl80211_set_ap(void *priv,
struct wpa_driver_ap_params *params)
{
struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct i802_link *link = bss->flink;
struct nl_msg *msg;
u8 cmd = NL80211_CMD_NEW_BEACON;
int ret = -ENOBUFS;
@@ -4727,10 +4834,27 @@ static int wpa_driver_nl80211_set_ap(void *priv,
struct wpa_driver_mesh_bss_params mesh_params;
#endif /* CONFIG_MESH */
- beacon_set = params->reenable ? 0 : bss->flink->beacon_set;
+ if (params->mld_ap) {
+ size_t i;
+
+ for (i = 0; i < bss->n_links; i++) {
+ if (bss->links[i].link_id == params->mld_link_id) {
+ link = &bss->links[i];
+ break;
+ }
+ }
+
+ if (i == bss->n_links) {
+ wpa_printf(MSG_DEBUG, "nl80211: link not found=%u",
+ params->mld_link_id);
+ return -EINVAL;
+ }
+ }
+ beacon_set = params->reenable ? 0 : link->beacon_set;
wpa_printf(MSG_DEBUG, "nl80211: Set beacon (beacon_set=%d)",
beacon_set);
+
if (beacon_set)
cmd = NL80211_CMD_SET_BEACON;
else if (!drv->device_ap_sme && !drv->use_monitor &&
@@ -4759,6 +4883,23 @@ static int wpa_driver_nl80211_set_ap(void *priv,
nl80211_put_dtim_period(msg, params->dtim_period) ||
nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid))
goto fail;
+
+ if (params->mld_ap) {
+ wpa_printf(MSG_DEBUG, "nl80211: link_id=%u",
+ params->mld_link_id);
+
+ if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID,
+ params->mld_link_id))
+ goto fail;
+
+ if (params->freq &&
+ nl80211_put_freq_params(msg, params->freq) < 0)
+ goto fail;
+
+ nl80211_link_set_freq(bss, params->mld_link_id,
+ params->freq->freq);
+ }
+
if (params->proberesp && params->proberesp_len) {
wpa_hexdump(MSG_DEBUG, "nl80211: proberesp (offload)",
params->proberesp, params->proberesp_len);
@@ -5027,17 +5168,17 @@ static int wpa_driver_nl80211_set_ap(void *priv,
wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
ret, strerror(-ret));
} else {
- bss->flink->beacon_set = 1;
+ link->beacon_set = 1;
nl80211_set_bss(bss, params->cts_protect, params->preamble,
params->short_slot_time, params->ht_opmode,
params->isolate, params->basic_rates);
nl80211_set_multicast_to_unicast(bss,
params->multicast_to_unicast);
if (beacon_set && params->freq &&
- params->freq->bandwidth != bss->flink->bandwidth) {
+ params->freq->bandwidth != link->bandwidth) {
wpa_printf(MSG_DEBUG,
"nl80211: Update BSS %s bandwidth: %d -> %d",
- bss->ifname, bss->flink->bandwidth,
+ bss->ifname, link->bandwidth,
params->freq->bandwidth);
ret = nl80211_set_channel(bss, params->freq, 1);
if (ret) {
@@ -5047,7 +5188,7 @@ static int wpa_driver_nl80211_set_ap(void *priv,
} else {
wpa_printf(MSG_DEBUG,
"nl80211: Frequency set succeeded for ht2040 coex");
- bss->flink->bandwidth = params->freq->bandwidth;
+ link->bandwidth = params->freq->bandwidth;
}
} else if (!beacon_set && params->freq) {
/*
@@ -5055,7 +5196,7 @@ static int wpa_driver_nl80211_set_ap(void *priv,
* mode only at the point when beaconing is started, so
* set the initial value here.
*/
- bss->flink->bandwidth = params->freq->bandwidth;
+ link->bandwidth = params->freq->bandwidth;
}
}
@@ -5077,111 +5218,6 @@ fail:
}
-static int nl80211_put_freq_params(struct nl_msg *msg,
- const struct hostapd_freq_params *freq)
-{
- enum hostapd_hw_mode hw_mode;
- int is_24ghz;
- u8 channel;
-
- wpa_printf(MSG_DEBUG, " * freq=%d", freq->freq);
- if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq))
- return -ENOBUFS;
-
- wpa_printf(MSG_DEBUG, " * eht_enabled=%d", freq->eht_enabled);
- wpa_printf(MSG_DEBUG, " * he_enabled=%d", freq->he_enabled);
- wpa_printf(MSG_DEBUG, " * vht_enabled=%d", freq->vht_enabled);
- wpa_printf(MSG_DEBUG, " * ht_enabled=%d", freq->ht_enabled);
- wpa_printf(MSG_DEBUG, " * radar_background=%d",
- freq->radar_background);
-
- hw_mode = ieee80211_freq_to_chan(freq->freq, &channel);
- is_24ghz = hw_mode == HOSTAPD_MODE_IEEE80211G ||
- hw_mode == HOSTAPD_MODE_IEEE80211B;
-
- if (freq->vht_enabled ||
- ((freq->he_enabled || freq->eht_enabled) && !is_24ghz)) {
- enum nl80211_chan_width cw;
-
- wpa_printf(MSG_DEBUG, " * bandwidth=%d", freq->bandwidth);
- switch (freq->bandwidth) {
- case 20:
- cw = NL80211_CHAN_WIDTH_20;
- break;
- case 40:
- cw = NL80211_CHAN_WIDTH_40;
- break;
- case 80:
- if (freq->center_freq2)
- cw = NL80211_CHAN_WIDTH_80P80;
- else
- cw = NL80211_CHAN_WIDTH_80;
- break;
- case 160:
- cw = NL80211_CHAN_WIDTH_160;
- break;
- case 320:
- cw = NL80211_CHAN_WIDTH_320;
- break;
- default:
- return -EINVAL;
- }
-
- wpa_printf(MSG_DEBUG, " * channel_width=%d", cw);
- wpa_printf(MSG_DEBUG, " * center_freq1=%d",
- freq->center_freq1);
- wpa_printf(MSG_DEBUG, " * center_freq2=%d",
- freq->center_freq2);
- if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, cw) ||
- nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1,
- freq->center_freq1) ||
- (freq->center_freq2 &&
- nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2,
- freq->center_freq2)))
- return -ENOBUFS;
- } else if (freq->ht_enabled) {
- enum nl80211_channel_type ct;
-
- wpa_printf(MSG_DEBUG, " * sec_channel_offset=%d",
- freq->sec_channel_offset);
- switch (freq->sec_channel_offset) {
- case -1:
- ct = NL80211_CHAN_HT40MINUS;
- break;
- case 1:
- ct = NL80211_CHAN_HT40PLUS;
- break;
- default:
- ct = NL80211_CHAN_HT20;
- break;
- }
-
- 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);
- if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
- NL80211_CHAN_NO_HT))
- return -ENOBUFS;
- }
- if (freq->radar_background &&
- nla_put_flag(msg, NL80211_ATTR_RADAR_BACKGROUND))
- return -ENOBUFS;
-
- return 0;
-}
-
static bool nl80211_link_valid(struct i802_bss *bss, s8 link_id)
{
u32 i;
--
2.38.1
More information about the Hostap
mailing list