[PATCH] wifi: brcmfmac: Set extsae_pwe parameter to Infineon firmware in SAP mode
From: GirishBukkasagara.Rudrappa <hidden>
Date: 2026-08-31 06:12:41
Subsystem:
broadcom brcm80211 ieee802.11 wireless drivers, the rest · Maintainers:
Arend van Spriel, Linus Torvalds
From: Girish Rudrappa <redacted> Parse and configure the extsae_pwe according to the information from the supported rate/extended support rate and RSNX IE Parse the beacon IEs on start_ap() and set the extsae_pwe iovar. Set sae_pwe to 2 when the RSNX IE advertises H2E, 1 when an H2E-only membership selector is present, 0 otherwise. The changes are tested with FW Version 7.45.286 Signed-off-by: Girish Rudrappa <redacted> --- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 77 +++++++++++++++++++ .../broadcom/brcm80211/brcmfmac/cyw/core.c | 6 ++ .../broadcom/brcm80211/brcmfmac/fwvid.h | 11 +++ 3 files changed, 94 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 872c48806d09..192ea19b216b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c@@ -5099,6 +5099,79 @@ brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif, return err; } +static s32 +brcmf_parse_configure_sae_pwe(struct brcmf_if *ifp, + struct cfg80211_ap_settings *settings) +{ + const struct brcmf_tlv *rsnx_ie; + const struct brcmf_tlv *ext_rate_ie; + const struct brcmf_tlv *supp_rate_ie; + u8 ie_len, i; + u32 wpa_auth = 0; + u32 sae_pwe = 0; /* 0 = Hunting-and-Pecking only, 1 = H2E only, 2 = both */ + s32 err = 0; + + if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE_EXT)) + return 0; + + err = brcmf_fil_bsscfg_int_get(ifp, "wpa_auth", &wpa_auth); + if (err || (wpa_auth & WPA3_AUTH_SAE_PSK) == 0) { + brcmf_dbg(INFO, "wpa_auth is not SAE:0x%x\n", wpa_auth); + return 0; + } + + rsnx_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, + settings->beacon.tail_len, WLAN_EID_RSNX); + + if (rsnx_ie && rsnx_ie->len && + (rsnx_ie->data[0] & WLAN_RSNX_CAPA_SAE_H2E)) + sae_pwe = 2; + + /* Found rsnx_ie with SAE_H2E, check the bss selector to know if it is + * a H2E only. + */ + + if (sae_pwe == 2) { + supp_rate_ie = brcmf_parse_tlvs((u8 *)settings->beacon.head, + settings->beacon.head_len, + WLAN_EID_SUPP_RATES); + ext_rate_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, + settings->beacon.tail_len, + WLAN_EID_EXT_SUPP_RATES); + if (ext_rate_ie) { + ie_len = ext_rate_ie->len; + for (i = 0; i < ie_len; i++) { + if ((ext_rate_ie->data[i] & 0x7f) == + BSS_MEMBERSHIP_SELECTOR_SAE_H2E) { + sae_pwe = 1; + break; + } + } + } + + /* If we cannot found H2E only selector in ext_supp_rate IE, + * traversal supp_rate IE to make sure it really doesn't exist + */ + if (sae_pwe == 2 && supp_rate_ie) { + ie_len = supp_rate_ie->len; + for (i = 0; i < ie_len; i++) { + if ((supp_rate_ie->data[i] & 0x7f) == + BSS_MEMBERSHIP_SELECTOR_SAE_H2E) { + sae_pwe = 1; + break; + } + } + } + } + + err = brcmf_fwvid_configure_sae_pwe(ifp, sae_pwe); + if (err == -EOPNOTSUPP) + return 0; + + brcmf_dbg(TRACE, "extsae_pwe=%u\n", sae_pwe); + return err; +} + static s32 brcmf_parse_configure_security(struct brcmf_if *ifp, struct cfg80211_ap_settings *settings,
@@ -5132,6 +5205,10 @@ brcmf_parse_configure_security(struct brcmf_if *ifp, err = brcmf_configure_wpaie(ifp, tmp_ie, true); if (err < 0) return err; + + err = brcmf_parse_configure_sae_pwe(ifp, settings); + if (err < 0) + return err; } } else { brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c
index 545eb9aae966..0443207dfe00 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c@@ -367,10 +367,16 @@ static void brcmf_cyw_register_event_handlers(struct brcmf_pub *drvr) brcmf_notify_mgmt_tx_status); } +static int brcmf_cyw_configure_sae_pwe(struct brcmf_if *ifp, u32 sae_pwe) +{ + return brcmf_fil_iovar_int_set(ifp, "extsae_pwe", sae_pwe); +} + const struct brcmf_fwvid_ops brcmf_cyw_ops = { .set_sae_password = brcmf_cyw_set_sae_pwd, .alloc_fweh_info = brcmf_cyw_alloc_fweh_info, .activate_events = brcmf_cyw_activate_events, .get_cfg80211_ops = brcmf_cyw_get_cfg80211_ops, .register_event_handlers = brcmf_cyw_register_event_handlers, + .configure_sae_pwe = brcmf_cyw_configure_sae_pwe, };
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwvid.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwvid.h
index f3e011d090f2..56d341a75a53 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwvid.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwvid.h@@ -18,6 +18,7 @@ struct brcmf_fwvid_ops { int (*activate_events)(struct brcmf_if *ifp); void (*get_cfg80211_ops)(struct brcmf_pub *drvr); void (*register_event_handlers)(struct brcmf_pub *drvr); + int (*configure_sae_pwe)(struct brcmf_if *ifp, u32 sae_pwe); }; /* exported functions */
@@ -40,6 +41,16 @@ static inline void brcmf_fwvid_feat_attach(struct brcmf_if *ifp) vops->feat_attach(ifp); } +static inline int brcmf_fwvid_configure_sae_pwe(struct brcmf_if *ifp, u32 sae_pwe) +{ + const struct brcmf_fwvid_ops *vops = ifp->drvr->vops; + + if (!vops || !vops->configure_sae_pwe) + return -EOPNOTSUPP; + + return vops->configure_sae_pwe(ifp, sae_pwe); +} + static inline int brcmf_fwvid_set_sae_password(struct brcmf_if *ifp, struct cfg80211_crypto_settings *crypto) {
--
2.53.0