brcmfmac: Make firmware path a module parameter
authorDaniel Kim <dekim@broadcom.com>
Sat, 12 Jul 2014 06:49:37 +0000 (08:49 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 15 Jul 2014 20:00:12 +0000 (16:00 -0400)
This patch makes firmware path a module parameter so that firmware and
nvram files can be loaded from the specified path.

Signed-off-by: Daniel Kim <dekim@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
drivers/net/wireless/brcm80211/brcmfmac/firmware.c
drivers/net/wireless/brcm80211/brcmfmac/firmware.h
drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h

index c0486329331b00875b96d2c802339e6edc6e00ca..67d91d5cc13d85de1e5c0395842c90f13d54cb16 100644 (file)
@@ -666,28 +666,34 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = {
        { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
 };
 
-static const char *brcmf_sdio_get_fwname(struct brcmf_chip *ci,
-                                        enum brcmf_firmware_type type)
+static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci,
+                                 struct brcmf_sdio_dev *sdiodev)
 {
        int i;
 
        for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) {
                if (brcmf_fwname_data[i].chipid == ci->chip &&
-                   brcmf_fwname_data[i].revmsk & BIT(ci->chiprev)) {
-                       switch (type) {
-                       case BRCMF_FIRMWARE_BIN:
-                               return brcmf_fwname_data[i].bin;
-                       case BRCMF_FIRMWARE_NVRAM:
-                               return brcmf_fwname_data[i].nv;
-                       default:
-                               brcmf_err("invalid firmware type (%d)\n", type);
-                               return NULL;
-                       }
-               }
+                   brcmf_fwname_data[i].revmsk & BIT(ci->chiprev))
+                       break;
        }
-       brcmf_err("Unknown chipid %d [%d]\n",
-                 ci->chip, ci->chiprev);
-       return NULL;
+
+       if (i == ARRAY_SIZE(brcmf_fwname_data)) {
+               brcmf_err("Unknown chipid %d [%d]\n", ci->chip, ci->chiprev);
+               return -ENODEV;
+       }
+
+       /* check if firmware path is provided by module parameter */
+       if (brcmf_firmware_path[0] != '\0') {
+               if (brcmf_firmware_path[strlen(brcmf_firmware_path) - 1] != '/')
+                       strcat(brcmf_firmware_path, "/");
+
+               strcpy(sdiodev->fw_name, brcmf_firmware_path);
+               strcpy(sdiodev->nvram_name, brcmf_firmware_path);
+       }
+       strcat(sdiodev->fw_name, brcmf_fwname_data[i].bin);
+       strcat(sdiodev->nvram_name, brcmf_fwname_data[i].nv);
+
+       return 0;
 }
 
 static void pkt_align(struct sk_buff *p, int len, int align)
@@ -4160,11 +4166,12 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
        brcmf_sdio_debugfs_create(bus);
        brcmf_dbg(INFO, "completed!!\n");
 
+       ret = brcmf_sdio_get_fwnames(bus->ci, sdiodev);
+       if (ret)
+               goto fail;
+
        ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM,
-                                    brcmf_sdio_get_fwname(bus->ci,
-                                                          BRCMF_FIRMWARE_BIN),
-                                    brcmf_sdio_get_fwname(bus->ci,
-                                                          BRCMF_FIRMWARE_NVRAM),
+                                    sdiodev->fw_name, sdiodev->nvram_name,
                                     brcmf_sdio_firmware_callback);
        if (ret != 0) {
                brcmf_err("async firmware request failed: %d\n", ret);
index 7b7d237c1ddb274ff663c24653a87b2727a89cdd..8ea9f283d2b8065f4766978c2e43e05e6576fba6 100644 (file)
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
+#include <linux/module.h>
 
 #include "dhd_dbg.h"
 #include "firmware.h"
 
+char brcmf_firmware_path[BRCMF_FW_PATH_LEN];
+module_param_string(firmware_path, brcmf_firmware_path,
+                   BRCMF_FW_PATH_LEN, 0440);
+
 enum nvram_parser_state {
        IDLE,
        KEY,
index 6431bfd7afffc6c544fa1e292b3a6a98cfd4a664..4d3482356b77b0e068e1dc095b8888a7c8477094 100644 (file)
 #define BRCMF_FW_REQ_FLAGS             0x00F0
 #define  BRCMF_FW_REQ_NV_OPTIONAL      0x0010
 
+#define        BRCMF_FW_PATH_LEN       256
+#define        BRCMF_FW_NAME_LEN       32
+
+extern char brcmf_firmware_path[];
+
 void brcmf_fw_nvram_free(void *nvram);
 /*
  * Request firmware(s) asynchronously. When the asynchronous request
index 3deab7959a0d9a5c3b22ad757caf4615b283b596..6c5e585ccda99fcf83cf8d8ae5e7a7b22130e542 100644 (file)
@@ -18,6 +18,8 @@
 #define        _BRCM_SDH_H_
 
 #include <linux/skbuff.h>
+#include <linux/firmware.h>
+#include "firmware.h"
 
 #define SDIO_FUNC_0            0
 #define SDIO_FUNC_1            1
@@ -182,6 +184,8 @@ struct brcmf_sdio_dev {
        uint max_segment_size;
        uint txglomsz;
        struct sg_table sgtable;
+       char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
+       char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
 };
 
 /* sdio core registers */