Thread (117 messages) 117 messages, 5 authors, 2022-01-31
STALE1631d REVIEWED: 1 (0M)
Revisions (2)
  1. rfc [diff vs current]
  2. v2 current

[PATCH v2 06/35] brcmfmac: firmware: Support passing in multiple board_types

From: Hector Martin <hidden>
Date: 2022-01-04 07:28:40
Also in: linux-acpi, linux-devicetree, linux-wireless, lkml
Subsystem: broadcom brcm80211 ieee802.11 wireless drivers, the rest · Maintainers: Arend van Spriel, Linus Torvalds

In order to make use of the multiple alt_path functionality, change
board_type to an array. Bus drivers can pass in a NULL-terminated list
of board type strings to try for the firmware fetch.

Acked-by: Linus Walleij <redacted>
Signed-off-by: Hector Martin <redacted>
---
 .../broadcom/brcm80211/brcmfmac/firmware.c    | 35 ++++++++++++-------
 .../broadcom/brcm80211/brcmfmac/firmware.h    |  2 +-
 .../broadcom/brcm80211/brcmfmac/pcie.c        |  4 ++-
 .../broadcom/brcm80211/brcmfmac/sdio.c        |  2 +-
 4 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
index 7570dbf22cdd..054ea3ed133e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -594,28 +594,39 @@ static int brcmf_fw_complete_request(const struct firmware *fw,
 	return (cur->flags & BRCMF_FW_REQF_OPTIONAL) ? 0 : ret;
 }
 
-static int brcm_alt_fw_paths(const char *path, const char *board_type,
+static int brcm_alt_fw_paths(const char *path, struct brcmf_fw *fwctx,
 			     const char *alt_paths[BRCMF_FW_MAX_ALT_PATHS])
 {
+	const char **board_types = fwctx->req->board_types;
+	unsigned int i;
 	char alt_path[BRCMF_FW_NAME_LEN];
 	const char *suffix;
 
 	memset(alt_paths, 0, array_size(sizeof(*alt_paths),
 					BRCMF_FW_MAX_ALT_PATHS));
 
+	if (!board_types[0])
+		return -ENOENT;
+
 	suffix = strrchr(path, '.');
 	if (!suffix || suffix == path)
 		return -EINVAL;
 
-	/* strip extension at the end */
-	strscpy(alt_path, path, BRCMF_FW_NAME_LEN);
-	alt_path[suffix - path] = 0;
+	for (i = 0; i < BRCMF_FW_MAX_ALT_PATHS; i++) {
+		if (!board_types[i])
+		    break;
 
-	strlcat(alt_path, ".", BRCMF_FW_NAME_LEN);
-	strlcat(alt_path, board_type, BRCMF_FW_NAME_LEN);
-	strlcat(alt_path, suffix, BRCMF_FW_NAME_LEN);
+		/* strip extension at the end */
+		strscpy(alt_path, path, BRCMF_FW_NAME_LEN);
+		alt_path[suffix - path] = 0;
 
-	alt_paths[0] = kstrdup(alt_path, GFP_KERNEL);
+		strlcat(alt_path, ".", BRCMF_FW_NAME_LEN);
+		strlcat(alt_path, board_types[i], BRCMF_FW_NAME_LEN);
+		strlcat(alt_path, suffix, BRCMF_FW_NAME_LEN);
+
+		alt_paths[i] = kstrdup(alt_path, GFP_KERNEL);
+		brcmf_dbg(TRACE, "FW alt path: %s\n", alt_paths[i]);
+	}
 
 	return 0;
 }
@@ -637,11 +648,10 @@ static int brcmf_fw_request_firmware(const struct firmware **fw,
 	unsigned int i;
 
 	/* Files can be board-specific, first try a board-specific path */
-	if (fwctx->req->board_type) {
+	if (fwctx->req->board_types[0]) {
 		const char *alt_paths[BRCMF_FW_MAX_ALT_PATHS];
 
-		if (brcm_alt_fw_paths(cur->path, fwctx->req->board_type,
-				      alt_paths) != 0)
+		if (brcm_alt_fw_paths(cur->path, fwctx, alt_paths) != 0)
 			goto fallback;
 
 		for (i = 0; i < BRCMF_FW_MAX_ALT_PATHS && alt_paths[i]; i++) {
@@ -750,8 +760,7 @@ int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req,
 	fwctx->done = fw_cb;
 
 	/* First try alternative board-specific path if any */
-	if (brcm_alt_fw_paths(first->path, req->board_type,
-			      fwctx->alt_paths) == 0) {
+	if (brcm_alt_fw_paths(first->path, fwctx, fwctx->alt_paths) == 0) {
 		fwctx->alt_index = 0;
 		ret = request_firmware_nowait(THIS_MODULE, true,
 					      fwctx->alt_paths[0],
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
index 7f4e6e359c82..3b60a0e290b0 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
@@ -68,7 +68,7 @@ struct brcmf_fw_request {
 	u16 domain_nr;
 	u16 bus_nr;
 	u32 n_items;
-	const char *board_type;
+	const char *board_types[BRCMF_FW_MAX_ALT_PATHS];
 	struct brcmf_fw_item items[];
 };
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 591f870d1e47..a52a6f8081eb 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -1877,11 +1877,13 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
 	fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL;
 	fwreq->items[BRCMF_PCIE_FW_CLM].type = BRCMF_FW_TYPE_BINARY;
 	fwreq->items[BRCMF_PCIE_FW_CLM].flags = BRCMF_FW_REQF_OPTIONAL;
-	fwreq->board_type = devinfo->settings->board_type;
 	/* NVRAM reserves PCI domain 0 for Broadcom's SDK faked bus */
 	fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus) + 1;
 	fwreq->bus_nr = devinfo->pdev->bus->number;
 
+	brcmf_dbg(PCIE, "Board: %s\n", devinfo->settings->board_type);
+	fwreq->board_types[0] = devinfo->settings->board_type;
+
 	return fwreq;
 }
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 7466e6fd6eca..ed944764f6ea 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4432,7 +4432,7 @@ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus)
 	fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
 	fwreq->items[BRCMF_SDIO_FW_CLM].type = BRCMF_FW_TYPE_BINARY;
 	fwreq->items[BRCMF_SDIO_FW_CLM].flags = BRCMF_FW_REQF_OPTIONAL;
-	fwreq->board_type = bus->sdiodev->settings->board_type;
+	fwreq->board_types[0] = bus->sdiodev->settings->board_type;
 
 	return fwreq;
 }
-- 
2.33.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help