Commit d09ae51a authored by Arend Van Spriel's avatar Arend Van Spriel Committed by Kalle Valo

brcmfmac: pass struct in brcmf_fw_get_firmwares()

Make the function brcmf_fw_get_firmwares() a bit more easy to extend
using a structure to pass the request parameters.
Reviewed-by: default avatarHante Meuleman <hante.meuleman@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: default avatarFranky Lin <franky.lin@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 41f573db
...@@ -438,18 +438,31 @@ void brcmf_fw_nvram_free(void *nvram) ...@@ -438,18 +438,31 @@ void brcmf_fw_nvram_free(void *nvram)
struct brcmf_fw { struct brcmf_fw {
struct device *dev; struct device *dev;
u16 flags; struct brcmf_fw_request *req;
const struct firmware *code; u32 curpos;
const char *nvram_name; void (*done)(struct device *dev, int err, struct brcmf_fw_request *req);
u16 domain_nr;
u16 bus_nr;
void (*done)(struct device *dev, int err, const struct firmware *fw,
void *nvram_image, u32 nvram_len);
}; };
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 = &req->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) static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
{ {
struct brcmf_fw *fwctx = ctx; struct brcmf_fw *fwctx = ctx;
struct brcmf_fw_item *cur;
u32 nvram_length = 0; u32 nvram_length = 0;
void *nvram = NULL; void *nvram = NULL;
u8 *data = NULL; u8 *data = NULL;
...@@ -457,83 +470,150 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) ...@@ -457,83 +470,150 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
bool raw_nvram; bool raw_nvram;
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev)); brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
cur = &fwctx->req->items[fwctx->curpos];
if (fw && fw->data) { if (fw && fw->data) {
data = (u8 *)fw->data; data = (u8 *)fw->data;
data_len = fw->size; data_len = fw->size;
raw_nvram = false; raw_nvram = false;
} else { } else {
data = bcm47xx_nvram_get_contents(&data_len); data = bcm47xx_nvram_get_contents(&data_len);
if (!data && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) if (!data && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
goto fail; goto fail;
raw_nvram = true; raw_nvram = true;
} }
if (data) if (data)
nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length, nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length,
fwctx->domain_nr, fwctx->bus_nr); fwctx->req->domain_nr,
fwctx->req->bus_nr);
if (raw_nvram) if (raw_nvram)
bcm47xx_nvram_release_contents(data); bcm47xx_nvram_release_contents(data);
release_firmware(fw); release_firmware(fw);
if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) if (!nvram && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
goto fail; goto fail;
fwctx->done(fwctx->dev, 0, fwctx->code, nvram, nvram_length); brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length);
kfree(fwctx); cur->nv_data.data = nvram;
cur->nv_data.len = nvram_length;
return; return;
fail: fail:
brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
release_firmware(fwctx->code); fwctx->done(fwctx->dev, -ENOENT, NULL);
fwctx->done(fwctx->dev, -ENOENT, NULL, NULL, 0); brcmf_fw_free_request(fwctx->req);
kfree(fwctx); 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 = &fwctx->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(&fw, cur->path, fwctx->dev);
if (ret < 0) {
brcmf_fw_request_done(NULL, fwctx);
} else if (!async && fw) {
brcmf_dbg(TRACE, "firmware %s %sfound\n", cur->path,
fw ? "" : "not ");
if (cur->type == BRCMF_FW_TYPE_BINARY)
cur->binary = fw;
else if (cur->type == BRCMF_FW_TYPE_NVRAM)
brcmf_fw_request_nvram_done(fw, fwctx);
else
release_firmware(fw);
return -EAGAIN;
}
return 0;
}
static void brcmf_fw_request_done(const struct firmware *fw, void *ctx)
{ {
struct brcmf_fw *fwctx = ctx; struct brcmf_fw *fwctx = ctx;
struct brcmf_fw_item *cur;
int ret = 0; int ret = 0;
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev)); cur = &fwctx->req->items[fwctx->curpos];
if (!fw) {
brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path,
fw ? "" : "not ");
if (fw) {
if (cur->type == BRCMF_FW_TYPE_BINARY)
cur->binary = fw;
else if (cur->type == BRCMF_FW_TYPE_NVRAM)
brcmf_fw_request_nvram_done(fw, fwctx);
else
release_firmware(fw);
} else if (cur->type == BRCMF_FW_TYPE_NVRAM) {
brcmf_fw_request_nvram_done(NULL, fwctx);
} else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) {
ret = -ENOENT; ret = -ENOENT;
goto fail; goto fail;
} }
/* only requested code so done here */
if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) do {
if (++fwctx->curpos == fwctx->req->n_items) {
ret = 0;
goto done; goto done;
}
fwctx->code = fw; ret = brcmf_fw_request_next_item(fwctx, false);
ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name, } while (ret == -EAGAIN);
fwctx->dev, GFP_KERNEL, fwctx,
brcmf_fw_request_nvram_done);
/* pass NULL to nvram callback for bcm47xx fallback */
if (ret)
brcmf_fw_request_nvram_done(NULL, fwctx);
return; return;
fail: fail:
brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret,
dev_name(fwctx->dev), cur->path);
brcmf_fw_free_request(fwctx->req);
fwctx->req = NULL;
done: done:
fwctx->done(fwctx->dev, ret, fw, NULL, 0); fwctx->done(fwctx->dev, ret, fwctx->req);
kfree(fwctx); kfree(fwctx);
} }
int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, static bool brcmf_fw_request_is_valid(struct brcmf_fw_request *req)
const char *code, const char *nvram, {
struct brcmf_fw_item *item;
int i;
if (!req->n_items)
return false;
for (i = 0, item = &req->items[0]; i < req->n_items; i++, item++) {
if (!item->path)
return false;
}
return true;
}
int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req,
void (*fw_cb)(struct device *dev, int err, void (*fw_cb)(struct device *dev, int err,
const struct firmware *fw, struct brcmf_fw_request *req))
void *nvram_image, u32 nvram_len),
u16 domain_nr, u16 bus_nr)
{ {
struct brcmf_fw *fwctx; struct brcmf_fw *fwctx;
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev)); brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
if (!fw_cb || !code) if (!fw_cb)
return -EINVAL; return -EINVAL;
if ((flags & BRCMF_FW_REQUEST_NVRAM) && !nvram) if (!brcmf_fw_request_is_valid(req))
return -EINVAL; return -EINVAL;
fwctx = kzalloc(sizeof(*fwctx), GFP_KERNEL); fwctx = kzalloc(sizeof(*fwctx), GFP_KERNEL);
...@@ -541,26 +621,11 @@ int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, ...@@ -541,26 +621,11 @@ int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
return -ENOMEM; return -ENOMEM;
fwctx->dev = dev; fwctx->dev = dev;
fwctx->flags = flags; fwctx->req = req;
fwctx->done = fw_cb; fwctx->done = fw_cb;
if (flags & BRCMF_FW_REQUEST_NVRAM)
fwctx->nvram_name = nvram;
fwctx->domain_nr = domain_nr;
fwctx->bus_nr = bus_nr;
return request_firmware_nowait(THIS_MODULE, true, code, dev,
GFP_KERNEL, fwctx,
brcmf_fw_request_code_done);
}
int brcmf_fw_get_firmwares(struct device *dev, u16 flags, brcmf_fw_request_next_item(fwctx, true);
const char *code, const char *nvram, return 0;
void (*fw_cb)(struct device *dev, int err,
const struct firmware *fw,
void *nvram_image, u32 nvram_len))
{
return brcmf_fw_get_firmwares_pcie(dev, flags, code, nvram, fw_cb, 0,
0);
} }
static void brcmf_fw_get_full_name(char fw_name[BRCMF_FW_NAME_LEN], static void brcmf_fw_get_full_name(char fw_name[BRCMF_FW_NAME_LEN],
......
...@@ -16,10 +16,7 @@ ...@@ -16,10 +16,7 @@
#ifndef BRCMFMAC_FIRMWARE_H #ifndef BRCMFMAC_FIRMWARE_H
#define BRCMFMAC_FIRMWARE_H #define BRCMFMAC_FIRMWARE_H
#define BRCMF_FW_REQUEST 0x000F #define BRCMF_FW_REQF_OPTIONAL 0x0001
#define BRCMF_FW_REQUEST_NVRAM 0x0001
#define BRCMF_FW_REQ_FLAGS 0x00F0
#define BRCMF_FW_REQ_NV_OPTIONAL 0x0010
#define BRCMF_FW_NAME_LEN 320 #define BRCMF_FW_NAME_LEN 320
...@@ -54,21 +51,39 @@ int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev, ...@@ -54,21 +51,39 @@ int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev,
u32 table_size, char fw_name[BRCMF_FW_NAME_LEN], u32 table_size, char fw_name[BRCMF_FW_NAME_LEN],
char nvram_name[BRCMF_FW_NAME_LEN]); char nvram_name[BRCMF_FW_NAME_LEN]);
void brcmf_fw_nvram_free(void *nvram); void brcmf_fw_nvram_free(void *nvram);
enum brcmf_fw_type {
BRCMF_FW_TYPE_BINARY,
BRCMF_FW_TYPE_NVRAM
};
struct brcmf_fw_item {
const char *path;
enum brcmf_fw_type type;
u16 flags;
union {
const struct firmware *binary;
struct {
void *data;
u32 len;
} nv_data;
};
};
struct brcmf_fw_request {
u16 domain_nr;
u16 bus_nr;
u32 n_items;
struct brcmf_fw_item items[0];
};
/* /*
* Request firmware(s) asynchronously. When the asynchronous request * Request firmware(s) asynchronously. When the asynchronous request
* fails it will not use the callback, but call device_release_driver() * fails it will not use the callback, but call device_release_driver()
* instead which will call the driver .remove() callback. * instead which will call the driver .remove() callback.
*/ */
int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req,
const char *code, const char *nvram,
void (*fw_cb)(struct device *dev, int err,
const struct firmware *fw,
void *nvram_image, u32 nvram_len),
u16 domain_nr, u16 bus_nr);
int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
const char *code, const char *nvram,
void (*fw_cb)(struct device *dev, int err, void (*fw_cb)(struct device *dev, int err,
const struct firmware *fw, struct brcmf_fw_request *req));
void *nvram_image, u32 nvram_len));
#endif /* BRCMFMAC_FIRMWARE_H */ #endif /* BRCMFMAC_FIRMWARE_H */
...@@ -1651,15 +1651,19 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = { ...@@ -1651,15 +1651,19 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
.write32 = brcmf_pcie_buscore_write32, .write32 = brcmf_pcie_buscore_write32,
}; };
#define BRCMF_PCIE_FW_CODE 0
#define BRCMF_PCIE_FW_NVRAM 1
static void brcmf_pcie_setup(struct device *dev, int ret, static void brcmf_pcie_setup(struct device *dev, int ret,
const struct firmware *fw, struct brcmf_fw_request *fwreq)
void *nvram, u32 nvram_len)
{ {
const struct firmware *fw;
void *nvram;
struct brcmf_bus *bus; struct brcmf_bus *bus;
struct brcmf_pciedev *pcie_bus_dev; struct brcmf_pciedev *pcie_bus_dev;
struct brcmf_pciedev_info *devinfo; struct brcmf_pciedev_info *devinfo;
struct brcmf_commonring **flowrings; struct brcmf_commonring **flowrings;
u32 i; u32 i, nvram_len;
/* check firmware loading result */ /* check firmware loading result */
if (ret) if (ret)
...@@ -1670,6 +1674,11 @@ static void brcmf_pcie_setup(struct device *dev, int ret, ...@@ -1670,6 +1674,11 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
devinfo = pcie_bus_dev->devinfo; devinfo = pcie_bus_dev->devinfo;
brcmf_pcie_attach(devinfo); brcmf_pcie_attach(devinfo);
fw = fwreq->items[BRCMF_PCIE_FW_CODE].binary;
nvram = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.data;
nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len;
kfree(fwreq);
/* Some of the firmwares have the size of the memory of the device /* Some of the firmwares have the size of the memory of the device
* defined inside the firmware. This is because part of the memory in * defined inside the firmware. This is because part of the memory in
* the device is shared and the devision is determined by FW. Parse * the device is shared and the devision is determined by FW. Parse
...@@ -1730,6 +1739,7 @@ static int ...@@ -1730,6 +1739,7 @@ static int
brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
int ret; int ret;
struct brcmf_fw_request *fwreq;
struct brcmf_pciedev_info *devinfo; struct brcmf_pciedev_info *devinfo;
struct brcmf_pciedev *pcie_bus_dev; struct brcmf_pciedev *pcie_bus_dev;
struct brcmf_bus *bus; struct brcmf_bus *bus;
...@@ -1800,12 +1810,26 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1800,12 +1810,26 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (ret) if (ret)
goto fail_bus; goto fail_bus;
ret = brcmf_fw_get_firmwares_pcie(bus->dev, BRCMF_FW_REQUEST_NVRAM | fwreq = kzalloc(sizeof(*fwreq) + 2 * sizeof(struct brcmf_fw_item),
BRCMF_FW_REQ_NV_OPTIONAL, GFP_KERNEL);
devinfo->fw_name, devinfo->nvram_name, if (!fwreq) {
brcmf_pcie_setup, domain_nr, bus_nr); ret = -ENOMEM;
goto fail_bus;
}
fwreq->items[BRCMF_PCIE_FW_CODE].path = devinfo->fw_name;
fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
fwreq->items[BRCMF_PCIE_FW_NVRAM].path = devinfo->nvram_name;
fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL;
fwreq->n_items = 2;
fwreq->domain_nr = domain_nr;
fwreq->bus_nr = bus_nr;
ret = brcmf_fw_get_firmwares(bus->dev, fwreq, brcmf_pcie_setup);
if (ret == 0) if (ret == 0)
return 0; return 0;
kfree(fwreq);
fail_bus: fail_bus:
kfree(bus->msgbuf); kfree(bus->msgbuf);
kfree(bus); kfree(bus);
......
...@@ -4031,14 +4031,19 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { ...@@ -4031,14 +4031,19 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
.get_fwname = brcmf_sdio_get_fwname, .get_fwname = brcmf_sdio_get_fwname,
}; };
#define BRCMF_SDIO_FW_CODE 0
#define BRCMF_SDIO_FW_NVRAM 1
static void brcmf_sdio_firmware_callback(struct device *dev, int err, static void brcmf_sdio_firmware_callback(struct device *dev, int err,
const struct firmware *code, struct brcmf_fw_request *fwreq)
void *nvram, u32 nvram_len)
{ {
struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_sdio_dev *sdiod = bus_if->bus_priv.sdio; struct brcmf_sdio_dev *sdiod = bus_if->bus_priv.sdio;
struct brcmf_sdio *bus = sdiod->bus; struct brcmf_sdio *bus = sdiod->bus;
struct brcmf_core *core = bus->sdio_core; struct brcmf_core *core = bus->sdio_core;
const struct firmware *code;
void *nvram;
u32 nvram_len;
u8 saveclk; u8 saveclk;
brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err); brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
...@@ -4046,6 +4051,11 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, ...@@ -4046,6 +4051,11 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
if (err) if (err)
goto fail; goto fail;
code = fwreq->items[BRCMF_SDIO_FW_CODE].binary;
nvram = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.data;
nvram_len = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.len;
kfree(fwreq);
/* try to download image and nvram to the dongle */ /* try to download image and nvram to the dongle */
bus->alp_only = true; bus->alp_only = true;
err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len); err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
...@@ -4150,6 +4160,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) ...@@ -4150,6 +4160,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
int ret; int ret;
struct brcmf_sdio *bus; struct brcmf_sdio *bus;
struct workqueue_struct *wq; struct workqueue_struct *wq;
struct brcmf_fw_request *fwreq;
brcmf_dbg(TRACE, "Enter\n"); brcmf_dbg(TRACE, "Enter\n");
...@@ -4239,11 +4250,24 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) ...@@ -4239,11 +4250,24 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
if (ret) if (ret)
goto fail; goto fail;
ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM, fwreq = kzalloc(sizeof(fwreq) + 2 * sizeof(struct brcmf_fw_item),
sdiodev->fw_name, sdiodev->nvram_name, GFP_KERNEL);
if (!fwreq) {
ret = -ENOMEM;
goto fail;
}
fwreq->items[BRCMF_SDIO_FW_CODE].path = sdiodev->fw_name;
fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
fwreq->items[BRCMF_SDIO_FW_NVRAM].path = sdiodev->nvram_name;
fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
fwreq->n_items = 2;
ret = brcmf_fw_get_firmwares(sdiodev->dev, fwreq,
brcmf_sdio_firmware_callback); brcmf_sdio_firmware_callback);
if (ret != 0) { if (ret != 0) {
brcmf_err("async firmware request failed: %d\n", ret); brcmf_err("async firmware request failed: %d\n", ret);
kfree(fwreq);
goto fail; goto fail;
} }
......
...@@ -1155,18 +1155,23 @@ static const struct brcmf_bus_ops brcmf_usb_bus_ops = { ...@@ -1155,18 +1155,23 @@ static const struct brcmf_bus_ops brcmf_usb_bus_ops = {
.get_fwname = brcmf_usb_get_fwname, .get_fwname = brcmf_usb_get_fwname,
}; };
#define BRCMF_USB_FW_CODE 0
static void brcmf_usb_probe_phase2(struct device *dev, int ret, static void brcmf_usb_probe_phase2(struct device *dev, int ret,
const struct firmware *fw, struct brcmf_fw_request *fwreq)
void *nvram, u32 nvlen)
{ {
struct brcmf_bus *bus = dev_get_drvdata(dev); struct brcmf_bus *bus = dev_get_drvdata(dev);
struct brcmf_usbdev_info *devinfo = bus->bus_priv.usb->devinfo; struct brcmf_usbdev_info *devinfo = bus->bus_priv.usb->devinfo;
const struct firmware *fw;
if (ret) if (ret)
goto error; goto error;
brcmf_dbg(USB, "Start fw downloading\n"); brcmf_dbg(USB, "Start fw downloading\n");
fw = fwreq->items[BRCMF_USB_FW_CODE].binary;
kfree(fwreq);
ret = check_file(fw->data); ret = check_file(fw->data);
if (ret < 0) { if (ret < 0) {
brcmf_err("invalid firmware\n"); brcmf_err("invalid firmware\n");
...@@ -1200,6 +1205,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) ...@@ -1200,6 +1205,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
struct brcmf_bus *bus = NULL; struct brcmf_bus *bus = NULL;
struct brcmf_usbdev *bus_pub = NULL; struct brcmf_usbdev *bus_pub = NULL;
struct device *dev = devinfo->dev; struct device *dev = devinfo->dev;
struct brcmf_fw_request *fwreq;
int ret; int ret;
brcmf_dbg(USB, "Enter\n"); brcmf_dbg(USB, "Enter\n");
...@@ -1250,11 +1256,22 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) ...@@ -1250,11 +1256,22 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
if (ret) if (ret)
goto fail; goto fail;
fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item),
GFP_KERNEL);
if (!fwreq) {
ret = -ENOMEM;
goto fail;
}
fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name;
fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
fwreq->n_items = 1;
/* request firmware here */ /* request firmware here */
ret = brcmf_fw_get_firmwares(dev, 0, devinfo->fw_name, NULL, ret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2);
brcmf_usb_probe_phase2);
if (ret) { if (ret) {
brcmf_err("firmware request failed: %d\n", ret); brcmf_err("firmware request failed: %d\n", ret);
kfree(fwreq);
goto fail; goto fail;
} }
...@@ -1447,11 +1464,25 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf) ...@@ -1447,11 +1464,25 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf)
{ {
struct usb_device *usb = interface_to_usbdev(intf); struct usb_device *usb = interface_to_usbdev(intf);
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
struct brcmf_fw_request *fwreq;
int ret;
brcmf_dbg(USB, "Enter\n"); brcmf_dbg(USB, "Enter\n");
return brcmf_fw_get_firmwares(&usb->dev, 0, devinfo->fw_name, NULL, fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item),
brcmf_usb_probe_phase2); GFP_KERNEL);
if (!fwreq)
return -ENOMEM;
fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name;
fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
fwreq->n_items = 1;
ret = brcmf_fw_get_firmwares(&usb->dev, fwreq, brcmf_usb_probe_phase2);
if (ret < 0)
kfree(fwreq);
return ret;
} }
#define BRCMF_USB_DEVICE(dev_id) \ #define BRCMF_USB_DEVICE(dev_id) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment