brcmfmac: Add support for host platform NVRAM loading.
authorHante Meuleman <meuleman@broadcom.com>
Thu, 20 Aug 2015 20:06:08 +0000 (22:06 +0200)
committerKalle Valo <kvalo@codeaurora.org>
Tue, 25 Aug 2015 12:32:32 +0000 (15:32 +0300)
Host platforms such as routers supported by OpenWRT can
support NVRAM reading directly from internal NVRAM store.
With this patch the nvram load routines will fall back to
this method when there is no nvram file and support is
available in the kernel.

Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/brcm80211/brcmfmac/firmware.c

index 743f16b6a07296e8e5b695598002d78669222870..971920f77b68eb1bcc02043d7a19f14c5a9e68b2 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/module.h>
+#include <linux/bcm47xx_nvram.h>
 
 #include "debug.h"
 #include "firmware.h"
@@ -426,18 +427,32 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
        struct brcmf_fw *fwctx = ctx;
        u32 nvram_length = 0;
        void *nvram = NULL;
+       u8 *data = NULL;
+       size_t data_len;
+       bool raw_nvram;
 
        brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
-       if (!fw && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
-               goto fail;
+       if (fw && fw->data) {
+               data = (u8 *)fw->data;
+               data_len = fw->size;
+               raw_nvram = false;
+       } else {
+               data = bcm47xx_nvram_get_contents(&data_len);
+               if (!data && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
+                       goto fail;
+               raw_nvram = true;
+       }
 
-       if (fw) {
-               nvram = brcmf_fw_nvram_strip(fw->data, fw->size, &nvram_length,
+       if (data)
+               nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length,
                                             fwctx->domain_nr, fwctx->bus_nr);
+
+       if (raw_nvram)
+               bcm47xx_nvram_release_contents(data);
+       if (fw)
                release_firmware(fw);
-               if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
-                       goto fail;
-       }
+       if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
+               goto fail;
 
        fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length);
        kfree(fwctx);
@@ -473,15 +488,9 @@ static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx)
        if (!ret)
                return;
 
-       /* when nvram is optional call .done() callback here */
-       if (fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL) {
-               fwctx->done(fwctx->dev, fw, NULL, 0);
-               kfree(fwctx);
-               return;
-       }
+       brcmf_fw_request_nvram_done(NULL, fwctx);
+       return;
 
-       /* failed nvram request */
-       release_firmware(fw);
 fail:
        brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
        device_release_driver(fwctx->dev);