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>
This commit is contained in:
parent
ac744395ba
commit
81d5f1bbc4
4 changed files with 27 additions and 1 deletions
|
@ -39,6 +39,7 @@
|
||||||
#define BRCMF_C_GET_BSSID 23
|
#define BRCMF_C_GET_BSSID 23
|
||||||
#define BRCMF_C_GET_SSID 25
|
#define BRCMF_C_GET_SSID 25
|
||||||
#define BRCMF_C_SET_SSID 26
|
#define BRCMF_C_SET_SSID 26
|
||||||
|
#define BRCMF_C_TERMINATED 28
|
||||||
#define BRCMF_C_GET_CHANNEL 29
|
#define BRCMF_C_GET_CHANNEL 29
|
||||||
#define BRCMF_C_SET_CHANNEL 30
|
#define BRCMF_C_SET_CHANNEL 30
|
||||||
#define BRCMF_C_GET_SRL 31
|
#define BRCMF_C_GET_SRL 31
|
||||||
|
|
|
@ -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);
|
extern int brcmf_attach(uint bus_hdrlen, struct device *dev);
|
||||||
/* Indication from bus module regarding removal/absence of dongle */
|
/* Indication from bus module regarding removal/absence of dongle */
|
||||||
extern void brcmf_detach(struct device *dev);
|
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 */
|
/* Indication from bus module to change flow-control state */
|
||||||
extern void brcmf_txflowblock(struct device *dev, bool state);
|
extern void brcmf_txflowblock(struct device *dev, bool state);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
void brcmf_detach(struct device *dev)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -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)
|
void brcmf_usb_exit(void)
|
||||||
{
|
{
|
||||||
|
struct device_driver *drv = &brcmf_usbdrvr.drvwrap.driver;
|
||||||
|
int ret;
|
||||||
|
|
||||||
brcmf_dbg(USB, "Enter\n");
|
brcmf_dbg(USB, "Enter\n");
|
||||||
|
ret = driver_for_each_device(drv, NULL, NULL,
|
||||||
|
brcmf_usb_reset_device);
|
||||||
usb_deregister(&brcmf_usbdrvr);
|
usb_deregister(&brcmf_usbdrvr);
|
||||||
brcmf_release_fw(&fw_image_list);
|
brcmf_release_fw(&fw_image_list);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue