diff options
author | Arend van Spriel <arend@broadcom.com> | 2013-04-23 06:53:14 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-04-23 14:17:03 -0400 |
commit | a786b38d542f62e19ffa8adbcbfc82065cd13a11 (patch) | |
tree | f4861959293722f2bb977a6ce148a42a2370575b | |
parent | 9a83f1ec670fa574ffbfa9fb1f3fdaa9c6be5974 (diff) |
brcmfmac: correct error handling in brcmf_fws_init()
In brcmf_fws_init() the error flows were not properly handled
and the caller ignored the return value. The only action that
is allowed to fail in brcmf_fws_init() is setting the tlv in
firmware as the feature is not supported on all devices.
Cc: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 28 |
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 a0afef26ac13..59c25463e428 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) | |||
899 | goto fail; | 899 | goto fail; |
900 | 900 | ||
901 | drvr->fw_signals = true; | 901 | drvr->fw_signals = true; |
902 | (void)brcmf_fws_init(drvr); | 902 | ret = brcmf_fws_init(drvr); |
903 | if (ret < 0) | ||
904 | goto fail; | ||
905 | |||
903 | brcmf_fws_add_interface(ifp); | 906 | brcmf_fws_add_interface(ifp); |
904 | 907 | ||
905 | drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev); | 908 | 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 b0591e3da49a..f9153b115dcf 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) | |||
1897 | BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS | | 1897 | BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS | |
1898 | BRCMF_FWS_FLAGS_HOST_PROPTXSTATUS_ACTIVE; | 1898 | BRCMF_FWS_FLAGS_HOST_PROPTXSTATUS_ACTIVE; |
1899 | 1899 | ||
1900 | rc = brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv); | 1900 | rc = brcmf_fweh_register(drvr, BRCMF_E_FIFO_CREDIT_MAP, |
1901 | brcmf_fws_notify_credit_map); | ||
1901 | if (rc < 0) { | 1902 | if (rc < 0) { |
1902 | brcmf_err("failed to set bdcv2 tlv signaling\n"); | 1903 | brcmf_err("register credit map handler failed\n"); |
1903 | goto fail; | 1904 | goto fail; |
1904 | } | 1905 | } |
1905 | 1906 | ||
1906 | if (brcmf_fweh_register(drvr, BRCMF_E_FIFO_CREDIT_MAP, | 1907 | /* setting the iovar may fail if feature is unsupported |
1907 | brcmf_fws_notify_credit_map)) { | 1908 | * so leave the rc as is so driver initialization can |
1908 | brcmf_err("register credit map handler failed\n"); | 1909 | * continue. |
1909 | goto fail; | 1910 | */ |
1911 | if (brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv)) { | ||
1912 | brcmf_err("failed to set bdcv2 tlv signaling\n"); | ||
1913 | goto fail_event; | ||
1910 | } | 1914 | } |
1911 | 1915 | ||
1912 | brcmf_fws_hanger_init(&drvr->fws->hanger); | 1916 | brcmf_fws_hanger_init(&drvr->fws->hanger); |
@@ -1922,9 +1926,9 @@ int brcmf_fws_init(struct brcmf_pub *drvr) | |||
1922 | drvr->fw_signals ? "enabled" : "disabled", tlv); | 1926 | drvr->fw_signals ? "enabled" : "disabled", tlv); |
1923 | return 0; | 1927 | return 0; |
1924 | 1928 | ||
1929 | fail_event: | ||
1930 | brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP); | ||
1925 | fail: | 1931 | fail: |
1926 | /* disable flow control entirely */ | ||
1927 | drvr->fw_signals = false; | ||
1928 | brcmf_fws_deinit(drvr); | 1932 | brcmf_fws_deinit(drvr); |
1929 | return rc; | 1933 | return rc; |
1930 | } | 1934 | } |
@@ -1937,6 +1941,14 @@ void brcmf_fws_deinit(struct brcmf_pub *drvr) | |||
1937 | if (!fws) | 1941 | if (!fws) |
1938 | return; | 1942 | return; |
1939 | 1943 | ||
1944 | /* disable firmware signalling entirely | ||
1945 | * to avoid using the workqueue. | ||
1946 | */ | ||
1947 | drvr->fw_signals = false; | ||
1948 | |||
1949 | if (drvr->fws->fws_wq) | ||
1950 | destroy_workqueue(drvr->fws->fws_wq); | ||
1951 | |||
1940 | /* cleanup */ | 1952 | /* cleanup */ |
1941 | brcmf_fws_lock(drvr, flags); | 1953 | brcmf_fws_lock(drvr, flags); |
1942 | brcmf_fws_cleanup(fws, -1); | 1954 | brcmf_fws_cleanup(fws, -1); |