diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index e5464f378..85d4b720e 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -2835,6 +2835,21 @@ int get_6ghz_sec_channel(int channel) } +bool is_same_band(int freq1, int freq2) +{ + if (IS_2P4GHZ(freq1) && IS_2P4GHZ(freq2)) + return true; + + if (IS_5GHZ(freq1) && IS_5GHZ(freq2)) + return true; + + if (is_6ghz_freq(freq1) && is_6ghz_freq(freq2)) + return true; + + return false; +} + + int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, size_t nei_rep_len) { diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h index 5426b41bb..38cc09174 100644 --- a/src/common/ieee802_11_common.h +++ b/src/common/ieee802_11_common.h @@ -283,6 +283,10 @@ bool is_6ghz_op_class(u8 op_class); bool is_6ghz_psc_frequency(int freq); int get_6ghz_sec_channel(int channel); +bool is_same_band(int freq1, int freq2); +#define IS_2P4GHZ(n) (n >= 2412 && n <= 2484) +#define IS_5GHZ(n) (n > 4000 && n < 5895) + int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, size_t nei_rep_len); diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 415a6adfb..92b041eb8 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -9203,6 +9203,46 @@ static void wpa_driver_nl80211_send_action_cancel_wait(void *priv) } +static int nl80211_put_any_link_id(struct nl_msg *msg, + struct driver_sta_mlo_info *mlo, + int freq) +{ + int i; + int link_id = -1; + int any_valid_link_id = -1; + + if (!mlo->valid_links) + return 0; + + /* First try to pick a link that uses the same band */ + for (i = 0; i < MAX_NUM_MLD_LINKS; i++) { + if (!(mlo->valid_links & BIT(i))) + continue; + + if (any_valid_link_id == -1) + any_valid_link_id = i; + + if (is_same_band(freq, mlo->links[i].freq)) { + link_id = i; + break; + } + } + + /* Use any valid link ID if no band match was found */ + if (link_id == -1) + link_id = any_valid_link_id; + + if (link_id == -1) { + wpa_printf(MSG_INFO, + "nl80211: No valid Link ID found for freq %u", freq); + return 0; + } + + wpa_printf(MSG_DEBUG, "nl80211: Add Link ID %d", link_id); + return nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id); +} + + static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq, unsigned int duration) { @@ -9214,7 +9254,8 @@ static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq, if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_REMAIN_ON_CHANNEL)) || nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) || - nla_put_u32(msg, NL80211_ATTR_DURATION, duration)) { + nla_put_u32(msg, NL80211_ATTR_DURATION, duration) || + nl80211_put_any_link_id(msg, &drv->sta_mlo_info, freq)) { nlmsg_free(msg); return -1; } diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h index f1739fada..8402e749e 100644 --- a/wpa_supplicant/scan.h +++ b/wpa_supplicant/scan.h @@ -38,9 +38,6 @@ */ #define TX_POWER_NO_CONSTRAINT 64 -#define IS_2P4GHZ(n) (n >= 2412 && n <= 2484) -#define IS_5GHZ(n) (n > 4000 && n < 5895) - int wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s); void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec); int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s,