driver: Allow to provide a link ID when setting a channel

This includes:

- Modifications of the driver API, to include the link ID as part
  of 'struct hostapd_freq_params'.
- Modifications to nl80211 driver.
- Modifications for the driver wrappers.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
This commit is contained in:
Ilan Peer 2023-05-22 22:33:34 +03:00 committed by Jouni Malinen
parent be44a7afd5
commit e3605e8093
4 changed files with 78 additions and 1 deletions

View file

@ -584,6 +584,17 @@ int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode,
return 0;
if (hapd->driver->set_freq == NULL)
return 0;
data.link_id = -1;
#ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap) {
data.link_id = hapd->mld_link_id;
wpa_printf(MSG_DEBUG,
"hostapd_set_freq: link_id=%d", data.link_id);
}
#endif /* CONFIG_IEEE80211BE */
return hapd->driver->set_freq(hapd->drv_priv, &data);
}

View file

@ -841,6 +841,11 @@ struct hostapd_freq_params {
* eht_enabled - Whether EHT is enabled
*/
bool eht_enabled;
/**
* link_id: If >=0 indicates the link of the AP MLD to configure
*/
int link_id;
};
/**

View file

@ -4120,6 +4120,29 @@ int wpa_driver_nl80211_authenticate_retry(struct wpa_driver_nl80211_data *drv)
}
static struct i802_link * nl80211_get_link(struct i802_bss *bss, s8 link_id)
{
unsigned int i;
for (i = 0; i < bss->n_links; i++) {
if (bss->links[i].link_id != link_id)
continue;
return &bss->links[i];
}
return bss->flink;
}
static void nl80211_link_set_freq(struct i802_bss *bss, s8 link_id, int freq)
{
struct i802_link *link = nl80211_get_link(bss, link_id);
link->freq = freq;
}
static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
size_t data_len, int noack,
unsigned int freq, int no_cck,
@ -5292,6 +5315,27 @@ static int nl80211_put_freq_params(struct nl_msg *msg,
}
static bool nl80211_link_valid(struct i802_bss *bss, s8 link_id)
{
unsigned int i;
if (link_id < 0)
return false;
for (i = 0; i < bss->n_links; i++) {
wpa_printf(MSG_DEBUG, "nl80211: %s - i=%u, link_id=%u",
__func__, i, bss->links[i].link_id);
if (bss->links[i].link_id == NL80211_DRV_LINK_ID_NA)
continue;
if (bss->links[i].link_id == link_id)
return true;
}
return false;
}
static int nl80211_set_channel(struct i802_bss *bss,
struct hostapd_freq_params *freq, int set_chan)
{
@ -5312,9 +5356,19 @@ static int nl80211_set_channel(struct i802_bss *bss,
return -1;
}
if (nl80211_link_valid(bss, freq->link_id)) {
wpa_printf(MSG_DEBUG, "nl80211: Set link_id=%u for freq",
freq->link_id);
if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, freq->link_id)) {
nlmsg_free(msg);
return -ENOBUFS;
}
}
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
if (ret == 0) {
bss->flink->freq = freq->freq;
nl80211_link_set_freq(bss, freq->link_id, freq->freq);
return 0;
}
wpa_printf(MSG_DEBUG, "nl80211: Failed to set channel (freq=%d): "

View file

@ -60,6 +60,9 @@ static inline int wpa_drv_associate(struct wpa_supplicant *wpa_s,
struct wpa_driver_associate_params *params)
{
if (wpa_s->driver->associate) {
if (params)
params->freq.link_id = -1;
return wpa_s->driver->associate(wpa_s->drv_priv, params);
}
return -1;
@ -1098,6 +1101,10 @@ static inline int wpa_drv_update_connect_params(
{
if (!wpa_s->driver->update_connect_params)
return -1;
if (params)
params->freq.link_id = -1;
return wpa_s->driver->update_connect_params(wpa_s->drv_priv, params,
mask);
}