Skip to content

Commit 2baa3aa

Browse files
Arend Van SprielKalle Valo
authored andcommitted
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]>
1 parent d09ae51 commit 2baa3aa

File tree

5 files changed

+147
-60
lines changed

5 files changed

+147
-60
lines changed

drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,3 +688,61 @@ int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev,
688688
return 0;
689689
}
690690

691+
struct brcmf_fw_request *
692+
brcmf_fw_alloc_request(u32 chip, u32 chiprev,
693+
struct brcmf_firmware_mapping mapping_table[],
694+
u32 table_size, struct brcmf_fw_name *fwnames,
695+
u32 n_fwnames)
696+
{
697+
struct brcmf_fw_request *fwreq;
698+
char chipname[12];
699+
const char *mp_path;
700+
u32 i, j;
701+
char end;
702+
size_t reqsz;
703+
704+
for (i = 0; i < table_size; i++) {
705+
if (mapping_table[i].chipid == chip &&
706+
mapping_table[i].revmask & BIT(chiprev))
707+
break;
708+
}
709+
710+
if (i == table_size) {
711+
brcmf_err("Unknown chipid %d [%d]\n", chip, chiprev);
712+
return NULL;
713+
}
714+
715+
reqsz = sizeof(*fwreq) + n_fwnames * sizeof(struct brcmf_fw_item);
716+
fwreq = kzalloc(reqsz, GFP_KERNEL);
717+
if (!fwreq)
718+
return NULL;
719+
720+
brcmf_chip_name(chip, chiprev, chipname, sizeof(chipname));
721+
722+
brcmf_info("using %s for chip %s\n",
723+
mapping_table[i].fw_base, chipname);
724+
725+
mp_path = brcmf_mp_global.firmware_path;
726+
end = mp_path[strlen(mp_path) - 1];
727+
fwreq->n_items = n_fwnames;
728+
729+
for (j = 0; j < n_fwnames; j++) {
730+
fwreq->items[j].path = fwnames[j].path;
731+
/* check if firmware path is provided by module parameter */
732+
if (brcmf_mp_global.firmware_path[0] != '\0') {
733+
strlcpy(fwnames[j].path, mp_path,
734+
BRCMF_FW_NAME_LEN);
735+
736+
if (end != '/') {
737+
strlcat(fwnames[j].path, "/",
738+
BRCMF_FW_NAME_LEN);
739+
}
740+
}
741+
brcmf_fw_get_full_name(fwnames[j].path,
742+
mapping_table[i].fw_base,
743+
fwnames[j].extension);
744+
fwreq->items[j].path = fwnames[j].path;
745+
}
746+
747+
return fwreq;
748+
}

drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@ struct brcmf_fw_request {
7777
struct brcmf_fw_item items[0];
7878
};
7979

