Indicate link reconfiguration with QCA vendor interface
Add support to indicate link reconfiguration event reported by the QCA vendor interface to the wpa_supplicant control interface. Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
This commit is contained in:
parent
7b9070229d
commit
8e16372cff
7 changed files with 133 additions and 0 deletions
|
@ -112,6 +112,8 @@ extern "C" {
|
||||||
#define WPA_EVENT_SKIP_ROAM "CTRL-EVENT-SKIP-ROAM "
|
#define WPA_EVENT_SKIP_ROAM "CTRL-EVENT-SKIP-ROAM "
|
||||||
/** TID-to-link mapping response event */
|
/** TID-to-link mapping response event */
|
||||||
#define WPA_EVENT_T2LM_UPDATE "CTRL-EVENT-T2LM-UPDATE "
|
#define WPA_EVENT_T2LM_UPDATE "CTRL-EVENT-T2LM-UPDATE "
|
||||||
|
/** MLO link reconfiguration event */
|
||||||
|
#define WPA_EVENT_LINK_RECONFIG "CTRL-EVENT-LINK-RECONFIG "
|
||||||
|
|
||||||
/** IP subnet status change notification
|
/** IP subnet status change notification
|
||||||
*
|
*
|
||||||
|
|
|
@ -5664,6 +5664,11 @@ enum wpa_event_type {
|
||||||
* Described in wpa_event_data.t2l_map_info.
|
* Described in wpa_event_data.t2l_map_info.
|
||||||
*/
|
*/
|
||||||
EVENT_TID_LINK_MAP,
|
EVENT_TID_LINK_MAP,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EVENT_LINK_RECONFIG - Notification that AP links removed
|
||||||
|
*/
|
||||||
|
EVENT_LINK_RECONFIG,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,7 @@ const char * event_to_string(enum wpa_event_type event)
|
||||||
E2S(LINK_CH_SWITCH);
|
E2S(LINK_CH_SWITCH);
|
||||||
E2S(LINK_CH_SWITCH_STARTED);
|
E2S(LINK_CH_SWITCH_STARTED);
|
||||||
E2S(TID_LINK_MAP);
|
E2S(TID_LINK_MAP);
|
||||||
|
E2S(LINK_RECONFIG);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
|
|
|
@ -281,6 +281,8 @@ void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv)
|
||||||
drv->pending_roam_data = NULL;
|
drv->pending_roam_data = NULL;
|
||||||
os_free(drv->pending_t2lm_data);
|
os_free(drv->pending_t2lm_data);
|
||||||
drv->pending_t2lm_data = NULL;
|
drv->pending_t2lm_data = NULL;
|
||||||
|
os_free(drv->pending_link_reconfig_data);
|
||||||
|
drv->pending_link_reconfig_data = NULL;
|
||||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||||
|
|
||||||
drv->auth_mld = false;
|
drv->auth_mld = false;
|
||||||
|
|
|
@ -257,6 +257,8 @@ struct wpa_driver_nl80211_data {
|
||||||
size_t pending_roam_data_len;
|
size_t pending_roam_data_len;
|
||||||
u8 *pending_t2lm_data;
|
u8 *pending_t2lm_data;
|
||||||
size_t pending_t2lm_data_len;
|
size_t pending_t2lm_data_len;
|
||||||
|
u8 *pending_link_reconfig_data;
|
||||||
|
size_t pending_link_reconfig_data_len;
|
||||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -422,6 +422,78 @@ convert_connect_fail_reason_codes(enum qca_sta_connect_fail_reason_codes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void qca_nl80211_link_reconfig_event(struct wpa_driver_nl80211_data *drv,
|
||||||
|
u8 *data, size_t len)
|
||||||
|
{
|
||||||
|
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_LINK_RECONFIG_MAX + 1];
|
||||||
|
u16 removed_links;
|
||||||
|
u8 *ap_mld;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_LINK_RECONFIG_MAX,
|
||||||
|
(struct nlattr *) data, len, NULL) ||
|
||||||
|
!tb[QCA_WLAN_VENDOR_ATTR_LINK_RECONFIG_AP_MLD_ADDR])
|
||||||
|
return;
|
||||||
|
|
||||||
|
ap_mld = nla_data(tb[QCA_WLAN_VENDOR_ATTR_LINK_RECONFIG_AP_MLD_ADDR]);
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: AP MLD address " MACSTR
|
||||||
|
" received in link reconfig event", MAC2STR(ap_mld));
|
||||||
|
if (!drv->sta_mlo_info.valid_links ||
|
||||||
|
os_memcmp(drv->sta_mlo_info.ap_mld_addr, ap_mld, ETH_ALEN) != 0) {
|
||||||
|
if (drv->pending_link_reconfig_data == data) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: Drop pending link reconfig event since AP MLD not matched even after new connect/roam event");
|
||||||
|
os_free(drv->pending_link_reconfig_data);
|
||||||
|
drv->pending_link_reconfig_data = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: Cache new link reconfig event till next connect/roam event");
|
||||||
|
if (drv->pending_link_reconfig_data) {
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: Override old link reconfig event data");
|
||||||
|
os_free(drv->pending_link_reconfig_data);
|
||||||
|
}
|
||||||
|
drv->pending_link_reconfig_data = os_memdup(data, len);
|
||||||
|
if (!drv->pending_link_reconfig_data)
|
||||||
|
return;
|
||||||
|
drv->pending_link_reconfig_data_len = len;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tb[QCA_WLAN_VENDOR_ATTR_LINK_RECONFIG_REMOVED_LINKS])
|
||||||
|
return;
|
||||||
|
removed_links = nla_get_u16(
|
||||||
|
tb[QCA_WLAN_VENDOR_ATTR_LINK_RECONFIG_REMOVED_LINKS]);
|
||||||
|
|
||||||
|
drv->sta_mlo_info.valid_links &= ~removed_links;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set default BSSID to the BSSID of the lowest link ID of remaining
|
||||||
|
* links when the link used for (re)association is removed.
|
||||||
|
*/
|
||||||
|
if (removed_links & BIT(drv->sta_mlo_info.assoc_link_id)) {
|
||||||
|
for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
|
||||||
|
if (!(drv->sta_mlo_info.valid_links & BIT(i)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
os_memcpy(drv->bssid, drv->sta_mlo_info.links[i].bssid,
|
||||||
|
ETH_ALEN);
|
||||||
|
drv->sta_mlo_info.assoc_link_id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: Removed MLO links bitmap: 0x%x",
|
||||||
|
removed_links);
|
||||||
|
|
||||||
|
wpa_supplicant_event(drv->ctx, EVENT_LINK_RECONFIG, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nl80211_parse_qca_vendor_mlo_link_info(struct driver_sta_mlo_info *mlo,
|
nl80211_parse_qca_vendor_mlo_link_info(struct driver_sta_mlo_info *mlo,
|
||||||
struct nlattr *mlo_links)
|
struct nlattr *mlo_links)
|
||||||
|
@ -1040,6 +1112,11 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
|
||||||
drv->pending_t2lm_data_len);
|
drv->pending_t2lm_data_len);
|
||||||
else
|
else
|
||||||
drv->sta_mlo_info.default_map = true;
|
drv->sta_mlo_info.default_map = true;
|
||||||
|
|
||||||
|
if (drv->pending_link_reconfig_data)
|
||||||
|
qca_nl80211_link_reconfig_event(
|
||||||
|
drv, drv->pending_link_reconfig_data,
|
||||||
|
drv->pending_link_reconfig_data_len);
|
||||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2994,6 +3071,9 @@ static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv,
|
||||||
case QCA_NL80211_VENDOR_SUBCMD_TID_TO_LINK_MAP:
|
case QCA_NL80211_VENDOR_SUBCMD_TID_TO_LINK_MAP:
|
||||||
qca_nl80211_tid_to_link_map_event(drv, data, len);
|
qca_nl80211_tid_to_link_map_event(drv, data, len);
|
||||||
break;
|
break;
|
||||||
|
case QCA_NL80211_VENDOR_SUBCMD_LINK_RECONFIG:
|
||||||
|
qca_nl80211_link_reconfig_event(drv, data, len);
|
||||||
|
break;
|
||||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||||
default:
|
default:
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
|
|
|
@ -5307,6 +5307,44 @@ static void wpas_tid_link_map(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wpas_link_reconfig(struct wpa_supplicant *wpa_s)
|
||||||
|
{
|
||||||
|
u8 bssid[ETH_ALEN];
|
||||||
|
|
||||||
|
if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "LINK_RECONFIG: Failed to get BSSID");
|
||||||
|
wpa_supplicant_deauthenticate(wpa_s,
|
||||||
|
WLAN_REASON_DEAUTH_LEAVING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) {
|
||||||
|
os_memcpy(wpa_s->bssid, bssid, ETH_ALEN);
|
||||||
|
wpa_supplicant_update_current_bss(wpa_s, wpa_s->bssid);
|
||||||
|
wpas_notify_bssid_changed(wpa_s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpa_drv_get_mlo_info(wpa_s) < 0) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"LINK_RECONFIG: Failed to get MLO connection info");
|
||||||
|
wpa_supplicant_deauthenticate(wpa_s,
|
||||||
|
WLAN_REASON_DEAUTH_LEAVING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpa_sm_set_ml_info(wpa_s)) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"LINK_RECONFIG: Failed to set MLO connection info to wpa_sm");
|
||||||
|
wpa_supplicant_deauthenticate(wpa_s,
|
||||||
|
WLAN_REASON_DEAUTH_LEAVING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_LINK_RECONFIG "valid_links=0x%x",
|
||||||
|
wpa_s->valid_links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
union wpa_event_data *data)
|
union wpa_event_data *data)
|
||||||
{
|
{
|
||||||
|
@ -5406,6 +5444,9 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
wpas_event_deauth(wpa_s,
|
wpas_event_deauth(wpa_s,
|
||||||
data ? &data->deauth_info : NULL);
|
data ? &data->deauth_info : NULL);
|
||||||
break;
|
break;
|
||||||
|
case EVENT_LINK_RECONFIG:
|
||||||
|
wpas_link_reconfig(wpa_s);
|
||||||
|
break;
|
||||||
case EVENT_MICHAEL_MIC_FAILURE:
|
case EVENT_MICHAEL_MIC_FAILURE:
|
||||||
wpa_supplicant_event_michael_mic_failure(wpa_s, data);
|
wpa_supplicant_event_michael_mic_failure(wpa_s, data);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue