123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- From 2baa3aaee27f137b8db9a9224d0fe9b281d28e34 Mon Sep 17 00:00:00 2001
- From: Arend Van Spriel <[email protected]>
- Date: Thu, 22 Mar 2018 21:28:27 +0100
- Subject: [PATCH] brcmfmac: introduce brcmf_fw_alloc_request() function
- The function brcmf_fw_alloc_request() takes a list of required files
- and allocated the struct brcmf_fw_request instance accordingly. The
- request can be modified by the caller before being passed to the
- brcmf_fw_request_firmwares() function.
- Reviewed-by: Hante Meuleman <[email protected]>
- Reviewed-by: Pieter-Paul Giesberts <[email protected]>
- Reviewed-by: Franky Lin <[email protected]>
- Signed-off-by: Arend van Spriel <[email protected]>
- Signed-off-by: Kalle Valo <[email protected]>
- ---
- .../broadcom/brcm80211/brcmfmac/firmware.c | 58 ++++++++++++++++++++++
- .../broadcom/brcm80211/brcmfmac/firmware.h | 11 ++++
- .../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 58 ++++++++++++----------
- .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 38 ++++++++------
- .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 42 +++++++++-------
- 5 files changed, 147 insertions(+), 60 deletions(-)
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
- @@ -688,3 +688,61 @@ int brcmf_fw_map_chip_to_name(u32 chip,
- return 0;
- }
-
- +struct brcmf_fw_request *
- +brcmf_fw_alloc_request(u32 chip, u32 chiprev,
- + struct brcmf_firmware_mapping mapping_table[],
- + u32 table_size, struct brcmf_fw_name *fwnames,
- + u32 n_fwnames)
- +{
- + struct brcmf_fw_request *fwreq;
- + char chipname[12];
- + const char *mp_path;
- + u32 i, j;
- + char end;
- + size_t reqsz;
- +
- + for (i = 0; i < table_size; i++) {
- + if (mapping_table[i].chipid == chip &&
- + mapping_table[i].revmask & BIT(chiprev))
- + break;
- + }
- +
- + if (i == table_size) {
- + brcmf_err("Unknown chipid %d [%d]\n", chip, chiprev);
- + return NULL;
- + }
- +
- + reqsz = sizeof(*fwreq) + n_fwnames * sizeof(struct brcmf_fw_item);
- + fwreq = kzalloc(reqsz, GFP_KERNEL);
- + if (!fwreq)
- + return NULL;
- +
- + brcmf_chip_name(chip, chiprev, chipname, sizeof(chipname));
- +
- + brcmf_info("using %s for chip %s\n",
- + mapping_table[i].fw_base, chipname);
- +
- + mp_path = brcmf_mp_global.firmware_path;
- + end = mp_path[strlen(mp_path) - 1];
- + fwreq->n_items = n_fwnames;
- +
- + for (j = 0; j < n_fwnames; j++) {
- + fwreq->items[j].path = fwnames[j].path;
- + /* check if firmware path is provided by module parameter */
- + if (brcmf_mp_global.firmware_path[0] != '\0') {
- + strlcpy(fwnames[j].path, mp_path,
- + BRCMF_FW_NAME_LEN);
- +
- + if (end != '/') {
- + strlcat(fwnames[j].path, "/",
- + BRCMF_FW_NAME_LEN);
- + }
- + }
- + brcmf_fw_get_full_name(fwnames[j].path,
- + mapping_table[i].fw_base,
- + fwnames[j].extension);
- + fwreq->items[j].path = fwnames[j].path;
- + }
- +
- + return fwreq;
- +}
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
- @@ -77,6 +77,17 @@ struct brcmf_fw_request {
- struct brcmf_fw_item items[0];
- };
-
- +struct brcmf_fw_name {
- + const char *extension;
- + char *path;
- +};
- +
- +struct brcmf_fw_request *
- +brcmf_fw_alloc_request(u32 chip, u32 chiprev,
- + struct brcmf_firmware_mapping mapping_table[],
- + u32 table_size, struct brcmf_fw_name *fwnames,
- + u32 n_fwnames);
- +
- /*
- * Request firmware(s) asynchronously. When the asynchronous request
- * fails it will not use the callback, but call device_release_driver()
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
- @@ -1735,6 +1735,31 @@ fail:
- device_release_driver(dev);
- }
-
- +static struct brcmf_fw_request *
- +brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
- +{
- + struct brcmf_fw_request *fwreq;
- + struct brcmf_fw_name fwnames[] = {
- + { ".bin", devinfo->fw_name },
- + { ".txt", devinfo->nvram_name },
- + };
- +
- + fwreq = brcmf_fw_alloc_request(devinfo->ci->chip, devinfo->ci->chiprev,
- + brcmf_pcie_fwnames,
- + ARRAY_SIZE(brcmf_pcie_fwnames),
- + fwnames, ARRAY_SIZE(fwnames));
- + if (!fwreq)
- + return NULL;
- +
- + fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
- + fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
- + fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL;
- + fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus);
- + fwreq->bus_nr = devinfo->pdev->bus->number;
- +
- + return fwreq;
- +}
- +
- static int
- brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
- {
- @@ -1743,13 +1768,8 @@ brcmf_pcie_probe(struct pci_dev *pdev, c
- struct brcmf_pciedev_info *devinfo;
- struct brcmf_pciedev *pcie_bus_dev;
- struct brcmf_bus *bus;
- - u16 domain_nr;
- - u16 bus_nr;
-
- - domain_nr = pci_domain_nr(pdev->bus) + 1;
- - bus_nr = pdev->bus->number;
- - brcmf_dbg(PCIE, "Enter %x:%x (%d/%d)\n", pdev->vendor, pdev->device,
- - domain_nr, bus_nr);
- + brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device);
-
- ret = -ENOMEM;
- devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
- @@ -1803,33 +1823,19 @@ brcmf_pcie_probe(struct pci_dev *pdev, c
- bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot);
- dev_set_drvdata(&pdev->dev, bus);
-
- - ret = brcmf_fw_map_chip_to_name(devinfo->ci->chip, devinfo->ci->chiprev,
- - brcmf_pcie_fwnames,
- - ARRAY_SIZE(brcmf_pcie_fwnames),
- - devinfo->fw_name, devinfo->nvram_name);
- - if (ret)
- - goto fail_bus;
- -
- - fwreq = kzalloc(sizeof(*fwreq) + 2 * sizeof(struct brcmf_fw_item),
- - GFP_KERNEL);
- + fwreq = brcmf_pcie_prepare_fw_request(devinfo);
- if (!fwreq) {
- 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)
- - return 0;
- + if (ret < 0) {
- + kfree(fwreq);
- + goto fail_bus;
- + }
- + return 0;
-
- - kfree(fwreq);
- fail_bus:
- kfree(bus->msgbuf);
- kfree(bus);
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
- @@ -4155,6 +4155,28 @@ fail:
- device_release_driver(dev);
- }
-
- +static struct brcmf_fw_request *
- +brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus)
- +{
- + struct brcmf_fw_request *fwreq;
- + struct brcmf_fw_name fwnames[] = {
- + { ".bin", bus->sdiodev->fw_name },
- + { ".txt", bus->sdiodev->nvram_name },
- + };
- +
- + fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev,
- + brcmf_sdio_fwnames,
- + ARRAY_SIZE(brcmf_sdio_fwnames),
- + fwnames, ARRAY_SIZE(fwnames));
- + if (!fwreq)
- + return NULL;
- +
- + fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
- + fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
- +
- + return fwreq;
- +}
- +
- struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
- {
- int ret;
- @@ -4244,26 +4266,12 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
-
- brcmf_dbg(INFO, "completed!!\n");
-
- - ret = brcmf_fw_map_chip_to_name(bus->ci->chip, bus->ci->chiprev,
- - brcmf_sdio_fwnames,
- - ARRAY_SIZE(brcmf_sdio_fwnames),
- - sdiodev->fw_name, sdiodev->nvram_name);
- - if (ret)
- - goto fail;
- -
- - fwreq = kzalloc(sizeof(fwreq) + 2 * sizeof(struct brcmf_fw_item),
- - GFP_KERNEL);
- + fwreq = brcmf_sdio_prepare_fw_request(bus);
- 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);
- if (ret != 0) {
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
- @@ -1200,6 +1200,27 @@ error:
- device_release_driver(dev);
- }
-
- +static struct brcmf_fw_request *
- +brcmf_usb_prepare_fw_request(struct brcmf_usbdev_info *devinfo)
- +{
- + struct brcmf_fw_request *fwreq;
- + struct brcmf_fw_name fwnames[] = {
- + { ".bin", devinfo->fw_name },
- + };
- +
- + fwreq = brcmf_fw_alloc_request(devinfo->bus_pub.devid,
- + devinfo->bus_pub.chiprev,
- + brcmf_usb_fwnames,
- + ARRAY_SIZE(brcmf_usb_fwnames),
- + fwnames, ARRAY_SIZE(fwnames));
- + if (!fwreq)
- + return NULL;
- +
- + fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
- +
- + return fwreq;
- +}
- +
- static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
- {
- struct brcmf_bus *bus = NULL;
- @@ -1249,24 +1270,12 @@ static int brcmf_usb_probe_cb(struct brc
- bus->chip = bus_pub->devid;
- bus->chiprev = bus_pub->chiprev;
-
- - ret = brcmf_fw_map_chip_to_name(bus_pub->devid, bus_pub->chiprev,
- - brcmf_usb_fwnames,
- - ARRAY_SIZE(brcmf_usb_fwnames),
- - devinfo->fw_name, NULL);
- - if (ret)
- - goto fail;
- -
- - fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item),
- - GFP_KERNEL);
- + fwreq = brcmf_usb_prepare_fw_request(devinfo);
- 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 */
- ret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2);
- if (ret) {
- @@ -1469,15 +1478,10 @@ static int brcmf_usb_reset_resume(struct
-
- brcmf_dbg(USB, "Enter\n");
-
- - fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item),
- - GFP_KERNEL);
- + fwreq = brcmf_usb_prepare_fw_request(devinfo);
- 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);
|