mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-07-19 22:16:59 +08:00
126 lines
4.6 KiB
Diff
126 lines
4.6 KiB
Diff
From 76efd4b5d7adea522c649c6b44d7379e981141b5 Mon Sep 17 00:00:00 2001
|
|
From: Hector Martin <marcan@marcan.st>
|
|
Date: Thu, 23 Dec 2021 22:32:08 +0900
|
|
Subject: [PATCH 092/171] 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).
|
|
|
|
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
|
Signed-off-by: Hector Martin <marcan@marcan.st>
|
|
---
|
|
.../broadcom/brcm80211/brcmfmac/firmware.c | 28 +++++++++++++++++--
|
|
1 file changed, 26 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
|
|
index d04a59cf4a1e..fbfc9458d240 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);
|
|
@@ -209,6 +216,7 @@ static int brcmf_init_nvram_parser(struct nvram_parser *nvp,
|
|
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);
|
|
@@ -368,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)
|
|
+{
|
|
+ BUG_ON(snprintf(&nvp->nvram[nvp->nvram_len], BRCMF_FW_MACADDR_LEN + 1,
|
|
+ BRCMF_FW_MACADDR_FMT, mac) != BRCMF_FW_MACADDR_LEN);
|
|
+ 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)
|
|
@@ -404,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) {
|
|
@@ -547,7 +570,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
|
|
|