Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mac80211: backport brcmfmac firmware & clm_blob loading rework
It backports remaining brcmfmac changes from 4.17. Signed-off-by: Rafał Miłecki <rafal@milecki.pl> (cherry picked from commit 7e8eb7f)
- Loading branch information
Rafał Miłecki
committed
Jun 23, 2018
1 parent
72f6025
commit 2811c97
Showing
8 changed files
with
1,392 additions
and
41 deletions.
There are no files selected for viewing
574 changes: 574 additions & 0 deletions
574
...rnel/mac80211/patches/327-v4.17-0007-brcmfmac-pass-struct-in-brcmf_fw_get_firmwares.patch
Large diffs are not rendered by default.
Oops, something went wrong.
328 changes: 328 additions & 0 deletions
328
.../mac80211/patches/327-v4.17-0008-brcmfmac-introduce-brcmf_fw_alloc_request-function.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,328 @@ | ||
From 2baa3aaee27f137b8db9a9224d0fe9b281d28e34 Mon Sep 17 00:00:00 2001 | ||
From: Arend Van Spriel <arend.vanspriel@broadcom.com> | ||
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 <hante.meuleman@broadcom.com> | ||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||
Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||
--- | ||
.../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); |
Oops, something went wrong.