Reset and reinitialize the device when the tx timeout occurs.

Signed-off-by: Hayes Wang <hayesw...@realtek.com>
---
 drivers/net/usb/r8152.c | 41 +++++++++++++++++++++++++++++++----------
 1 file changed, 31 insertions(+), 10 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 6c0ec37..2de8ce4 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1764,16 +1764,6 @@ static void rtl_drop_queued_tx(struct r8152 *tp)
        }
 }
 
-static void rtl8152_tx_timeout(struct net_device *netdev)
-{
-       struct r8152 *tp = netdev_priv(netdev);
-       int i;
-
-       netif_warn(tp, tx_err, netdev, "Tx timeout\n");
-       for (i = 0; i < RTL8152_MAX_TX; i++)
-               usb_unlink_urb(tp->tx_info[i].urb);
-}
-
 static void rtl8152_set_rx_mode(struct net_device *netdev)
 {
        struct r8152 *tp = netdev_priv(netdev);
@@ -3150,6 +3140,37 @@ out:
        return res;
 }
 
+static void rtl8152_tx_timeout(struct net_device *netdev)
+{
+       struct r8152 *tp = netdev_priv(netdev);
+
+       netif_warn(tp, tx_err, netdev, "Tx timeout\n");
+
+       if (usb_autopm_get_interface(tp->intf) < 0)
+               return;
+
+       netif_stop_queue(netdev);
+       clear_bit(WORK_ENABLE, &tp->flags);
+       usb_kill_urb(tp->intr_urb);
+       cancel_delayed_work_sync(&tp->schedule);
+       tp->rtl_ops.down(tp);
+
+       usb_reset_device(tp->udev);
+
+       tp->rtl_ops.init(tp);
+       tp->rtl_ops.up(tp);
+       rtl8152_set_speed(tp, AUTONEG_ENABLE,
+                         tp->mii.supports_gmii ? SPEED_1000 : SPEED_100,
+                         DUPLEX_FULL);
+       tp->speed = 0;
+       netif_carrier_off(netdev);
+       netif_start_queue(netdev);
+       set_bit(WORK_ENABLE, &tp->flags);
+       usb_submit_urb(tp->intr_urb, GFP_KERNEL);
+
+       usb_autopm_put_interface(tp->intf);
+}
+
 static const struct net_device_ops rtl8152_netdev_ops = {
        .ndo_open               = rtl8152_open,
        .ndo_stop               = rtl8152_close,
-- 
1.8.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to