mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
ethernet: reset ethernet when resume [1/1]
PD#SWPL-6608 Problem: system will report tx error somethime after resume Solution: reset ethernet when resume Verify: verify on u200 board Change-Id: I9863a8a50c08addd4e2d8c024f46a2e7568c28b4 Signed-off-by: Zhuo Wang <zhuo.wang@amlogic.com>
This commit is contained in:
@@ -124,6 +124,15 @@ static void stmmac_exit_fs(struct net_device *dev);
|
||||
|
||||
#define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
|
||||
|
||||
/*won't be valid unless enable amlogic priv code*/
|
||||
#ifdef CONFIG_AMLOGIC_ETH_PRIVE
|
||||
#undef TX_MONITOR
|
||||
#endif
|
||||
|
||||
#ifdef TX_MONITOR
|
||||
static struct workqueue_struct *moniter_tx_wq;
|
||||
static struct delayed_work moniter_tx_worker;
|
||||
#endif
|
||||
/**
|
||||
* stmmac_verify_args - verify the driver parameters.
|
||||
* Description: it checks the driver parameters and set a default in case of
|
||||
@@ -1876,7 +1885,9 @@ static int stmmac_open(struct net_device *dev)
|
||||
|
||||
napi_enable(&priv->napi);
|
||||
netif_start_queue(dev);
|
||||
|
||||
#ifdef TX_MONITOR
|
||||
queue_delayed_work(moniter_tx_wq, &moniter_tx_worker, HZ);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
lpiirq_error:
|
||||
@@ -2722,12 +2733,18 @@ static int stmmac_poll(struct napi_struct *napi, int budget)
|
||||
* netdev structure and arrange for the device to be reset to a sane state
|
||||
* in order to transmit a new packet.
|
||||
*/
|
||||
#ifdef TX_MONITOR
|
||||
unsigned int timeout_err;
|
||||
#endif
|
||||
static void stmmac_tx_timeout(struct net_device *dev)
|
||||
{
|
||||
struct stmmac_priv *priv = netdev_priv(dev);
|
||||
|
||||
/* Clear Tx resources and restart transmitting again */
|
||||
stmmac_tx_err(priv);
|
||||
#ifdef TX_MONITOR
|
||||
timeout_err = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3248,6 +3265,23 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef TX_MONITOR
|
||||
struct stmmac_priv *priv_monitor;
|
||||
static void moniter_tx_handler(struct work_struct *work)
|
||||
{
|
||||
if (priv_monitor) {
|
||||
if (timeout_err) {
|
||||
pr_info("reset eth\n");
|
||||
stmmac_release(priv_monitor->dev);
|
||||
stmmac_open(priv_monitor->dev);
|
||||
timeout_err = 0;
|
||||
}
|
||||
} else {
|
||||
pr_info("device not init yet!\n");
|
||||
}
|
||||
queue_delayed_work(moniter_tx_wq, &moniter_tx_worker, HZ);
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* stmmac_dvr_probe
|
||||
* @device: device pointer
|
||||
@@ -3266,6 +3300,10 @@ int stmmac_dvr_probe(struct device *device,
|
||||
struct net_device *ndev = NULL;
|
||||
struct stmmac_priv *priv;
|
||||
|
||||
#ifdef TX_MONITOR
|
||||
moniter_tx_wq = create_singlethread_workqueue("eth_moniter_tx_wq");
|
||||
INIT_DELAYED_WORK(&moniter_tx_worker, moniter_tx_handler);
|
||||
#endif
|
||||
ndev = alloc_etherdev(sizeof(struct stmmac_priv));
|
||||
if (!ndev)
|
||||
return -ENOMEM;
|
||||
@@ -3414,6 +3452,9 @@ int stmmac_dvr_probe(struct device *device,
|
||||
#ifdef CONFIG_DWMAC_MESON
|
||||
ret = gmac_create_sysfs(
|
||||
mdiobus_get_phy(priv->mii, priv->plat->phy_addr), priv->ioaddr);
|
||||
#endif
|
||||
#ifdef TX_MONITOR
|
||||
priv_monitor = priv;
|
||||
#endif
|
||||
return ret;
|
||||
|
||||
@@ -3485,6 +3526,9 @@ int stmmac_suspend(struct device *dev)
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
unsigned long flags;
|
||||
|
||||
#ifdef TX_MONITOR
|
||||
cancel_delayed_work_sync(&moniter_tx_worker);
|
||||
#endif
|
||||
if (!ndev || !netif_running(ndev))
|
||||
return 0;
|
||||
|
||||
@@ -3590,7 +3634,6 @@ int stmmac_resume(struct device *dev)
|
||||
|
||||
stmmac_init_tx_coalesce(priv);
|
||||
stmmac_set_rx_mode(ndev);
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_ETH_PRIVE
|
||||
netif_device_attach(ndev);
|
||||
#endif
|
||||
@@ -3603,6 +3646,10 @@ int stmmac_resume(struct device *dev)
|
||||
if (priv->phydev)
|
||||
phy_start(priv->phydev);
|
||||
|
||||
#ifdef TX_MONITOR
|
||||
queue_delayed_work(moniter_tx_wq, &moniter_tx_worker, HZ);
|
||||
timeout_err = 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(stmmac_resume);
|
||||
|
||||
Reference in New Issue
Block a user