Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+49 -36
+17 -18
drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
··· 442 442 const char *nvram_name; 443 443 u16 domain_nr; 444 444 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, 446 446 void *nvram_image, u32 nvram_len); 447 447 }; 448 448 ··· 477 477 if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) 478 478 goto fail; 479 479 480 - fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length); 480 + fwctx->done(fwctx->dev, 0, fwctx->code, nvram, nvram_length); 481 481 kfree(fwctx); 482 482 return; 483 483 484 484 fail: 485 485 brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); 486 486 release_firmware(fwctx->code); 487 - device_release_driver(fwctx->dev); 487 + fwctx->done(fwctx->dev, -ENOENT, NULL, NULL, 0); 488 488 kfree(fwctx); 489 489 } 490 490 491 491 static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx) 492 492 { 493 493 struct brcmf_fw *fwctx = ctx; 494 - int ret; 494 + int ret = 0; 495 495 496 496 brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev)); 497 - if (!fw) 497 + if (!fw) { 498 + ret = -ENOENT; 498 499 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; 505 500 } 501 + /* only requested code so done here */ 502 + if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) 503 + goto done; 504 + 506 505 fwctx->code = fw; 507 506 ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name, 508 507 fwctx->dev, GFP_KERNEL, fwctx, 509 508 brcmf_fw_request_nvram_done); 510 509 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); 515 513 return; 516 514 517 515 fail: 518 516 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); 520 519 kfree(fwctx); 521 520 } 522 521 523 522 int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, 524 523 const char *code, const char *nvram, 525 - void (*fw_cb)(struct device *dev, 524 + void (*fw_cb)(struct device *dev, int err, 526 525 const struct firmware *fw, 527 526 void *nvram_image, u32 nvram_len), 528 527 u16 domain_nr, u16 bus_nr) ··· 554 555 555 556 int brcmf_fw_get_firmwares(struct device *dev, u16 flags, 556 557 const char *code, const char *nvram, 557 - void (*fw_cb)(struct device *dev, 558 + void (*fw_cb)(struct device *dev, int err, 558 559 const struct firmware *fw, 559 560 void *nvram_image, u32 nvram_len)) 560 561 {
+2 -2
drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
··· 73 73 */ 74 74 int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, 75 75 const char *code, const char *nvram, 76 - void (*fw_cb)(struct device *dev, 76 + void (*fw_cb)(struct device *dev, int err, 77 77 const struct firmware *fw, 78 78 void *nvram_image, u32 nvram_len), 79 79 u16 domain_nr, u16 bus_nr); 80 80 int brcmf_fw_get_firmwares(struct device *dev, u16 flags, 81 81 const char *code, const char *nvram, 82 - void (*fw_cb)(struct device *dev, 82 + void (*fw_cb)(struct device *dev, int err, 83 83 const struct firmware *fw, 84 84 void *nvram_image, u32 nvram_len)); 85 85
+1 -1
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
··· 2145 2145 struct brcmf_fws_info *fws = drvr_to_fws(ifp->drvr); 2146 2146 struct brcmf_fws_mac_descriptor *entry; 2147 2147 2148 - if (!ifp->ndev || fws->fcmode == BRCMF_FWS_FCMODE_NONE) 2148 + if (!ifp->ndev || !brcmf_fws_queue_skbs(fws)) 2149 2149 return; 2150 2150 2151 2151 entry = &fws->desc.iface[ifp->ifidx];
+12 -5
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
··· 1650 1650 .write32 = brcmf_pcie_buscore_write32, 1651 1651 }; 1652 1652 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, 1654 1655 void *nvram, u32 nvram_len) 1655 1656 { 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; 1659 1660 struct brcmf_commonring **flowrings; 1660 - int ret; 1661 1661 u32 i; 1662 1662 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; 1663 1670 brcmf_pcie_attach(devinfo); 1664 1671 1665 1672 /* Some of the firmwares have the size of the memory of the device
+12 -6
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
··· 3982 3982 .get_memdump = brcmf_sdio_bus_get_memdump, 3983 3983 }; 3984 3984 3985 - static void brcmf_sdio_firmware_callback(struct device *dev, 3985 + static void brcmf_sdio_firmware_callback(struct device *dev, int err, 3986 3986 const struct firmware *code, 3987 3987 void *nvram, u32 nvram_len) 3988 3988 { 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; 3993 3992 u8 saveclk; 3994 3993 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; 3996 3999 3997 4000 if (!bus_if->drvr) 3998 4001 return; 4002 + 4003 + bus = sdiodev->bus; 3999 4004 4000 4005 /* try to download image and nvram to the dongle */ 4001 4006 bus->alp_only = true; ··· 4088 4083 fail: 4089 4084 brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err); 4090 4085 device_release_driver(dev); 4086 + device_release_driver(&sdiodev->func[2]->dev); 4091 4087 } 4092 4088 4093 4089 struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+5 -4
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
··· 1159 1159 return ret; 1160 1160 } 1161 1161 1162 - static void brcmf_usb_probe_phase2(struct device *dev, 1162 + static void brcmf_usb_probe_phase2(struct device *dev, int ret, 1163 1163 const struct firmware *fw, 1164 1164 void *nvram, u32 nvlen) 1165 1165 { 1166 1166 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; 1169 1171 1170 1172 brcmf_dbg(USB, "Start fw downloading\n"); 1171 1173 1172 - devinfo = bus->bus_priv.usb->devinfo; 1173 1174 ret = check_file(fw->data); 1174 1175 if (ret < 0) { 1175 1176 brcmf_err("invalid firmware\n");