From 1b14b38b11ba2bd69d86c04043f1fc06ad52e528 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Mon, 22 May 2023 22:33:30 +0300 Subject: [PATCH] nl80211: Fetch EML/MLD capabilities Retrieve the EML capabilities as well as the MLD capabilities and ops from nl80211 and expose them using the new driver interface get_mld_capa(). Signed-off-by: Benjamin Berg --- src/drivers/driver_nl80211.c | 32 +++++++++++++++++++++++++++++++ src/drivers/driver_nl80211.h | 2 ++ src/drivers/driver_nl80211_capa.c | 8 ++++++++ 3 files changed, 42 insertions(+) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 79f03b0f1..dfc192f61 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -13186,6 +13186,37 @@ static int nl80211_get_ext_capab(void *priv, enum wpa_driver_if_type type, } +static int nl80211_get_mld_capab(void *priv, enum wpa_driver_if_type type, + u16 *eml_capa, u16 *mld_capa_and_ops) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + enum nl80211_iftype nlmode; + unsigned int i; + + if (!eml_capa || !mld_capa_and_ops) + return -1; + + nlmode = wpa_driver_nl80211_if_type(type); + + /* By default, set to zero */ + *eml_capa = 0; + *mld_capa_and_ops = 0; + + /* Replace the default value if a per-interface type value exists */ + for (i = 0; i < drv->num_iface_capa; i++) { + if (nlmode == drv->iface_capa[i].iftype) { + *eml_capa = drv->iface_capa[i].eml_capa; + *mld_capa_and_ops = + drv->iface_capa[i].mld_capa_and_ops; + break; + } + } + + return 0; +} + + static int nl80211_update_connection_params( void *priv, struct wpa_driver_associate_params *params, enum wpa_drv_update_connect_params_mask mask) @@ -13614,6 +13645,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = { .do_acs = nl80211_do_acs, .configure_data_frame_filters = nl80211_configure_data_frame_filters, .get_ext_capab = nl80211_get_ext_capab, + .get_mld_capab = nl80211_get_mld_capab, .update_connect_params = nl80211_update_connection_params, .send_external_auth_status = nl80211_send_external_auth_status, .set_4addr_mode = nl80211_set_4addr_mode, diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h index bc1399f58..cd883e44b 100644 --- a/src/drivers/driver_nl80211.h +++ b/src/drivers/driver_nl80211.h @@ -123,6 +123,8 @@ struct wpa_driver_nl80211_data { enum nl80211_iftype iftype; u8 *ext_capa, *ext_capa_mask; unsigned int ext_capa_len; + u16 eml_capa; + u16 mld_capa_and_ops; } iface_capa[NL80211_IFTYPE_MAX]; unsigned int num_iface_capa; diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c index 9711379cd..5e6406885 100644 --- a/src/drivers/driver_nl80211_capa.c +++ b/src/drivers/driver_nl80211_capa.c @@ -858,6 +858,14 @@ static void wiphy_info_extended_capab(struct wpa_driver_nl80211_data *drv, wpa_hexdump(MSG_DEBUG, "nl80211: Extended capabilities mask", capa->ext_capa_mask, capa->ext_capa_len); + if (tb1[NL80211_ATTR_EML_CAPABILITY] && + tb1[NL80211_ATTR_MLD_CAPA_AND_OPS]) { + capa->eml_capa = + nla_get_u16(tb1[NL80211_ATTR_EML_CAPABILITY]); + capa->mld_capa_and_ops = + nla_get_u16(tb1[NL80211_ATTR_MLD_CAPA_AND_OPS]); + } + drv->num_iface_capa++; if (drv->num_iface_capa == NL80211_IFTYPE_MAX) break;