From c9106d2df0151341512e53a99ac785ea0afa3a05 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 3 Jun 2019 17:13:16 +0800 Subject: [PATCH] phy/realtek: fixup WOL on shutdown Signed-off-by: Nick --- drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c | 6 ++++ drivers/net/phy/realtek.c | 35 +++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c index d3073cd..537436a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c @@ -26,6 +26,7 @@ #include "dwmac_dma.h" #endif #include "stmmac_platform.h" +#include #define ETHMAC_SPEED_10 BIT(1) @@ -463,6 +464,7 @@ static int meson6_dwmac_resume(struct device *dev) } EXPORT_SYMBOL_GPL(meson6_dwmac_resume); +void rtl8211f_shutdown(void); void meson6_dwmac_shutdown(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); @@ -489,6 +491,7 @@ void meson6_dwmac_shutdown(struct platform_device *pdev) } dwmac_meson_disable_analog(&pdev->dev); } + //stmmac_release(ndev); //stmmac_pltfr_suspend(&pdev->dev); if (priv->phydev) { @@ -500,6 +503,9 @@ void meson6_dwmac_shutdown(struct platform_device *pdev) } } stmmac_pltfr_suspend(&pdev->dev); + + if (is_meson_gxm_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu()) + rtl8211f_shutdown(); } #endif diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 31bc5a34..4df28bf 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -33,6 +33,8 @@ #define RTL821x_INER_INIT 0x6400 #define RTL821x_INSR 0x13 #define RTL8211E_INER_LINK_STATUS 0x400 +#define RTL8211F_BMCR 0x00 +#define RTL821x_EPAGSR 0x1f #define RTL8211F_INER_LINK_STATUS 0x0010 #define RTL8211F_INSR 0x1d @@ -43,6 +45,8 @@ MODULE_DESCRIPTION("Realtek PHY driver"); MODULE_AUTHOR("Johnson Leung"); MODULE_LICENSE("GPL"); +struct phy_device *g_phydev; + #ifdef CONFIG_AMLOGIC_ETH_PRIVE unsigned int support_external_phy_wol; #endif @@ -156,6 +160,8 @@ static int rtl8211f_config_init(struct phy_device *phydev) /* restore to default page 0 */ phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0); + g_phydev = phydev; + return 0; } @@ -165,6 +171,7 @@ int rtl8211f_suspend(struct phy_device *phydev) int value = 0; if (support_external_phy_wol) { + printk("rtl8211f_suspend...\n"); mutex_lock(&phydev->lock); phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd8a); /*set magic packet for wol*/ @@ -211,6 +218,34 @@ int rtl8211f_resume(struct phy_device *phydev) return 0; } + +void rtl8211f_shutdown(void) +{ + int value; + + if (support_external_phy_wol) { + printk("rtl8211f_shutdown...\n"); + mutex_lock(&g_phydev->lock); + /*set speed to 10Mbps */ + phy_write(g_phydev, RTL821x_EPAGSR, 0x0); /*set page 0x0*/ + phy_write(g_phydev, RTL8211F_BMCR, 0x0); /* 10Mbps */ + phy_write(g_phydev, RTL8211F_PAGE_SELECT, 0xd8a); + /*set magic packet for wol*/ + phy_write(g_phydev, 0x10, 0x1000); + phy_write(g_phydev, 0x11, 0x9fff); + /*pad isolation*/ + value = phy_read(g_phydev, 0x13); + phy_write(g_phydev, 0x13, value | (0x1 << 15)); + /*pin 31 pull high*/ + phy_write(g_phydev, RTL8211F_PAGE_SELECT, 0xd40); + value = phy_read(g_phydev, 0x16); + phy_write(g_phydev, 0x16, value | (1 << 5)); + phy_write(g_phydev, RTL8211F_PAGE_SELECT, 0); + + mutex_unlock(&g_phydev->lock); + } +} + #endif static struct phy_driver realtek_drvs[] = { { -- 2.7.4