diff options
author | Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 2009-07-30 19:41:37 +0300 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-04 16:44:16 -0400 |
commit | 7eaab7086c3a313d76c217f98bc610c523d9bc2c (patch) | |
tree | d984e1056aac37ecb215581d790f6c96fd6b11e5 /drivers/net/wireless/rndis_wlan.c | |
parent | 005ba2f17e68b4da6a2c2c01c826294beac50415 (diff) | |
download | linux-7eaab7086c3a313d76c217f98bc610c523d9bc2c.tar.gz linux-7eaab7086c3a313d76c217f98bc610c523d9bc2c.tar.bz2 linux-7eaab7086c3a313d76c217f98bc610c523d9bc2c.zip |
rndis_wlan: reset device and restore multicast list on rndis_wlan_reset()
Reset device properly with RNDIS_MSG_RESET in rndis_wlan_reset() and restore
multicast list afterwards.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rndis_wlan.c')
-rw-r--r-- | drivers/net/wireless/rndis_wlan.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index dee05511d591..bfb9861a0366 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -594,6 +594,28 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) } +static int rndis_reset(struct usbnet *usbdev) +{ + struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_reset *reset; + int ret; + + mutex_lock(&priv->command_lock); + + reset = (void *)priv->command_buffer; + memset(reset, 0, sizeof(*reset)); + reset->msg_type = RNDIS_MSG_RESET; + reset->msg_len = cpu_to_le32(sizeof(*reset)); + ret = rndis_command(usbdev, (void *)reset, CONTROL_BUFFER_SIZE); + + mutex_unlock(&priv->command_lock); + + if (ret < 0) + return ret; + return 0; +} + + /* * Specs say that we can only set config parameters only soon after device * initialization. @@ -2500,9 +2522,17 @@ static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf) static int rndis_wlan_reset(struct usbnet *usbdev) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + int retval; devdbg(usbdev, "rndis_wlan_reset"); + retval = rndis_reset(usbdev); + if (retval) + devwarn(usbdev, "rndis_reset() failed: %d", retval); + + /* rndis_reset cleared multicast list, so restore here. */ + set_multicast_list(usbdev); + queue_delayed_work(priv->workqueue, &priv->stats_work, round_jiffies_relative(STATS_UPDATE_JIFFIES)); |