From nobody Sat Jul 25 17:33:46 2026 Received: from smtp2.infineon.com (smtp2.infineon.com [217.10.52.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7DC352E9730; Wed, 15 Jul 2026 08:57:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.10.52.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784105845; cv=none; b=YJ+RhViu86bmyYcSHHtpYmHIdrIcfLbMUYMIr2D3fBruxyA852jnF5MVqzGVaUuf1VZKCnwPRswp0LcCKCgmXgjBsi5EMEe9F9fo+do5tTRf0sCMls23lgbEBgi8fgo06vb85K2R/J8FNh6hb0VCZXLJyLrdWrW+w4JlocTNRfg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784105845; c=relaxed/simple; bh=H3tEyMuL1HuuXYVJhV1jlSDPXN/KnCS+k3Ma6If9f3E=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DoxQGh1IBSSagahu9jHTlGjJwX04O7urVdY9cIKarNRmbEyWjXfH0wfQ76zwWuN8ZJr6wdy6UOJ2O/vgCmf3e7n3YFNiQ4QgRRjyxNr/5XA+9rAuAxnVWAOP68GmwYzz1PB6kPe0oqa98B8Ndds26hyng5jNwWMOh6Ge+j092ws= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=infineon.com; spf=pass smtp.mailfrom=infineon.com; dkim=pass (1024-bit key) header.d=infineon.com header.i=@infineon.com header.b=UX3xUjuS; arc=none smtp.client-ip=217.10.52.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=infineon.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=infineon.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=infineon.com header.i=@infineon.com header.b="UX3xUjuS" DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=infineon.com; i=@infineon.com; q=dns/txt; s=IFXMAIL; t=1784105843; x=1815641843; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=H3tEyMuL1HuuXYVJhV1jlSDPXN/KnCS+k3Ma6If9f3E=; b=UX3xUjuSIqKaIMZtSCAUnS9hGBVDXKlwjk7/Si5/Xnj34rdN4SdUdp6t B7yTfoRbA+P8+L26gsmfyfrV08pI/jt92XvKrhZIQGNMFYWKO6nt85o2+ LZfI1KDAmIvgEFMipDmJi5jBy5REIu5fz9/FcrFXtVypk+qKbGro4FGQo M=; X-CSE-ConnectionGUID: WiaiaWR2Ry60EkTME69Cpg== X-CSE-MsgGUID: A/gyPgA3TE2TB4gkAi0SiA== X-IronPort-AV: E=McAfee;i="6800,10657,11847"; a="167626912" X-IronPort-AV: E=Sophos;i="6.25,165,1779141600"; d="scan'208";a="167626912" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO MUCSE819.infineon.com) ([172.23.29.45]) by smtp2.infineon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2026 10:57:15 +0200 Received: from MUCSE809.infineon.com (172.23.29.35) by MUCSE819.infineon.com (172.23.29.45) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.43; Wed, 15 Jul 2026 10:57:14 +0200 Received: from ISCN5CG5251XQT.infineon.com (10.161.6.196) by MUCSE809.infineon.com (172.23.29.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.43; Wed, 15 Jul 2026 10:57:11 +0200 From: Jason Huang To: CC: , , , , Jason Huang , Kurt Lee Subject: [PATCH v5] wifi: brcmfmac: add DPP support Date: Wed, 15 Jul 2026 16:47:20 +0800 Message-ID: <20260715084718.667522-1-Jason.Huang2@infineon.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260708071230.312836-1-Jason.Huang2@infineon.com> References: <20260708071230.312836-1-Jason.Huang2@infineon.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: MUCSE815.infineon.com (172.23.29.41) To MUCSE809.infineon.com (172.23.29.35) Content-Type: text/plain; charset="utf-8" From: Jason Huang Add DPP AKM handling and RSN parsing support. Map DPP to the firmware wpa_auth value and recognize DPP public action frames in the P2P action-frame TX path. Gate sup_wpa programming on firmware supplicant capability. Disable it only when the selected connection mode does not use firmware supplicant. This keeps pure SAE and 802.1X firmware-supplicant paths intact while avoiding stale firmware supplicant state for DPP. Signed-off-by: Kurt Lee Signed-off-by: Jason Huang Acked-by: Arend van Spriel --- Changes since v4: - Drop the pre-existing P2P device vif fixes; they are now a standalone wireless patch. - Keep this patch limited to DPP AKM/RSN parsing and DPP public action frame handling. .../broadcom/brcm80211/brcmfmac/cfg80211.c | 151 ++++++++++-------- .../broadcom/brcm80211/brcmfmac/p2p.c | 54 +++++-- .../broadcom/brcm80211/include/brcmu_wifi.h | 2 + 3 files changed, 130 insertions(+), 77 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/= drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 4b70845e1a26..d61c3e03a106 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -2154,6 +2155,9 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cf= g80211_connect_params *sme) val =3D WPA2_AUTH_PSK | WPA2_AUTH_FT; profile->is_ft =3D true; break; + case WLAN_AKM_SUITE_WFA_DPP: + val =3D WFA_AUTH_DPP; + break; default: bphy_err(drvr, "invalid akm suite (%d)\n", sme->crypto.akm_suites[0]); @@ -2466,43 +2470,50 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct = net_device *ndev, goto done; } =20 - if (sme->crypto.psk && - profile->use_fwsup !=3D BRCMF_PROFILE_FWSUP_SAE) { - if (WARN_ON(profile->use_fwsup !=3D BRCMF_PROFILE_FWSUP_NONE)) { - err =3D -EINVAL; - goto done; - } - brcmf_dbg(INFO, "using PSK offload\n"); - profile->use_fwsup =3D BRCMF_PROFILE_FWSUP_PSK; - } - - if (profile->use_fwsup !=3D BRCMF_PROFILE_FWSUP_NONE) { - /* enable firmware supplicant for this interface */ - err =3D brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1); - if (err < 0) { - bphy_err(drvr, "failed to enable fw supplicant\n"); - goto done; + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWSUP)) { + u32 akm =3D sme->crypto.n_akm_suites ? sme->crypto.akm_suites[0] : 0; + bool is_sae_akm =3D akm =3D=3D WLAN_AKM_SUITE_SAE || + akm =3D=3D WLAN_AKM_SUITE_FT_OVER_SAE; + + if (sme->crypto.psk && !is_sae_akm && + profile->use_fwsup !=3D BRCMF_PROFILE_FWSUP_SAE) { + if (WARN_ON(profile->use_fwsup !=3D + BRCMF_PROFILE_FWSUP_NONE)) { + err =3D -EINVAL; + goto done; + } + brcmf_dbg(INFO, "using PSK offload\n"); + profile->use_fwsup =3D BRCMF_PROFILE_FWSUP_PSK; } - } - - if (profile->use_fwsup =3D=3D BRCMF_PROFILE_FWSUP_PSK) - err =3D brcmf_set_pmk(ifp, sme->crypto.psk, - BRCMF_WSEC_MAX_PSK_LEN); - else if (profile->use_fwsup =3D=3D BRCMF_PROFILE_FWSUP_SAE) { - /* clean up user-space RSNE */ - err =3D brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0); - if (err) { - bphy_err(drvr, "failed to clean up user-space RSNE\n"); - goto done; + if (profile->use_fwsup !=3D BRCMF_PROFILE_FWSUP_NONE) { + /* enable firmware supplicant for this interface */ + err =3D brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1); + if (err < 0) { + bphy_err(drvr, "failed to enable fw supplicant\n"); + goto done; + } + } else { + err =3D brcmf_fil_iovar_int_set(ifp, "sup_wpa", 0); } - err =3D brcmf_fwvid_set_sae_password(ifp, &sme->crypto); - if (!err && sme->crypto.psk) + if (profile->use_fwsup =3D=3D BRCMF_PROFILE_FWSUP_PSK) err =3D brcmf_set_pmk(ifp, sme->crypto.psk, BRCMF_WSEC_MAX_PSK_LEN); + else if (profile->use_fwsup =3D=3D BRCMF_PROFILE_FWSUP_SAE && + sme->crypto.sae_pwd && + brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE)) { + /* clean up user-space RSNE */ + if (brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0)) { + bphy_err(drvr, "failed to clean up user-space RSNE\n"); + goto done; + } + err =3D brcmf_fwvid_set_sae_password(ifp, &sme->crypto); + if (!err && sme->crypto.psk) + err =3D brcmf_set_pmk(ifp, sme->crypto.psk, + BRCMF_WSEC_MAX_PSK_LEN); + } + if (err) + goto done; } - if (err) - goto done; - /* Join with specific BSSID and cached SSID * If SSID is zero join based on BSSID only */ @@ -4519,6 +4530,11 @@ static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn= _ie) return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) =3D=3D 0); } =20 +static bool brcmf_valid_dpp_suite(u8 *oui) +{ + return get_unaligned_be32(oui) =3D=3D WLAN_AKM_SUITE_WFA_DPP; +} + static s32 brcmf_configure_wpaie(struct brcmf_if *ifp, const struct brcmf_vs_tlv *wpa_ie, @@ -4632,42 +4648,47 @@ brcmf_configure_wpaie(struct brcmf_if *ifp, goto exit; } for (i =3D 0; i < count; i++) { - if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) { + if (brcmf_valid_dpp_suite(&data[offset])) { + wpa_auth |=3D WFA_AUTH_DPP; + offset +=3D TLV_OUI_LEN; + } else if (brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) { + offset +=3D TLV_OUI_LEN; + switch (data[offset]) { + case RSN_AKM_NONE: + brcmf_dbg(TRACE, "RSN_AKM_NONE\n"); + wpa_auth |=3D WPA_AUTH_NONE; + break; + case RSN_AKM_UNSPECIFIED: + brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n"); + is_rsn_ie ? + (wpa_auth |=3D WPA2_AUTH_UNSPECIFIED) : + (wpa_auth |=3D WPA_AUTH_UNSPECIFIED); + break; + case RSN_AKM_PSK: + brcmf_dbg(TRACE, "RSN_AKM_PSK\n"); + is_rsn_ie ? (wpa_auth |=3D WPA2_AUTH_PSK) : + (wpa_auth |=3D WPA_AUTH_PSK); + break; + case RSN_AKM_SHA256_PSK: + brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n"); + wpa_auth |=3D WPA2_AUTH_PSK_SHA256; + break; + case RSN_AKM_SHA256_1X: + brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n"); + wpa_auth |=3D WPA2_AUTH_1X_SHA256; + break; + case RSN_AKM_SAE: + brcmf_dbg(TRACE, "RSN_AKM_SAE\n"); + wpa_auth |=3D WPA3_AUTH_SAE_PSK; + break; + default: + bphy_err(drvr, "Invalid key mgmt info\n"); + } + } else { err =3D -EINVAL; bphy_err(drvr, "invalid OUI\n"); goto exit; } - offset +=3D TLV_OUI_LEN; - switch (data[offset]) { - case RSN_AKM_NONE: - brcmf_dbg(TRACE, "RSN_AKM_NONE\n"); - wpa_auth |=3D WPA_AUTH_NONE; - break; - case RSN_AKM_UNSPECIFIED: - brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n"); - is_rsn_ie ? (wpa_auth |=3D WPA2_AUTH_UNSPECIFIED) : - (wpa_auth |=3D WPA_AUTH_UNSPECIFIED); - break; - case RSN_AKM_PSK: - brcmf_dbg(TRACE, "RSN_AKM_PSK\n"); - is_rsn_ie ? (wpa_auth |=3D WPA2_AUTH_PSK) : - (wpa_auth |=3D WPA_AUTH_PSK); - break; - case RSN_AKM_SHA256_PSK: - brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n"); - wpa_auth |=3D WPA2_AUTH_PSK_SHA256; - break; - case RSN_AKM_SHA256_1X: - brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n"); - wpa_auth |=3D WPA2_AUTH_1X_SHA256; - break; - case RSN_AKM_SAE: - brcmf_dbg(TRACE, "RSN_AKM_SAE\n"); - wpa_auth |=3D WPA3_AUTH_SAE_PSK; - break; - default: - bphy_err(drvr, "Invalid key mgmt info\n"); - } offset++; } =20 @@ -4687,10 +4708,12 @@ brcmf_configure_wpaie(struct brcmf_if *ifp, */ if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 | WPA2_AUTH_1X_SHA256 | + WFA_AUTH_DPP | WPA3_AUTH_SAE_PSK))) { err =3D -EINVAL; goto exit; } + /* Firmware has requirement that WPA2_AUTH_PSK/ * WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI * is to be included in the rsn ie. diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drive= rs/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c index 6e0c90f4718b..58a9738e81ac 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c @@ -6,6 +6,7 @@ #include #include #include +#include #include =20 #include @@ -44,9 +45,6 @@ =20 #define BRCMF_SCB_TIMEOUT_VALUE 20 =20 -#define P2P_VER 9 /* P2P version: 9=3DWiFi P2P v1.0 */ -#define P2P_PUB_AF_CATEGORY 0x04 -#define P2P_PUB_AF_ACTION 0x09 #define P2P_AF_CATEGORY 0x7f #define P2P_OUI "\x50\x6F\x9A" /* P2P OUI */ #define P2P_OUI_LEN 3 /* P2P OUI length */ @@ -143,10 +141,10 @@ struct brcmf_p2p_scan_le { /** * struct brcmf_p2p_pub_act_frame - WiFi P2P Public Action Frame * - * @category: P2P_PUB_AF_CATEGORY - * @action: P2P_PUB_AF_ACTION + * @category: WLAN_CATEGORY_PUBLIC + * @action: WLAN_PUB_ACTION_VENDOR_SPECIFIC * @oui: P2P_OUI - * @oui_type: OUI type - P2P_VER + * @oui_type: OUI type - WLAN_OUI_TYPE_WFA_P2P * @subtype: OUI subtype - P2P_TYPE_* * @dialog_token: nonzero, identifies req/rsp transaction * @elts: Variable length information elements. @@ -166,7 +164,7 @@ struct brcmf_p2p_pub_act_frame { * * @category: P2P_AF_CATEGORY * @oui: OUI - P2P_OUI - * @type: OUI Type - P2P_VER + * @type: OUI Type - WLAN_OUI_TYPE_WFA_P2P * @subtype: OUI Subtype - P2P_AF_* * @dialog_token: nonzero, identifies req/resp tranaction * @elts: Variable length information elements. @@ -228,10 +226,38 @@ static bool brcmf_p2p_is_pub_action(void *frame, u32 = frame_len) if (frame_len < sizeof(*pact_frm)) return false; =20 - if (pact_frm->category =3D=3D P2P_PUB_AF_CATEGORY && - pact_frm->action =3D=3D P2P_PUB_AF_ACTION && - pact_frm->oui_type =3D=3D P2P_VER && - memcmp(pact_frm->oui, P2P_OUI, P2P_OUI_LEN) =3D=3D 0) + if (pact_frm->category =3D=3D WLAN_CATEGORY_PUBLIC && + pact_frm->action =3D=3D WLAN_PUB_ACTION_VENDOR_SPECIFIC && + pact_frm->oui_type =3D=3D WLAN_OUI_TYPE_WFA_P2P && + get_unaligned_be24(pact_frm->oui) =3D=3D WLAN_OUI_WFA) + return true; + + return false; +} + +/** + * brcmf_p2p_is_dpp_pub_action() - true if dpp public type frame. + * + * @frame: action frame data. + * @frame_len: length of action frame data. + * + * Determine if action frame is dpp public action type + */ +static bool brcmf_p2p_is_dpp_pub_action(void *frame, u32 frame_len) +{ + struct brcmf_p2p_pub_act_frame *pact_frm; + + if (!frame) + return false; + + pact_frm =3D (struct brcmf_p2p_pub_act_frame *)frame; + if (frame_len < sizeof(struct brcmf_p2p_pub_act_frame) - 1) + return false; + + if (pact_frm->category =3D=3D WLAN_CATEGORY_PUBLIC && + pact_frm->action =3D=3D WLAN_PUB_ACTION_VENDOR_SPECIFIC && + pact_frm->oui_type =3D=3D WLAN_OUI_TYPE_WFA_DPP && + get_unaligned_be24(pact_frm->oui) =3D=3D WLAN_OUI_WFA) return true; =20 return false; @@ -257,7 +283,7 @@ static bool brcmf_p2p_is_p2p_action(void *frame, u32 fr= ame_len) return false; =20 if (act_frm->category =3D=3D P2P_AF_CATEGORY && - act_frm->type =3D=3D P2P_VER && + act_frm->type =3D=3D WLAN_OUI_TYPE_WFA_P2P && memcmp(act_frm->oui, P2P_OUI, P2P_OUI_LEN) =3D=3D 0) return true; =20 @@ -1789,7 +1815,9 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg8021= 1_info *cfg, goto exit; } } else if (brcmf_p2p_is_p2p_action(action_frame->data, - action_frame_len)) { + action_frame_len) || + brcmf_p2p_is_dpp_pub_action(action_frame->data, + action_frame_len)) { /* do not configure anything. it will be */ /* sent with a default configuration */ } else { diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h b= /drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h index 7552bdb91991..c465208c4331 100644 --- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h +++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h @@ -233,6 +233,8 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec) =20 #define WPA3_AUTH_SAE_PSK 0x40000 /* SAE with 4-way handshake */ =20 +#define WFA_AUTH_DPP 0x200000 /* WFA DPP AUTH */ + #define DOT11_DEFAULT_RTS_LEN 2347 #define DOT11_DEFAULT_FRAG_LEN 2346 =20 base-commit: 3737936e2be920977aea7d9f7eb8cb4468d700d7 --=20 2.25.1