From 9128c8a45a0263987f1b9b697dfac9b2c7690d25 Mon Sep 17 00:00:00 2001 From: August <2819763+Dangku@users.noreply.github.com> Date: Tue, 4 Jun 2024 11:38:45 +0800 Subject: [PATCH] gmac: support rtl8211f phy --- drivers/net/ethernet/allwinner/sunxi-gmac.c | 7 +- drivers/net/phy/realtek.c | 72 +++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/allwinner/sunxi-gmac.c b/drivers/net/ethernet/allwinner/sunxi-gmac.c index 8f83d6e52..26ceaaf56 100644 --- a/drivers/net/ethernet/allwinner/sunxi-gmac.c +++ b/drivers/net/ethernet/allwinner/sunxi-gmac.c @@ -72,6 +72,7 @@ #define circ_inc(n, s) (((n) + 1) % (s)) #define YT8531_PHY_ID 0x4f51e91b +#define RTL8211FCG_PHY_ID 0x001cc916 #define GETH_MAC_ADDRESS "00:00:00:00:00:00" static char *mac_str = GETH_MAC_ADDRESS; @@ -802,7 +803,9 @@ static int geth_phy_init(struct net_device *ndev) if (!phydev_tmp) continue; - if (phydev_tmp->phy_id == EPHY_ID || phydev_tmp->phy_id == YT8531_PHY_ID) { + pr_err("BPI: addr=%d is not null, phydev_tmp->phy_id=%x \n", addr, phydev_tmp->phy_id); + + if (phydev_tmp->phy_id == EPHY_ID || phydev_tmp->phy_id == YT8531_PHY_ID || phydev_tmp->phy_id == RTL8211FCG_PHY_ID) { phydev = phydev_tmp; priv->phy_addr = addr; break; @@ -2139,6 +2142,8 @@ static int geth_hw_init(struct platform_device *pdev) if (!of_property_read_u32(np, "rx-delay", &value)) priv->rx_delay = value; + + pr_info("BPI: tx_delay=%d rx_delay=%d\n", priv->tx_delay, priv->rx_delay); /* config pinctrl */ if (EXT_PHY == priv->phy_ext) { diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 879ca37c8..237a384e2 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -401,6 +401,76 @@ static int rtl8125_config_aneg(struct phy_device *phydev) return __genphy_config_aneg(phydev, ret); } +static int aml_rtl8211f_read_status(struct phy_device *phydev) +{ + unsigned int aml_link_speed = 0; + int aml_lpadv = 0; + int err, old_link = phydev->link; + + /* Update the link, but return if there was an error */ + err = genphy_update_link(phydev); + if (err) + return err; + + /* why bother the PHY if nothing can have changed */ + if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) + return 0; + + phydev->speed = SPEED_UNKNOWN; + phydev->duplex = DUPLEX_UNKNOWN; + phydev->pause = 0; + phydev->asym_pause = 0; + + err = genphy_read_lpa(phydev); + if (err < 0) + return err; + + if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) { + // phy_resolve_aneg_linkmode(phydev); + aml_lpadv = phy_read_paged(phydev, 0xa43, 0x1a); + if (aml_lpadv < 0) + return aml_lpadv; + + phydev->duplex = aml_lpadv & 0x8 ? DUPLEX_FULL : DUPLEX_HALF; + phydev->link = aml_lpadv & 0x4 ? 1 : 0; + aml_link_speed = (aml_lpadv & 0x30) >> 4; + + switch (aml_link_speed) { + case 0: + phydev->speed = SPEED_10; + break; + case 1: + phydev->speed = SPEED_100; + break; + case 2: + phydev->speed = SPEED_1000; + break; + default: + pr_info("wzh no match speed\n"); + break; + } + } else if (phydev->autoneg == AUTONEG_DISABLE) { + int bmcr = phy_read(phydev, MII_BMCR); + + if (bmcr < 0) + return bmcr; + + if (bmcr & BMCR_FULLDPLX) + phydev->duplex = DUPLEX_FULL; + else + phydev->duplex = DUPLEX_HALF; + + if (bmcr & BMCR_SPEED1000) + phydev->speed = SPEED_1000; + else if (bmcr & BMCR_SPEED100) + phydev->speed = SPEED_100; + else + phydev->speed = SPEED_10; + } + + return 0; +} + static int rtl8125_read_status(struct phy_device *phydev) { if (phydev->autoneg == AUTONEG_ENABLE) { @@ -517,6 +587,8 @@ static struct phy_driver realtek_drvs[] = { .config_init = &rtl8211f_config_init, .ack_interrupt = &rtl8211f_ack_interrupt, .config_intr = &rtl8211f_config_intr, + .read_status = &aml_rtl8211f_read_status, + //.read_status = genphy_read_status, .suspend = genphy_suspend, .resume = genphy_resume, .read_page = rtl821x_read_page,