Indicate TID to link mapping changes with QCA vendor interface
Add support to indicate TID-to-link mapping changes reported by the QCA vendor interface to the wpa_supplicant control interface. Signed-off-by: Shivani Baranwal <quic_shivbara@quicinc.com>
This commit is contained in:
parent
95c3f0d1e4
commit
7b9070229d
7 changed files with 244 additions and 2 deletions
|
@ -110,6 +110,8 @@ extern "C" {
|
||||||
#define WPA_EVENT_DO_ROAM "CTRL-EVENT-DO-ROAM "
|
#define WPA_EVENT_DO_ROAM "CTRL-EVENT-DO-ROAM "
|
||||||
/** Decision made to skip a within-ESS roam */
|
/** Decision made to skip a within-ESS roam */
|
||||||
#define WPA_EVENT_SKIP_ROAM "CTRL-EVENT-SKIP-ROAM "
|
#define WPA_EVENT_SKIP_ROAM "CTRL-EVENT-SKIP-ROAM "
|
||||||
|
/** TID-to-link mapping response event */
|
||||||
|
#define WPA_EVENT_T2LM_UPDATE "CTRL-EVENT-T2LM-UPDATE "
|
||||||
|
|
||||||
/** IP subnet status change notification
|
/** IP subnet status change notification
|
||||||
*
|
*
|
||||||
|
|
|
@ -430,6 +430,18 @@ struct wpa_driver_scan_ssid {
|
||||||
size_t ssid_len;
|
size_t ssid_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct t2lm_mapping {
|
||||||
|
/**
|
||||||
|
* downlink - Bitmap of TIDs mapped with a link in downlink direction
|
||||||
|
*/
|
||||||
|
u8 downlink;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uplink - Bitmap of TIDs mapped with a link in uplink direction
|
||||||
|
*/
|
||||||
|
u8 uplink;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct wpa_driver_scan_params - Scan parameters
|
* struct wpa_driver_scan_params - Scan parameters
|
||||||
* Data for struct wpa_driver_ops::scan2().
|
* Data for struct wpa_driver_ops::scan2().
|
||||||
|
@ -2911,6 +2923,7 @@ struct weighted_pcl {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct driver_sta_mlo_info {
|
struct driver_sta_mlo_info {
|
||||||
|
bool default_map;
|
||||||
u16 req_links; /* bitmap of requested link IDs */
|
u16 req_links; /* bitmap of requested link IDs */
|
||||||
u16 valid_links; /* bitmap of accepted link IDs */
|
u16 valid_links; /* bitmap of accepted link IDs */
|
||||||
u8 assoc_link_id;
|
u8 assoc_link_id;
|
||||||
|
@ -2919,6 +2932,7 @@ struct driver_sta_mlo_info {
|
||||||
u8 addr[ETH_ALEN];
|
u8 addr[ETH_ALEN];
|
||||||
u8 bssid[ETH_ALEN];
|
u8 bssid[ETH_ALEN];
|
||||||
unsigned int freq;
|
unsigned int freq;
|
||||||
|
struct t2lm_mapping t2lmap;
|
||||||
} links[MAX_NUM_MLD_LINKS];
|
} links[MAX_NUM_MLD_LINKS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5640,6 +5654,16 @@ enum wpa_event_type {
|
||||||
* Described in wpa_event_data.ch_switch.
|
* Described in wpa_event_data.ch_switch.
|
||||||
*/
|
*/
|
||||||
EVENT_LINK_CH_SWITCH_STARTED,
|
EVENT_LINK_CH_SWITCH_STARTED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EVENT_TID_LINK_MAP - MLD event to set TID-to-link mapping
|
||||||
|
*
|
||||||
|
* This event is used by the driver to indicate the received TID-to-link
|
||||||
|
* mapping response from the associated AP MLD.
|
||||||
|
*
|
||||||
|
* Described in wpa_event_data.t2l_map_info.
|
||||||
|
*/
|
||||||
|
EVENT_TID_LINK_MAP,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -6564,6 +6588,15 @@ union wpa_event_data {
|
||||||
const u8 *td_bitmap;
|
const u8 *td_bitmap;
|
||||||
size_t td_bitmap_len;
|
size_t td_bitmap_len;
|
||||||
} port_authorized;
|
} port_authorized;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct tid_link_map_info - Data for EVENT_TID_LINK_MAP
|
||||||
|
*/
|
||||||
|
struct tid_link_map_info {
|
||||||
|
bool default_map;
|
||||||
|
u8 valid_links;
|
||||||
|
struct t2lm_mapping t2lmap[MAX_NUM_MLD_LINKS];
|
||||||
|
} t2l_map_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -98,6 +98,7 @@ const char * event_to_string(enum wpa_event_type event)
|
||||||
E2S(PASN_AUTH);
|
E2S(PASN_AUTH);
|
||||||
E2S(LINK_CH_SWITCH);
|
E2S(LINK_CH_SWITCH);
|
||||||
E2S(LINK_CH_SWITCH_STARTED);
|
E2S(LINK_CH_SWITCH_STARTED);
|
||||||
|
E2S(TID_LINK_MAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
|
|
|
@ -279,6 +279,8 @@ void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv)
|
||||||
#ifdef CONFIG_DRIVER_NL80211_QCA
|
#ifdef CONFIG_DRIVER_NL80211_QCA
|
||||||
os_free(drv->pending_roam_data);
|
os_free(drv->pending_roam_data);
|
||||||
drv->pending_roam_data = NULL;
|
drv->pending_roam_data = NULL;
|
||||||
|
os_free(drv->pending_t2lm_data);
|
||||||
|
drv->pending_t2lm_data = NULL;
|
||||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||||
|
|
||||||
drv->auth_mld = false;
|
drv->auth_mld = false;
|
||||||
|
@ -10592,8 +10594,10 @@ static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
|
||||||
struct driver_sta_mlo_info *mlo = &drv->sta_mlo_info;
|
struct driver_sta_mlo_info *mlo = &drv->sta_mlo_info;
|
||||||
|
|
||||||
res = os_snprintf(pos, end - pos,
|
res = os_snprintf(pos, end - pos,
|
||||||
"ap_mld_addr=" MACSTR "\n",
|
"ap_mld_addr=" MACSTR "\n"
|
||||||
MAC2STR(mlo->ap_mld_addr));
|
"default_map=%d\n",
|
||||||
|
MAC2STR(mlo->ap_mld_addr),
|
||||||
|
mlo->default_map);
|
||||||
if (os_snprintf_error(end - pos, res))
|
if (os_snprintf_error(end - pos, res))
|
||||||
return pos - buf;
|
return pos - buf;
|
||||||
pos += res;
|
pos += res;
|
||||||
|
@ -10612,6 +10616,18 @@ static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
|
||||||
if (os_snprintf_error(end - pos, res))
|
if (os_snprintf_error(end - pos, res))
|
||||||
return pos - buf;
|
return pos - buf;
|
||||||
pos += res;
|
pos += res;
|
||||||
|
|
||||||
|
if (!mlo->default_map) {
|
||||||
|
res = os_snprintf(
|
||||||
|
pos, end - pos,
|
||||||
|
"uplink_map[%u]=%x\n"
|
||||||
|
"downlink_map[%u]=%x\n",
|
||||||
|
i, mlo->links[i].t2lmap.uplink,
|
||||||
|
i, mlo->links[i].t2lmap.downlink);
|
||||||
|
if (os_snprintf_error(end - pos, res))
|
||||||
|
return pos - buf;
|
||||||
|
pos += res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -255,6 +255,8 @@ struct wpa_driver_nl80211_data {
|
||||||
bool roam_indication_done;
|
bool roam_indication_done;
|
||||||
u8 *pending_roam_data;
|
u8 *pending_roam_data;
|
||||||
size_t pending_roam_data_len;
|
size_t pending_roam_data_len;
|
||||||
|
u8 *pending_t2lm_data;
|
||||||
|
size_t pending_t2lm_data_len;
|
||||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -714,6 +714,126 @@ static void nl80211_parse_mlo_info(struct wpa_driver_nl80211_data *drv,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_DRIVER_NL80211_QCA
|
||||||
|
static void
|
||||||
|
qca_nl80211_tid_to_link_map_event(struct wpa_driver_nl80211_data *drv,
|
||||||
|
u8 *data, size_t len)
|
||||||
|
{
|
||||||
|
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TID_TO_LINK_MAP_MAX + 1];
|
||||||
|
struct nlattr *tids;
|
||||||
|
union wpa_event_data event;
|
||||||
|
u8 *ap_mld;
|
||||||
|
int i, rem, tidnum = 0;
|
||||||
|
|
||||||
|
os_memset(&event, 0, sizeof(event));
|
||||||
|
|
||||||
|
if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TID_TO_LINK_MAP_MAX,
|
||||||
|
(struct nlattr *) data, len, NULL) ||
|
||||||
|
!tb[QCA_WLAN_VENDOR_ATTR_TID_TO_LINK_MAP_AP_MLD_ADDR])
|
||||||
|
return;
|
||||||
|
|
||||||
|
ap_mld = nla_data(tb[QCA_WLAN_VENDOR_ATTR_TID_TO_LINK_MAP_AP_MLD_ADDR]);
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: AP MLD address " MACSTR
|
||||||
|
" received in TID to link mapping 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_t2lm_data == data) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: Drop pending TID-to-link mapping event since AP MLD not matched even after new connect/roam event");
|
||||||
|
os_free(drv->pending_t2lm_data);
|
||||||
|
drv->pending_t2lm_data = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: Cache new TID-to-link map event until the next connect/roam event");
|
||||||
|
if (drv->pending_t2lm_data) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: Override old TID-to-link map event data");
|
||||||
|
os_free(drv->pending_t2lm_data);
|
||||||
|
}
|
||||||
|
drv->pending_t2lm_data = os_memdup(data, len);
|
||||||
|
if (!drv->pending_t2lm_data)
|
||||||
|
return;
|
||||||
|
drv->pending_t2lm_data_len = len;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tb[QCA_WLAN_VENDOR_ATTR_TID_TO_LINK_MAP_STATUS]) {
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: Default TID-to-link map");
|
||||||
|
event.t2l_map_info.default_map = true;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.t2l_map_info.default_map = false;
|
||||||
|
|
||||||
|
nla_for_each_nested(tids,
|
||||||
|
tb[QCA_WLAN_VENDOR_ATTR_TID_TO_LINK_MAP_STATUS],
|
||||||
|
rem) {
|
||||||
|
u16 uplink, downlink;
|
||||||
|
struct nlattr *tid[QCA_WLAN_VENDOR_ATTR_LINK_TID_MAP_STATUS_MAX + 1];
|
||||||
|
|
||||||
|
if (nla_parse_nested(
|
||||||
|
tid, QCA_WLAN_VENDOR_ATTR_LINK_TID_MAP_STATUS_MAX,
|
||||||
|
tids, NULL)) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: TID-to-link: nla_parse_nested() failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tid[QCA_WLAN_VENDOR_ATTR_LINK_TID_MAP_STATUS_UPLINK]) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: TID-to-link: uplink not present for tid: %d",
|
||||||
|
tidnum);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uplink = nla_get_u16(tid[QCA_WLAN_VENDOR_ATTR_LINK_TID_MAP_STATUS_UPLINK]);
|
||||||
|
|
||||||
|
if (!tid[QCA_WLAN_VENDOR_ATTR_LINK_TID_MAP_STATUS_DOWNLINK]) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: TID-to-link: downlink not present for tid: %d",
|
||||||
|
tidnum);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
downlink = nla_get_u16(tid[QCA_WLAN_VENDOR_ATTR_LINK_TID_MAP_STATUS_DOWNLINK]);
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: TID-to-link: Received uplink %x downlink %x",
|
||||||
|
uplink, downlink);
|
||||||
|
for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
|
||||||
|
if (!(drv->sta_mlo_info.valid_links & BIT(i)))
|
||||||
|
continue;
|
||||||
|
if (uplink & BIT(i))
|
||||||
|
event.t2l_map_info.t2lmap[i].uplink |=
|
||||||
|
BIT(tidnum);
|
||||||
|
if (downlink & BIT(i))
|
||||||
|
event.t2l_map_info.t2lmap[i].downlink |=
|
||||||
|
BIT(tidnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
tidnum++;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
drv->sta_mlo_info.default_map = event.t2l_map_info.default_map;
|
||||||
|
|
||||||
|
event.t2l_map_info.valid_links = drv->sta_mlo_info.valid_links;
|
||||||
|
for (i = 0; i < MAX_NUM_MLD_LINKS && !drv->sta_mlo_info.default_map;
|
||||||
|
i++) {
|
||||||
|
if (!(drv->sta_mlo_info.valid_links & BIT(i)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
drv->sta_mlo_info.links[i].t2lmap.uplink =
|
||||||
|
event.t2l_map_info.t2lmap[i].uplink;
|
||||||
|
drv->sta_mlo_info.links[i].t2lmap.downlink =
|
||||||
|
event.t2l_map_info.t2lmap[i].downlink;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_supplicant_event(drv->ctx, EVENT_TID_LINK_MAP, &event);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||||
|
|
||||||
|
|
||||||
static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
|
static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
|
||||||
enum nl80211_commands cmd, bool qca_roam_auth,
|
enum nl80211_commands cmd, bool qca_roam_auth,
|
||||||
struct nlattr *status,
|
struct nlattr *status,
|
||||||
|
@ -913,6 +1033,14 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
|
||||||
* operation that happened in parallel with the disconnection request.
|
* operation that happened in parallel with the disconnection request.
|
||||||
*/
|
*/
|
||||||
drv->ignore_next_local_disconnect = 0;
|
drv->ignore_next_local_disconnect = 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_DRIVER_NL80211_QCA
|
||||||
|
if (drv->pending_t2lm_data)
|
||||||
|
qca_nl80211_tid_to_link_map_event(drv, drv->pending_t2lm_data,
|
||||||
|
drv->pending_t2lm_data_len);
|
||||||
|
else
|
||||||
|
drv->sta_mlo_info.default_map = true;
|
||||||
|
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2863,6 +2991,9 @@ static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv,
|
||||||
qca_nl80211_pasn_auth(drv, data, len);
|
qca_nl80211_pasn_auth(drv, data, len);
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_PASN */
|
#endif /* CONFIG_PASN */
|
||||||
|
case QCA_NL80211_VENDOR_SUBCMD_TID_TO_LINK_MAP:
|
||||||
|
qca_nl80211_tid_to_link_map_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,
|
||||||
|
|
|
@ -5254,6 +5254,59 @@ static void wpas_event_unprot_beacon(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char * bitmap_to_str(u8 value, char *buf)
|
||||||
|
{
|
||||||
|
char *pos = buf;
|
||||||
|
int i, k = 0;
|
||||||
|
|
||||||
|
for (i = 7; i >= 0; i--)
|
||||||
|
pos[k++] = (value & BIT(i)) ? '1' : '0';
|
||||||
|
|
||||||
|
pos[8] = '\0';
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wpas_tid_link_map(struct wpa_supplicant *wpa_s,
|
||||||
|
struct tid_link_map_info *info)
|
||||||
|
{
|
||||||
|
char map_info[1000], *pos, *end;
|
||||||
|
int res, i;
|
||||||
|
|
||||||
|
pos = map_info;
|
||||||
|
end = pos + sizeof(map_info);
|
||||||
|
res = os_snprintf(map_info, sizeof(map_info), "default=%d",
|
||||||
|
info->default_map);
|
||||||
|
if (os_snprintf_error(end - pos, res))
|
||||||
|
return;
|
||||||
|
pos += res;
|
||||||
|
|
||||||
|
if (!info->default_map) {
|
||||||
|
for (i = 0; i < MAX_NUM_MLD_LINKS && end > pos; i++) {
|
||||||
|
char uplink_map_str[9];
|
||||||
|
char downlink_map_str[9];
|
||||||
|
|
||||||
|
if (!(info->valid_links & BIT(i)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bitmap_to_str(info->t2lmap[i].uplink, uplink_map_str);
|
||||||
|
bitmap_to_str(info->t2lmap[i].downlink,
|
||||||
|
downlink_map_str);
|
||||||
|
|
||||||
|
res = os_snprintf(pos, end - pos,
|
||||||
|
" link_id=%d up_link=%s down_link=%s",
|
||||||
|
i, uplink_map_str,
|
||||||
|
downlink_map_str);
|
||||||
|
if (os_snprintf_error(end - pos, res))
|
||||||
|
return;
|
||||||
|
pos += res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_T2LM_UPDATE "%s", map_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -6159,6 +6212,10 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
wpas_dpp_tx_wait_expire(wpa_s);
|
wpas_dpp_tx_wait_expire(wpa_s);
|
||||||
#endif /* CONFIG_DPP */
|
#endif /* CONFIG_DPP */
|
||||||
break;
|
break;
|
||||||
|
case EVENT_TID_LINK_MAP:
|
||||||
|
if (data)
|
||||||
|
wpas_tid_link_map(wpa_s, &data->t2l_map_info);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
|
wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue