aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2013-01-02 09:22:40 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-01-07 15:16:56 -0500
commit81d5f1bbc47961b2347d2b92b2aec56e6bad8779 (patch)
tree21d36ca3a10a49a9df577301d2abb4d86058a27a
parentac744395ba0a0491f8524a8371ad6f7df67bf673 (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>
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c11
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c13
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 @@
39#define BRCMF_C_GET_BSSID 23 39#define BRCMF_C_GET_BSSID 23
40#define BRCMF_C_GET_SSID 25 40#define BRCMF_C_GET_SSID 25
41#define BRCMF_C_SET_SSID 26 41#define BRCMF_C_SET_SSID 26
42#define BRCMF_C_TERMINATED 28
42#define BRCMF_C_GET_CHANNEL 29 43#define BRCMF_C_GET_CHANNEL 29
43#define BRCMF_C_SET_CHANNEL 30 44#define BRCMF_C_SET_CHANNEL 30
44#define BRCMF_C_GET_SRL 31 45#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,
154extern int brcmf_attach(uint bus_hdrlen, struct device *dev); 154extern int brcmf_attach(uint bus_hdrlen, struct device *dev);
155/* Indication from bus module regarding removal/absence of dongle */ 155/* Indication from bus module regarding removal/absence of dongle */
156extern void brcmf_detach(struct device *dev); 156extern void brcmf_detach(struct device *dev);
157 157/* Indication from bus module that dongle should be reset */
158extern void brcmf_dev_reset(struct device *dev);
158/* Indication from bus module to change flow-control state */ 159/* Indication from bus module to change flow-control state */
159extern void brcmf_txflowblock(struct device *dev, bool state); 160extern void brcmf_txflowblock(struct device *dev, bool state);
160 161
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)
845 } 845 }
846} 846}
847 847
848void brcmf_dev_reset(struct device *dev)
849{
850 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
851 struct brcmf_pub *drvr = bus_if->drvr;
852
853 if (drvr == NULL)
854 return;
855
856 brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
857}
858
848void brcmf_detach(struct device *dev) 859void brcmf_detach(struct device *dev)
849{ 860{
850 int i; 861 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)
1524 } 1524 }
1525} 1525}
1526 1526
1527static int brcmf_usb_reset_device(struct device *dev, void *notused)
1528{
1529 /* device past is the usb interface so we
1530 * need to use parent here.
1531 */
1532 brcmf_dev_reset(dev->parent);
1533 return 0;
1534}
1527 1535
1528void brcmf_usb_exit(void) 1536void brcmf_usb_exit(void)
1529{ 1537{
1538 struct device_driver *drv = &brcmf_usbdrvr.drvwrap.driver;
1539 int ret;
1540
1530 brcmf_dbg(USB, "Enter\n"); 1541 brcmf_dbg(USB, "Enter\n");
1542 ret = driver_for_each_device(drv, NULL, NULL,
1543 brcmf_usb_reset_device);
1531 usb_deregister(&brcmf_usbdrvr); 1544 usb_deregister(&brcmf_usbdrvr);
1532 brcmf_release_fw(&fw_image_list); 1545 brcmf_release_fw(&fw_image_list);
1533} 1546}