mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Michael Reeves via B4 Relay <devnull+michael.reeves077.gmail.com@kernel.org>
To: Arend van Spriel <arend.vanspriel@broadcom.com>,
	 Pieter-Paul Giesberts <pieterpg@broadcom.com>,
	 "Franky Lin (Zhenhui)" <frankyl@broadcom.com>,
	 Mathy Vanhoef <vanhoefm@gmail.com>,
	Kalle Valo <kvalo@kernel.org>,  Kees Cook <kees@kernel.org>,
	"Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: linux-wireless@vger.kernel.org, brcm80211@lists.linux.dev,
	 brcm80211-dev-list.pdl@broadcom.com, asahi@lists.linux.dev,
	 Hector Martin <marcan@marcan.st>,
	Daniel Berlin <dberlin@dberlin.org>,  Janne Grunau <j@jannau.net>,
	linux-kernel@vger.kernel.org,
	 Hante Meuleman <meuleman@broadcom.com>,
	linux-hardening@vger.kernel.org,
	 Michael Reeves <michael.reeves077@gmail.com>
Subject: [PATCH 11/13] wifi: brcmfmac: Support versioned join requests
Date: Fri, 25 Sep 2026 23:43:46 +1000	[thread overview]
Message-ID: <20260925-brcm4388-submit-v1-11-b5cbc2cde2fb@gmail.com> (raw)
In-Reply-To: <20260925-brcm4388-submit-v1-0-b5cbc2cde2fb@gmail.com>

From: Hector Martin <marcan@marcan.st>

Newer firmware uses version 1 join and association structures with
explicit version headers.

Query join_ver and build version 1 requests when required. Retain legacy
layouts for older firmware and fall back to BRCMF_C_SET_SSID when the
join iovar returns -EBADE. Use the selected association layout for IBSS
joins too. Report unsupported join versions rather than guessing their
request layout.

Signed-off-by: Hector Martin <marcan@marcan.st>
Signed-off-by: Daniel Berlin <dberlin@dberlin.org>
Co-developed-by: Michael Reeves <michael.reeves077@gmail.com>
Signed-off-by: Michael Reeves <michael.reeves077@gmail.com>
---
 .../broadcom/brcm80211/brcmfmac/cfg80211.c         | 73 +++++++++++++++++++---
 .../wireless/broadcom/brcm80211/brcmfmac/core.h    |  1 +
 .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 19 ++++++
 .../broadcom/brcm80211/brcmfmac/fwil_types.h       | 29 +++++++++
 4 files changed, 113 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 2ce7041be6..2a742ae8cc 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -1653,6 +1653,36 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason,
 	brcmf_dbg(TRACE, "Exit\n");
 }
 
+static int brcmf_set_ssid(struct brcmf_if *ifp,
+			  const struct brcmf_join_params *legacy, size_t legacy_size)
+{
+	struct brcmf_join_params_v1_le *params;
+	u32 count = le32_to_cpu(legacy->params_le.chanspec_num);
+	size_t size;
+	int err;
+
+	if (!ifp->drvr->join_version)
+		return brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
+					     (void *)legacy, legacy_size);
+	if (ifp->drvr->join_version != 1)
+		return -EOPNOTSUPP;
+
+	size = struct_size(params, assoc_le.chanspec_list, count);
+	params = kzalloc(size, GFP_KERNEL);
+	if (!params)
+		return -ENOMEM;
+
+	params->ssid_le = legacy->ssid_le;
+	params->assoc_le.version = cpu_to_le16(1);
+	ether_addr_copy(params->assoc_le.bssid, legacy->params_le.bssid);
+	params->assoc_le.chanspec_num = legacy->params_le.chanspec_num;
+	memcpy(params->assoc_le.chanspec_list, legacy->params_le.chanspec_list,
+	       count * sizeof(__le16));
+	err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, params, size);
+	kfree(params);
+	return err;
+}
+
 static s32
 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
 		      struct cfg80211_ibss_params *params)
@@ -1791,8 +1821,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
 	cfg->ibss_starter = false;
 
 
