diff options
author | Arend van Spriel | 2013-01-02 15:22:40 +0100 |
---|---|---|
committer | John W. Linville | 2013-01-07 15:16:56 -0500 |
commit | 81d5f1bbc47961b2347d2b92b2aec56e6bad8779 (patch) | |
tree | 21d36ca3a10a49a9df577301d2abb4d86058a27a /drivers/net | |
parent | ac744395ba0a0491f8524a8371ad6f7df67bf673 (diff) |
brcmfmac: assure USB dongle firmware is reset upon module unload
Upon unloading the brcmfmac module the USB firmware should be reset
as the device remains powered. The reset assures a known device
state when a new brcmfmac driver load is being done.
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/usb.c | 13 |
4 files changed, 27 insertions, 1 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index fd672bf53867..7245b171190a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -39,6 +39,7 @@ #define BRCMF_C_GET_BSSID 23 #define BRCMF_C_GET_SSID 25 #define BRCMF_C_SET_SSID 26 +#define BRCMF_C_TERMINATED 28 #define BRCMF_C_GET_CHANNEL 29 #define BRCMF_C_SET_CHANNEL 30 #define BRCMF_C_GET_SRL 31 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index dd38b78a9726..358b54fff795 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -154,7 +154,8 @@ static inline void brcmf_rx_packet(struct device *dev, int ifidx, extern int brcmf_attach(uint bus_hdrlen, struct device *dev); /* Indication from bus module regarding removal/absence of dongle */ extern void brcmf_detach(struct device *dev); - +/* Indication from bus module that dongle should be reset */ +extern void brcmf_dev_reset(struct device *dev); /* Indication from bus module to change flow-control state */ extern void brcmf_txflowblock(struct device *dev, bool state); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 74a616b4de8e..16efcb48dfbc 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -845,6 +845,17 @@ static void brcmf_bus_detach(struct brcmf_pub *drvr) } } +void brcmf_dev_reset(struct device *dev) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_pub *drvr = bus_if->drvr; + + if (drvr == NULL) + return; + + brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1); +} + void brcmf_detach(struct device *dev) { int i; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 22eae57d9546..1df85955ad93 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -1524,10 +1524,23 @@ static void brcmf_release_fw(struct list_head *q) } } +static int brcmf_usb_reset_device(struct device *dev, void *notused) +{ + /* device past is the usb interface so we + * need to use parent here. + */ + brcmf_dev_reset(dev->parent); + return 0; +} void brcmf_usb_exit(void) { + struct device_driver *drv = &brcmf_usbdrvr.drvwrap.driver; + int ret; + brcmf_dbg(USB, "Enter\n"); + ret = driver_for_each_device(drv, NULL, NULL, + brcmf_usb_reset_device); usb_deregister(&brcmf_usbdrvr); brcmf_release_fw(&fw_image_list); } |