diff options
Diffstat (limited to 'drivers/net/wireless/broadcom')
8 files changed, 52 insertions, 39 deletions
| diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index cd1d6730eab7..617199c0e5a0 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -5225,7 +5225,6 @@ void brcmf_cfg80211_free_netdev(struct net_device *ndev)  	if (vif)  		brcmf_free_vif(vif); -	free_netdev(ndev);  }  static bool brcmf_is_linkup(const struct brcmf_event_msg *e) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index a3d82368f1a9..511d190c6cca 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -624,7 +624,8 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,  		if (!ndev)  			return ERR_PTR(-ENOMEM); -		ndev->destructor = brcmf_cfg80211_free_netdev; +		ndev->needs_free_netdev = true; +		ndev->priv_destructor = brcmf_cfg80211_free_netdev;  		ifp = netdev_priv(ndev);  		ifp->ndev = ndev;  		/* store mapping ifidx to bsscfgidx */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c index c7c1e9906500..d231042f19d6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c @@ -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; - -	brcmf_fw_request_nvram_done(NULL, fwctx); +	/* 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))  { diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h index d3c9f0d52ae3..8fa4b7e1ab3d 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h @@ -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)); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c index 72373e59308e..f59642b2c935 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c @@ -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]; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index f36b96dc6acd..f878706613e6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -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 diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index fc64b8913aa6..5653d6dd38f6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -3422,7 +3422,7 @@ static int brcmf_sdio_bus_preinit(struct device *dev)  		/* otherwise, set txglomalign */  		value = sdiodev->settings->bus.sdio.sd_sgentry_align;  		/* SDIO ADMA requires at least 32 bit alignment */ -		value = max_t(u32, value, 4); +		value = max_t(u32, value, ALIGNMENT);  		err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value,  					   sizeof(u32));  	} @@ -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 @@ release:  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) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index e4d545f9edee..0eea48e73331 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -1159,17 +1159,18 @@ fail:  	return ret;  } -static void brcmf_usb_probe_phase2(struct device *dev, +static void brcmf_usb_probe_phase2(struct device *dev, int ret,  				   const struct firmware *fw,  				   void *nvram, u32 nvlen)  {  	struct brcmf_bus *bus = dev_get_drvdata(dev); -	struct brcmf_usbdev_info *devinfo; -	int ret; +	struct brcmf_usbdev_info *devinfo = bus->bus_priv.usb->devinfo; + +	if (ret) +		goto error;  	brcmf_dbg(USB, "Start fw downloading\n"); -	devinfo = bus->bus_priv.usb->devinfo;  	ret = check_file(fw->data);  	if (ret < 0) {  		brcmf_err("invalid firmware\n"); |