Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit afd64631 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'wireless-drivers-for-davem-2017-06-20' of...

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 05cf0d1b 35abcd4f
Loading
Loading
Loading
Loading
+17 −18
Original line number Diff line number Diff line
@@ -442,7 +442,7 @@ struct brcmf_fw {
	const char *nvram_name;
	u16 domain_nr;
	u16 bus_nr;
	void (*done)(struct device *dev, const struct firmware *fw,
	void (*done)(struct device *dev, int err, const struct firmware *fw,
		     void *nvram_image, u32 nvram_len);
};

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

	fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length);
	fwctx->done(fwctx->dev, 0, fwctx->code, nvram, nvram_length);
	kfree(fwctx);
	return;

fail:
	brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
	release_firmware(fwctx->code);
	device_release_driver(fwctx->dev);
	fwctx->done(fwctx->dev, -ENOENT, NULL, NULL, 0);
	kfree(fwctx);
}

static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx)
{
	struct brcmf_fw *fwctx = ctx;
	int ret;
	int ret = 0;

	brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
	if (!fw)
	if (!fw) {
		ret = -ENOENT;
		goto fail;

	/* only requested code so done here */
	if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) {
		fwctx->done(fwctx->dev, fw, NULL, 0);
		kfree(fwctx);
		return;
	}
	/* only requested code so done here */
	if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM))
		goto done;

	fwctx->code = fw;
	ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name,
				      fwctx->dev, GFP_KERNEL, fwctx,
				      brcmf_fw_request_nvram_done);

	if (!ret)
		return;

	/* pass NULL to nvram callback for bcm47xx fallback */
	if (ret)
		brcmf_fw_request_nvram_done(NULL, fwctx);
	return;

fail:
	brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
	device_release_driver(fwctx->dev);
done:
	fwctx->done(fwctx->dev, ret, fw, NULL, 0);
	kfree(fwctx);
}

int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
				const char *code, const char *nvram,
				void (*fw_cb)(struct device *dev,
				void (*fw_cb)(struct device *dev, int err,
					      const struct firmware *fw,
					      void *nvram_image, u32 nvram_len),
				u16 domain_nr, u16 bus_nr)
@@ -555,7 +554,7 @@ int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,

int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
			   const char *code, const char *nvram,
			   void (*fw_cb)(struct device *dev,
			   void (*fw_cb)(struct device *dev, int err,
					 const struct firmware *fw,
					 void *nvram_image, u32 nvram_len))
{
+2 −2
Original line number Diff line number Diff line
@@ -73,13 +73,13 @@ void brcmf_fw_nvram_free(void *nvram);
 */
int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
				const char *code, const char *nvram,
				void (*fw_cb)(struct device *dev,
				void (*fw_cb)(struct device *dev, int err,
					      const struct firmware *fw,
					      void *nvram_image, u32 nvram_len),
				u16 domain_nr, u16 bus_nr);
int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
			   const char *code, const char *nvram,
			   void (*fw_cb)(struct device *dev,
			   void (*fw_cb)(struct device *dev, int err,
					 const struct firmware *fw,
					 void *nvram_image, u32 nvram_len));

+1 −1
Original line number Diff line number Diff line
@@ -2145,7 +2145,7 @@ void brcmf_fws_add_interface(struct brcmf_if *ifp)
	struct brcmf_fws_info *fws = drvr_to_fws(ifp->drvr);
	struct brcmf_fws_mac_descriptor *entry;

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

	entry = &fws->desc.iface[ifp->ifidx];
+12 −5
Original line number Diff line number Diff line
@@ -1650,16 +1650,23 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
	.write32 = brcmf_pcie_buscore_write32,
};

static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw,
static void brcmf_pcie_setup(struct device *dev, int ret,
			     const struct firmware *fw,
			     void *nvram, u32 nvram_len)
{
	struct brcmf_bus *bus = dev_get_drvdata(dev);
	struct brcmf_pciedev *pcie_bus_dev = bus->bus_priv.pcie;
	struct brcmf_pciedev_info *devinfo = pcie_bus_dev->devinfo;
	struct brcmf_bus *bus;
	struct brcmf_pciedev *pcie_bus_dev;
	struct brcmf_pciedev_info *devinfo;
	struct brcmf_commonring **flowrings;
	int ret;
	u32 i;

	/* check firmware loading result */
	if (ret)
		goto fail;

	bus = dev_get_drvdata(dev);
	pcie_bus_dev = bus->bus_priv.pcie;
	devinfo = pcie_bus_dev->devinfo;
	brcmf_pcie_attach(devinfo);

	/* Some of the firmwares have the size of the memory of the device
+12 −6
Original line number Diff line number Diff line
@@ -3982,21 +3982,26 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
	.get_memdump = brcmf_sdio_bus_get_memdump,
};

static void brcmf_sdio_firmware_callback(struct device *dev,
static void brcmf_sdio_firmware_callback(struct device *dev, int err,
					 const struct firmware *code,
					 void *nvram, u32 nvram_len)
{
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
	struct brcmf_sdio *bus = sdiodev->bus;
	int err = 0;
	struct brcmf_bus *bus_if;
	struct brcmf_sdio_dev *sdiodev;
	struct brcmf_sdio *bus;
	u8 saveclk;

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

	if (!bus_if->drvr)
		return;

	bus = sdiodev->bus;

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

struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
Loading