-	err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
-				     &join_params, join_params_size);
+	err = brcmf_set_ssid(ifp, &join_params, join_params_size);
 	if (err) {
 		bphy_err(drvr, "WLC_SET_SSID failed (%d)\n", err);
 		goto done;
@@ -2281,6 +2310,30 @@ static void brcmf_set_join_pref(struct brcmf_if *ifp,
 		bphy_err(drvr, "Set join_pref error (%d)\n", err);
 }
 
+static int brcmf_join_v1(struct brcmf_if *ifp,
+			 const struct brcmf_ext_join_params_le *legacy)
+{
+	struct brcmf_ext_join_params_v1_le *params;
+	u32 count = le32_to_cpu(legacy->assoc_le.chanspec_num);
+	size_t size = struct_size(params, assoc_le.chanspec_list, count);
+	int err;
+
+	params = kzalloc(size, GFP_KERNEL);
+	if (!params)
+		return -ENOMEM;
+	params->version = cpu_to_le16(1);
+	params->ssid_le = legacy->ssid_le;
+	params->scan_le = legacy->scan_le;
+	params->assoc_le.version = cpu_to_le16(1);
+	ether_addr_copy(params->assoc_le.bssid, legacy->assoc_le.bssid);
+	params->assoc_le.chanspec_num = legacy->assoc_le.chanspec_num;
+	memcpy(params->assoc_le.chanspec_list, legacy->assoc_le.chanspec_list,
+	       count * sizeof(__le16));
+	err = brcmf_fil_bsscfg_data_set(ifp, "join", params, size);
+	kfree(params);
+	return err;
+}
+
 static s32
 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
 		       struct cfg80211_connect_params *sme)
@@ -2302,6 +2355,8 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
 	u32 ssid_len;
 
 	brcmf_dbg(TRACE, "Enter\n");
+	if (drvr->join_version > 1)
+		return -EOPNOTSUPP;
 	if (!check_vif_up(ifp->vif))
 		return -EIO;
 
@@ -2492,14 +2547,15 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
 
 	brcmf_set_join_pref(ifp, &sme->bss_select);
 
-	err  = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
-					 join_params_size);
+	if (ifp->drvr->join_version == 1)
+		err = brcmf_join_v1(ifp, ext_join_params);
+	else
+		err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
+						join_params_size);
 	kfree(ext_join_params);
-	if (!err)
-		/* This is it. join command worked, we are done */
+	if (err != -EBADE)
 		goto done;
 
-	/* join command failed, fallback to set ssid */
 	memset(&join_params, 0, sizeof(join_params));
 	join_params_size = sizeof(join_params.ssid_le);
 
@@ -2516,8 +2572,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
 		join_params.params_le.chanspec_num = cpu_to_le32(1);
 		join_params_size += sizeof(join_params.params_le);
 	}
-	err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
-				     &join_params, join_params_size);
+	err = brcmf_set_ssid(ifp, &join_params, join_params_size);
 	if (err)
 		bphy_err(drvr, "BRCMF_C_SET_SSID failed (%d)\n", err);
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
index fe909f7add..320473970d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
@@ -162,6 +162,7 @@ struct brcmf_pub {
 	const struct brcmf_fwvid_ops *vops;
 	void *vdata;
 	struct scan_param_struct_handler scan_param_handler;
+	u16 join_version;
 };
 
 /* forward declarations */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index 44c0082e21..27fa3a7941 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -160,6 +160,10 @@ static void brcmf_feat_wlc_version_overrides(struct brcmf_pub *drv)
 
 	brcmf_dbg(INFO, "WLC version: %d.%d\n", major, minor);
 
+	if (major >= 17 || (major == 16 && minor >= 1) ||
+	    (major == 14 && (minor == 2 || minor == 4)))
+		drv->join_version = 1;
+
 	for (i = 0; i < ARRAY_SIZE(brcmf_feat_wlcfeat_map); i++) {
 		e = &brcmf_feat_wlcfeat_map[i];
 		if (major > e->min_ver_major ||
@@ -297,6 +301,20 @@ static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
 	}
 }
 
