aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/brcm80211/brcmfmac
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c28
2 files changed, 24 insertions, 9 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index a0afef26ac1..59c25463e42 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -899,7 +899,10 @@ int brcmf_bus_start(struct device *dev)
goto fail;
drvr->fw_signals = true;
- (void)brcmf_fws_init(drvr);
+ ret = brcmf_fws_init(drvr);
+ if (ret < 0)
+ goto fail;
+
brcmf_fws_add_interface(ifp);
drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index b0591e3da49..f9153b115dc 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1897,16 +1897,20 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS |
BRCMF_FWS_FLAGS_HOST_PROPTXSTATUS_ACTIVE;
- rc = brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv);
+ rc = brcmf_fweh_register(drvr, BRCMF_E_FIFO_CREDIT_MAP,
+ brcmf_fws_notify_credit_map);
if (rc < 0) {
- brcmf_err("failed to set bdcv2 tlv signaling\n");
+ brcmf_err("register credit map handler failed\n");
goto fail;
}
- if (brcmf_fweh_register(drvr, BRCMF_E_FIFO_CREDIT_MAP,
- brcmf_fws_notify_credit_map)) {
- brcmf_err("register credit map handler failed\n");
- goto fail;
+ /* setting the iovar may fail if feature is unsupported
+ * so leave the rc as is so driver initialization can
+ * continue.
+ */
+ if (brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv)) {
+ brcmf_err("failed to set bdcv2 tlv signaling\n");
+ goto fail_event;
}
brcmf_fws_hanger_init(&drvr->fws->hanger);
@@ -1922,9 +1926,9 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
drvr->fw_signals ? "enabled" : "disabled", tlv);
return 0;
+fail_event:
+ brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP);
fail:
- /* disable flow control entirely */
- drvr->fw_signals = false;
brcmf_fws_deinit(drvr);
return rc;
}
@@ -1937,6 +1941,14 @@ void brcmf_fws_deinit(struct brcmf_pub *drvr)
if (!fws)
return;
+ /* disable firmware signalling entirely
+ * to avoid using the workqueue.
+ */
+ drvr->fw_signals = false;
+
+ if (drvr->fws->fws_wq)
+ destroy_workqueue(drvr->fws->fws_wq);
+
/* cleanup */
brcmf_fws_lock(drvr, flags);
brcmf_fws_cleanup(fws, -1);