80+
struct brcmf_fw_name {
81+
const char *extension;
82+
char *path;
83+
};
84+
85+
struct brcmf_fw_request *
86+
brcmf_fw_alloc_request(u32 chip, u32 chiprev,
87+
struct brcmf_firmware_mapping mapping_table[],
88+
u32 table_size, struct brcmf_fw_name *fwnames,
89+
u32 n_fwnames);
90+
8091
/*
8192
* Request firmware(s) asynchronously. When the asynchronous request
8293
* fails it will not use the callback, but call device_release_driver()

drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,6 +1735,31 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
17351735
device_release_driver(dev);
17361736
}
17371737

1738+
static struct brcmf_fw_request *
1739+
brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
1740+
{
1741+
struct brcmf_fw_request *fwreq;
1742+
struct brcmf_fw_name fwnames[] = {
1743+
{ ".bin", devinfo->fw_name },
1744+
{ ".txt", devinfo->nvram_name },
1745+
};
1746+
1747+
fwreq = brcmf_fw_alloc_request(devinfo->ci->chip, devinfo->ci->chiprev,
1748+
brcmf_pcie_fwnames,
1749+
ARRAY_SIZE(brcmf_pcie_fwnames),
1750+
fwnames, ARRAY_SIZE(fwnames));
1751+
if (!fwreq)
1752+
return NULL;
1753+
1754+
fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
1755+
fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
1756+
fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL;
1757+
fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus);
1758+
fwreq->bus_nr = devinfo->pdev->bus->number;
1759+
1760+
return fwreq;
1761+
}
1762+
17381763
static int
17391764
brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
17401765
{
@@ -1743,13 +1768,8 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
17431768
struct brcmf_pciedev_info *devinfo;
17441769
struct brcmf_pciedev *pcie_bus_dev;
17451770
struct brcmf_bus *bus;
1746-
u16 domain_nr;
1747-
u16 bus_nr;
17481771

1749-
domain_nr = pci_domain_nr(pdev->bus) + 1;
1750-
bus_nr = pdev->bus->number;
1751-
brcmf_dbg(PCIE, "Enter %x:%x (%d/%d)\n", pdev->vendor, pdev->device,
1752-
domain_nr, bus_nr);
1772+
brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device);
17531773

17541774
ret = -ENOMEM;
17551775
devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
@@ -1803,33 +1823,19 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
18031823
bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot);
18041824
dev_set_drvdata(&pdev->dev, bus);
18051825

1806-
ret = brcmf_fw_map_chip_to_name(devinfo->ci->chip, devinfo->ci->chiprev,
1807-
brcmf_pcie_fwnames,
1808-
ARRAY_SIZE(brcmf_pcie_fwnames),
1809-
devinfo->fw_name, devinfo->nvram_name);
1810-
if (ret)
1811-
goto fail_bus;
1812-
1813-
fwreq = kzalloc(sizeof(*fwreq) + 2 * sizeof(struct brcmf_fw_item),
1814-
GFP_KERNEL);
1826+
fwreq = brcmf_pcie_prepare_fw_request(devinfo);
18151827
if (!fwreq) {
18161828
ret = -ENOMEM;
18171829
goto fail_bus;
18181830
}
18191831

1820-
fwreq->items[BRCMF_PCIE_FW_CODE].path = devinfo->fw_name;
1821-
fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
1822-
fwreq->items[BRCMF_PCIE_FW_NVRAM].path = devinfo->nvram_name;
1823-
fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
1824-
fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL;
1825-
fwreq->n_items = 2;
1826-
fwreq->domain_nr = domain_nr;
1827-
fwreq->bus_nr = bus_nr;
18281832
ret = brcmf_fw_get_firmwares(bus->dev, fwreq, brcmf_pcie_setup);
1829-
if (ret == 0)
1830-
return 0;
1833+
if (ret < 0) {
1834+
kfree(fwreq);
1835+
goto fail_bus;
1836+
}
1837+
return 0;
18311838

1832-
kfree(fwreq);
18331839
fail_bus:
18341840
kfree(bus->msgbuf);
18351841
kfree(bus);

drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4155,6 +4155,28 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
41554155
device_release_driver(dev);
41564156
}
41574157

4158+
static struct brcmf_fw_request *
4159+
brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus)
4160+
{
4161+
struct brcmf_fw_request *fwreq;
4162+
struct brcmf_fw_name fwnames[] = {
4163+
{ ".bin", bus->sdiodev->fw_name },
4164+
{ ".txt", bus->sdiodev->nvram_name },
4165+
};
4166+
4167+
fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev,
4168+
brcmf_sdio_fwnames,
4169+
ARRAY_SIZE(brcmf_sdio_fwnames),
4170+
fwnames, ARRAY_SIZE(fwnames));
4171+
if (!fwreq)
4172+
return NULL;
4173+
4174+
fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
4175+
fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
4176+
4177+
return fwreq;
4178+
}
4179+
41584180
struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
41594181
{
41604182
int ret;
@@ -4243,26 +4265,12 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
42434265

42444266
brcmf_dbg(INFO, "completed!!\n");
42454267

4246-
ret = brcmf_fw_map_chip_to_name(bus->ci->chip, bus->ci->chiprev,
4247-
brcmf_sdio_fwnames,
4248-
ARRAY_SIZE(brcmf_sdio_fwnames),
4249-
sdiodev->fw_name, sdiodev->nvram_name);
4250-
if (ret)
4251-
goto fail;
4252-
4253-
fwreq = kzalloc(sizeof(fwreq) + 2 * sizeof(struct brcmf_fw_item),
4254-
GFP_KERNEL);
4268+
fwreq = brcmf_sdio_prepare_fw_request(bus);
42554269
if (!fwreq) {
42564270
ret = -ENOMEM;
42574271
goto fail;
42584272
}
42594273

4260-
fwreq->items[BRCMF_SDIO_FW_CODE].path = sdiodev->fw_name;
4261-
fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
4262-
fwreq->items[BRCMF_SDIO_FW_NVRAM].path = sdiodev->nvram_name;
4263-
fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
4264-
fwreq->n_items = 2;
4265-
42664274
ret = brcmf_fw_get_firmwares(sdiodev->dev, fwreq,
42674275
brcmf_sdio_firmware_callback);
42684276
if (ret != 0) {

drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,27 @@ static void brcmf_usb_probe_phase2(struct device *dev, int ret,
12001200
device_release_driver(dev);
12011201
}
12021202

1203+
static struct brcmf_fw_request *
1204+
brcmf_usb_prepare_fw_request(struct brcmf_usbdev_info *devinfo)
1205+
{
1206+
struct brcmf_fw_request *fwreq;
1207+
struct brcmf_fw_name fwnames[] = {
1208+
{ ".bin", devinfo->fw_name },
1209+
};
1210+
1211+
fwreq = brcmf_fw_alloc_request(devinfo->bus_pub.devid,
1212+
devinfo->bus_pub.chiprev,
1213+
brcmf_usb_fwnames,
1214+
ARRAY_SIZE(brcmf_usb_fwnames),
1215+
fwnames, ARRAY_SIZE(fwnames));
1216+
if (!fwreq)
1217+
return NULL;
1218+
1219+
fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
1220+
1221+
return fwreq;
1222+
}
1223+
12031224
static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
12041225
{
12051226
struct brcmf_bus *bus = NULL;
@@ -1249,24 +1270,12 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
12491270
bus->chip = bus_pub->devid;
12501271
bus->chiprev = bus_pub->chiprev;
12511272

1252-
ret = brcmf_fw_map_chip_to_name(bus_pub->devid, bus_pub->chiprev,
1253-
brcmf_usb_fwnames,
1254-
ARRAY_SIZE(brcmf_usb_fwnames),
1255-
devinfo->fw_name, NULL);
1256-
if (ret)
1257-
goto fail;
1258-
1259-
fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item),
1260-
GFP_KERNEL);
1273+
fwreq = brcmf_usb_prepare_fw_request(devinfo);
12611274
if (!fwreq) {
12621275
ret = -ENOMEM;
12631276
goto fail;
12641277
}
12651278

1266-
fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name;
1267-
fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
1268-
fwreq->n_items = 1;
1269-
12701279
/* request firmware here */
12711280
ret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2);
12721281
if (ret) {
@@ -1469,15 +1478,10 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf)
14691478

14701479
brcmf_dbg(USB, "Enter\n");
14711480

1472-
fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item),
1473-
GFP_KERNEL);
1481+
fwreq = brcmf_usb_prepare_fw_request(devinfo);
14741482
if (!fwreq)
14751483
return -ENOMEM;
14761484

1477-
fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name;
1478-
fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
1479-
fwreq->n_items = 1;
1480-
14811485
ret = brcmf_fw_get_firmwares(&usb->dev, fwreq, brcmf_usb_probe_phase2);
14821486
if (ret < 0)
14831487
kfree(fwreq);

0 commit comments

Comments
 (0)