Skip to content

Commit afd6463

Browse files
committed
Merge tag 'wireless-drivers-for-davem-2017-06-20' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers
Kalle Valo says: ==================== wireless-drivers fixes for 4.12 Two important fixes for brcmfmac. The rest of the brcmfmac patches are either code preparation and fixing a new build warning. brcmfmac * fix a NULL pointer dereference during resume * fix a NULL pointer dereference with USB devices, a regression from v4.12-rc1 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 05cf0d1 + 35abcd4 commit afd6463

File tree

6 files changed

+49
-36
lines changed

6 files changed

+49
-36
lines changed

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

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ struct brcmf_fw {
442442
const char *nvram_name;
443443
u16 domain_nr;
444444
u16 bus_nr;
445-
void (*done)(struct device *dev, const struct firmware *fw,
445+
void (*done)(struct device *dev, int err, const struct firmware *fw,
446446
void *nvram_image, u32 nvram_len);
447447
};
448448

@@ -477,52 +477,51 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
477477
if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
478478
goto fail;
479479

480-
fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length);
480+
fwctx->done(fwctx->dev, 0, fwctx->code, nvram, nvram_length);
481481
kfree(fwctx);
482482
return;
483483

484484
fail:
485485
brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
486486
release_firmware(fwctx->code);
487-
device_release_driver(fwctx->dev);
487+
fwctx->done(fwctx->dev, -ENOENT, NULL, NULL, 0);
488488
kfree(fwctx);
489489
}
490490

491491
static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx)
492492
{
493493
struct brcmf_fw *fwctx = ctx;
494-
int ret;
494+
int ret = 0;
495495

496496
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
497-
if (!fw)
497+
if (!fw) {
498+
ret = -ENOENT;
498499
goto fail;
499-
500-
/* only requested code so done here */
501-
if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) {
502-
fwctx->done(fwctx->dev, fw, NULL, 0);
503-
kfree(fwctx);
504-
return;
505500
}
501+
/* only requested code so done here */
502+
if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM))
503+
goto done;
504+
506505
fwctx->code = fw;
507506
ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name,
508507
fwctx->dev, GFP_KERNEL, fwctx,
509508
brcmf_fw_request_nvram_done);
510509

511-
if (!ret)
512-
return;
513-
514-
brcmf_fw_request_nvram_done(NULL, fwctx);
510+
/* pass NULL to nvram callback for bcm47xx fallback */
511+
if (ret)
512+
brcmf_fw_request_nvram_done(NULL, fwctx);
515513
return;
516514

517515
fail:
518516
brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
519-
device_release_driver(fwctx->dev);
517+
done:
518+
fwctx->done(fwctx->dev, ret, fw, NULL, 0);
520519
kfree(fwctx);
521520
}
522521

523522
int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
524523
const char *code, const char *nvram,
525-
void (*fw_cb)(struct device *dev,
524+
void (*fw_cb)(struct device *dev, int err,
526525
const struct firmware *fw,
527526
void *nvram_image, u32 nvram_len),
528527
u16 domain_nr, u16 bus_nr)
@@ -555,7 +554,7 @@ int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
555554

556555
int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
557556
const char *code, const char *nvram,
558-
void (*fw_cb)(struct device *dev,
557+
void (*fw_cb)(struct device *dev, int err,
559558
const struct firmware *fw,
560559
void *nvram_image, u32 nvram_len))
561560
{

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,13 @@ void brcmf_fw_nvram_free(void *nvram);
7373
*/
7474
int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
7575
const char *code, const char *nvram,
76-
void (*fw_cb)(struct device *dev,
76+
void (*fw_cb)(struct device *dev, int err,
7777
const struct firmware *fw,
7878
void *nvram_image, u32 nvram_len),
7979
u16 domain_nr, u16 bus_nr);
8080
int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
8181
const char *code, const char *nvram,
82-
void (*fw_cb)(struct device *dev,
82+
void (*fw_cb)(struct device *dev, int err,
8383
const struct firmware *fw,
8484
void *nvram_image, u32 nvram_len));
8585

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2145,7 +2145,7 @@ void brcmf_fws_add_interface(struct brcmf_if *ifp)
21452145
struct brcmf_fws_info *fws = drvr_to_fws(ifp->drvr);
21462146
struct brcmf_fws_mac_descriptor *entry;
21472147

2148-
if (!ifp->ndev || fws->fcmode == BRCMF_FWS_FCMODE_NONE)
2148+
if (!ifp->ndev || !brcmf_fws_queue_skbs(fws))
21492149
return;
21502150

21512151
entry = &fws->desc.iface[ifp->ifidx];

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,16 +1650,23 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
16501650
.write32 = brcmf_pcie_buscore_write32,
16511651
};
16521652

