From 8231f67218e584be61d32b24bd17cc55e500638c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 21 Jul 2019 23:09:53 +0200 Subject: [PATCH] mac80211: brcmfmac: backport fixes from kernel 5.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- ...cmfmac-use-strlcpy-instead-of-strcpy.patch | 26 +++ ...ac-add-160MHz-in-chandef_to_chanspec.patch | 55 ++++++ ...fix-NULL-pointer-derefence-during-US.patch | 167 ++++++++++++++++++ ...-the-order-of-things-in-brcmf_detach.patch | 66 +++++++ ...irmware-command-in-brcmf_netdev_open.patch | 29 +++ ...vents-in-brcmf_fweh_detach-will-alwa.patch | 37 ++++ ...d-firmware-commands-when-bus-is-down.patch | 78 ++++++++ ...imply-remove-flowring-if-bus-is-down.patch | 32 ++++ ...unnecessary-strlcpy-upon-obtaining-v.patch | 27 +++ ...und-bug-with-some-inconsistent-BSSes.patch | 2 +- ...62-brcmfmac-Disable-power-management.patch | 2 +- 11 files changed, 519 insertions(+), 2 deletions(-) create mode 100644 package/kernel/mac80211/patches/467-v5.4-brcmfmac-use-strlcpy-instead-of-strcpy.patch create mode 100644 package/kernel/mac80211/patches/468-v5.4-0001-brcmfmac-add-160MHz-in-chandef_to_chanspec.patch create mode 100644 package/kernel/mac80211/patches/469-v5.4-0001-Revert-brcmfmac-fix-NULL-pointer-derefence-during-US.patch create mode 100644 package/kernel/mac80211/patches/469-v5.4-0002-brcmfmac-change-the-order-of-things-in-brcmf_detach.patch create mode 100644 package/kernel/mac80211/patches/469-v5.4-0003-brcmfmac-avoid-firmware-command-in-brcmf_netdev_open.patch create mode 100644 package/kernel/mac80211/patches/469-v5.4-0004-brcmfmac-clear-events-in-brcmf_fweh_detach-will-alwa.patch create mode 100644 package/kernel/mac80211/patches/469-v5.4-0005-brcmfmac-avoid-firmware-commands-when-bus-is-down.patch create mode 100644 package/kernel/mac80211/patches/469-v5.4-0006-brcmfmac-simply-remove-flowring-if-bus-is-down.patch create mode 100644 package/kernel/mac80211/patches/469-v5.4-0007-brcmfmac-remove-unnecessary-strlcpy-upon-obtaining-v.patch diff --git a/package/kernel/mac80211/patches/467-v5.4-brcmfmac-use-strlcpy-instead-of-strcpy.patch b/package/kernel/mac80211/patches/467-v5.4-brcmfmac-use-strlcpy-instead-of-strcpy.patch new file mode 100644 index 0000000000..8731a99fd7 --- /dev/null +++ b/package/kernel/mac80211/patches/467-v5.4-brcmfmac-use-strlcpy-instead-of-strcpy.patch @@ -0,0 +1,26 @@ +From bbfab331e3abd9fa8767eea6bf5c4684cdd4b934 Mon Sep 17 00:00:00 2001 +From: Neo Jou +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 +Signed-off-by: Kalle Valo +--- + 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", diff --git a/package/kernel/mac80211/patches/468-v5.4-0001-brcmfmac-add-160MHz-in-chandef_to_chanspec.patch b/package/kernel/mac80211/patches/468-v5.4-0001-brcmfmac-add-160MHz-in-chandef_to_chanspec.patch new file mode 100644 index 0000000000..a3a3006c90 --- /dev/null +++ b/package/kernel/mac80211/patches/468-v5.4-0001-brcmfmac-add-160MHz-in-chandef_to_chanspec.patch @@ -0,0 +1,55 @@ +From 46f24cd5980de4302982d38ebb6620560ead10b3 Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +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 +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +--- + .../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; + } + diff --git a/package/kernel/mac80211/patches/469-v5.4-0001-Revert-brcmfmac-fix-NULL-pointer-derefence-during-US.patch b/package/kernel/mac80211/patches/469-v5.4-0001-Revert-brcmfmac-fix-NULL-pointer-derefence-during-US.patch new file mode 100644 index 0000000000..70b5a6d377 --- /dev/null +++ b/package/kernel/mac80211/patches/469-v5.4-0001-Revert-brcmfmac-fix-NULL-pointer-derefence-during-US.patch @@ -0,0 +1,167 @@ +From 7acf04a0ae2adf5d3e9de9adeec3129e74bf6ef2 Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +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 +--- + .../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, diff --git a/package/kernel/mac80211/patches/469-v5.4-0002-brcmfmac-change-the-order-of-things-in-brcmf_detach.patch b/package/kernel/mac80211/patches/469-v5.4-0002-brcmfmac-change-the-order-of-things-in-brcmf_detach.patch new file mode 100644 index 0000000000..2affe12f45 --- /dev/null +++ b/package/kernel/mac80211/patches/469-v5.4-0002-brcmfmac-change-the-order-of-things-in-brcmf_detach.patch @@ -0,0 +1,66 @@ +From 701fb69f2c36cba83583990e67a3925f920fd96a Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +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 +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Tested-by: Rafał Miłecki +--- + .../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); + } + diff --git a/package/kernel/mac80211/patches/469-v5.4-0003-brcmfmac-avoid-firmware-command-in-brcmf_netdev_open.patch b/package/kernel/mac80211/patches/469-v5.4-0003-brcmfmac-avoid-firmware-command-in-brcmf_netdev_open.patch new file mode 100644 index 0000000000..567abe0d21 --- /dev/null +++ b/package/kernel/mac80211/patches/469-v5.4-0003-brcmfmac-avoid-firmware-command-in-brcmf_netdev_open.patch @@ -0,0 +1,29 @@ +From 1be747d977014fea13dbac0de885c0c358eb393c Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +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 +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +--- + 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); + diff --git a/package/kernel/mac80211/patches/469-v5.4-0004-brcmfmac-clear-events-in-brcmf_fweh_detach-will-alwa.patch b/package/kernel/mac80211/patches/469-v5.4-0004-brcmfmac-clear-events-in-brcmf_fweh_detach-will-alwa.patch new file mode 100644 index 0000000000..8483249db6 --- /dev/null +++ b/package/kernel/mac80211/patches/469-v5.4-0004-brcmfmac-clear-events-in-brcmf_fweh_detach-will-alwa.patch @@ -0,0 +1,37 @@ +From 0d91defd7bfc42c0ed053ba03b5ea2eff2e1d2f5 Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +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 +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +--- + 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)); diff --git a/package/kernel/mac80211/patches/469-v5.4-0005-brcmfmac-avoid-firmware-commands-when-bus-is-down.patch b/package/kernel/mac80211/patches/469-v5.4-0005-brcmfmac-avoid-firmware-commands-when-bus-is-down.patch new file mode 100644 index 0000000000..4cfc0d008e --- /dev/null +++ b/package/kernel/mac80211/patches/469-v5.4-0005-brcmfmac-avoid-firmware-commands-when-bus-is-down.patch @@ -0,0 +1,78 @@ +From 66ab63fbb33bf367807e3e471231379dce6f8b8c Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +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 +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +--- + .../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; diff --git a/package/kernel/mac80211/patches/469-v5.4-0006-brcmfmac-simply-remove-flowring-if-bus-is-down.patch b/package/kernel/mac80211/patches/469-v5.4-0006-brcmfmac-simply-remove-flowring-if-bus-is-down.patch new file mode 100644 index 0000000000..fd010f2a8f --- /dev/null +++ b/package/kernel/mac80211/patches/469-v5.4-0006-brcmfmac-simply-remove-flowring-if-bus-is-down.patch @@ -0,0 +1,32 @@ +From dabf1e17d33e087d4e24e6d0224cf9bc04ebfcc1 Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +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 +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +--- + 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); diff --git a/package/kernel/mac80211/patches/469-v5.4-0007-brcmfmac-remove-unnecessary-strlcpy-upon-obtaining-v.patch b/package/kernel/mac80211/patches/469-v5.4-0007-brcmfmac-remove-unnecessary-strlcpy-upon-obtaining-v.patch new file mode 100644 index 0000000000..a1fcebd512 --- /dev/null +++ b/package/kernel/mac80211/patches/469-v5.4-0007-brcmfmac-remove-unnecessary-strlcpy-upon-obtaining-v.patch @@ -0,0 +1,27 @@ +From 979c9a17fc78f3b8393fd92ca250fe4239872eee Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +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 +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +--- + 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", diff --git a/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch index 45cfb1ddbf..912fe8ca14 100644 --- a/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch +++ b/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch @@ -10,7 +10,7 @@ Signed-off-by: Rafał Miłecki --- a/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_pub *drvr = cfg->pub; struct wireless_dev *wdev; diff --git a/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch b/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch index 5cbc48f76a..578b3e0399 100644 --- a/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch +++ b/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch @@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell --- a/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 * FW later while initializing the dongle */