Take WiFi patches from Asahi Linux to read OTP

This means firmware will be selected automatically like macOS
does. These patches also fix a couple of bugs and make a few
optimisations.

For this firmware selection:

 # in macos (or linux if you have a copy of the wifi folder):
git clone https://github.com/AsahiLinux/asahi-installer --depth=1
cd asahi-installer/src
python3 -m firmware.wifi /usr/share/firmware/wifi firmware.tar
 # in linux
cd /lib/firmware
sudo tar xf /path/to/firmware.tar
This commit is contained in:
Redecorating
2021-12-24 17:23:00 +11:00
parent 8374c4f31d
commit e9cd73ca95
33 changed files with 3558 additions and 991 deletions
@@ -0,0 +1,49 @@
From 3f43bc112ea442739258e2c6b143408c7c45e2e9 Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Tue, 21 Dec 2021 19:32:16 +0900
Subject: [PATCH 01/30] brcmfmac: pcie: Declare missing firmware files in
pcie.c
Move one of the declarations from sdio.c to pcie.c, since it makes no
sense in the former (SDIO support is optional), and add missing ones.
Signed-off-by: Hector Martin <marcan@marcan.st>
Fixes: 75729e110e68 ("brcmfmac: expose firmware config files through modinfo")
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 7 +++++++
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 1 -
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 8b149996f..aed49416c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -59,6 +59,13 @@ BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie");
BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie");
BRCMF_FW_DEF(4371, "brcmfmac4371-pcie");
+/* firmware config files */
+MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.txt");
+MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.txt");
+
+/* per-board firmware binaries */
+MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.bin");
+
static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602),
BRCMF_FW_ENTRY(BRCM_CC_43465_CHIP_ID, 0xFFFFFFF0, 4366C),
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 8effeb7a7..5d156e591 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -629,7 +629,6 @@ BRCMF_FW_CLM_DEF(43752, "brcmfmac43752-sdio");
/* firmware config files */
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.txt");
-MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.txt");
/* per-board firmware binaries */
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.bin");
--
2.34.1
File diff suppressed because it is too large Load Diff
-147
View File
@@ -1,147 +0,0 @@
From a128c070e189999215e9ebd9dbb0cec795f5d175 Mon Sep 17 00:00:00 2001
From: Aditya Garg <gargaditya08@live.com>
Date: Tue, 28 Sep 2021 16:23:49 +0530
Subject: [PATCH] Add support for BCM4377
Co-authored-by: Aun-Ali Zaidi <admin@kodeit.net>
Co-authored-by: Houjun Liu <hliu@shabang.cf>
Co-authored-by: emergenz <franz.srambical@gmail.com>
Co-authored-by: Orlando Chamberlain <redecorating@protonmail.com>
---
.../broadcom/brcm80211/brcmfmac/chip.c | 4 +++
.../broadcom/brcm80211/brcmfmac/pcie.c | 32 +++++++++++++++----
.../broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++
3 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index 1bf0fa8f0..1e1b23bf4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -727,6 +727,8 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
return 0x160000;
case CY_CC_43752_CHIP_ID:
return 0x170000;
+ case BRCM_CC_4377_CHIP_ID:
+ return 0x170000;
case BRCM_CC_4378_CHIP_ID:
return 0x352000;
default:
@@ -1428,6 +1430,8 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
reg = chip->ops->read32(chip->ctx, addr);
return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
+ case BRCM_CC_4377_CHIP_ID:
+ return false;
case BRCM_CC_4378_CHIP_ID:
return false;
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index ce8c552c6..6f0166b33 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -59,6 +59,7 @@ BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie");
BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie");
BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie");
BRCMF_FW_DEF(4371, "brcmfmac4371-pcie");
+BRCMF_FW_DEF(4377, "brcmfmac4377-pcie");
BRCMF_FW_DEF(4378, "brcmfmac4378-pcie");
static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
@@ -81,6 +82,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43664_CHIP_ID, 0xFFFFFFF0, 4366C),
BRCMF_FW_ENTRY(BRCM_CC_43666_CHIP_ID, 0xFFFFFFF0, 4366C),
BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
+ BRCMF_FW_ENTRY(BRCM_CC_4377_CHIP_ID, 0xFFFFFFFF, 4377),
BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0xFFFFFFFF, 4378),
};
@@ -586,23 +588,33 @@ brcmf_pcie_reg_map(struct brcmf_pciedev_info *devinfo, u32 reg)
{
switch(reg) {
case BRCMF_PCIE_PCIE2REG_INTMASK:
- if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID)
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID)
+ return BRCMF_PCIE_64_PCIE2REG_INTMASK;
+ else if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID)
return BRCMF_PCIE_64_PCIE2REG_INTMASK;
return reg;
case BRCMF_PCIE_PCIE2REG_MAILBOXINT:
- if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID)
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID)
+ return BRCMF_PCIE_64_PCIE2REG_MAILBOXINT;
+ else if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID)
return BRCMF_PCIE_64_PCIE2REG_MAILBOXINT;
return reg;
case BRCMF_PCIE_PCIE2REG_MAILBOXMASK:
- if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID)
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID)
+ return BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK;
+ else if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID)
return BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK;
return reg;
case BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0:
- if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID)
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID)
+ return BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_0;
+ else if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID)
return BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_0;
return reg;
case BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1:
- if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID)
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID)
+ return BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_1;
+ else if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID)
return BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_1;
return reg;
default:
@@ -1018,7 +1030,10 @@ static void brcmf_pcie_intr_disable(struct brcmf_pciedev_info *devinfo)
static void brcmf_pcie_intr_enable(struct brcmf_pciedev_info *devinfo)
{
- if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID)
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID)
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK,
+ BRCMF_PCIE_64_MB_INT_D2H_DB);
+ else if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID)
brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK,
BRCMF_PCIE_64_MB_INT_D2H_DB);
else
@@ -1053,7 +1068,9 @@ static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg)
struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
u32 status, mask;
- if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID)
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID)
+ mask = BRCMF_PCIE_64_MB_INT_D2H_DB;
+ else if(devinfo->ci->chip == BRCM_CC_4378_CHIP_ID)
mask = BRCMF_PCIE_64_MB_INT_D2H_DB;
else
mask = BRCMF_PCIE_MB_INT_D2H_DB;
@@ -2363,6 +2380,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = {
BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_2G_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4371_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID),
{ /* end: all zeroes */ }
};
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
index 242df778f..eb3f361a2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -50,6 +50,7 @@
#define BRCM_CC_43664_CHIP_ID 43664
#define BRCM_CC_43666_CHIP_ID 43666
#define BRCM_CC_4371_CHIP_ID 0x4371
+#define BRCM_CC_4377_CHIP_ID 0x4377
#define BRCM_CC_4378_CHIP_ID 0x4378
#define CY_CC_4373_CHIP_ID 0x4373
#define CY_CC_43012_CHIP_ID 43012
@@ -85,6 +86,7 @@
#define BRCM_PCIE_4366_2G_DEVICE_ID 0x43c4
#define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5
#define BRCM_PCIE_4371_DEVICE_ID 0x440d
+#define BRCM_PCIE_4377_DEVICE_ID 0x4488
#define BRCM_PCIE_4378_DEVICE_ID 0x4425
@@ -0,0 +1,166 @@
From 59c61aa5ad2e12fdbccb5712d35c203cf9079230 Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Sat, 18 Dec 2021 20:38:34 +0900
Subject: [PATCH 02/30] brcmfmac: firmware: Support having multiple alt paths
Apple platforms have firmware and config files identified with multiple
dimensions. We want to be able to find the most specific firmware
available for any given platform, progressively trying more general
firmwares.
First, add support for having multiple alternate firmware paths.
Signed-off-by: Hector Martin <marcan@marcan.st>
---
.../broadcom/brcm80211/brcmfmac/firmware.c | 74 ++++++++++++++-----
1 file changed, 55 insertions(+), 19 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
index 0eb13e5df..dff974955 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -427,6 +427,8 @@ void brcmf_fw_nvram_free(void *nvram)
struct brcmf_fw {
struct device *dev;
struct brcmf_fw_request *req;
+ const char **alt_paths;
+ int alt_index;
u32 curpos;
void (*done)(struct device *dev, int err, struct brcmf_fw_request *req);
};
@@ -592,9 +594,10 @@ static int brcmf_fw_complete_request(const struct firmware *fw,
return (cur->flags & BRCMF_FW_REQF_OPTIONAL) ? 0 : ret;
}
-static char *brcm_alt_fw_path(const char *path, const char *board_type)
+static const char **brcm_alt_fw_paths(const char *path, const char *board_type)
{
char alt_path[BRCMF_FW_NAME_LEN];
+ char **alt_paths;
char suffix[5];
strscpy(alt_path, path, BRCMF_FW_NAME_LEN);
@@ -609,27 +612,45 @@ static char *brcm_alt_fw_path(const char *path, const char *board_type)
strlcat(alt_path, board_type, BRCMF_FW_NAME_LEN);
strlcat(alt_path, suffix, BRCMF_FW_NAME_LEN);
- return kstrdup(alt_path, GFP_KERNEL);
+ alt_paths = kzalloc(sizeof(char *) * 2, GFP_KERNEL);
+ alt_paths[0] = kstrdup(alt_path, GFP_KERNEL);
+
+ return (const char **)alt_paths;
+}
+
+static void brcm_free_alt_fw_paths(const char **alt_paths)
+{
+ int i;
+
+ if (!alt_paths)
+ return;
+
+ for (i = 0; alt_paths[i]; i++)
+ kfree(alt_paths[i]);
+
+ kfree(alt_paths);
}
static int brcmf_fw_request_firmware(const struct firmware **fw,
struct brcmf_fw *fwctx)
{
struct brcmf_fw_item *cur = &fwctx->req->items[fwctx->curpos];
- int ret;
+ int ret, i;
/* Files can be board-specific, first try a board-specific path */
if (cur->type == BRCMF_FW_TYPE_NVRAM && fwctx->req->board_type) {
- char *alt_path;
-
- alt_path = brcm_alt_fw_path(cur->path, fwctx->req->board_type);
- if (!alt_path)
+ const char **alt_paths = brcm_alt_fw_paths(cur->path, fwctx);
+ if (!alt_paths)
goto fallback;
- ret = request_firmware(fw, alt_path, fwctx->dev);
- kfree(alt_path);
- if (ret == 0)
- return ret;
+ for (i = 0; alt_paths[i]; i++) {
+ ret = firmware_request_nowarn(fw, alt_paths[i], fwctx->dev);
+ if (ret == 0) {
+ brcm_free_alt_fw_paths(alt_paths);
+ return ret;
+ }
+ }
+ brcm_free_alt_fw_paths(alt_paths);
}
fallback:
@@ -641,6 +662,9 @@ static void brcmf_fw_request_done(const struct firmware *fw, void *ctx)
struct brcmf_fw *fwctx = ctx;
int ret;
+ brcm_free_alt_fw_paths(fwctx->alt_paths);
+ fwctx->alt_paths = NULL;
+
ret = brcmf_fw_complete_request(fw, fwctx);
while (ret == 0 && ++fwctx->curpos < fwctx->req->n_items) {
@@ -662,13 +686,26 @@ static void brcmf_fw_request_done_alt_path(const struct firmware *fw, void *ctx)
struct brcmf_fw_item *first = &fwctx->req->items[0];
int ret = 0;
- /* Fall back to canonical path if board firmware not found */
- if (!fw)
+ if (fw) {
+ brcmf_fw_request_done(fw, ctx);
+ return;
+ }
+
+ fwctx->alt_index++;
+ if (fwctx->alt_paths[fwctx->alt_index]) {
+ /* Try the next alt firmware */
+ ret = request_firmware_nowait(THIS_MODULE, true,
+ fwctx->alt_paths[fwctx->alt_index],
+ fwctx->dev, GFP_KERNEL, fwctx,
+ brcmf_fw_request_done_alt_path);
+ } else {
+ /* Fall back to canonical path if board firmware not found */
ret = request_firmware_nowait(THIS_MODULE, true, first->path,
fwctx->dev, GFP_KERNEL, fwctx,
brcmf_fw_request_done);
+ }
- if (fw || ret < 0)
+ if (ret < 0)
brcmf_fw_request_done(fw, ctx);
}
@@ -693,7 +730,6 @@ int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req,
{
struct brcmf_fw_item *first = &req->items[0];
struct brcmf_fw *fwctx;
- char *alt_path;
int ret;
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
@@ -712,12 +748,12 @@ 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 */
- alt_path = brcm_alt_fw_path(first->path, fwctx->req->board_type);
- if (alt_path) {
- ret = request_firmware_nowait(THIS_MODULE, true, alt_path,
+ fwctx->alt_paths = brcm_alt_fw_paths(first->path, fwctx);
+ if (fwctx->alt_paths) {
+ fwctx->alt_index = 0;
+ ret = request_firmware_nowait(THIS_MODULE, true, fwctx->alt_paths[0],
fwctx->dev, GFP_KERNEL, fwctx,
brcmf_fw_request_done_alt_path);
- kfree(alt_path);
} else {
ret = request_firmware_nowait(THIS_MODULE, true, first->path,
fwctx->dev, GFP_KERNEL, fwctx,
--
2.34.1
@@ -0,0 +1,56 @@
From 637e3946944e25c98c8955ec2a84133b79afca4d Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Sat, 18 Dec 2021 20:52:04 +0900
Subject: [PATCH 03/30] brcmfmac: firmware: Handle per-board clm_blob files
Teach brcm_alt_fw_paths to correctly split off variable length
extensions, and enable alt firmware lookups for the CLM blob firmware
requests.
Apple platforms have per-board CLM blob files.
Signed-off-by: Hector Martin <marcan@marcan.st>
---
.../broadcom/brcm80211/brcmfmac/firmware.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
index dff974955..16f342bc5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -598,16 +598,16 @@ static const char **brcm_alt_fw_paths(const char *path, const char *board_type)
{
char alt_path[BRCMF_FW_NAME_LEN];
char **alt_paths;
- char suffix[5];
+ const char *suffix;
- strscpy(alt_path, path, BRCMF_FW_NAME_LEN);
- /* At least one character + suffix */
- if (strlen(alt_path) < 5)
+ suffix = strrchr(path, '.');
+ if (!suffix || suffix == path)
return NULL;
- /* strip .txt or .bin at the end */
- strscpy(suffix, alt_path + strlen(alt_path) - 4, 5);
- alt_path[strlen(alt_path) - 4] = 0;
+ /* strip extension at the end */
+ strscpy(alt_path, path, BRCMF_FW_NAME_LEN);
+ alt_path[suffix - path] = 0;
+
strlcat(alt_path, ".", BRCMF_FW_NAME_LEN);
strlcat(alt_path, board_type, BRCMF_FW_NAME_LEN);
strlcat(alt_path, suffix, BRCMF_FW_NAME_LEN);
@@ -638,7 +638,7 @@ static int brcmf_fw_request_firmware(const struct firmware **fw,
int ret, i;
/* Files can be board-specific, first try a board-specific path */
- if (cur->type == BRCMF_FW_TYPE_NVRAM && fwctx->req->board_type) {
+ if (fwctx->req->board_type) {
const char **alt_paths = brcm_alt_fw_paths(cur->path, fwctx);
if (!alt_paths)
goto fallback;
--
2.34.1
@@ -0,0 +1,345 @@
From 95cfbeaaac15e765969a5048c6815c83d59adeec Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Tue, 21 Dec 2021 17:13:49 +0900
Subject: [PATCH 04/30] brcmfmac: pcie/sdio/usb: Get CLM blob via standard
firmware mechanism
Now that the firmware fetcher can handle per-board CLM files, load the
CLM blob alongside the other firmware files and change the bus API to
just return the existing blob, instead of fetching the filename.
This enables per-board CLM blobs, which are required on Apple platforms.
Signed-off-by: Hector Martin <marcan@marcan.st>
---
.../broadcom/brcm80211/brcmfmac/bus.h | 12 +++----
.../broadcom/brcm80211/brcmfmac/common.c | 12 ++-----
.../broadcom/brcm80211/brcmfmac/pcie.c | 32 +++++++++++--------
.../broadcom/brcm80211/brcmfmac/sdio.c | 29 +++++++++--------
.../broadcom/brcm80211/brcmfmac/sdio.h | 2 ++
.../broadcom/brcm80211/brcmfmac/usb.c | 22 +++----------
6 files changed, 47 insertions(+), 62 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
index 3f5da3bb6..7880f77a4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -7,6 +7,8 @@
#define BRCMFMAC_BUS_H
#include "debug.h"
+#include <linux/kernel.h>
+#include <linux/firmware.h>
/* IDs of the 6 default common rings of msgbuf protocol */
#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT 0
@@ -60,7 +62,7 @@ struct brcmf_bus_dcmd {
* @wowl_config: specify if dongle is configured for wowl when going to suspend
* @get_ramsize: obtain size of device memory.
* @get_memdump: obtain device memory dump in provided buffer.
- * @get_fwname: obtain firmware name.
+ * @get_clm: obtain CLM firmware blob.
*
* This structure provides an abstract interface towards the
* bus specific driver. For control messages to common driver
@@ -77,8 +79,7 @@ struct brcmf_bus_ops {
void (*wowl_config)(struct device *dev, bool enabled);
size_t (*get_ramsize)(struct device *dev);
int (*get_memdump)(struct device *dev, void *data, size_t len);
- int (*get_fwname)(struct device *dev, const char *ext,
- unsigned char *fw_name);
+ int (*get_clm)(struct device *dev, const struct firmware **fw);
void (*debugfs_create)(struct device *dev);
int (*reset)(struct device *dev);
};
@@ -220,10 +221,9 @@ int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len)
}
static inline
-int brcmf_bus_get_fwname(struct brcmf_bus *bus, const char *ext,
- unsigned char *fw_name)
+int brcmf_bus_get_clm(struct brcmf_bus *bus, const struct firmware **fw)
{
- return bus->ops->get_fwname(bus->dev, ext, fw_name);
+ return bus->ops->get_clm(bus->dev, fw);
}
static inline
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index e3758bd86..ec4cb7050 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -123,7 +123,6 @@ static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
struct brcmf_bus *bus = drvr->bus_if;
struct brcmf_dload_data_le *chunk_buf;
const struct firmware *clm = NULL;
- u8 clm_name[BRCMF_FW_NAME_LEN];
u32 chunk_len;
u32 datalen;
u32 cumulative_len;
@@ -133,15 +132,8 @@ static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
brcmf_dbg(TRACE, "Enter\n");
- memset(clm_name, 0, sizeof(clm_name));
- err = brcmf_bus_get_fwname(bus, ".clm_blob", clm_name);
- if (err) {
- bphy_err(drvr, "get CLM blob file name failed (%d)\n", err);
- return err;
- }
-
- err = firmware_request_nowarn(&clm, clm_name, bus->dev);
- if (err) {
+ err = brcmf_bus_get_clm(bus, &clm);
+ if (err || !clm) {
brcmf_info("no clm_blob available (err=%d), device may have limited channels available\n",
err);
return 0;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index aed49416c..ea8776fd2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -65,6 +65,7 @@ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.txt");
/* per-board firmware binaries */
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.bin");
+MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.clm_blob");
static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602),
@@ -260,6 +261,8 @@ struct brcmf_pciedev_info {
struct pci_dev *pdev;
char fw_name[BRCMF_FW_NAME_LEN];
char nvram_name[BRCMF_FW_NAME_LEN];
+ char clm_name[BRCMF_FW_NAME_LEN];
+ const struct firmware *clm_fw;
void __iomem *regs;
void __iomem *tcm;
u32 ram_base;
@@ -1408,23 +1411,18 @@ static int brcmf_pcie_get_memdump(struct device *dev, void *data, size_t len)
return 0;
}
-static
-int brcmf_pcie_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
+static int brcmf_pcie_get_clm(struct device *dev, const struct firmware **fw)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
- struct brcmf_fw_request *fwreq;
- struct brcmf_fw_name fwnames[] = {
- { ext, fw_name },
- };
+ struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
+ struct brcmf_pciedev_info *devinfo = buspub->devinfo;
- fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev,
- brcmf_pcie_fwnames,
- ARRAY_SIZE(brcmf_pcie_fwnames),
- fwnames, ARRAY_SIZE(fwnames));
- if (!fwreq)
- return -ENOMEM;
+ if (!devinfo->clm_fw) {
+ return -ENOENT;
+ }
- kfree(fwreq);
+ *fw = devinfo->clm_fw;
+ devinfo->clm_fw = NULL;
return 0;
}
@@ -1470,7 +1468,7 @@ static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
.wowl_config = brcmf_pcie_wowl_config,
.get_ramsize = brcmf_pcie_get_ramsize,
.get_memdump = brcmf_pcie_get_memdump,
- .get_fwname = brcmf_pcie_get_fwname,
+ .get_clm = brcmf_pcie_get_clm,
.reset = brcmf_pcie_reset,
};
@@ -1755,6 +1753,7 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
#define BRCMF_PCIE_FW_CODE 0
#define BRCMF_PCIE_FW_NVRAM 1
+#define BRCMF_PCIE_FW_CLM 2
static void brcmf_pcie_setup(struct device *dev, int ret,
struct brcmf_fw_request *fwreq)
@@ -1779,6 +1778,7 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
fw = fwreq->items[BRCMF_PCIE_FW_CODE].binary;
nvram = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.data;
nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len;
+ devinfo->clm_fw = fwreq->items[BRCMF_PCIE_FW_CLM].binary;
kfree(fwreq);
ret = brcmf_chip_get_raminfo(devinfo->ci);
@@ -1855,6 +1855,7 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
struct brcmf_fw_name fwnames[] = {
{ ".bin", devinfo->fw_name },
{ ".txt", devinfo->nvram_name },
+ { ".clm_blob", devinfo->clm_name },
};
fwreq = brcmf_fw_alloc_request(devinfo->ci->chip, devinfo->ci->chiprev,
@@ -1867,6 +1868,8 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
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;
@@ -2005,6 +2008,7 @@ brcmf_pcie_remove(struct pci_dev *pdev)
brcmf_pcie_release_ringbuffers(devinfo);
brcmf_pcie_reset_device(devinfo);
brcmf_pcie_release_resource(devinfo);
+ release_firmware(devinfo->clm_fw);
if (devinfo->ci)
brcmf_chip_detach(devinfo->ci);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 5d156e591..593ddd237 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4129,23 +4129,17 @@ brcmf_sdio_watchdog(struct timer_list *t)
}
}
-static
-int brcmf_sdio_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
+static int brcmf_sdio_get_clm(struct device *dev, const struct firmware **fw)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
- struct brcmf_fw_request *fwreq;
- struct brcmf_fw_name fwnames[] = {
- { ext, fw_name },
- };
+ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
- fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev,
- brcmf_sdio_fwnames,
- ARRAY_SIZE(brcmf_sdio_fwnames),
- fwnames, ARRAY_SIZE(fwnames));
- if (!fwreq)
- return -ENOMEM;
+ if (!sdiodev->clm_fw) {
+ return -ENOENT;
+ }
- kfree(fwreq);
+ *fw = sdiodev->clm_fw;
+ sdiodev->clm_fw = NULL;
return 0;
}
@@ -4188,13 +4182,14 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
.wowl_config = brcmf_sdio_wowl_config,
.get_ramsize = brcmf_sdio_bus_get_ramsize,
.get_memdump = brcmf_sdio_bus_get_memdump,
- .get_fwname = brcmf_sdio_get_fwname,
+ .get_clm = brcmf_sdio_get_clm,
.debugfs_create = brcmf_sdio_debugfs_create,
.reset = brcmf_sdio_bus_reset
};
#define BRCMF_SDIO_FW_CODE 0
#define BRCMF_SDIO_FW_NVRAM 1
+#define BRCMF_SDIO_FW_CLM 2
static void brcmf_sdio_firmware_callback(struct device *dev, int err,
struct brcmf_fw_request *fwreq)
@@ -4217,6 +4212,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
code = fwreq->items[BRCMF_SDIO_FW_CODE].binary;
nvram = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.data;
nvram_len = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.len;
+ sdiod->clm_fw = fwreq->items[BRCMF_SDIO_FW_CLM].binary;
kfree(fwreq);
/* try to download image and nvram to the dongle */
@@ -4415,6 +4411,7 @@ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus)
struct brcmf_fw_name fwnames[] = {
{ ".bin", bus->sdiodev->fw_name },
{ ".txt", bus->sdiodev->nvram_name },
+ { ".clm_blob", bus->sdiodev->clm_name },
};
fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev,
@@ -4426,6 +4423,8 @@ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus)
fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
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;
return fwreq;
@@ -4582,6 +4581,8 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
if (bus->sdiodev->settings)
brcmf_release_module_param(bus->sdiodev->settings);
+ release_firmware(bus->sdiodev->clm_fw);
+ bus->sdiodev->clm_fw = NULL;
kfree(bus->rxbuf);
kfree(bus->hdrbuf);
kfree(bus);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index 15d2c02fa..7b74c295e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -186,9 +186,11 @@ struct brcmf_sdio_dev {
struct sg_table sgtable;
char fw_name[BRCMF_FW_NAME_LEN];
char nvram_name[BRCMF_FW_NAME_LEN];
+ char clm_name[BRCMF_FW_NAME_LEN];
bool wowl_enabled;
enum brcmf_sdiod_state state;
struct brcmf_sdiod_freezer *freezer;
+ const struct firmware *clm_fw;
};
/* sdio core registers */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index 9fb68c2dc..b8a8bf774 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -1154,24 +1154,10 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
return NULL;
}
-static
-int brcmf_usb_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
+static int brcmf_usb_get_clm(struct device *dev, const struct firmware **fw)
{
- struct brcmf_bus *bus = dev_get_drvdata(dev);
- struct brcmf_fw_request *fwreq;
- struct brcmf_fw_name fwnames[] = {
- { ext, fw_name },
- };
-
- fwreq = brcmf_fw_alloc_request(bus->chip, bus->chiprev,
- brcmf_usb_fwnames,
- ARRAY_SIZE(brcmf_usb_fwnames),
- fwnames, ARRAY_SIZE(fwnames));
- if (!fwreq)
- return -ENOMEM;
-
- kfree(fwreq);
- return 0;
+ /* No CLM blobs for USB devices... */
+ return -ENOENT;
}
static const struct brcmf_bus_ops brcmf_usb_bus_ops = {
@@ -1180,7 +1166,7 @@ static const struct brcmf_bus_ops brcmf_usb_bus_ops = {
.txdata = brcmf_usb_tx,
.txctl = brcmf_usb_tx_ctlpkt,
.rxctl = brcmf_usb_rx_ctlpkt,
- .get_fwname = brcmf_usb_get_fwname,
+ .get_clm = brcmf_usb_get_clm,
};
#define BRCMF_USB_FW_CODE 0
--
2.34.1
@@ -1,28 +0,0 @@
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 8b149996f..78f2cc7c1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -2022,6 +2022,11 @@ static int brcmf_pcie_pm_enter_D3(struct device *dev)
bus = dev_get_drvdata(dev);
devinfo = bus->bus_priv.pcie->devinfo;
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID) {
+ brcmf_dbg(PCIE, "Skip enter D3 for 4377, remember to rfkill block before this\n");
+ return 0;
+ }
+
brcmf_bus_change_state(bus, BRCMF_BUS_DOWN);
devinfo->mbdata_completed = false;
@@ -2054,6 +2059,11 @@ static int brcmf_pcie_pm_leave_D3(struct device *dev)
devinfo = bus->bus_priv.pcie->devinfo;
brcmf_dbg(PCIE, "Enter, dev=%p, bus=%p\n", dev, bus);
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID) {
+ brcmf_dbg(PCIE, "Skip leave D3 for 4377, remember to rfkill unblock after this\n");
+ return 0;
+ }
+
/* Check if device is still up and running, if so we are ready */
if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0) {
brcmf_dbg(PCIE, "Try to wakeup device....\n");
@@ -0,0 +1,135 @@
From f7df4e463c323eaf303ca4d1a6721c8458a8cdd1 Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Tue, 21 Dec 2021 17:38:37 +0900
Subject: [PATCH 05/30] brcmfmac: firmware: Support passing in multiple
board_types
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.
Signed-off-by: Hector Martin <marcan@marcan.st>
---
.../broadcom/brcm80211/brcmfmac/firmware.c | 35 +++++++++++++------
.../broadcom/brcm80211/brcmfmac/firmware.h | 2 +-
.../broadcom/brcm80211/brcmfmac/pcie.c | 7 +++-
.../broadcom/brcm80211/brcmfmac/sdio.c | 4 ++-
4 files changed, 35 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
index 16f342bc5..02e36fa3d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -594,26 +594,41 @@ static int brcmf_fw_complete_request(const struct firmware *fw,
return (cur->flags & BRCMF_FW_REQF_OPTIONAL) ? 0 : ret;
}
-static const char **brcm_alt_fw_paths(const char *path, const char *board_type)
+static const char **brcm_alt_fw_paths(const char *path, struct brcmf_fw *fwctx)
{
+ const char **board_types = fwctx->req->board_types;
+ int board_type_count = 0;
+ int i;
char alt_path[BRCMF_FW_NAME_LEN];
char **alt_paths;
const char *suffix;
+ if (!board_types || !board_types[0])
+ return NULL;
+
+ while (*board_types++)
+ board_type_count++;
+
suffix = strrchr(path, '.');
if (!suffix || suffix == path)
return NULL;
- /* strip extension at the end */
- strscpy(alt_path, path, BRCMF_FW_NAME_LEN);
- alt_path[suffix - path] = 0;
+ alt_paths = kzalloc(sizeof(char *) * (board_type_count + 1),
+ GFP_KERNEL);
+
+ board_types = fwctx->req->board_types;
+ for (i = 0; i < board_type_count; i++) {
+ /* strip extension at the end */
+ strscpy(alt_path, path, BRCMF_FW_NAME_LEN);
+ alt_path[suffix - path] = 0;
- strlcat(alt_path, ".", BRCMF_FW_NAME_LEN);
- strlcat(alt_path, board_type, BRCMF_FW_NAME_LEN);
- strlcat(alt_path, suffix, BRCMF_FW_NAME_LEN);
+ 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 = kzalloc(sizeof(char *) * 2, GFP_KERNEL);
- alt_paths[0] = kstrdup(alt_path, GFP_KERNEL);
+ alt_paths[i] = kstrdup(alt_path, GFP_KERNEL);
+ brcmf_dbg(TRACE, "FW alt path: %s\n", alt_paths[i]);
+ }
return (const char **)alt_paths;
}
@@ -638,7 +653,7 @@ static int brcmf_fw_request_firmware(const struct firmware **fw,
int ret, i;
/* Files can be board-specific, first try a board-specific path */
- if (fwctx->req->board_type) {
+ if (fwctx->req->board_types) {
const char **alt_paths = brcm_alt_fw_paths(cur->path, fwctx);
if (!alt_paths)
goto fallback;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
index e290dec9c..d94a1d5be 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
@@ -66,7 +66,7 @@ struct brcmf_fw_request {
u16 domain_nr;
u16 bus_nr;
u32 n_items;
- const char *board_type;
+ const char **board_types;
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 ea8776fd2..cdfb32d6f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -1870,11 +1870,16 @@ 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 = devm_kzalloc(&devinfo->pdev->dev,
+ sizeof(const char *) * 2,
+ GFP_KERNEL);
+ 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 593ddd237..637aef30c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4425,7 +4425,9 @@ 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 = devm_kzalloc(bus->sdiodev->dev,
+ sizeof(const char *) * 2, GFP_KERNEL);
+ fwreq->board_types[0] = bus->sdiodev->settings->board_type;
return fwreq;
}
--
2.34.1
@@ -0,0 +1,301 @@
From 5e341c53e88383a998f3618e999762f660a26c02 Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Tue, 21 Dec 2021 17:26:34 +0900
Subject: [PATCH 06/30] brcmfmac: pcie: Read Apple OTP information
On Apple platforms, the One Time Programmable ROM in the Broadcom chips
contains information about the specific board design (module, vendor,
version) that is required to select the correct NVRAM file. Parse this
OTP ROM and extract the required strings.
Note that the user OTP offset/size is per-chip. This patch does not add
any chips yet.
Signed-off-by: Hector Martin <marcan@marcan.st>
---
.../broadcom/brcm80211/brcmfmac/pcie.c | 221 ++++++++++++++++++
include/linux/bcma/bcma_driver_chipcommon.h | 1 +
2 files changed, 222 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index cdfb32d6f..3cc79d912 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -255,6 +255,15 @@ struct brcmf_pcie_core_info {
u32 wrapbase;
};
+#define BRCMF_OTP_MAX_PARAM_LEN 16
+
+struct brcmf_otp_params {
+ char module[BRCMF_OTP_MAX_PARAM_LEN];
+ char vendor[BRCMF_OTP_MAX_PARAM_LEN];
+ char version[BRCMF_OTP_MAX_PARAM_LEN];
+ bool valid;
+};
+
struct brcmf_pciedev_info {
enum brcmf_pcie_state state;
bool in_irq;
@@ -282,6 +291,7 @@ struct brcmf_pciedev_info {
void (*write_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
u16 value);
struct brcmf_mp_device *settings;
+ struct brcmf_otp_params otp;
};
struct brcmf_pcie_ringbuf {
@@ -353,6 +363,15 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
static struct brcmf_fw_request *
brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo);
+static u16
+brcmf_pcie_read_reg16(struct brcmf_pciedev_info *devinfo, u32 reg_offset)
+{
+ void __iomem *address = devinfo->regs + reg_offset;
+
+ return (ioread16(address));
+}
+
+
static u32
brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset)
{
@@ -539,6 +558,8 @@ brcmf_pcie_copy_dev_tomem(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
}
+#define READCC32(devinfo, reg) brcmf_pcie_read_reg32(devinfo, \
+ CHIPCREGOFFS(reg))
#define WRITECC32(devinfo, reg, value) brcmf_pcie_write_reg32(devinfo, \
CHIPCREGOFFS(reg), value)
@@ -1751,6 +1772,200 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
.write32 = brcmf_pcie_buscore_write32,
};
+#define BRCMF_OTP_SYS_VENDOR 0x15
+#define BRCMF_OTP_BRCM_CIS 0x80
+
+#define BRCMF_OTP_VENDOR_HDR 0x00000008
+
+static int
+brcmf_pcie_parse_otp_sys_vendor(struct brcmf_pciedev_info *devinfo,
+ u8 *data, size_t size)
+{
+ int idx = 4;
+ const char *chip_params;
+ const char *module_params;
+ const char *p;
+
+ /* 4-byte header and two empty strings */
+ if (size < 6)
+ return -EINVAL;
+
+ if (get_unaligned_le32(data) != BRCMF_OTP_VENDOR_HDR)
+ return -EINVAL;
+
+ chip_params = &data[idx];
+
+ /* Skip first string, including terminator */
+ idx += strnlen(chip_params, size - idx) + 1;
+ if (idx >= size)
+ return -EINVAL;
+
+ module_params = &data[idx];
+
+ /* Skip to terminator of second string */
+ idx += strnlen(module_params, size - idx);
+ if (idx >= size)
+ return -EINVAL;
+
+ /* At this point both strings are guaranteed NUL-terminated */
+ brcmf_dbg(PCIE, "OTP: chip_params='%s' module_params='%s'\n",
+ chip_params, module_params);
+
+ p = module_params;
+ while (*p) {
+ char tag = *p++;
+ const char *end;
+ size_t len;
+
+ if (tag == ' ') /* Skip extra spaces */
+ continue;
+
+ if (*p++ != '=') /* implicit NUL check */
+ return -EINVAL;
+
+ /* *p might be NUL here, if so end == p and len == 0 */
+ end = strchrnul(p, ' ');
+ len = end - p;
+
+ /* leave 1 byte for NUL in destination string */
+ if (len > (BRCMF_OTP_MAX_PARAM_LEN - 1))
+ return -EINVAL;
+
+ /* Copy len characters plus a NUL terminator */
+ switch (tag) {
+ case 'M':
+ strlcpy(devinfo->otp.module, p, len + 1);
+ break;
+ case 'V':
+ strlcpy(devinfo->otp.vendor, p, len + 1);
+ break;
+ case 'm':
+ strlcpy(devinfo->otp.version, p, len + 1);
+ break;
+ }
+
+ /* Skip to space separator or NUL */
+ p = end;
+ }
+
+ brcmf_dbg(PCIE, "OTP: module=%s vendor=%s version=%s\n",
+ devinfo->otp.module, devinfo->otp.vendor,
+ devinfo->otp.version);
+
+ if (!devinfo->otp.module ||
+ !devinfo->otp.vendor ||
+ !devinfo->otp.version)
+ return -EINVAL;
+
+ devinfo->otp.valid = true;
+ return 0;
+}
+
+static int
+brcmf_pcie_parse_otp(struct brcmf_pciedev_info *devinfo, u8 *otp, size_t size)
+{
+ int p = 0;
+ int ret = -1;
+
+ brcmf_dbg(PCIE, "parse_otp size=%ld\n", size);
+
+ while (p < (size - 1)) {
+ u8 type = otp[p];
+ u8 length = otp[p + 1];
+
+ if (type == 0)
+ break;
+
+ if ((p + 2 + length) > size)
+ break;
+
+ switch (type) {
+ case BRCMF_OTP_SYS_VENDOR:
+ brcmf_dbg(PCIE, "OTP @ 0x%x (0x%x): SYS_VENDOR\n",
+ p, length);
+ ret = brcmf_pcie_parse_otp_sys_vendor(devinfo,
+ &otp[p + 2],
+ length);
+ break;
+ case BRCMF_OTP_BRCM_CIS:
+ brcmf_dbg(PCIE, "OTP @ 0x%x (0x%x): BRCM_CIS\n",
+ p, length);
+ break;
+ default:
+ brcmf_dbg(PCIE, "OTP @ 0x%x (0x%x): Unknown type 0x%x\n",
+ p, length, type);
+ break;
+ }
+
+ p += 2 + length;
+ }
+
+ return ret;
+}
+
+static int brcmf_pcie_read_otp(struct brcmf_pciedev_info *devinfo)
+{
+ const struct pci_dev *pdev = devinfo->pdev;
+ struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev);
+ u32 coreid, base, words, idx, sromctl;
+ u16 *otp;
+ struct brcmf_core *core;
+ int ret;
+
+ switch (devinfo->ci->chip) {
+ default:
+ /* OTP not supported on this chip */
+ return 0;
+ }
+
+ core = brcmf_chip_get_core(devinfo->ci, coreid);
+ if (!core) {
+ brcmf_err(bus, "No OTP core\n");
+ return -ENODEV;
+ }
+
+ if (coreid == BCMA_CORE_CHIPCOMMON) {
+ /*
+ * Chips with OTP accessed via ChipCommon need additional
+ * handling to access the OTP
+ */
+ brcmf_pcie_select_core(devinfo, coreid);
+ sromctl = READCC32(devinfo, sromcontrol);
+
+ if (!(sromctl & BCMA_CC_SROM_CONTROL_OTP_PRESENT)) {
+ /* Chip lacks OTP, try without it... */
+ brcmf_err(bus,
+ "OTP unavailable, using default firmware\n");
+ return 0;
+ }
+
+ /* Map OTP to shadow area */
+ WRITECC32(devinfo, sromcontrol,
+ sromctl | BCMA_CC_SROM_CONTROL_OTPSEL);
+ }
+
+ otp = kzalloc(sizeof(u16) * words, GFP_KERNEL);
+
+ /* Map bus window to SROM/OTP shadow area in core */
+ base = brcmf_pcie_buscore_prep_addr(devinfo->pdev, base + core->base);
+
+ brcmf_dbg(PCIE, "OTP data:\n");
+ for (idx = 0; idx < words; idx++) {
+ otp[idx] = brcmf_pcie_read_reg16(devinfo, base + 2 * idx);
+ brcmf_dbg(PCIE, "[%8x] 0x%04x\n", base + 2 * idx, otp[idx]);
+ }
+
+ if (coreid == BCMA_CORE_CHIPCOMMON) {
+ brcmf_pcie_select_core(devinfo, coreid);
+ WRITECC32(devinfo, sromcontrol, sromctl);
+ }
+
+ ret = brcmf_pcie_parse_otp(devinfo, (u8 *)otp, 2 * words);
+ kfree(otp);
+
+ return ret;
+}
+
#define BRCMF_PCIE_FW_CODE 0
#define BRCMF_PCIE_FW_NVRAM 1
#define BRCMF_PCIE_FW_CLM 2
@@ -1951,6 +2166,12 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (ret)
goto fail_bus;
+ ret = brcmf_pcie_read_otp(devinfo);
+ if (ret) {
+ brcmf_err(bus, "failed to parse OTP\n");
+ goto fail_brcmf;
+ }
+
fwreq = brcmf_pcie_prepare_fw_request(devinfo);
if (!fwreq) {
ret = -ENOMEM;
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index d35b92060..c91db7460 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -270,6 +270,7 @@
#define BCMA_CC_SROM_CONTROL_OP_WRDIS 0x40000000
#define BCMA_CC_SROM_CONTROL_OP_WREN 0x60000000
#define BCMA_CC_SROM_CONTROL_OTPSEL 0x00000010
+#define BCMA_CC_SROM_CONTROL_OTP_PRESENT 0x00000020
#define BCMA_CC_SROM_CONTROL_LOCK 0x00000008
#define BCMA_CC_SROM_CONTROL_SIZE_MASK 0x00000006
#define BCMA_CC_SROM_CONTROL_SIZE_1K 0x00000000
--
2.34.1
@@ -0,0 +1,76 @@
From 5a9d560acd1ed5a2b1d16c124aba6ff3f2205483 Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Tue, 21 Dec 2021 17:27:19 +0900
Subject: [PATCH 07/30] brcmfmac: of: Fetch Apple properties
On Apple ARM64 platforms, firmware selection requires two properties
that come from system firmware: the module-instance (aka "island", a
codename representing a given hardware platform) and the antenna-sku.
The module-instance is hard-coded in per-board DTS files, while the
antenna-sku is forwarded by our bootloader from the Apple Device Tree
into the FDT. Grab them from the DT so firmware selection can use
them.
The module-instance is used to construct a board_type by prepending it
with "apple,".
Signed-off-by: Hector Martin <marcan@marcan.st>
---
.../broadcom/brcm80211/brcmfmac/common.h | 1 +
.../wireless/broadcom/brcm80211/brcmfmac/of.c | 20 ++++++++++++++++++-
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
index 8b5f49997..d4aa25d64 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -50,6 +50,7 @@ struct brcmf_mp_device {
bool ignore_probe_fail;
struct brcmfmac_pd_cc *country_codes;
const char *board_type;
+ const char *antenna_sku;
union {
struct brcmfmac_sdio_pd sdio;
} bus;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
index 513c7e642..31407d3a1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
@@ -63,14 +63,32 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
{
struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio;
struct device_node *root, *np = dev->of_node;
+ const char *prop;
int irq;
int err;
u32 irqf;
u32 val;
+ /*
+ * Apple ARM64 platforms have their own idea of board type, passed in
+ * via the device tree. They also have an antenna SKU parameter
+ */
+ if (!of_property_read_string(np, "apple,module-instance", &prop)) {
+ const char *prefix = "apple,";
+ int len = strlen(prefix) + strlen(prop) + 1;
+ char *board_type = devm_kzalloc(dev, len, GFP_KERNEL);
+
+ strlcpy(board_type, prefix, len);
+ strlcat(board_type, prop, len);
+ settings->board_type = board_type;
+ }
+
+ if (!of_property_read_string(np, "apple,antenna-sku", &prop))
+ settings->antenna_sku = devm_kstrdup(dev, prop, GFP_KERNEL);
+
/* Set board-type to the first string of the machine compatible prop */
root = of_find_node_by_path("/");
- if (root) {
+ if (root && !settings->board_type) {
int i, len;
char *board_type;
const char *tmp;
--
2.34.1
@@ -0,0 +1,160 @@
From 9d6841d0ecb677e20436d60f6d82fb006613972b Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Tue, 21 Dec 2021 17:45:21 +0900
Subject: [PATCH 08/30] brcmfmac: pcie: Perform firmware selection for Apple
platforms
On Apple platforms, firmware selection uses the following elements:
Property Example Source
============== ======= ========================
* Chip name 4378 Device ID
* Chip revision B1 OTP
* Platform shikoku DT (ARM64) or ACPI (x86)
* Module type RASP OTP
* Module vendor m OTP
* Module version 6.11 OTP
* Antenna SKU X3 DT (ARM64) or ??? (x86)
In macOS, these firmwares are stored using filenames in this format
under /usr/share/firmware/wifi:
C-4378__s-B1/P-shikoku-X3_M-RASP_V-m__m-6.11.txt
To prepare firmwares for Linux, we rename these to a scheme following
the existing brcmfmac convention:
brcmfmac<chip><lower(rev)>-pcie.apple,<platform>-<mod_type>-\
<mod_vendor>-<mod_version>-<antenna_sku>.txt
The NVRAM uses all the components, while the firmware and CLM blob only
use the chip/revision/platform/antenna_sku:
brcmfmac<chip><lower(rev)>-pcie.apple,<platform>-<antenna_sku>.bin
e.g.
brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m-6.11-X3.txt
brcm/brcmfmac4378b1-pcie.apple,shikoku-X3.bin
In addition, since there are over 1000 files in total, many of which are
symlinks or outright duplicates, we deduplicate and prune the firmware
tree to reduce firmware filenames to fewer dimensions. For example, the
shikoku platform (MacBook Air M1 2020) simplifies to just 4 files:
brcm/brcmfmac4378b1-pcie.apple,shikoku.clm_blob
brcm/brcmfmac4378b1-pcie.apple,shikoku.bin
brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m.txt
brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-u.txt
This reduces the total file count to around 170, of which 75 are
symlinks and 95 are regular files: 7 firmware blobs, 27 CLM blobs, and
61 NVRAM config files. We also slightly process NVRAM files to correct
some formatting issues and add a missing default macaddr= property.
To handle this, the driver must try the following path formats when
looking for firmware files:
brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m-6.11-X3.txt
brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m-6.11.txt
brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m.txt
brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP.txt
brcm/brcmfmac4378b1-pcie.apple,shikoku-X3.txt *
brcm/brcmfmac4378b1-pcie.apple,shikoku.txt
* Not relevant for NVRAM, only for for firmware/CLM.
The chip revision nominally comes from OTP on Apple platforms, but it
can be mapped to the PCI revision number, so we ignore the OTP revision
and continue to use the existing PCI revision mechanism to identify chip
revisions, as the driver already does for other chips. Unfortunately,
the mapping is not consistent between different chip types, so this has
to be determined experimentally.
Signed-off-by: Hector Martin <marcan@marcan.st>
---
.../broadcom/brcm80211/brcmfmac/pcie.c | 68 +++++++++++++++++--
1 file changed, 63 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 3cc79d912..42b3c17ba 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -2089,11 +2089,69 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
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 = devm_kzalloc(&devinfo->pdev->dev,
- sizeof(const char *) * 2,
- GFP_KERNEL);
- fwreq->board_types[0] = devinfo->settings->board_type;
+ /* Apple platforms with fancy firmware/NVRAM selection */
+ if (devinfo->settings->board_type &&
+ devinfo->settings->antenna_sku &&
+ devinfo->otp.valid) {
+ char *buf;
+ int len;
+
+ brcmf_dbg(PCIE, "Apple board: %s\n",
+ devinfo->settings->board_type);
+
+ /* Example: apple,shikoku-RASP-m-6.11-X3 */
+ len = (strlen(devinfo->settings->board_type) + 1 +
+ strlen(devinfo->otp.module) + 1 +
+ strlen(devinfo->otp.vendor) + 1 +
+ strlen(devinfo->otp.version) + 1 +
+ strlen(devinfo->settings->antenna_sku) + 1);
+
+ fwreq->board_types = devm_kzalloc(&devinfo->pdev->dev,
+ sizeof(const char *) * 7,
+ GFP_KERNEL);
+
+ /* apple,shikoku */
+ fwreq->board_types[5] = devinfo->settings->board_type;
+
+ buf = devm_kzalloc(&devinfo->pdev->dev, len, GFP_KERNEL);
+
+ strlcpy(buf, devinfo->settings->board_type, len);
+ strlcat(buf, "-", len);
+ strlcat(buf, devinfo->settings->antenna_sku, len);
+ /* apple,shikoku-X3 */
+ fwreq->board_types[4] = devm_kstrdup(&devinfo->pdev->dev, buf,
+ GFP_KERNEL);
+
+ strlcpy(buf, devinfo->settings->board_type, len);
+ strlcat(buf, "-", len);
+ strlcat(buf, devinfo->otp.module, len);
+ /* apple,shikoku-RASP */
+ fwreq->board_types[3] = devm_kstrdup(&devinfo->pdev->dev, buf,
+ GFP_KERNEL);
+
+ strlcat(buf, "-", len);
+ strlcat(buf, devinfo->otp.vendor, len);
+ /* apple,shikoku-RASP-m */
+ fwreq->board_types[2] = devm_kstrdup(&devinfo->pdev->dev, buf,
+ GFP_KERNEL);
+
+ strlcat(buf, "-", len);
+ strlcat(buf, devinfo->otp.version, len);
+ /* apple,shikoku-RASP-m-6.11 */
+ fwreq->board_types[1] = devm_kstrdup(&devinfo->pdev->dev, buf,
+ GFP_KERNEL);
+
+ strlcat(buf, "-", len);
+ strlcat(buf, devinfo->settings->antenna_sku, len);
+ /* apple,shikoku-RASP-m-6.11-X3 */
+ fwreq->board_types[0] = buf;
+ } else {
+ brcmf_dbg(PCIE, "Board: %s\n", devinfo->settings->board_type);
+ fwreq->board_types = devm_kzalloc(&devinfo->pdev->dev,
+ sizeof(const char *) * 2,
+ GFP_KERNEL);
+ fwreq->board_types[0] = devinfo->settings->board_type;
+ }
return fwreq;
}
--
2.34.1
@@ -0,0 +1,125 @@
From 3b481da6295a389716c2d8fcfb4b5b87a0ef4103 Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Thu, 23 Dec 2021 22:32:08 +0900
Subject: [PATCH 09/30] brcmfmac: firmware: Allow platform to override macaddr
On Device Tree platforms, it is customary to be able to set the MAC
address via the Device Tree, as it is often stored in system firmware.
This is particularly relevant for Apple ARM64 platforms, where this
information comes from system configuration and passed through by the
bootloader into the DT.
Implement support for this by fetching the platform MAC address and
adding or replacing the macaddr= property in nvram. This becomes the
dongle's default MAC address.
On platforms with an SROM MAC address, this overrides it. On platforms
without one, such as Apple ARM64 devices, this is required for the
firmware to boot (it will fail if it does not have a valid MAC at all).
Signed-off-by: Hector Martin <marcan@marcan.st>
---
.../broadcom/brcm80211/brcmfmac/firmware.c | 30 +++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
index 02e36fa3d..dc4151bcc 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -21,6 +21,8 @@
#define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */
#define BRCMF_FW_NVRAM_PCIEDEV_LEN 10 /* pcie/1/4/ + \0 */
#define BRCMF_FW_DEFAULT_BOARDREV "boardrev=0xff"
+#define BRCMF_FW_MACADDR_FMT "macaddr=%pM"
+#define BRCMF_FW_MACADDR_LEN (7 + ETH_ALEN * 3)
enum nvram_parser_state {
IDLE,
@@ -57,6 +59,7 @@ struct nvram_parser {
bool multi_dev_v1;
bool multi_dev_v2;
bool boardrev_found;
+ bool strip_mac;
};
/*
@@ -121,6 +124,10 @@ static enum nvram_parser_state brcmf_nvram_handle_key(struct nvram_parser *nvp)
nvp->multi_dev_v2 = true;
if (strncmp(&nvp->data[nvp->entry], "boardrev", 8) == 0)
nvp->boardrev_found = true;
+ /* strip macaddr if platform MAC overrides */
+ if (nvp->strip_mac &&
+ strncmp(&nvp->data[nvp->entry], "macaddr", 7) == 0)
+ st = COMMENT;
} else if (!is_nvram_char(c) || c == ' ') {
brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n",
nvp->line, nvp->column);
@@ -207,6 +214,9 @@ static int brcmf_init_nvram_parser(struct nvram_parser *nvp,
size = BRCMF_FW_MAX_NVRAM_SIZE;
else
size = data_len;
+ /* Add space for properties we may add */
+ size += strlen(BRCMF_FW_DEFAULT_BOARDREV) + 1;
+ size += BRCMF_FW_MACADDR_LEN + 1;
/* Alloc for extra 0 byte + roundup by 4 + length field */
size += 1 + 3 + sizeof(u32);
nvp->nvram = kzalloc(size, GFP_KERNEL);
@@ -366,22 +376,34 @@ static void brcmf_fw_add_defaults(struct nvram_parser *nvp)
nvp->nvram_len++;
}
+static void brcmf_fw_add_macaddr(struct nvram_parser *nvp, u8 *mac)
+{
+ snprintf(&nvp->nvram[nvp->nvram_len], BRCMF_FW_MACADDR_LEN + 1,
+ BRCMF_FW_MACADDR_FMT, mac);
+ nvp->nvram_len += BRCMF_FW_MACADDR_LEN + 1;
+}
+
/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a fil
* and ending in a NUL. Removes carriage returns, empty lines, comment lines,
* and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
* End of buffer is completed with token identifying length of buffer.
*/
static void *brcmf_fw_nvram_strip(const u8 *data, size_t data_len,
- u32 *new_length, u16 domain_nr, u16 bus_nr)
+ u32 *new_length, u16 domain_nr, u16 bus_nr,
+ struct device *dev)
{
struct nvram_parser nvp;
u32 pad;
u32 token;
__le32 token_le;
+ u8 mac[ETH_ALEN];
if (brcmf_init_nvram_parser(&nvp, data, data_len) < 0)
return NULL;
+ if (eth_platform_get_mac_address(dev, mac) == 0)
+ nvp.strip_mac = true;
+
while (nvp.pos < data_len) {
nvp.state = nv_parser_states[nvp.state](&nvp);
if (nvp.state == END)
@@ -402,6 +424,9 @@ static void *brcmf_fw_nvram_strip(const u8 *data, size_t data_len,
brcmf_fw_add_defaults(&nvp);
+ if (nvp.strip_mac)
+ brcmf_fw_add_macaddr(&nvp, mac);
+
pad = nvp.nvram_len;
*new_length = roundup(nvp.nvram_len + 1, 4);
while (pad != *new_length) {
@@ -546,7 +571,8 @@ static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
if (data)
nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length,
fwctx->req->domain_nr,
- fwctx->req->bus_nr);
+ fwctx->req->bus_nr,
+ fwctx->dev);
if (free_bcm47xx_nvram)
bcm47xx_nvram_release_contents(data);
--
2.34.1
@@ -0,0 +1,34 @@
From 037883f3157a508078ffcaf336475645fa373f6a Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Tue, 21 Dec 2021 17:39:04 +0900
Subject: [PATCH 10/30] brcmfmac: msgbuf: Increase RX ring sizes to 1024
Newer chips used on Apple platforms have more than max_rxbufpost greater
than 512, which causes warnings when brcmf_msgbuf_rxbuf_data_fill tries
to put more in the ring than fit. Increase the ring sizes to 1024.
Signed-off-by: Hector Martin <marcan@marcan.st>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
index 2e322edbb..6a849f4a9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
@@ -8,10 +8,10 @@
#ifdef CONFIG_BRCMFMAC_PROTO_MSGBUF
#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM 64
-#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM 512
+#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM 1024
#define BRCMF_D2H_MSGRING_CONTROL_COMPLETE_MAX_ITEM 64
#define BRCMF_D2H_MSGRING_TX_COMPLETE_MAX_ITEM 1024
-#define BRCMF_D2H_MSGRING_RX_COMPLETE_MAX_ITEM 512
+#define BRCMF_D2H_MSGRING_RX_COMPLETE_MAX_ITEM 1024
#define BRCMF_H2D_TXFLOWRING_MAX_ITEM 512
#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE 40
--
2.34.1
@@ -0,0 +1,62 @@
From caea8fe9c9524950fedd3b317a05556dca105403 Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Tue, 21 Dec 2021 17:44:00 +0900
Subject: [PATCH 11/30] brcmfmac: pcie: Fix crashes due to early IRQs
The driver was enabling IRQs before the message processing was
initialized. This could cause IRQs to come in too early and crash the
driver. Instead, move the IRQ enable and hostready to a bus preinit
function, at which point everything is properly initialized.
Fixes: 9e37f045d5e7 ("brcmfmac: Adding PCIe bus layer support.")
Signed-off-by: Hector Martin <marcan@marcan.st>
---
.../broadcom/brcm80211/brcmfmac/pcie.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 42b3c17ba..a4b49d175 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -1380,6 +1380,20 @@ static void brcmf_pcie_down(struct device *dev)
}
+static int brcmf_pcie_preinit(struct device *dev)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
+
+ brcmf_dbg(PCIE, "Enter\n");
+
+ brcmf_pcie_intr_enable(buspub->devinfo);
+ brcmf_pcie_hostready(buspub->devinfo);
+
+ return 0;
+}
+
+
static int brcmf_pcie_tx(struct device *dev, struct sk_buff *skb)
{
return 0;
@@ -1482,6 +1496,7 @@ static int brcmf_pcie_reset(struct device *dev)
}
static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
+ .preinit = brcmf_pcie_preinit,
.txdata = brcmf_pcie_tx,
.stop = brcmf_pcie_down,
.txctl = brcmf_pcie_tx_ctlpkt,
@@ -2048,9 +2063,6 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
init_waitqueue_head(&devinfo->mbdata_resp_wait);
- brcmf_pcie_intr_enable(devinfo);
- brcmf_pcie_hostready(devinfo);
-
ret = brcmf_attach(&devinfo->pdev->dev);
if (ret)
goto fail;
--
2.34.1
@@ -0,0 +1,266 @@
From fa24c7e164edae9afea03d4af6264e0151b42649 Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Tue, 21 Dec 2021 17:25:35 +0900
Subject: [PATCH 12/30] brcmfmac: pcie: Support PCIe core revisions >= 64
These newer PCIe core revisions include new sets of registers that must
be used instead of the legacy ones. Introduce a brcmf_pcie_reginfo to
hold the specific register offsets and values to use for a given
platform, and change all the register accesses to indirect through it.
Signed-off-by: Hector Martin <marcan@marcan.st>
---
.../broadcom/brcm80211/brcmfmac/pcie.c | 127 +++++++++++++++---
1 file changed, 107 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index a4b49d175..4a6370efb 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -117,6 +117,14 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
#define BRCMF_PCIE_PCIE2REG_CONFIGDATA 0x124
#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0 0x140
#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1 0x144
+#define BRCMF_PCIE_PCIE2REG_D2H_MAILBOX_0 0x148
+#define BRCMF_PCIE_PCIE2REG_D2H_MAILBOX_1 0x14c
+
+#define BRCMF_PCIE_64_PCIE2REG_INTMASK 0xC14
+#define BRCMF_PCIE_64_PCIE2REG_MAILBOXINT 0xC30
+#define BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK 0xC34
+#define BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_0 0xA20
+#define BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_1 0xA24
#define BRCMF_PCIE2_INTA 0x01
#define BRCMF_PCIE2_INTB 0x02
@@ -137,6 +145,8 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
#define BRCMF_PCIE_MB_INT_D2H3_DB0 0x400000
#define BRCMF_PCIE_MB_INT_D2H3_DB1 0x800000
+#define BRCMF_PCIE_MB_INT_FN0 (BRCMF_PCIE_MB_INT_FN0_0 | \
+ BRCMF_PCIE_MB_INT_FN0_1)
#define BRCMF_PCIE_MB_INT_D2H_DB (BRCMF_PCIE_MB_INT_D2H0_DB0 | \
BRCMF_PCIE_MB_INT_D2H0_DB1 | \
BRCMF_PCIE_MB_INT_D2H1_DB0 | \
@@ -146,6 +156,40 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_PCIE_MB_INT_D2H3_DB0 | \
BRCMF_PCIE_MB_INT_D2H3_DB1)
+#define BRCMF_PCIE_64_MB_INT_D2H0_DB0 0x1
+#define BRCMF_PCIE_64_MB_INT_D2H0_DB1 0x2
+#define BRCMF_PCIE_64_MB_INT_D2H1_DB0 0x4
+#define BRCMF_PCIE_64_MB_INT_D2H1_DB1 0x8
+#define BRCMF_PCIE_64_MB_INT_D2H2_DB0 0x10
+#define BRCMF_PCIE_64_MB_INT_D2H2_DB1 0x20
+#define BRCMF_PCIE_64_MB_INT_D2H3_DB0 0x40
+#define BRCMF_PCIE_64_MB_INT_D2H3_DB1 0x80
+#define BRCMF_PCIE_64_MB_INT_D2H4_DB0 0x100
+#define BRCMF_PCIE_64_MB_INT_D2H4_DB1 0x200
+#define BRCMF_PCIE_64_MB_INT_D2H5_DB0 0x400
+#define BRCMF_PCIE_64_MB_INT_D2H5_DB1 0x800
+#define BRCMF_PCIE_64_MB_INT_D2H6_DB0 0x1000
+#define BRCMF_PCIE_64_MB_INT_D2H6_DB1 0x2000
+#define BRCMF_PCIE_64_MB_INT_D2H7_DB0 0x4000
+#define BRCMF_PCIE_64_MB_INT_D2H7_DB1 0x8000
+
+#define BRCMF_PCIE_64_MB_INT_D2H_DB (BRCMF_PCIE_64_MB_INT_D2H0_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H0_DB1 | \
+ BRCMF_PCIE_64_MB_INT_D2H1_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H1_DB1 | \
+ BRCMF_PCIE_64_MB_INT_D2H2_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H2_DB1 | \
+ BRCMF_PCIE_64_MB_INT_D2H3_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H3_DB1 | \
+ BRCMF_PCIE_64_MB_INT_D2H4_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H4_DB1 | \
+ BRCMF_PCIE_64_MB_INT_D2H5_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H5_DB1 | \
+ BRCMF_PCIE_64_MB_INT_D2H6_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H6_DB1 | \
+ BRCMF_PCIE_64_MB_INT_D2H7_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H7_DB1)
+
#define BRCMF_PCIE_SHARED_VERSION_7 7
#define BRCMF_PCIE_MIN_SHARED_VERSION 5
#define BRCMF_PCIE_MAX_SHARED_VERSION BRCMF_PCIE_SHARED_VERSION_7
@@ -272,6 +316,7 @@ struct brcmf_pciedev_info {
char nvram_name[BRCMF_FW_NAME_LEN];
char clm_name[BRCMF_FW_NAME_LEN];
const struct firmware *clm_fw;
+ const struct brcmf_pcie_reginfo *reginfo;
void __iomem *regs;
void __iomem *tcm;
u32 ram_base;
@@ -358,6 +403,36 @@ static const u32 brcmf_ring_itemsize[BRCMF_NROF_COMMON_MSGRINGS] = {
BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE
};
+struct brcmf_pcie_reginfo {
+ u32 intmask;
+ u32 mailboxint;
+ u32 mailboxmask;
+ u32 h2d_mailbox_0;
+ u32 h2d_mailbox_1;
+ u32 int_d2h_db;
+ u32 int_fn0;
+};
+
+static const struct brcmf_pcie_reginfo brcmf_reginfo_default = {
+ .intmask = BRCMF_PCIE_PCIE2REG_INTMASK,
+ .mailboxint = BRCMF_PCIE_PCIE2REG_MAILBOXINT,
+ .mailboxmask = BRCMF_PCIE_PCIE2REG_MAILBOXMASK,
+ .h2d_mailbox_0 = BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0,
+ .h2d_mailbox_1 = BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1,
+ .int_d2h_db = BRCMF_PCIE_MB_INT_D2H_DB,
+ .int_fn0 = BRCMF_PCIE_MB_INT_FN0,
+};
+
+static const struct brcmf_pcie_reginfo brcmf_reginfo_64 = {
+ .intmask = BRCMF_PCIE_64_PCIE2REG_INTMASK,
+ .mailboxint = BRCMF_PCIE_64_PCIE2REG_MAILBOXINT,
+ .mailboxmask = BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK,
+ .h2d_mailbox_0 = BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_0,
+ .h2d_mailbox_1 = BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_1,
+ .int_d2h_db = BRCMF_PCIE_64_MB_INT_D2H_DB,
+ .int_fn0 = 0,
+};
+
static void brcmf_pcie_setup(struct device *dev, int ret,
struct brcmf_fw_request *fwreq);
static struct brcmf_fw_request *
@@ -841,30 +916,29 @@ static void brcmf_pcie_bus_console_read(struct brcmf_pciedev_info *devinfo,
static void brcmf_pcie_intr_disable(struct brcmf_pciedev_info *devinfo)
{
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, 0);
+ brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->mailboxmask, 0);
}
static void brcmf_pcie_intr_enable(struct brcmf_pciedev_info *devinfo)
{
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK,
- BRCMF_PCIE_MB_INT_D2H_DB |
- BRCMF_PCIE_MB_INT_FN0_0 |
- BRCMF_PCIE_MB_INT_FN0_1);
+ brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->mailboxmask,
+ devinfo->reginfo->int_d2h_db |
+ devinfo->reginfo->int_fn0);
}
static void brcmf_pcie_hostready(struct brcmf_pciedev_info *devinfo)
{
if (devinfo->shared.flags & BRCMF_PCIE_SHARED_HOSTRDY_DB1)
brcmf_pcie_write_reg32(devinfo,
- BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1, 1);
+ devinfo->reginfo->h2d_mailbox_1, 1);
}
static irqreturn_t brcmf_pcie_quick_check_isr(int irq, void *arg)
{
struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
- if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT)) {
+ if (brcmf_pcie_read_reg32(devinfo, devinfo->reginfo->mailboxint)) {
brcmf_pcie_intr_disable(devinfo);
brcmf_dbg(PCIE, "Enter\n");
return IRQ_WAKE_THREAD;
@@ -879,15 +953,14 @@ static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg)
u32 status;
devinfo->in_irq = true;
- status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
+ status = brcmf_pcie_read_reg32(devinfo, devinfo->reginfo->mailboxint);
brcmf_dbg(PCIE, "Enter %x\n", status);
if (status) {
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
+ brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->mailboxint,
status);
- if (status & (BRCMF_PCIE_MB_INT_FN0_0 |
- BRCMF_PCIE_MB_INT_FN0_1))
+ if (status & devinfo->reginfo->int_fn0)
brcmf_pcie_handle_mb_data(devinfo);
- if (status & BRCMF_PCIE_MB_INT_D2H_DB) {
+ if (status & devinfo->reginfo->int_d2h_db) {
if (devinfo->state == BRCMFMAC_PCIE_STATE_UP)
brcmf_proto_msgbuf_rx_trigger(
&devinfo->pdev->dev);
@@ -946,8 +1019,8 @@ static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo)
if (devinfo->in_irq)
brcmf_err(bus, "Still in IRQ (processing) !!!\n");
- status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status);
+ status = brcmf_pcie_read_reg32(devinfo, devinfo->reginfo->mailboxint);
+ brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->mailboxint, status);
devinfo->irq_allocated = false;
}
@@ -999,7 +1072,7 @@ static int brcmf_pcie_ring_mb_ring_bell(void *ctx)
brcmf_dbg(PCIE, "RING !\n");
/* Any arbitrary value will do, lets use 1 */
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0, 1);
+ brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->h2d_mailbox_0, 1);
return 0;
}
@@ -1756,15 +1829,22 @@ static int brcmf_pcie_buscoreprep(void *ctx)
static int brcmf_pcie_buscore_reset(void *ctx, struct brcmf_chip *chip)
{
struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx;
- u32 val;
+ struct brcmf_core *core;
+ u32 val, reg;
devinfo->ci = chip;
brcmf_pcie_reset_device(devinfo);
- val = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
+ /* reginfo is not ready yet */
+ core = brcmf_chip_get_core(chip, BCMA_CORE_PCIE2);
+ if (core->rev >= 64)
+ reg = BRCMF_PCIE_64_PCIE2REG_MAILBOXINT;
+ else
+ reg = BRCMF_PCIE_PCIE2REG_MAILBOXINT;
+
+ val = brcmf_pcie_read_reg32(devinfo, reg);
if (val != 0xffffffff)
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
- val);
+ brcmf_pcie_write_reg32(devinfo, reg, val);
return 0;
}
@@ -2176,6 +2256,7 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct brcmf_pciedev_info *devinfo;
struct brcmf_pciedev *pcie_bus_dev;
struct brcmf_bus *bus;
+ struct brcmf_core *core;
brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device);
@@ -2194,6 +2275,12 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto fail;
}
+ core = brcmf_chip_get_core(devinfo->ci, BCMA_CORE_PCIE2);
+ if (core->rev >= 64)
+ devinfo->reginfo = &brcmf_reginfo_64;
+ else
+ devinfo->reginfo = &brcmf_reginfo_default;
+
pcie_bus_dev = kzalloc(sizeof(*pcie_bus_dev), GFP_KERNEL);
if (pcie_bus_dev == NULL) {
ret = -ENOMEM;
@@ -2362,7 +2449,7 @@ static int brcmf_pcie_pm_leave_D3(struct device *dev)
brcmf_dbg(PCIE, "Enter, dev=%p, bus=%p\n", dev, bus);
/* Check if device is still up and running, if so we are ready */
- if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0) {
+ if (brcmf_pcie_read_reg32(devinfo, devinfo->reginfo->intmask) != 0) {
brcmf_dbg(PCIE, "Try to wakeup device....\n");
if (brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D0_INFORM))
goto cleanup;
--
2.34.1
@@ -0,0 +1,96 @@
From 395b965fa51c7ad26284c6fefd7d05c3339bb24d Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Tue, 21 Dec 2021 17:46:40 +0900
Subject: [PATCH 13/30] brcmfmac: pcie: Add IDs/properties for BCM4378
This chip is present on Apple M1 (t8103) platforms:
* atlantisb (apple,j274): Mac mini (M1, 2020)
* honshu (apple,j293): MacBook Pro (13-inch, M1, 2020)
* shikoku (apple,j313): MacBook Air (M1, 2020)
* capri (apple,j456): iMac (24-inch, 4x USB-C, M1, 2020)
* santorini (apple,j457): iMac (24-inch, 2x USB-C, M1, 2020)
Signed-off-by: Hector Martin <marcan@marcan.st>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 2 ++
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 8 ++++++++
.../net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++
3 files changed, 12 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index 1ee49f9e3..56a6f4168 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -731,6 +731,8 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
return 0x160000;
case CY_CC_43752_CHIP_ID:
return 0x170000;
+ case BRCM_CC_4378_CHIP_ID:
+ return 0x352000;
default:
brcmf_err("unknown chip: %s\n", ci->pub.name);
break;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 4a6370efb..785090570 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -58,6 +58,7 @@ BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie");
BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie");
BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie");
BRCMF_FW_DEF(4371, "brcmfmac4371-pcie");
+BRCMF_FW_CLM_DEF(4378B1, "brcmfmac4378b1-pcie");
/* firmware config files */
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.txt");
@@ -87,6 +88,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43664_CHIP_ID, 0xFFFFFFF0, 4366C),
BRCMF_FW_ENTRY(BRCM_CC_43666_CHIP_ID, 0xFFFFFFF0, 4366C),
BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
+ BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0xFFFFFFFF, 4378B1), /* 3 */
};
#define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */
@@ -2008,6 +2010,11 @@ static int brcmf_pcie_read_otp(struct brcmf_pciedev_info *devinfo)
int ret;
switch (devinfo->ci->chip) {
+ case BRCM_CC_4378_CHIP_ID:
+ coreid = BCMA_CORE_GCI;
+ base = 0x1120;
+ words = 0x170;
+ break;
default:
/* OTP not supported on this chip */
return 0;
@@ -2515,6 +2522,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = {
BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_2G_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4371_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID),
{ /* end: all zeroes */ }
};
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
index 9d8132016..8f552b53f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -50,6 +50,7 @@
#define BRCM_CC_43664_CHIP_ID 43664
#define BRCM_CC_43666_CHIP_ID 43666
#define BRCM_CC_4371_CHIP_ID 0x4371
+#define BRCM_CC_4378_CHIP_ID 0x4378
#define CY_CC_4373_CHIP_ID 0x4373
#define CY_CC_43012_CHIP_ID 43012
#define CY_CC_43752_CHIP_ID 43752
@@ -85,6 +86,7 @@
#define BRCM_PCIE_4366_2G_DEVICE_ID 0x43c4
#define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5
#define BRCM_PCIE_4371_DEVICE_ID 0x440d
+#define BRCM_PCIE_4378_DEVICE_ID 0x4425
/* brcmsmac IDs */
--
2.34.1
@@ -0,0 +1,53 @@
From d7efc0ae360df39dea3a843fb7bd57127652f728 Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Thu, 23 Dec 2021 19:51:11 +0900
Subject: [PATCH 14/30] ACPI / property: Support strings in Apple _DSM props
The Wi-Fi module in Apple machines has a "module-instance" device
property that specifies the platform type and is used for firmware
selection. Its value is a string, so add support for string values in
acpi_extract_apple_properties().
Signed-off-by: Hector Martin <marcan@marcan.st>
---
drivers/acpi/x86/apple.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/x86/apple.c b/drivers/acpi/x86/apple.c
index c285c91a5..1f5a0694c 100644
--- a/drivers/acpi/x86/apple.c
+++ b/drivers/acpi/x86/apple.c
@@ -70,13 +70,16 @@ void acpi_extract_apple_properties(struct acpi_device *adev)
if ( key->type != ACPI_TYPE_STRING ||
(val->type != ACPI_TYPE_INTEGER &&
- val->type != ACPI_TYPE_BUFFER))
+ val->type != ACPI_TYPE_BUFFER &&
+ val->type != ACPI_TYPE_STRING))
continue; /* skip invalid properties */
__set_bit(i, valid);
newsize += key->string.length + 1;
if ( val->type == ACPI_TYPE_BUFFER)
newsize += val->buffer.length;
+ else if ( val->type == ACPI_TYPE_STRING)
+ newsize += val->string.length + 1;
}
numvalid = bitmap_weight(valid, numprops);
@@ -118,6 +121,12 @@ void acpi_extract_apple_properties(struct acpi_device *adev)
newprops[v].type = val->type;
if (val->type == ACPI_TYPE_INTEGER) {
newprops[v].integer.value = val->integer.value;
+ } else if (val->type == ACPI_TYPE_STRING) {
+ newprops[v].string.length = val->string.length;
+ newprops[v].string.pointer = free_space;
+ memcpy(free_space, val->string.pointer,
+ val->string.length);
+ free_space += val->string.length + 1;
} else {
newprops[v].buffer.length = val->buffer.length;
newprops[v].buffer.pointer = free_space;
--
2.34.1
@@ -0,0 +1,127 @@
From 5aa741e9fbe7650a4018be84e6a3b60905625107 Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Thu, 23 Dec 2021 19:51:36 +0900
Subject: [PATCH 15/30] brcmfmac: acpi: Add support for fetching Apple ACPI
properties
On DT platforms, the module-instance and antenna-sku-info properties
are passed in the DT. On ACPI platforms, module-instance is passed via
the analogous Apple device property mechanism, while the antenna SKU
info is instead obtained via an ACPI method that grabs it from
non-volatile storage.
Add support for this, to allow proper firmware selection on Apple
platforms.
Signed-off-by: Hector Martin <marcan@marcan.st>
---
.../broadcom/brcm80211/brcmfmac/Makefile | 2 +
.../broadcom/brcm80211/brcmfmac/acpi.c | 52 +++++++++++++++++++
.../broadcom/brcm80211/brcmfmac/common.c | 1 +
.../broadcom/brcm80211/brcmfmac/common.h | 9 ++++
4 files changed, 64 insertions(+)
create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/acpi.c
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
index 13c13504a..19009eb9d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
@@ -47,3 +47,5 @@ brcmfmac-$(CONFIG_OF) += \
of.o
brcmfmac-$(CONFIG_DMI) += \
dmi.o
+brcmfmac-$(CONFIG_ACPI) += \
+ acpi.o
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/acpi.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/acpi.c
new file mode 100644
index 000000000..b70cd6970
--- /dev/null
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/acpi.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Copyright The Asahi Linux Contributors
+ */
+
+#include <linux/acpi.h>
+#include "debug.h"
+#include "core.h"
+#include "common.h"
+
+void brcmf_acpi_probe(struct device *dev, enum brcmf_bus_type bus_type,
+ struct brcmf_mp_device *settings)
+{
+ acpi_status status;
+ struct acpi_device *adev = ACPI_COMPANION(dev);
+ const union acpi_object *o;
+ struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
+
+ if (!adev) {
+ return;
+ }
+
+ if (!ACPI_FAILURE(acpi_dev_get_property(adev, "module-instance",
+ ACPI_TYPE_STRING, &o))) {
+ const char *prefix = "apple,";
+ int len = strlen(prefix) + o->string.length + 1;
+ char *board_type = devm_kzalloc(dev, len, GFP_KERNEL);
+
+ strlcpy(board_type, prefix, len);
+ strlcat(board_type, o->string.pointer, len);
+ brcmf_dbg(INFO, "ACPI module-instance=%s\n", o->string.pointer);
+ settings->board_type = board_type;
+ } else {
+ brcmf_dbg(INFO, "No ACPI module-instance\n");
+ }
+
+ status = acpi_evaluate_object(adev->handle, "RWCV", NULL, &buf);
+ o = buf.pointer;
+ if (!ACPI_FAILURE(status) && o && o->type == ACPI_TYPE_BUFFER &&
+ o->buffer.length >= 2) {
+ char *antenna_sku = devm_kzalloc(dev, 3, GFP_KERNEL);
+
+ memcpy(antenna_sku, o->buffer.pointer, 2);
+ brcmf_dbg(INFO, "ACPI RWCV data=%*phN antenna-sku=%s\n",
+ (int)o->buffer.length, o->buffer.pointer,
+ antenna_sku);
+
+ settings->antenna_sku = antenna_sku;
+ } else {
+ brcmf_dbg(INFO, "No ACPI antenna-sku\n");
+ }
+}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index ec4cb7050..0151d129c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -437,6 +437,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
/* No platform data for this device, try OF and DMI data */
brcmf_dmi_probe(settings, chip, chiprev);
brcmf_of_probe(dev, bus_type, settings);
+ brcmf_acpi_probe(dev, bus_type, settings);
}
return settings;
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
index d4aa25d64..a88c4a931 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -73,6 +73,15 @@ static inline void
brcmf_dmi_probe(struct brcmf_mp_device *settings, u32 chip, u32 chiprev) {}
#endif
+#ifdef CONFIG_ACPI
+void brcmf_acpi_probe(struct device *dev, enum brcmf_bus_type bus_type,
+ struct brcmf_mp_device *settings);
+#else
+static inline void brcmf_acpi_probe(struct device *dev,
+ enum brcmf_bus_type bus_type,
+ struct brcmf_mp_device *settings) {}
+#endif
+
u8 brcmf_map_prio_to_prec(void *cfg, u8 prio);
u8 brcmf_map_prio_to_aci(void *cfg, u8 prio);
--
2.34.1
@@ -0,0 +1,83 @@
From 7d0f1f3475206fe2a37ee9e3180783d1c72daaaa Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Thu, 23 Dec 2021 19:30:17 +0900
Subject: [PATCH 16/30] brcmfmac: pcie: Provide a buffer of random bytes to the
device
Newer Apple firmwares on chipsets without a hardware RNG require the
host to provide a buffer of 256 random bytes to the device on
initialization. This buffer is present immediately before NVRAM,
suffixed by a footer containing a magic number and the buffer length.
This won't affect chips/firmwares that do not use this feature, so do it
unconditionally.
Signed-off-by: Hector Martin <marcan@marcan.st>
---
.../broadcom/brcm80211/brcmfmac/pcie.c | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 785090570..bd55f5a30 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -12,6 +12,7 @@
#include <linux/interrupt.h>
#include <linux/bcma/bcma.h>
#include <linux/sched.h>
+#include <linux/random.h>
#include <asm/unaligned.h>
#include <soc.h>
@@ -1660,6 +1661,13 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
return 0;
}
+struct brcmf_random_seed_footer {
+ __le32 length;
+ __le32 magic;
+};
+
+#define BRCMF_RANDOM_SEED_MAGIC 0xfeedc0de
+#define BRCMF_RANDOM_SEED_LENGTH 0x100
static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
const struct firmware *fw, void *nvram,
@@ -1691,11 +1699,34 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
brcmf_pcie_write_ram32(devinfo, devinfo->ci->ramsize - 4, 0);
if (nvram) {
+ size_t rand_len = BRCMF_RANDOM_SEED_LENGTH;
+ struct brcmf_random_seed_footer footer = {
+ .length = cpu_to_le32(rand_len),
+ .magic = cpu_to_le32(BRCMF_RANDOM_SEED_MAGIC),
+ };
+ void *randbuf;
+
brcmf_dbg(PCIE, "Download NVRAM %s\n", devinfo->nvram_name);
address = devinfo->ci->rambase + devinfo->ci->ramsize -
nvram_len;
brcmf_pcie_copy_mem_todev(devinfo, address, nvram, nvram_len);
brcmf_fw_nvram_free(nvram);
+
+ /*
+ * Some Apple chips/firmwares expect a buffer of random data
+ * to be present before NVRAM
+ */
+ brcmf_dbg(PCIE, "Download random seed\n");
+
+ address -= sizeof(footer);
+ brcmf_pcie_copy_mem_todev(devinfo, address, &footer,
+ sizeof(footer));
+
+ address -= rand_len;
+ randbuf = kzalloc(rand_len, GFP_KERNEL);
+ get_random_bytes(randbuf, rand_len);
+ brcmf_pcie_copy_mem_todev(devinfo, address, randbuf, rand_len);
+ kfree(randbuf);
} else {
brcmf_dbg(PCIE, "No matching NVRAM file found %s\n",
devinfo->nvram_name);
--
2.34.1
@@ -1,20 +1,25 @@
From c7ea284aa5575ce2254642fe12e4f550180424e8 Mon Sep 17 00:00:00 2001 From 255bc66f8a00a5d100d82ccfeb162a59312c9609 Mon Sep 17 00:00:00 2001
From: Aditya Garg <gargaditya08@live.com> From: Hector Martin <marcan@marcan.st>
Date: Sat, 2 Oct 2021 11:55:04 +0530 Date: Tue, 21 Dec 2021 17:50:15 +0900
Subject: [PATCH] Add support for BCM4355 Subject: [PATCH 17/30] brcmfmac: pcie: Add IDs/properties for BCM4355
Co-authored-by: Aun-Ali Zaidi <admin@kodeit.net> This chip is present on at least these Apple T2 Macs:
* hawaii: MacBook Air 13" (Late 2018)
* hawaii: MacBook Air 13" (True Tone, 2019)
Signed-off-by: Hector Martin <marcan@marcan.st>
--- ---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 1 + drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 1 +
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 3 +++ drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 8 ++++++++
drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++ .../net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++
3 files changed, 6 insertions(+) 3 files changed, 11 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index 1e1b23bf4..7086de030 100644 index 56a6f4168..fdff7f5fc 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -724,6 +724,7 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci) @@ -726,6 +726,7 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
return 0x200000; return 0x200000;
case BRCM_CC_4359_CHIP_ID: case BRCM_CC_4359_CHIP_ID:
return (ci->pub.chiprev < 9) ? 0x180000 : 0x160000; return (ci->pub.chiprev < 9) ? 0x180000 : 0x160000;
@@ -23,26 +28,38 @@ index 1e1b23bf4..7086de030 100644
case CY_CC_4373_CHIP_ID: case CY_CC_4373_CHIP_ID:
return 0x160000; return 0x160000;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 6f0166b33..19e8238fe 100644 index bd55f5a30..035656433 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -49,6 +49,7 @@ enum brcmf_pcie_state { @@ -49,6 +49,7 @@ enum brcmf_pcie_state {
BRCMF_FW_DEF(43602, "brcmfmac43602-pcie"); BRCMF_FW_DEF(43602, "brcmfmac43602-pcie");
BRCMF_FW_DEF(4350, "brcmfmac4350-pcie"); BRCMF_FW_DEF(4350, "brcmfmac4350-pcie");
BRCMF_FW_DEF(4350C, "brcmfmac4350c2-pcie"); BRCMF_FW_DEF(4350C, "brcmfmac4350c2-pcie");
+BRCMF_FW_DEF(4355, "brcmfmac4355-pcie"); +BRCMF_FW_CLM_DEF(4355C1, "brcmfmac4355c1-pcie");
BRCMF_FW_CLM_DEF(4356, "brcmfmac4356-pcie"); BRCMF_FW_CLM_DEF(4356, "brcmfmac4356-pcie");
BRCMF_FW_CLM_DEF(43570, "brcmfmac43570-pcie"); BRCMF_FW_CLM_DEF(43570, "brcmfmac43570-pcie");
BRCMF_FW_DEF(4358, "brcmfmac4358-pcie"); BRCMF_FW_DEF(4358, "brcmfmac4358-pcie");
@@ -68,6 +69,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { @@ -75,6 +76,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_4350_CHIP_ID, 0x000000FF, 4350C), BRCMF_FW_ENTRY(BRCM_CC_4350_CHIP_ID, 0x000000FF, 4350C),
BRCMF_FW_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFF00, 4350), BRCMF_FW_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFF00, 4350),
BRCMF_FW_ENTRY(BRCM_CC_43525_CHIP_ID, 0xFFFFFFF0, 4365C), BRCMF_FW_ENTRY(BRCM_CC_43525_CHIP_ID, 0xFFFFFFF0, 4365C),
+ BRCMF_FW_ENTRY(BRCM_CC_4355_CHIP_ID, 0xFFFFFFFF, 4355), + BRCMF_FW_ENTRY(BRCM_CC_4355_CHIP_ID, 0xFFFFFFFF, 4355C1), /* 12 */
BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356),
BRCMF_FW_ENTRY(BRCM_CC_43567_CHIP_ID, 0xFFFFFFFF, 43570), BRCMF_FW_ENTRY(BRCM_CC_43567_CHIP_ID, 0xFFFFFFFF, 43570),
BRCMF_FW_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570), BRCMF_FW_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570),
@@ -2362,6 +2364,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = { @@ -2041,6 +2043,11 @@ static int brcmf_pcie_read_otp(struct brcmf_pciedev_info *devinfo)
int ret;
switch (devinfo->ci->chip) {
+ case BRCM_CC_4355_CHIP_ID:
+ coreid = BCMA_CORE_CHIPCOMMON;
+ base = 0x800;
+ words = 0x112;
+ break;
case BRCM_CC_4378_CHIP_ID:
coreid = BCMA_CORE_GCI;
base = 0x1120;
@@ -2535,6 +2542,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = {
BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID), BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID),
BRCMF_PCIE_DEVICE_SUB(0x4355, BRCM_PCIE_VENDOR_ID_BROADCOM, 0x4355), BRCMF_PCIE_DEVICE_SUB(0x4355, BRCM_PCIE_VENDOR_ID_BROADCOM, 0x4355),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_RAW_DEVICE_ID), BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_RAW_DEVICE_ID),
@@ -51,7 +68,7 @@ index 6f0166b33..19e8238fe 100644
BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID), BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID), BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID),
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
index eb3f361a2..8536a285d 100644 index 8f552b53f..9636ab4dd 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h --- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -36,6 +36,7 @@ @@ -36,6 +36,7 @@
@@ -70,3 +87,6 @@ index eb3f361a2..8536a285d 100644
#define BRCM_PCIE_4356_DEVICE_ID 0x43ec #define BRCM_PCIE_4356_DEVICE_ID 0x43ec
#define BRCM_PCIE_43567_DEVICE_ID 0x43d3 #define BRCM_PCIE_43567_DEVICE_ID 0x43d3
#define BRCM_PCIE_43570_DEVICE_ID 0x43d9 #define BRCM_PCIE_43570_DEVICE_ID 0x43d9
--
2.34.1

Some files were not shown because too many files have changed in this diff Show More