|
|
@@ -613,9 +613,11 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
|
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;
|
|
|
|
|
|
@@ -627,7 +629,6 @@ static void fs_timeout(struct net_device *dev)
|
|
|
phy_stop(dev->phydev);
|
|
|
(*fep->ops->stop)(dev);
|
|
|
(*fep->ops->restart)(dev);
|
|
|
- phy_start(dev->phydev);
|
|
|
}
|
|
|
|
|
|
phy_start(dev->phydev);
|
|
|
@@ -639,6 +640,13 @@ static void fs_timeout(struct net_device *dev)
|
|
|
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
|
|
|
*-----------------------------------------------------------------------------*/
|
|
|
@@ -759,6 +767,7 @@ static int fs_enet_close(struct net_device *dev)
|
|
|
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);
|
|
|
@@ -1019,6 +1028,7 @@ static int fs_enet_probe(struct platform_device *ofdev)
|
|
|
|
|
|
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;
|