1653-
static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw,
1653+
static void brcmf_pcie_setup(struct device *dev, int ret,
1654+
const struct firmware *fw,
16541655
void *nvram, u32 nvram_len)
16551656
{
1656-
struct brcmf_bus *bus = dev_get_drvdata(dev);
1657-
struct brcmf_pciedev *pcie_bus_dev = bus->bus_priv.pcie;
1658-
struct brcmf_pciedev_info *devinfo = pcie_bus_dev->devinfo;
1657+
struct brcmf_bus *bus;
1658+
struct brcmf_pciedev *pcie_bus_dev;
1659+
struct brcmf_pciedev_info *devinfo;
16591660
struct brcmf_commonring **flowrings;
1660-
int ret;
16611661
u32 i;
16621662

1663+
/* check firmware loading result */
1664+
if (ret)
1665+
goto fail;
1666+
1667+
bus = dev_get_drvdata(dev);
1668+
pcie_bus_dev = bus->bus_priv.pcie;
1669+
devinfo = pcie_bus_dev->devinfo;
16631670
brcmf_pcie_attach(devinfo);
16641671

16651672
/* Some of the firmwares have the size of the memory of the device

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3982,21 +3982,26 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
39823982
.get_memdump = brcmf_sdio_bus_get_memdump,
39833983
};
39843984

3985-
static void brcmf_sdio_firmware_callback(struct device *dev,
3985+
static void brcmf_sdio_firmware_callback(struct device *dev, int err,
39863986
const struct firmware *code,
39873987
void *nvram, u32 nvram_len)
39883988
{
3989-
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
3990-
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
3991-
struct brcmf_sdio *bus = sdiodev->bus;
3992-
int err = 0;
3989+
struct brcmf_bus *bus_if;
3990+
struct brcmf_sdio_dev *sdiodev;
3991+
struct brcmf_sdio *bus;
39933992
u8 saveclk;
39943993

3995-
brcmf_dbg(TRACE, "Enter: dev=%s\n", dev_name(dev));
3994+
brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
3995+
bus_if = dev_get_drvdata(dev);
3996+
sdiodev = bus_if->bus_priv.sdio;
3997+
if (err)
3998+
goto fail;
39963999

39974000
if (!bus_if->drvr)
39984001
return;
39994002

4003+
bus = sdiodev->bus;
4004+
40004005
/* try to download image and nvram to the dongle */
40014006
bus->alp_only = true;
40024007
err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
@@ -4083,6 +4088,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev,
40834088
fail:
40844089
brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err);
40854090
device_release_driver(dev);
4091+
device_release_driver(&sdiodev->func[2]->dev);
40864092
}
40874093

40884094
struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,17 +1159,18 @@ static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
11591159
return ret;
11601160
}
11611161

1162-
static void brcmf_usb_probe_phase2(struct device *dev,
1162+
static void brcmf_usb_probe_phase2(struct device *dev, int ret,
11631163
const struct firmware *fw,
11641164
void *nvram, u32 nvlen)
11651165
{
11661166
struct brcmf_bus *bus = dev_get_drvdata(dev);
1167-
struct brcmf_usbdev_info *devinfo;
1168-
int ret;
1167+
struct brcmf_usbdev_info *devinfo = bus->bus_priv.usb->devinfo;
1168+
1169+
if (ret)
1170+
goto error;
11691171

11701172
brcmf_dbg(USB, "Start fw downloading\n");
11711173

1172-
devinfo = bus->bus_priv.usb->devinfo;
11731174
ret = check_file(fw->data);
11741175
if (ret < 0) {
11751176
brcmf_err("invalid firmware\n");

0 commit comments

Comments
 (0)