mac80211: brcmfmac: backport fixes from kernel 5.4
This fixes: 1) Crash during USB disconnect 2) Crash in brcmf_txfinalize() on rmmod with packets queued 3) Some errors in exit path Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
		| @@ -0,0 +1,26 @@ | |||||||
|  | From bbfab331e3abd9fa8767eea6bf5c4684cdd4b934 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Neo Jou <neojou@gmail.com> | ||||||
|  | Date: Tue, 21 May 2019 17:12:20 +0800 | ||||||
|  | Subject: [PATCH] brcmfmac: use strlcpy() instead of strcpy() | ||||||
|  |  | ||||||
|  | The function strcpy() is inherently not safe. Though the function | ||||||
|  | works without problems here, it would be better to use other safer | ||||||
|  | function, e.g. strlcpy(), to replace strcpy() still. | ||||||
|  |  | ||||||
|  | Signed-off-by: Neo Jou <neojou@gmail.com> | ||||||
|  | Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||||
|  | --- | ||||||
|  |  drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||||
|  | @@ -269,7 +269,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i | ||||||
|  |   | ||||||
|  |  	/* query for 'ver' to get version info from firmware */ | ||||||
|  |  	memset(buf, 0, sizeof(buf)); | ||||||
|  | -	strcpy(buf, "ver"); | ||||||
|  | +	strlcpy(buf, "ver", sizeof(buf)); | ||||||
|  |  	err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf)); | ||||||
|  |  	if (err < 0) { | ||||||
|  |  		bphy_err(drvr, "Retrieving version information failed, %d\n", | ||||||
| @@ -0,0 +1,55 @@ | |||||||
|  | From 46f24cd5980de4302982d38ebb6620560ead10b3 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | Date: Thu, 11 Jul 2019 10:45:30 +0200 | ||||||
|  | Subject: [PATCH 1/3] brcmfmac: add 160MHz in chandef_to_chanspec() | ||||||
|  |  | ||||||
|  | The function chandef_to_chanspec() was not handling 160MHz bandwidth | ||||||
|  | resulting in wrong encoding of the channel. That resulting in firmware | ||||||
|  | rejecting the provided channel specification. | ||||||
|  |  | ||||||
|  | Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> | ||||||
|  | Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||||
|  | Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||||||
|  | Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | --- | ||||||
|  |  .../broadcom/brcm80211/brcmfmac/cfg80211.c    | 21 ++++++++++++++++++- | ||||||
|  |  1 file changed, 20 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||||
|  | @@ -287,8 +287,26 @@ static u16 chandef_to_chanspec(struct br | ||||||
|  |  		else | ||||||
|  |  			ch_inf.sb = BRCMU_CHAN_SB_UU; | ||||||
|  |  		break; | ||||||
|  | -	case NL80211_CHAN_WIDTH_80P80: | ||||||
|  |  	case NL80211_CHAN_WIDTH_160: | ||||||
|  | +		ch_inf.bw = BRCMU_CHAN_BW_160; | ||||||
|  | +		if (primary_offset == -70) | ||||||
|  | +			ch_inf.sb = BRCMU_CHAN_SB_LLL; | ||||||
|  | +		else if (primary_offset == -50) | ||||||
|  | +			ch_inf.sb = BRCMU_CHAN_SB_LLU; | ||||||
|  | +		else if (primary_offset == -30) | ||||||
|  | +			ch_inf.sb = BRCMU_CHAN_SB_LUL; | ||||||
|  | +		else if (primary_offset == -10) | ||||||
|  | +			ch_inf.sb = BRCMU_CHAN_SB_LUU; | ||||||
|  | +		else if (primary_offset == 10) | ||||||
|  | +			ch_inf.sb = BRCMU_CHAN_SB_ULL; | ||||||
|  | +		else if (primary_offset == 30) | ||||||
|  | +			ch_inf.sb = BRCMU_CHAN_SB_ULU; | ||||||
|  | +		else if (primary_offset == 50) | ||||||
|  | +			ch_inf.sb = BRCMU_CHAN_SB_UUL; | ||||||
|  | +		else | ||||||
|  | +			ch_inf.sb = BRCMU_CHAN_SB_UUU; | ||||||
|  | +		break; | ||||||
|  | +	case NL80211_CHAN_WIDTH_80P80: | ||||||
|  |  	case NL80211_CHAN_WIDTH_5: | ||||||
|  |  	case NL80211_CHAN_WIDTH_10: | ||||||
|  |  	default: | ||||||
|  | @@ -307,6 +325,7 @@ static u16 chandef_to_chanspec(struct br | ||||||
|  |  	} | ||||||
|  |  	d11inf->encchspec(&ch_inf); | ||||||
|  |   | ||||||
|  | +	brcmf_dbg(TRACE, "chanspec: 0x%x\n", ch_inf.chspec); | ||||||
|  |  	return ch_inf.chspec; | ||||||
|  |  } | ||||||
|  |   | ||||||
| @@ -0,0 +1,167 @@ | |||||||
|  | From 7acf04a0ae2adf5d3e9de9adeec3129e74bf6ef2 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | Date: Thu, 11 Jul 2019 11:05:06 +0200 | ||||||
|  | Subject: [PATCH 1/7] Revert "brcmfmac: fix NULL pointer derefence during USB | ||||||
|  |  disconnect" | ||||||
|  |  | ||||||
|  | This reverts commit 5cdb0ef6144f47440850553579aa923c20a63f23. Subsequent | ||||||
|  | changes make rework the driver code fixing the issue differently. | ||||||
|  |  | ||||||
|  | Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | --- | ||||||
|  |  .../wireless/broadcom/brcm80211/brcmfmac/bcdc.c  | 11 ++--------- | ||||||
|  |  .../wireless/broadcom/brcm80211/brcmfmac/bcdc.h  |  6 ++---- | ||||||
|  |  .../wireless/broadcom/brcm80211/brcmfmac/core.c  |  4 +--- | ||||||
|  |  .../broadcom/brcm80211/brcmfmac/fwsignal.c       | 16 ++++------------ | ||||||
|  |  .../broadcom/brcm80211/brcmfmac/fwsignal.h       |  3 +-- | ||||||
|  |  .../wireless/broadcom/brcm80211/brcmfmac/proto.c | 10 ++-------- | ||||||
|  |  .../wireless/broadcom/brcm80211/brcmfmac/proto.h |  3 +-- | ||||||
|  |  7 files changed, 13 insertions(+), 40 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | ||||||
|  | @@ -490,18 +490,11 @@ fail: | ||||||
|  |  	return -ENOMEM; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr) | ||||||
|  | -{ | ||||||
|  | -	struct brcmf_bcdc *bcdc = drvr->proto->pd; | ||||||
|  | - | ||||||
|  | -	brcmf_fws_detach_pre_delif(bcdc->fws); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr) | ||||||
|  | +void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) | ||||||
|  |  { | ||||||
|  |  	struct brcmf_bcdc *bcdc = drvr->proto->pd; | ||||||
|  |   | ||||||
|  |  	drvr->proto->pd = NULL; | ||||||
|  | -	brcmf_fws_detach_post_delif(bcdc->fws); | ||||||
|  | +	brcmf_fws_detach(bcdc->fws); | ||||||
|  |  	kfree(bcdc); | ||||||
|  |  } | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h | ||||||
|  | @@ -18,16 +18,14 @@ | ||||||
|  |   | ||||||
|  |  #ifdef CPTCFG_BRCMFMAC_PROTO_BCDC | ||||||
|  |  int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr); | ||||||
|  | -void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr); | ||||||
|  | -void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr); | ||||||
|  | +void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr); | ||||||
|  |  void brcmf_proto_bcdc_txflowblock(struct device *dev, bool state); | ||||||
|  |  void brcmf_proto_bcdc_txcomplete(struct device *dev, struct sk_buff *txp, | ||||||
|  |  				 bool success); | ||||||
|  |  struct brcmf_fws_info *drvr_to_fws(struct brcmf_pub *drvr); | ||||||
|  |  #else | ||||||
|  |  static inline int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { return 0; } | ||||||
|  | -static void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr) {}; | ||||||
|  | -static inline void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr) {} | ||||||
|  | +static inline void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) {} | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  |  #endif /* BRCMFMAC_BCDC_H */ | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||||
|  | @@ -1344,8 +1344,6 @@ void brcmf_detach(struct device *dev) | ||||||
|  |   | ||||||
|  |  	brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); | ||||||
|  |   | ||||||
|  | -	brcmf_proto_detach_pre_delif(drvr); | ||||||
|  | - | ||||||
|  |  	/* make sure primary interface removed last */ | ||||||
|  |  	for (i = BRCMF_MAX_IFS-1; i > -1; i--) | ||||||
|  |  		brcmf_remove_interface(drvr->iflist[i], false); | ||||||
|  | @@ -1355,7 +1353,7 @@ void brcmf_detach(struct device *dev) | ||||||
|  |   | ||||||
|  |  	brcmf_bus_stop(drvr->bus_if); | ||||||
|  |   | ||||||
|  | -	brcmf_proto_detach_post_delif(drvr); | ||||||
|  | +	brcmf_proto_detach(drvr); | ||||||
|  |   | ||||||
|  |  	bus_if->drvr = NULL; | ||||||
|  |  	wiphy_free(drvr->wiphy); | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | ||||||
|  | @@ -2416,25 +2416,17 @@ struct brcmf_fws_info *brcmf_fws_attach( | ||||||
|  |  	return fws; | ||||||
|  |   | ||||||
|  |  fail: | ||||||
|  | -	brcmf_fws_detach_pre_delif(fws); | ||||||
|  | -	brcmf_fws_detach_post_delif(fws); | ||||||
|  | +	brcmf_fws_detach(fws); | ||||||
|  |  	return ERR_PTR(rc); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -void brcmf_fws_detach_pre_delif(struct brcmf_fws_info *fws) | ||||||
|  | +void brcmf_fws_detach(struct brcmf_fws_info *fws) | ||||||
|  |  { | ||||||
|  |  	if (!fws) | ||||||
|  |  		return; | ||||||
|  | -	if (fws->fws_wq) { | ||||||
|  | -		destroy_workqueue(fws->fws_wq); | ||||||
|  | -		fws->fws_wq = NULL; | ||||||
|  | -	} | ||||||
|  | -} | ||||||
|  |   | ||||||
|  | -void brcmf_fws_detach_post_delif(struct brcmf_fws_info *fws) | ||||||
|  | -{ | ||||||
|  | -	if (!fws) | ||||||
|  | -		return; | ||||||
|  | +	if (fws->fws_wq) | ||||||
|  | +		destroy_workqueue(fws->fws_wq); | ||||||
|  |   | ||||||
|  |  	/* cleanup */ | ||||||
|  |  	brcmf_fws_lock(fws); | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h | ||||||
|  | @@ -19,8 +19,7 @@ | ||||||
|  |  #define FWSIGNAL_H_ | ||||||
|  |   | ||||||
|  |  struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr); | ||||||
|  | -void brcmf_fws_detach_pre_delif(struct brcmf_fws_info *fws); | ||||||
|  | -void brcmf_fws_detach_post_delif(struct brcmf_fws_info *fws); | ||||||
|  | +void brcmf_fws_detach(struct brcmf_fws_info *fws); | ||||||
|  |  void brcmf_fws_debugfs_create(struct brcmf_pub *drvr); | ||||||
|  |  bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws); | ||||||
|  |  bool brcmf_fws_fc_active(struct brcmf_fws_info *fws); | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c | ||||||
|  | @@ -67,22 +67,16 @@ fail: | ||||||
|  |  	return -ENOMEM; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -void brcmf_proto_detach_post_delif(struct brcmf_pub *drvr) | ||||||
|  | +void brcmf_proto_detach(struct brcmf_pub *drvr) | ||||||
|  |  { | ||||||
|  |  	brcmf_dbg(TRACE, "Enter\n"); | ||||||
|  |   | ||||||
|  |  	if (drvr->proto) { | ||||||
|  |  		if (drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) | ||||||
|  | -			brcmf_proto_bcdc_detach_post_delif(drvr); | ||||||
|  | +			brcmf_proto_bcdc_detach(drvr); | ||||||
|  |  		else if (drvr->bus_if->proto_type == BRCMF_PROTO_MSGBUF) | ||||||
|  |  			brcmf_proto_msgbuf_detach(drvr); | ||||||
|  |  		kfree(drvr->proto); | ||||||
|  |  		drvr->proto = NULL; | ||||||
|  |  	} | ||||||
|  |  } | ||||||
|  | - | ||||||
|  | -void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr) | ||||||
|  | -{ | ||||||
|  | -	if (drvr->proto && drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) | ||||||
|  | -		brcmf_proto_bcdc_detach_pre_delif(drvr); | ||||||
|  | -} | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h | ||||||
|  | @@ -54,8 +54,7 @@ struct brcmf_proto { | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  int brcmf_proto_attach(struct brcmf_pub *drvr); | ||||||
|  | -void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr); | ||||||
|  | -void brcmf_proto_detach_post_delif(struct brcmf_pub *drvr); | ||||||
|  | +void brcmf_proto_detach(struct brcmf_pub *drvr); | ||||||
|  |   | ||||||
|  |  static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, | ||||||
|  |  				      struct sk_buff *skb, | ||||||
| @@ -0,0 +1,66 @@ | |||||||
|  | From 701fb69f2c36cba83583990e67a3925f920fd96a Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | Date: Thu, 11 Jul 2019 11:05:07 +0200 | ||||||
|  | Subject: [PATCH 2/7] brcmfmac: change the order of things in brcmf_detach() | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Type: text/plain; charset=UTF-8 | ||||||
|  | Content-Transfer-Encoding: 8bit | ||||||
|  |  | ||||||
|  | When brcmf_detach() from the bus layer upon rmmod we can no longer | ||||||
|  | communicate. Hence we will set the bus state to DOWN and cleanup | ||||||
|  | the event and protocol layer. The network interfaces need to be | ||||||
|  | deleted before brcmf_cfg80211_detach() because the latter does the | ||||||
|  | wiphy_unregister() which issues a warning if there are still network | ||||||
|  | devices linked to the wiphy instance. | ||||||
|  |  | ||||||
|  | Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> | ||||||
|  | Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||||
|  | Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||||||
|  | Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | Tested-by: Rafał Miłecki <rafal@milecki.pl> | ||||||
|  | --- | ||||||
|  |  .../broadcom/brcm80211/brcmfmac/core.c        | 27 ++++++++++--------- | ||||||
|  |  1 file changed, 14 insertions(+), 13 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||||
|  | @@ -1337,25 +1337,26 @@ void brcmf_detach(struct device *dev) | ||||||
|  |  	unregister_inet6addr_notifier(&drvr->inet6addr_notifier); | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | -	/* stop firmware event handling */ | ||||||
|  | -	brcmf_fweh_detach(drvr); | ||||||
|  | -	if (drvr->config) | ||||||
|  | -		brcmf_p2p_detach(&drvr->config->p2p); | ||||||
|  | - | ||||||
|  |  	brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); | ||||||
|  | - | ||||||
|  | -	/* make sure primary interface removed last */ | ||||||
|  | -	for (i = BRCMF_MAX_IFS-1; i > -1; i--) | ||||||
|  | -		brcmf_remove_interface(drvr->iflist[i], false); | ||||||
|  | - | ||||||
|  | -	brcmf_cfg80211_detach(drvr->config); | ||||||
|  | -	drvr->config = NULL; | ||||||
|  | - | ||||||
|  |  	brcmf_bus_stop(drvr->bus_if); | ||||||
|  |   | ||||||
|  | +	brcmf_fweh_detach(drvr); | ||||||
|  |  	brcmf_proto_detach(drvr); | ||||||
|  |   | ||||||
|  | +	/* make sure primary interface removed last */ | ||||||
|  | +	for (i = BRCMF_MAX_IFS - 1; i > -1; i--) { | ||||||
|  | +		if (drvr->iflist[i]) | ||||||
|  | +			brcmf_del_if(drvr, drvr->iflist[i]->bsscfgidx, false); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (drvr->config) { | ||||||
|  | +		brcmf_p2p_detach(&drvr->config->p2p); | ||||||
|  | +		brcmf_cfg80211_detach(drvr->config); | ||||||
|  | +		drvr->config = NULL; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	bus_if->drvr = NULL; | ||||||
|  | + | ||||||
|  |  	wiphy_free(drvr->wiphy); | ||||||
|  |  } | ||||||
|  |   | ||||||
| @@ -0,0 +1,29 @@ | |||||||
|  | From 1be747d977014fea13dbac0de885c0c358eb393c Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | Date: Thu, 11 Jul 2019 11:05:08 +0200 | ||||||
|  | Subject: [PATCH 3/7] brcmfmac: avoid firmware command in brcmf_netdev_open() | ||||||
|  |  when bus is down | ||||||
|  |  | ||||||
|  | No point in sending a firmware command when bus is down so make it | ||||||
|  | conditional checking the state. | ||||||
|  |  | ||||||
|  | Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> | ||||||
|  | Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||||
|  | Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||||||
|  | Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | --- | ||||||
|  |  drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 ++- | ||||||
|  |  1 file changed, 2 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||||
|  | @@ -589,7 +589,8 @@ static int brcmf_netdev_stop(struct net_ | ||||||
|  |   | ||||||
|  |  	brcmf_cfg80211_down(ndev); | ||||||
|  |   | ||||||
|  | -	brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", NULL, 0); | ||||||
|  | +	if (ifp->drvr->bus_if->state == BRCMF_BUS_UP) | ||||||
|  | +		brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", NULL, 0); | ||||||
|  |   | ||||||
|  |  	brcmf_net_setcarrier(ifp, false); | ||||||
|  |   | ||||||
| @@ -0,0 +1,37 @@ | |||||||
|  | From 0d91defd7bfc42c0ed053ba03b5ea2eff2e1d2f5 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | Date: Thu, 11 Jul 2019 11:05:09 +0200 | ||||||
|  | Subject: [PATCH 4/7] brcmfmac: clear events in brcmf_fweh_detach() will always | ||||||
|  |  fail | ||||||
|  |  | ||||||
|  | Clearing firmware events in brcmf_fweh_detach() is always failing | ||||||
|  | because it is called only upon driver remove and communication | ||||||
|  | with firmware is no longer possible. | ||||||
|  |  | ||||||
|  | Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> | ||||||
|  | Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||||
|  | Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||||||
|  | Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | --- | ||||||
|  |  drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 9 --------- | ||||||
|  |  1 file changed, 9 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | ||||||
|  | @@ -314,16 +314,7 @@ void brcmf_fweh_attach(struct brcmf_pub | ||||||
|  |  void brcmf_fweh_detach(struct brcmf_pub *drvr) | ||||||
|  |  { | ||||||
|  |  	struct brcmf_fweh_info *fweh = &drvr->fweh; | ||||||
|  | -	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); | ||||||
|  | -	s8 eventmask[BRCMF_EVENTING_MASK_LEN]; | ||||||
|  |   | ||||||
|  | -	if (ifp) { | ||||||
|  | -		/* clear all events */ | ||||||
|  | -		memset(eventmask, 0, BRCMF_EVENTING_MASK_LEN); | ||||||
|  | -		(void)brcmf_fil_iovar_data_set(ifp, "event_msgs", | ||||||
|  | -					       eventmask, | ||||||
|  | -					       BRCMF_EVENTING_MASK_LEN); | ||||||
|  | -	} | ||||||
|  |  	/* cancel the worker */ | ||||||
|  |  	cancel_work_sync(&fweh->event_work); | ||||||
|  |  	WARN_ON(!list_empty(&fweh->event_q)); | ||||||
| @@ -0,0 +1,78 @@ | |||||||
|  | From 66ab63fbb33bf367807e3e471231379dce6f8b8c Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | Date: Thu, 11 Jul 2019 11:05:10 +0200 | ||||||
|  | Subject: [PATCH 5/7] brcmfmac: avoid firmware commands when bus is down | ||||||
|  |  | ||||||
|  | Upon rmmod a few attempts are made to inform firmware, but there is | ||||||
|  | no point as the bus is down and these will fail. Avoid them to keep | ||||||
|  | the logs clean. | ||||||
|  |  | ||||||
|  | Reported-by: Stefan Wahren <stefan.wahren@i2se.com> | ||||||
|  | Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> | ||||||
|  | Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||||
|  | Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||||||
|  | Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | --- | ||||||
|  |  .../broadcom/brcm80211/brcmfmac/cfg80211.c    | 23 +++++++++++-------- | ||||||
|  |  1 file changed, 13 insertions(+), 10 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||||
|  | @@ -1297,17 +1297,21 @@ static void brcmf_link_down(struct brcmf | ||||||
|  |  { | ||||||
|  |  	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy); | ||||||
|  |  	struct brcmf_pub *drvr = cfg->pub; | ||||||
|  | +	bool bus_up = drvr->bus_if->state == BRCMF_BUS_UP; | ||||||
|  |  	s32 err = 0; | ||||||
|  |   | ||||||
|  |  	brcmf_dbg(TRACE, "Enter\n"); | ||||||
|  |   | ||||||
|  |  	if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) { | ||||||
|  | -		brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n "); | ||||||
|  | -		err = brcmf_fil_cmd_data_set(vif->ifp, | ||||||
|  | -					     BRCMF_C_DISASSOC, NULL, 0); | ||||||
|  | -		if (err) { | ||||||
|  | -			bphy_err(drvr, "WLC_DISASSOC failed (%d)\n", err); | ||||||
|  | +		if (bus_up) { | ||||||
|  | +			brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n"); | ||||||
|  | +			err = brcmf_fil_cmd_data_set(vif->ifp, | ||||||
|  | +						     BRCMF_C_DISASSOC, NULL, 0); | ||||||
|  | +			if (err) | ||||||
|  | +				bphy_err(drvr, "WLC_DISASSOC failed (%d)\n", | ||||||
|  | +					 err); | ||||||
|  |  		} | ||||||
|  | + | ||||||
|  |  		if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) || | ||||||
|  |  		    (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) | ||||||
|  |  			cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0, | ||||||
|  | @@ -1317,7 +1321,8 @@ static void brcmf_link_down(struct brcmf | ||||||
|  |  	clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); | ||||||
|  |  	brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0); | ||||||
|  |  	if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_NONE) { | ||||||
|  | -		brcmf_set_pmk(vif->ifp, NULL, 0); | ||||||
|  | +		if (bus_up) | ||||||
|  | +			brcmf_set_pmk(vif->ifp, NULL, 0); | ||||||
|  |  		vif->profile.use_fwsup = BRCMF_PROFILE_FWSUP_NONE; | ||||||
|  |  	} | ||||||
|  |  	brcmf_dbg(TRACE, "Exit\n"); | ||||||
|  | @@ -5006,18 +5011,16 @@ static int brcmf_cfg80211_get_channel(st | ||||||
|  |  	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | ||||||
|  |  	struct net_device *ndev = wdev->netdev; | ||||||
|  |  	struct brcmf_pub *drvr = cfg->pub; | ||||||
|  | -	struct brcmf_if *ifp; | ||||||
|  |  	struct brcmu_chan ch; | ||||||
|  |  	enum nl80211_band band = 0; | ||||||
|  |  	enum nl80211_chan_width width = 0; | ||||||
|  |  	u32 chanspec; | ||||||
|  |  	int freq, err; | ||||||
|  |   | ||||||
|  | -	if (!ndev) | ||||||
|  | +	if (!ndev || drvr->bus_if->state != BRCMF_BUS_UP) | ||||||
|  |  		return -ENODEV; | ||||||
|  | -	ifp = netdev_priv(ndev); | ||||||
|  |   | ||||||
|  | -	err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec); | ||||||
|  | +	err = brcmf_fil_iovar_int_get(netdev_priv(ndev), "chanspec", &chanspec); | ||||||
|  |  	if (err) { | ||||||
|  |  		bphy_err(drvr, "chanspec failed (%d)\n", err); | ||||||
|  |  		return err; | ||||||
| @@ -0,0 +1,32 @@ | |||||||
|  | From dabf1e17d33e087d4e24e6d0224cf9bc04ebfcc1 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | Date: Thu, 11 Jul 2019 11:05:11 +0200 | ||||||
|  | Subject: [PATCH 6/7] brcmfmac: simply remove flowring if bus is down | ||||||
|  |  | ||||||
|  | When the bus is down, eg. due to rmmod, there is no need to | ||||||
|  | attempt to inform firmware about it. | ||||||
|  |  | ||||||
|  | Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> | ||||||
|  | Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||||
|  | Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||||||
|  | Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | --- | ||||||
|  |  drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 7 +++++++ | ||||||
|  |  1 file changed, 7 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||||
|  | @@ -1408,6 +1408,13 @@ void brcmf_msgbuf_delete_flowring(struct | ||||||
|  |  	u8 ifidx; | ||||||
|  |  	int err; | ||||||
|  |   | ||||||
|  | +	/* no need to submit if firmware can not be reached */ | ||||||
|  | +	if (drvr->bus_if->state != BRCMF_BUS_UP) { | ||||||
|  | +		brcmf_dbg(MSGBUF, "bus down, flowring will be removed\n"); | ||||||
|  | +		brcmf_msgbuf_remove_flowring(msgbuf, flowid); | ||||||
|  | +		return; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT]; | ||||||
|  |  	brcmf_commonring_lock(commonring); | ||||||
|  |  	ret_ptr = brcmf_commonring_reserve_for_write(commonring); | ||||||
| @@ -0,0 +1,27 @@ | |||||||
|  | From 979c9a17fc78f3b8393fd92ca250fe4239872eee Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | Date: Thu, 11 Jul 2019 11:05:12 +0200 | ||||||
|  | Subject: [PATCH 7/7] brcmfmac: remove unnecessary strlcpy() upon obtaining | ||||||
|  |  "ver" iovar | ||||||
|  |  | ||||||
|  | Recently a strcpy() was replaced by strlcpy(). However, the strcpy() | ||||||
|  | was not needed in the first place. So removing that line of code. | ||||||
|  |  | ||||||
|  | Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> | ||||||
|  | Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||||
|  | Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||||||
|  | Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||||
|  | --- | ||||||
|  |  drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 1 - | ||||||
|  |  1 file changed, 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||||
|  | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||||
|  | @@ -269,7 +269,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_i | ||||||
|  |   | ||||||
|  |  	/* query for 'ver' to get version info from firmware */ | ||||||
|  |  	memset(buf, 0, sizeof(buf)); | ||||||
|  | -	strlcpy(buf, "ver", sizeof(buf)); | ||||||
|  |  	err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf)); | ||||||
|  |  	if (err < 0) { | ||||||
|  |  		bphy_err(drvr, "Retrieving version information failed, %d\n", | ||||||
| @@ -10,7 +10,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | |||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||||
| @@ -620,8 +620,36 @@ static struct wireless_dev *brcmf_cfg802 | @@ -639,8 +639,36 @@ static struct wireless_dev *brcmf_cfg802 | ||||||
|  	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |  	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | ||||||
|  	struct brcmf_pub *drvr = cfg->pub; |  	struct brcmf_pub *drvr = cfg->pub; | ||||||
|  	struct wireless_dev *wdev; |  	struct wireless_dev *wdev; | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org> | |||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||||
| @@ -2774,6 +2774,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip | @@ -2798,6 +2798,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip | ||||||
|  	 * preference in cfg struct to apply this to |  	 * preference in cfg struct to apply this to | ||||||
|  	 * FW later while initializing the dongle |  	 * FW later while initializing the dongle | ||||||
|  	 */ |  	 */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Rafał Miłecki
					Rafał Miłecki