eth: restart eth0 when resume [1/1]

PD#SWPL-114869

Problem:
phy not work atfer resume sometimes

Solution:
restart ethernet after resume

Verify:
QA_verify with oppen

Change-Id: I88bac8f0c24f0e2890b24a1508e05e74ed667b5c
Signed-off-by: Zhuo Wang <zhuo.wang@amlogic.com>
This commit is contained in:
Zhuo Wang
2023-03-10 09:10:40 +00:00
committed by Dongjin Kim
parent 208adc6548
commit c4abb04923
4 changed files with 40 additions and 11 deletions

View File

@@ -420,6 +420,7 @@ static void set_wol_notify_bl30(u32 enable_bl30)
scpi_set_ethernet_wol(enable_bl30);
}
#endif
unsigned int internal_phy;
static int aml_custom_setting(struct platform_device *pdev, struct meson8b_dwmac *dwmac)
{
struct device_node *np = pdev->dev.of_node;
@@ -433,6 +434,9 @@ static int aml_custom_setting(struct platform_device *pdev, struct meson8b_dwmac
writel(mc_val, dwmac->regs + PRG_ETH0);
}
if (of_property_read_u32(np, "internal_phy", &internal_phy) != 0)
pr_info("use default internal_phy as 0\n");
ndev->wol_enabled = true;
return 0;
}
@@ -594,8 +598,10 @@ static void meson8b_dwmac_shutdown(struct platform_device *pdev)
pr_info("aml_eth_shutdown\n");
ret = stmmac_suspend(priv->device);
if (dwmac->data->suspend)
ret = dwmac->data->suspend(dwmac);
if (internal_phy != 2) {
if (dwmac->data->suspend)
ret = dwmac->data->suspend(dwmac);
}
}
static int dwmac_suspend(struct meson8b_dwmac *dwmac)
@@ -620,6 +626,7 @@ static void dwmac_resume(struct meson8b_dwmac *dwmac)
}
int backup_adv;
int without_reset;
static int meson8b_suspend(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
@@ -629,8 +636,8 @@ static int meson8b_suspend(struct device *dev)
int ret;
/*open wol*/
if (wol_switch_from_user) {
/*open wol, shutdown phy when not link*/
if ((wol_switch_from_user) && phydev->link) {
set_wol_notify_bl31(true);
set_wol_notify_bl30(true);
device_init_wakeup(dev, true);
@@ -643,14 +650,18 @@ static int meson8b_suspend(struct device *dev)
genphy_restart_aneg(phydev);
msleep(3000);
ret = stmmac_suspend(dev);
without_reset = 1;
} else {
set_wol_notify_bl31(false);
set_wol_notify_bl30(false);
device_init_wakeup(dev, false);
ret = stmmac_suspend(dev);
if (dwmac->data->suspend)
ret = dwmac->data->suspend(dwmac);
if (internal_phy != 2) {
if (dwmac->data->suspend)
ret = dwmac->data->suspend(dwmac);
}
without_reset = 0;
}
return ret;
@@ -666,7 +677,7 @@ static int meson8b_resume(struct device *dev)
priv->wolopts = 0;
if (wol_switch_from_user) {
if ((wol_switch_from_user) && (without_reset)) {
ret = stmmac_resume(dev);
if (get_resume_method() == ETH_PHY_WAKEUP) {
@@ -683,9 +694,13 @@ static int meson8b_resume(struct device *dev)
mii_lpa_to_linkmode_lpa_t(phydev->advertising, backup_adv);
genphy_restart_aneg(phydev);
} else {
if (dwmac->data->resume)
dwmac->data->resume(dwmac);
if (internal_phy != 2) {
if (dwmac->data->resume)
dwmac->data->resume(dwmac);
}
ret = stmmac_resume(dev);
pr_info("wzh %s\n", __func__);
stmmac_global_err(priv);
}
return ret;
}

View File

@@ -395,4 +395,7 @@ static inline int stmmac_selftest_get_count(struct stmmac_priv *priv)
}
#endif /* CONFIG_STMMAC_SELFTESTS */
#if IS_ENABLED(CONFIG_AMLOGIC_ETH_PRIVE)
void stmmac_global_err(struct stmmac_priv *priv);
#endif
#endif /* __STMMAC_H__ */

View File

@@ -276,6 +276,15 @@ static void stmmac_service_event_schedule(struct stmmac_priv *priv)
queue_work(priv->wq, &priv->service_task);
}
#if IS_ENABLED(CONFIG_AMLOGIC_ETH_PRIVE)
void stmmac_global_err(struct stmmac_priv *priv)
{
netif_carrier_off(priv->dev);
set_bit(STMMAC_RESET_REQUESTED, &priv->state);
stmmac_service_event_schedule(priv);
}
EXPORT_SYMBOL_GPL(stmmac_global_err);
#else
static void stmmac_global_err(struct stmmac_priv *priv)
{
netif_carrier_off(priv->dev);
@@ -283,6 +292,7 @@ static void stmmac_global_err(struct stmmac_priv *priv)
stmmac_service_event_schedule(priv);
}
#endif
/**
* stmmac_clk_csr_set - dynamically set the MDC clock
* @priv: driver private structure

View File

@@ -984,7 +984,8 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)
struct phy_device *phydev = phy_dat;
struct phy_driver *drv = phydev->drv;
irqreturn_t ret;
#if IS_ENABLED(CONFIG_AMLOGIC_ETH_PRIVE)
#else
/* Wakeup interrupts may occur during a system sleep transition.
* Postpone handling until the PHY has resumed.
*/
@@ -1006,7 +1007,7 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)
disable_irq_nosync(irq);
return IRQ_HANDLED;
}
#endif
mutex_lock(&phydev->lock);
ret = drv->handle_interrupt(phydev);
mutex_unlock(&phydev->lock);