brcmfmac: Try product-specific clm_blob names first
authorPhil Elwell <phil@raspberrypi.com>
Thu, 22 Jul 2021 13:34:42 +0000 (14:34 +0100)
committerDom Cobley <popcornmix@gmail.com>
Mon, 21 Mar 2022 16:04:21 +0000 (16:04 +0000)
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c

index 3f5da3b..ba3c58c 100644 (file)
@@ -78,7 +78,7 @@ struct brcmf_bus_ops {
        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);
+                         unsigned char *fw_name, bool board_specific);
        void (*debugfs_create)(struct device *dev);
        int (*reset)(struct device *dev);
 };
@@ -223,7 +223,14 @@ static inline
 int brcmf_bus_get_fwname(struct brcmf_bus *bus, const char *ext,
                         unsigned char *fw_name)
 {
-       return bus->ops->get_fwname(bus->dev, ext, fw_name);
+       return bus->ops->get_fwname(bus->dev, ext, fw_name, false);
+}
+
+static inline
+int brcmf_bus_get_board_fwname(struct brcmf_bus *bus, const char *ext,
+                              unsigned char *fw_name)
+{
+       return bus->ops->get_fwname(bus->dev, ext, fw_name, true);
 }
 
 static inline
index e3758bd..9047a08 100644 (file)
@@ -134,13 +134,23 @@ 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);
+       err = brcmf_bus_get_board_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 (clm_name[0])
+               err = firmware_request_nowarn(&clm, clm_name, bus->dev);
+       if (err || !clm_name[0]) {
+               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) {
                brcmf_info("no clm_blob available (err=%d), device may have limited channels available\n",
                           err);
index 193181c..714811b 100644 (file)
@@ -645,7 +645,7 @@ static int brcmf_fw_request_firmware(const struct firmware **fw,
                if (!alt_path)
                        goto fallback;
 
-               ret = request_firmware(fw, alt_path, fwctx->dev);
+               ret = firmware_request_nowarn(fw, alt_path, fwctx->dev);
                kfree(alt_path);
                if (ret == 0)
                        return ret;
index 8b14999..3a45391 100644 (file)
@@ -1402,7 +1402,8 @@ static int brcmf_pcie_get_memdump(struct device *dev, void *data, size_t len)
 }
 
 static
-int brcmf_pcie_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
+int brcmf_pcie_get_fwname(struct device *dev, const char *ext, u8 *fw_name,
+                         bool board_specific)
 {
        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
        struct brcmf_fw_request *fwreq;
@@ -1410,6 +1411,10 @@ int brcmf_pcie_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
                { ext, fw_name },
        };
 
+       if (board_specific) {
+               fw_name[0] = 0;
+               return 0;
+       }
        fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev,
                                       brcmf_pcie_fwnames,
                                       ARRAY_SIZE(brcmf_pcie_fwnames),
index 14b2cda..6bcaa40 100644 (file)
@@ -4132,14 +4132,24 @@ brcmf_sdio_watchdog(struct timer_list *t)
 }
 
 static
-int brcmf_sdio_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
+int brcmf_sdio_get_fwname(struct device *dev, const char *ext, u8 *fw_name,
+                         bool board_specific)
 {
        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
        struct brcmf_fw_request *fwreq;
+       u8 board_ext[BRCMF_FW_NAME_LEN];
        struct brcmf_fw_name fwnames[] = {
                { ext, fw_name },
        };
 
+       if (board_specific) {
+               strlcpy(board_ext, ".", BRCMF_FW_NAME_LEN);
+               strlcat(board_ext, sdiodev->settings->board_type,
+                       BRCMF_FW_NAME_LEN);
+               strlcat(board_ext, ext, BRCMF_FW_NAME_LEN);
+               fwnames[0].extension = board_ext;
+       }
        fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev,
                                       brcmf_sdio_fwnames,
                                       ARRAY_SIZE(brcmf_sdio_fwnames),
index 9fb68c2..9bf2dbd 100644 (file)
@@ -1155,7 +1155,8 @@ error:
 }
 
 static
-int brcmf_usb_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
+int brcmf_usb_get_fwname(struct device *dev, const char *ext, u8 *fw_name,
+                        bool board_specific)
 {
        struct brcmf_bus *bus = dev_get_drvdata(dev);
        struct brcmf_fw_request *fwreq;
@@ -1163,6 +1164,10 @@ int brcmf_usb_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
                { ext, fw_name },
        };
 
+       if (board_specific) {
+               fw_name[0] = 0;
+               return 0;
+       }
        fwreq = brcmf_fw_alloc_request(bus->chip, bus->chiprev,
                                       brcmf_usb_fwnames,
                                       ARRAY_SIZE(brcmf_usb_fwnames),