AP MLD: Channel switch for specific link

Link ID needs to be specified for MLD case when doing channel switch.
Add it to the driver command.

Signed-off-by: Chenming Huang <quic_chenhuan@quicinc.com>
This commit is contained in:
Chenming Huang 2023-11-27 08:09:05 +05:30 committed by Jouni Malinen
parent 1b448c8650
commit 40410c04f4
7 changed files with 26 additions and 2 deletions

View file

@ -2568,6 +2568,12 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
if (ret) if (ret)
return ret; return ret;
settings.link_id = -1;
#ifdef CONFIG_IEEE80211BE
if (iface->num_bss && iface->bss[0]->conf->mld_ap)
settings.link_id = iface->bss[0]->mld_link_id;
#endif /* CONFIG_IEEE80211BE */
ret = hostapd_ctrl_check_freq_params(&settings.freq_params, ret = hostapd_ctrl_check_freq_params(&settings.freq_params,
settings.punct_bitmap); settings.punct_bitmap);
if (ret) { if (ret) {

View file

@ -983,6 +983,11 @@ static int hostapd_dfs_request_channel_switch(struct hostapd_iface *iface,
os_memset(&csa_settings, 0, sizeof(csa_settings)); os_memset(&csa_settings, 0, sizeof(csa_settings));
csa_settings.cs_count = 5; csa_settings.cs_count = 5;
csa_settings.block_tx = 1; csa_settings.block_tx = 1;
csa_settings.link_id = -1;
#ifdef CONFIG_IEEE80211BE
if (iface->bss[0]->conf->mld_ap)
csa_settings.link_id = iface->bss[0]->mld_link_id;
#endif /* CONFIG_IEEE80211BE */
#ifdef CONFIG_MESH #ifdef CONFIG_MESH
if (iface->mconf) if (iface->mconf)
ieee80211_mode = IEEE80211_MODE_MESH; ieee80211_mode = IEEE80211_MODE_MESH;

View file

@ -4008,6 +4008,11 @@ static int hostapd_fill_csa_settings(struct hostapd_data *hapd,
settings->counter_offset_presp[0] = hapd->cs_c_off_proberesp; settings->counter_offset_presp[0] = hapd->cs_c_off_proberesp;
settings->counter_offset_beacon[1] = hapd->cs_c_off_ecsa_beacon; settings->counter_offset_beacon[1] = hapd->cs_c_off_ecsa_beacon;
settings->counter_offset_presp[1] = hapd->cs_c_off_ecsa_proberesp; settings->counter_offset_presp[1] = hapd->cs_c_off_ecsa_proberesp;
settings->link_id = -1;
#ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap)
settings->link_id = hapd->mld_link_id;
#endif /* CONFIG_IEEE80211BE */
return 0; return 0;
} }

View file

@ -2709,6 +2709,7 @@ struct beacon_data {
* @counter_offset_beacon: Offset to the count field in beacon's tail * @counter_offset_beacon: Offset to the count field in beacon's tail
* @counter_offset_presp: Offset to the count field in probe resp. * @counter_offset_presp: Offset to the count field in probe resp.
* @punct_bitmap - Preamble puncturing bitmap * @punct_bitmap - Preamble puncturing bitmap
* @link_id: Link ID to determine the link for MLD; -1 for non-MLD
*/ */
struct csa_settings { struct csa_settings {
u8 cs_count; u8 cs_count;
@ -2722,6 +2723,7 @@ struct csa_settings {
u16 counter_offset_presp[2]; u16 counter_offset_presp[2];
u16 punct_bitmap; u16 punct_bitmap;
int link_id;
}; };
/** /**

View file

@ -11121,7 +11121,7 @@ static int nl80211_switch_channel(void *priv, struct csa_settings *settings)
int i; int i;
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d channel=%d sec_channel_offset=%d width=%d cf1=%d cf2=%d puncturing_bitmap=0x%04x%s%s%s)", "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d channel=%d sec_channel_offset=%d width=%d cf1=%d cf2=%d puncturing_bitmap=0x%04x link_id=%d%s%s%s)",
settings->cs_count, settings->block_tx, settings->cs_count, settings->block_tx,
settings->freq_params.freq, settings->freq_params.freq,
settings->freq_params.channel, settings->freq_params.channel,
@ -11130,6 +11130,7 @@ static int nl80211_switch_channel(void *priv, struct csa_settings *settings)
settings->freq_params.center_freq1, settings->freq_params.center_freq1,
settings->freq_params.center_freq2, settings->freq_params.center_freq2,
settings->punct_bitmap, settings->punct_bitmap,
settings->link_id,
settings->freq_params.ht_enabled ? " ht" : "", settings->freq_params.ht_enabled ? " ht" : "",
settings->freq_params.vht_enabled ? " vht" : "", settings->freq_params.vht_enabled ? " vht" : "",
settings->freq_params.he_enabled ? " he" : ""); settings->freq_params.he_enabled ? " he" : "");
@ -11203,7 +11204,9 @@ static int nl80211_switch_channel(void *priv, struct csa_settings *settings)
nla_put_flag(msg, NL80211_ATTR_CH_SWITCH_BLOCK_TX)) || nla_put_flag(msg, NL80211_ATTR_CH_SWITCH_BLOCK_TX)) ||
(settings->punct_bitmap && (settings->punct_bitmap &&
nla_put_u32(msg, NL80211_ATTR_PUNCT_BITMAP, nla_put_u32(msg, NL80211_ATTR_PUNCT_BITMAP,
settings->punct_bitmap))) settings->punct_bitmap)) ||
(settings->link_id != NL80211_DRV_LINK_ID_NA &&
nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, settings->link_id)))
goto error; goto error;
/* beacon_after params */ /* beacon_after params */

View file

@ -1846,6 +1846,8 @@ int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos)
if (ret) if (ret)
return ret; return ret;
settings.link_id = -1;
return ap_switch_channel(wpa_s, &settings); return ap_switch_channel(wpa_s, &settings);
} }
#endif /* CONFIG_CTRL_IFACE */ #endif /* CONFIG_CTRL_IFACE */

View file

@ -9796,6 +9796,7 @@ static int wpas_p2p_move_go_csa(struct wpa_supplicant *wpa_s)
os_memset(&csa_settings, 0, sizeof(csa_settings)); os_memset(&csa_settings, 0, sizeof(csa_settings));
csa_settings.cs_count = P2P_GO_CSA_COUNT; csa_settings.cs_count = P2P_GO_CSA_COUNT;
csa_settings.block_tx = P2P_GO_CSA_BLOCK_TX; csa_settings.block_tx = P2P_GO_CSA_BLOCK_TX;
csa_settings.link_id = -1;
csa_settings.freq_params.freq = params.freq; csa_settings.freq_params.freq = params.freq;
csa_settings.freq_params.sec_channel_offset = conf->secondary_channel; csa_settings.freq_params.sec_channel_offset = conf->secondary_channel;
csa_settings.freq_params.ht_enabled = conf->ieee80211n; csa_settings.freq_params.ht_enabled = conf->ieee80211n;