Skip to content

Commit d700d26

Browse files
committed
Merge branch 'realtek-EEE'
Heiner Kallweit says: ==================== net: phy: realtek: map vendor-specific EEE registers to standard MMD registers EEE-related registers on newer integrated PHY's have the standard layout, but are accessible not via MMD but via vendor-specific registers. Emulating the standard MMD registers allows to use the generic functions for EEE control and to significantly simplify the r8169 driver. v2: - rebase patch 2 ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 2441ba4 + 2e779dd commit d700d26

File tree

2 files changed

+67
-148
lines changed

2 files changed

+67
-148
lines changed

drivers/net/ethernet/realtek/r8169_main.c

Lines changed: 24 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,13 @@ static bool rtl_is_8168evl_up(struct rtl8169_private *tp)
733733
tp->mac_version != RTL_GIGA_MAC_VER_39;
734734
}
735735

736+
static bool rtl_supports_eee(struct rtl8169_private *tp)
737+
{
738+
return tp->mac_version >= RTL_GIGA_MAC_VER_34 &&
739+
tp->mac_version != RTL_GIGA_MAC_VER_37 &&
740+
tp->mac_version != RTL_GIGA_MAC_VER_39;
741+
}
742+
736743
struct rtl_cond {
737744
bool (*check)(struct rtl8169_private *);
738745
const char *msg;
@@ -1945,144 +1952,40 @@ static int rtl_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
19451952
return 0;
19461953
}
19471954

1948-
static int rtl_get_eee_supp(struct rtl8169_private *tp)
1949-
{
1950-
struct phy_device *phydev = tp->phydev;
1951-
int ret;
1952-
1953-
switch (tp->mac_version) {
1954-
case RTL_GIGA_MAC_VER_34:
1955-
case RTL_GIGA_MAC_VER_35:
1956-
case RTL_GIGA_MAC_VER_36:
1957-
case RTL_GIGA_MAC_VER_38:
1958-
ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
1959-
break;
1960-
case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51:
1961-
ret = phy_read_paged(phydev, 0x0a5c, 0x12);
1962-
break;
1963-
default:
1964-
ret = -EPROTONOSUPPORT;
1965-
break;
1966-
}
1967-
1968-
return ret;
1969-
}
1970-
1971-
static int rtl_get_eee_lpadv(struct rtl8169_private *tp)
1972-
{
1973-
struct phy_device *phydev = tp->phydev;
1974-
int ret;
1975-
1976-
switch (tp->mac_version) {
1977-
case RTL_GIGA_MAC_VER_34:
1978-
case RTL_GIGA_MAC_VER_35:
1979-
case RTL_GIGA_MAC_VER_36:
1980-
case RTL_GIGA_MAC_VER_38:
1981-
ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
1982-
break;
1983-
case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51:
1984-
ret = phy_read_paged(phydev, 0x0a5d, 0x11);
1985-
break;
1986-
default:
1987-
ret = -EPROTONOSUPPORT;
1988-
break;
1989-
}
1990-
1991-
return ret;
1992-
}
1993-
1994-
static int rtl_get_eee_adv(struct rtl8169_private *tp)
1995-
{
1996-
struct phy_device *phydev = tp->phydev;
1997-
int ret;
1998-
1999-
switch (tp->mac_version) {
2000-
case RTL_GIGA_MAC_VER_34:
2001-
case RTL_GIGA_MAC_VER_35:
2002-
case RTL_GIGA_MAC_VER_36:
2003-
case RTL_GIGA_MAC_VER_38:
2004-
ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
2005-
break;
2006-
case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51:
2007-
ret = phy_read_paged(phydev, 0x0a5d, 0x10);
2008-
break;
2009-
default:
2010-
ret = -EPROTONOSUPPORT;
2011-
break;
2012-
}
2013-
2014-
return ret;
2015-
}
2016-
2017-
static int rtl_set_eee_adv(struct rtl8169_private *tp, int val)
2018-
{
2019-
struct phy_device *phydev = tp->phydev;
2020-
int ret = 0;
2021-
2022-
switch (tp->mac_version) {
2023-
case RTL_GIGA_MAC_VER_34:
2024-
case RTL_GIGA_MAC_VER_35:
2025-
case RTL_GIGA_MAC_VER_36:
2026-
case RTL_GIGA_MAC_VER_38:
2027-
ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
2028-
break;
2029-
case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51:
2030-
phy_write_paged(phydev, 0x0a5d, 0x10, val);
2031-
break;
2032-
default:
2033-
ret = -EPROTONOSUPPORT;
2034-
break;
2035-
}
2036-
2037-
return ret;
2038-
}
2039-
20401955
static int rtl8169_get_eee(struct net_device *dev, struct ethtool_eee *data)
20411956
{
20421957
struct rtl8169_private *tp = netdev_priv(dev);
20431958
struct device *d = tp_to_dev(tp);
20441959
int ret;
20451960

1961+
if (!rtl_supports_eee(tp))
1962+
return -EOPNOTSUPP;
1963+
20461964
pm_runtime_get_noresume(d);
20471965

20481966
if (!pm_runtime_active(d)) {
20491967
ret = -EOPNOTSUPP;
2050-
goto out;
1968+
} else {
1969+
ret = phy_ethtool_get_eee(tp->phydev, data);
20511970
}
20521971

2053-
/* Get Supported EEE */
2054-
ret = rtl_get_eee_supp(tp);
2055-
if (ret < 0)
2056-
goto out;
2057-
data->supported = mmd_eee_cap_to_ethtool_sup_t(ret);
2058-
2059-
/* Get advertisement EEE */
2060-
ret = rtl_get_eee_adv(tp);
2061-
if (ret < 0)
2062-
goto out;
2063-
data->advertised = mmd_eee_adv_to_ethtool_adv_t(ret);
2064-
data->eee_enabled = !!data->advertised;
2065-
2066-
/* Get LP advertisement EEE */
2067-
ret = rtl_get_eee_lpadv(tp);
2068-
if (ret < 0)
2069-
goto out;
2070-
data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(ret);
2071-
data->eee_active = !!(data->advertised & data->lp_advertised);
2072-
out:
20731972
pm_runtime_put_noidle(d);
2074-
return ret < 0 ? ret : 0;
1973+
1974+
return ret;
20751975
}
20761976