+static void brcmf_feat_join_params(struct brcmf_if *ifp)
+{
+	struct brcmf_join_version_le version = {};
+	int err;
+
+	err = brcmf_fil_iovar_data_get(ifp, "join_ver", &version,
+				       sizeof(version));
+	if (!err)
+		ifp->drvr->join_version = le16_to_cpu(version.major);
+	if (ifp->drvr->join_version > 1)
+		bphy_err(ifp->drvr, "unsupported join params v%u\n",
+			 ifp->drvr->join_version);
+}
+
 static void brcmf_feat_scan_params(struct brcmf_if *ifp)
 {
 	struct brcmf_pub *drvr = ifp->drvr;
@@ -430,6 +448,7 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
 	brcmf_feat_event_msgs_ext(ifp);
 
 	brcmf_feat_wlc_version_overrides(drvr);
+	brcmf_feat_join_params(ifp);
 	brcmf_feat_firmware_overrides(drvr);
 
 	brcmf_fwvid_feat_attach(ifp);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index dbba883bba..917966ad70 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -584,6 +584,35 @@ struct brcmf_ext_join_params_le {
 	struct brcmf_assoc_params_le assoc_le;
 };
 
+struct brcmf_assoc_params_v1_le {
+	__le16 version;
+	__le16 flags;
+	u8 bssid[ETH_ALEN];
+	__le16 bssid_cnt;
+	__le32 chanspec_num;
+	__le16 chanspec_list[];
+};
+
+struct brcmf_join_params_v1_le {
+	struct brcmf_ssid_le ssid_le;
+	struct brcmf_assoc_params_v1_le assoc_le;
+};
+
+struct brcmf_join_version_le {
+	__le16 version;
+	__le16 length;
+	__le16 major;
+	u8 pad[2];
+};
+
+struct brcmf_ext_join_params_v1_le {
+	__le16 version;
+	__le16 pad;
+	struct brcmf_ssid_le ssid_le;
+	struct brcmf_join_scan_params_le scan_le;
+	struct brcmf_assoc_params_v1_le assoc_le;
+};
+
 struct brcmf_wsec_key {
 	u32 index;		/* key index */
 	u32 len;		/* key length */

-- 
2.55.0



  parent reply	other threads:[~2026-09-25 13:43 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-25 13:43 [PATCH 00/13] wifi: brcmfmac: Add BCM4388 support Michael Reeves via B4 Relay
2026-09-25 13:43 ` [PATCH 01/13] wifi: brcmfmac: pcie: Report the detected chip ID to the bus Michael Reeves via B4 Relay
2026-09-25 13:43 ` [PATCH 02/13] wifi: brcmfmac: Match complete firmware capability names Michael Reeves via B4 Relay
2026-09-25 13:43 ` [PATCH 03/13] wifi: brcmfmac: Fall back to RSSI-only default join preferences Michael Reeves via B4 Relay
2026-09-25 13:43 ` [PATCH 04/13] wifi: brcmfmac: Support newer PCIe core startup and interrupts Michael Reeves via B4 Relay
2026-09-25 13:43 ` [PATCH 05/13] wifi: brcmfmac: Negotiate PCIe mailbox transport with firmware Michael Reeves via B4 Relay
2026-09-25 13:43 ` [PATCH 06/13] wifi: brcmfmac: Load signed PCIe firmware images Michael Reeves via B4 Relay
2026-09-25 13:43 ` [PATCH 07/13] wifi: brcmfmac: Use event_msgs_ext for event masks Michael Reeves via B4 Relay
2026-09-25 13:43 ` [PATCH 08/13] wifi: brcmfmac: Handle larger firmware band lists Michael Reeves via B4 Relay
2026-09-25 13:43 ` [PATCH 09/13] wifi: brcmfmac: Accept newer BSS information versions Michael Reeves via B4 Relay
2026-09-25 13:43 ` [PATCH 10/13] wifi: brcmfmac: Support versioned scan parameter layouts Michael Reeves via B4 Relay
2026-09-25 13:43 ` Michael Reeves via B4 Relay [this message]
2026-09-25 13:43 ` [PATCH 12/13] wifi: brcmfmac: Handle extended PMK command payloads Michael Reeves via B4 Relay
2026-09-25 13:43 ` [PATCH 13/13] wifi: brcmfmac: Add BCM4388 support Michael Reeves via B4 Relay

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260925-brcm4388-submit-v1-11-b5cbc2cde2fb@gmail.com \
    --to=devnull+michael.reeves077.gmail.com@kernel.org \
    --cc=arend.vanspriel@broadcom.com \
    --cc=asahi@lists.linux.dev \
    --cc=brcm80211-dev-list.pdl@broadcom.com \
    --cc=brcm80211@lists.linux.dev \
    --cc=dberlin@dberlin.org \
    --cc=frankyl@broadcom.com \
    --cc=gustavoars@kernel.org \
    --cc=j@jannau.net \
    --cc=kees@kernel.org \
    --cc=kvalo@kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=marcan@marcan.st \
    --cc=meuleman@broadcom.com \
    --cc=michael.reeves077@gmail.com \
    --cc=pieterpg@broadcom.com \
    --cc=vanhoefm@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®