#define CX82310_MTU    1514
 #define CMD_EP         0x01
 
+struct cx82310_priv {
+       struct work_struct reenable_work;
+       struct usbnet *dev;
+};
+
 /*
  * execute control command
  *  - optionally send some data (command parameters)
        return ret;
 }
 
+static int cx82310_enable_ethernet(struct usbnet *dev)
+{
+       int ret = cx82310_cmd(dev, CMD_ETHERNET_MODE, true, "\x01", 1, NULL, 0);
+
+       if (ret)
+               netdev_err(dev->net, "unable to enable ethernet mode: %d\n",
+                          ret);
+       return ret;
+}
+
+static void cx82310_reenable_work(struct work_struct *work)
+{
+       struct cx82310_priv *priv = container_of(work, struct cx82310_priv,
+                                                reenable_work);
+       cx82310_enable_ethernet(priv->dev);
+}
+
 #define partial_len    data[0]         /* length of partial packet data */
 #define partial_rem    data[1]         /* remaining (missing) data length */
 #define partial_data   data[2]         /* partial packet data */
        struct usb_device *udev = dev->udev;
        u8 link[3];
        int timeout = 50;
+       struct cx82310_priv *priv;
 
        /* avoid ADSL modems - continue only if iProduct is "USB NET CARD" */
        if (usb_string(udev, udev->descriptor.iProduct, buf, sizeof(buf)) > 0
        if (!dev->partial_data)
                return -ENOMEM;
 
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               ret = -ENOMEM;
+               goto err_partial;
+       }
+       dev->driver_priv = priv;
+       INIT_WORK(&priv->reenable_work, cx82310_reenable_work);
+       priv->dev = dev;
+
        /* wait for firmware to become ready (indicated by the link being up) */
        while (--timeout) {
                ret = cx82310_cmd(dev, CMD_GET_LINK_STATUS, true, NULL, 0,
        }
 
        /* enable ethernet mode (?) */
-       ret = cx82310_cmd(dev, CMD_ETHERNET_MODE, true, "\x01", 1, NULL, 0);
-       if (ret) {
-               dev_err(&udev->dev, "unable to enable ethernet mode: %d\n",
-                       ret);
+       if (cx82310_enable_ethernet(dev))
                goto err;
-       }
 
        /* get the MAC address */
        ret = cx82310_cmd(dev, CMD_GET_MAC_ADDR, true, NULL, 0,
 
        return 0;
 err:
+       kfree(dev->driver_priv);
+err_partial:
        kfree((void *)dev->partial_data);
        return ret;
 }
 
 static void cx82310_unbind(struct usbnet *dev, struct usb_interface *intf)
 {
+       struct cx82310_priv *priv = dev->driver_priv;
+
        kfree((void *)dev->partial_data);
+       cancel_work_sync(&priv->reenable_work);
+       kfree(dev->driver_priv);
 }
 
 /*
 {
        int len;
        struct sk_buff *skb2;
+       struct cx82310_priv *priv = dev->driver_priv;
 
        /*
         * If the last skb ended with an incomplete packet, this skb contains
                        break;
                }
 
-               if (len > CX82310_MTU) {
+               if (len == 0xffff) {
+                       netdev_info(dev->net, "router was rebooted, re-enabling ethernet mode");
+                       schedule_work(&priv->reenable_work);
+               } else if (len > CX82310_MTU) {
                        dev_err(&dev->udev->dev, "RX packet too long: %d B\n",
                                len);
                        return 0;