20771977
static int rtl8169_set_eee(struct net_device *dev, struct ethtool_eee *data)
20781978
{
20791979
struct rtl8169_private *tp = netdev_priv(dev);
20801980
struct device *d = tp_to_dev(tp);
2081-
int old_adv, adv = 0, cap, ret;
1981+
int ret;
1982+
1983+
if (!rtl_supports_eee(tp))
1984+
return -EOPNOTSUPP;
20821985

20831986
pm_runtime_get_noresume(d);
20841987

2085-
if (!dev->phydev || !pm_runtime_active(d)) {
1988+
if (!pm_runtime_active(d)) {
20861989
ret = -EOPNOTSUPP;
20871990
goto out;
20881991
}
@@ -2093,38 +1996,10 @@ static int rtl8169_set_eee(struct net_device *dev, struct ethtool_eee *data)
20931996
goto out;
20941997
}
20951998

2096-
/* Get Supported EEE */
2097-
ret = rtl_get_eee_supp(tp);
2098-
if (ret < 0)
2099-
goto out;
2100-
cap = ret;
2101-
2102-
ret = rtl_get_eee_adv(tp);
2103-
if (ret < 0)
2104-
goto out;
2105-
old_adv = ret;
2106-
2107-
if (data->eee_enabled) {
2108-
adv = !data->advertised ? cap :
2109-
ethtool_adv_to_mmd_eee_adv_t(data->advertised) & cap;
2110-
/* Mask prohibited EEE modes */
2111-
adv &= ~dev->phydev->eee_broken_modes;
2112-
}
2113-
2114-
if (old_adv != adv) {
2115-
ret = rtl_set_eee_adv(tp, adv);
2116-
if (ret < 0)
2117-
goto out;
2118-
2119-
/* Restart autonegotiation so the new modes get sent to the
2120-
* link partner.
2121-
*/
2122-
ret = phy_restart_aneg(dev->phydev);
2123-
}
2124-
1999+
ret = phy_ethtool_set_eee(tp->phydev, data);
21252000
out:
21262001
pm_runtime_put_noidle(d);
2127-
return ret < 0 ? ret : 0;
2002+
return ret;
21282003
}
21292004

21302005
static const struct ethtool_ops rtl8169_ethtool_ops = {
@@ -2151,10 +2026,11 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
21512026

21522027
static void rtl_enable_eee(struct rtl8169_private *tp)
21532028
{
2154-
int supported = rtl_get_eee_supp(tp);
2029+
struct phy_device *phydev = tp->phydev;
2030+
int supported = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
21552031

21562032
if (supported > 0)
2157-
rtl_set_eee_adv(tp, supported);
2033+
phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, supported);
21582034
}
21592035

21602036
static void rtl8169_get_mac_version(struct rtl8169_private *tp)

drivers/net/phy/realtek.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,45 @@ static int rtl8366rb_config_init(struct phy_device *phydev)
266266
return ret;
267267
}
268268

269+
static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
270+
{
271+
int ret;
272+
273+
if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
274+
rtl821x_write_page(phydev, 0xa5c);
275+
ret = __phy_read(phydev, 0x12);
276+
rtl821x_write_page(phydev, 0);
277+
} else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
278+
rtl821x_write_page(phydev, 0xa5d);
279+
ret = __phy_read(phydev, 0x10);
280+
rtl821x_write_page(phydev, 0);
281+
} else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE) {
282+
rtl821x_write_page(phydev, 0xa5d);
283+
ret = __phy_read(phydev, 0x11);
284+
rtl821x_write_page(phydev, 0);
285+
} else {
286+
ret = -EOPNOTSUPP;
287+
}
288+
289+
return ret;
290+
}
291+
292+
static int rtlgen_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
293+
u16 val)
294+
{
295+
int ret;
296+
297+
if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
298+
rtl821x_write_page(phydev, 0xa5d);
299+
ret = __phy_write(phydev, 0x10, val);
300+
rtl821x_write_page(phydev, 0);
301+
} else {
302+
ret = -EOPNOTSUPP;
303+
}
304+
305+
return ret;
306+
}
307+
269308
static int rtl8125_get_features(struct phy_device *phydev)
270309
{
271310
int val;
@@ -422,6 +461,8 @@ static struct phy_driver realtek_drvs[] = {
422461
.resume = genphy_resume,
423462
.read_page = rtl821x_read_page,
424463
.write_page = rtl821x_write_page,
464+
.read_mmd = rtlgen_read_mmd,
465+
.write_mmd = rtlgen_write_mmd,
425466
}, {
426467
.name = "RTL8125 2.5Gbps internal",
427468
.match_phy_device = rtl8125_match_phy_device,
@@ -432,6 +473,8 @@ static struct phy_driver realtek_drvs[] = {
432473
.resume = genphy_resume,
433474
.read_page = rtl821x_read_page,
434475
.write_page = rtl821x_write_page,
476+
.read_mmd = rtlgen_read_mmd,
477+
.write_mmd = rtlgen_write_mmd,
435478
}, {
436479
PHY_ID_MATCH_EXACT(0x001cc961),
437480
.name = "RTL8366RB Gigabit Ethernet",

0 commit comments

Comments
 (0)