return NETDEV_TX_OK;
 }
 
-static void fs_timeout(struct net_device *dev)
+static void fs_timeout_work(struct work_struct *work)
 {
-       struct fs_enet_private *fep = netdev_priv(dev);
+       struct fs_enet_private *fep = container_of(work, struct fs_enet_private,
+                                                  timeout_work);
+       struct net_device *dev = fep->ndev;
        unsigned long flags;
        int wake = 0;
 
                phy_stop(dev->phydev);
                (*fep->ops->stop)(dev);
                (*fep->ops->restart)(dev);
-               phy_start(dev->phydev);
        }
 
        phy_start(dev->phydev);
                netif_wake_queue(dev);
 }
 
+static void fs_timeout(struct net_device *dev)
+{
+       struct fs_enet_private *fep = netdev_priv(dev);
+
+       schedule_work(&fep->timeout_work);
+}
+
 /*-----------------------------------------------------------------------------
  *  generic link-change handler - should be sufficient for most cases
  *-----------------------------------------------------------------------------*/
        netif_stop_queue(dev);
        netif_carrier_off(dev);
        napi_disable(&fep->napi);
+       cancel_work_sync(&fep->timeout_work);
        phy_stop(dev->phydev);
 
        spin_lock_irqsave(&fep->lock, flags);
 
        ndev->netdev_ops = &fs_enet_netdev_ops;
        ndev->watchdog_timeo = 2 * HZ;
+       INIT_WORK(&fep->timeout_work, fs_timeout_work);
        netif_napi_add(ndev, &fep->napi, fs_enet_napi, fpi->napi_weight);
 
        ndev->ethtool_ops = &fs_ethtool_ops;
 
        spinlock_t lock;        /* during all ops except TX pckt processing */
        spinlock_t tx_lock;     /* during fs_start_xmit and fs_tx         */
        struct fs_platform_info *fpi;
+       struct work_struct timeout_work;
        const struct fs_ops *ops;
        int rx_ring, tx_ring;
        dma_addr_t ring_mem_addr;