Make the function brcmf_fw_get_firmwares() a bit more easy to extend
using a structure to pass the request parameters.
Reviewed-by: Hante Meuleman
Reviewed-by: Pieter-Paul Giesberts
Reviewed-by: Franky Lin
Signed-off-by: Arend van Spriel
---
.../broadcom/brcm80211/brcmfmac/firmware.c | 175 ++---
.../broadcom/brcm80211/brcmfmac/firmware.h | 43 +++--
.../wireless/broadcom/brcm80211/brcmfmac/pcie.c| 38 -
.../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 32 +++-
.../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 43 -
5 files changed, 245 insertions(+), 86 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
index 6945f58..b5f9430 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -438,18 +438,31 @@ void brcmf_fw_nvram_free(void *nvram)
struct brcmf_fw {
struct device *dev;
- u16 flags;
- const struct firmware *code;
- const char *nvram_name;
- u16 domain_nr;
- u16 bus_nr;
- void (*done)(struct device *dev, int err, const struct firmware *fw,
-void *nvram_image, u32 nvram_len);
+ struct brcmf_fw_request *req;
+ u32 curpos;
+ void (*done)(struct device *dev, int err, struct brcmf_fw_request *req);
};
+static void brcmf_fw_request_done(const struct firmware *fw, void *ctx);
+
+static void brcmf_fw_free_request(struct brcmf_fw_request *req)
+{
+ struct brcmf_fw_item *item;
+ int i;
+
+ for (i = 0, item = >items[0]; i < req->n_items; i++, item++) {
+ if (item->type == BRCMF_FW_TYPE_BINARY)
+ release_firmware(item->binary);
+ else if (item->type == BRCMF_FW_TYPE_NVRAM)
+ brcmf_fw_nvram_free(item->nv_data.data);
+ }
+ kfree(req);
+}
+
static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
{
struct brcmf_fw *fwctx = ctx;
+ struct brcmf_fw_item *cur;
u32 nvram_length = 0;
void *nvram = NULL;
u8 *data = NULL;
@@ -457,83 +470,150 @@ static void brcmf_fw_request_nvram_done(const struct
firmware *fw, void *ctx)
bool raw_nvram;
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
+
+ cur = >req->items[fwctx->curpos];
+
if (fw && fw->data) {
data = (u8 *)fw->data;
data_len = fw->size;
raw_nvram = false;
} else {
data = bcm47xx_nvram_get_contents(_len);
- if (!data && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
+ if (!data && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
goto fail;
raw_nvram = true;
}
if (data)
nvram = brcmf_fw_nvram_strip(data, data_len, _length,
-fwctx->domain_nr, fwctx->bus_nr);
+fwctx->req->domain_nr,
+fwctx->req->bus_nr);
if (raw_nvram)
bcm47xx_nvram_release_contents(data);
release_firmware(fw);
- if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
+ if (!nvram && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
goto fail;
- fwctx->done(fwctx->dev, 0, fwctx->code, nvram, nvram_length);
- kfree(fwctx);
+ brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length);
+ cur->nv_data.data = nvram;
+ cur->nv_data.len = nvram_length;
return;
fail:
brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
- release_firmware(fwctx->code);
- fwctx->done(fwctx->dev, -ENOENT, NULL, NULL, 0);
+ fwctx->done(fwctx->dev, -ENOENT, NULL);
+ brcmf_fw_free_request(fwctx->req);
kfree(fwctx);
}
-static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx)
+static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async)
+{
+ struct brcmf_fw_item *cur;
+ const struct firmware *fw = NULL;
+ int ret;
+
+ cur = >req->items[fwctx->curpos];
+
+ brcmf_dbg(TRACE, "%srequest for %s\n", async ? "async " : "",
+ cur->path);
+
+ if (async)
+ ret = request_firmware_nowait(THIS_MODULE, true, cur->path,
+ fwctx->dev, GFP_KERNEL, fwctx,
+ brcmf_fw_request_done);
+ else
+ ret = request_firmware(, cur->path, fwctx->dev);
+
+ if (ret < 0) {
+ brcmf_fw_request_done(NULL, fwctx);
+ } else if (!async && fw) {
+