netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/2] r8169: add EEE support for RTL8168g+
@ 2019-01-25 19:37 Heiner Kallweit
  2019-01-25 19:38 ` [PATCH net-next 1/2] r8169: add general EEE support for chip versions from RTL8168g Heiner Kallweit
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Heiner Kallweit @ 2019-01-25 19:37 UTC (permalink / raw)
  To: Realtek linux nic maintainers, David Miller; +Cc: netdev@vger.kernel.org

This series adds general EEE support to be used with ethtool.
In addition it implements EEE for chip versions from RTL8168g.
The first patch leaves the default chip settings and the
second enables EEE per default. This allows us to revert patch 2
w/o removing EEE support completely if we should face issues with
EEE on particular chip versions.

Unfortunately Realtek decided not to use the standard EEE MMD
registers but to use proprietary registers. Therefore we can't
use phylib functions like phy_ethtool_set_eee and have to
reimplement the functionality.

Tested on a system with RTL8168g (chip version 40).

Heiner Kallweit (2):
  r8169: add general EEE support for chip versions from RTL8168g
  r8169: enable EEE per default on chip versions from RTL8168g

 drivers/net/ethernet/realtek/r8169.c | 216 +++++++++++++++++++++++++--
 1 file changed, 206 insertions(+), 10 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH net-next 1/2] r8169: add general EEE support for chip versions from RTL8168g
  2019-01-25 19:37 [PATCH net-next 0/2] r8169: add EEE support for RTL8168g+ Heiner Kallweit
@ 2019-01-25 19:38 ` Heiner Kallweit
  2019-01-25 19:39 ` [PATCH net-next 2/2] r8169: enable EEE per default on " Heiner Kallweit
  2019-01-26  6:03 ` [PATCH net-next 0/2] r8169: add EEE support for RTL8168g+ David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Heiner Kallweit @ 2019-01-25 19:38 UTC (permalink / raw)
  To: Realtek linux nic maintainers, David Miller; +Cc: netdev@vger.kernel.org

This patch adds the general framework to deal with EEE in this driver
plus EEE support for chip versions from RTL8168g. We don't touch the
default chip settings, therefore EEE will usually be disabled and it's
up to the user to enable it.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/net/ethernet/realtek/r8169.c | 202 +++++++++++++++++++++++++--
 1 file changed, 192 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 83c4663e6..f46bf1187 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -1984,6 +1984,172 @@ static int rtl_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
 	return 0;
 }
 
+static int rtl_get_eee_supp(struct rtl8169_private *tp)
+{
+	struct phy_device *phydev = tp->phydev;
+	int ret;
+
+	switch (tp->mac_version) {
+	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51:
+		phy_write(phydev, 0x1f, 0x0a5c);
+		ret = phy_read(phydev, 0x12);
+		phy_write(phydev, 0x1f, 0x0000);
+		break;
+	default:
+		ret = -EPROTONOSUPPORT;
+		break;
+	}
+
+	return ret;
+}
+
+static int rtl_get_eee_lpadv(struct rtl8169_private *tp)
+{
+	struct phy_device *phydev = tp->phydev;
+	int ret;
+
+	switch (tp->mac_version) {
+	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51:
+		phy_write(phydev, 0x1f, 0x0a5d);
+		ret = phy_read(phydev, 0x11);
+		phy_write(phydev, 0x1f, 0x0000);
+		break;
+	default:
+		ret = -EPROTONOSUPPORT;
+		break;
+	}
+
+	return ret;
+}
+
+static int rtl_get_eee_adv(struct rtl8169_private *tp)
+{
+	struct phy_device *phydev = tp->phydev;
+	int ret;
+
+	switch (tp->mac_version) {
+	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51:
+		phy_write(phydev, 0x1f, 0x0a5d);
+		ret = phy_read(phydev, 0x10);
+		phy_write(phydev, 0x1f, 0x0000);
+		break;
+	default:
+		ret = -EPROTONOSUPPORT;
+		break;
+	}
+
+	return ret;
+}
+
+static int rtl_set_eee_adv(struct rtl8169_private *tp, int val)
+{
+	struct phy_device *phydev = tp->phydev;
+	int ret = 0;
+
+	switch (tp->mac_version) {
+	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51:
+		phy_write(phydev, 0x1f, 0x0a5d);
+		phy_write(phydev, 0x10, val);
+		phy_write(phydev, 0x1f, 0x0000);
+		break;
+	default:
+		ret = -EPROTONOSUPPORT;
+		break;
+	}
+
+	return ret;
+}
+
+static int rtl8169_get_eee(struct net_device *dev, struct ethtool_eee *data)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	struct device *d = tp_to_dev(tp);
+	int ret;
+
+	pm_runtime_get_noresume(d);
+
+	if (!pm_runtime_active(d)) {
+		ret = -EOPNOTSUPP;
+		goto out;
+	}
+
+	/* Get Supported EEE */
+	ret = rtl_get_eee_supp(tp);
+	if (ret < 0)
+		goto out;
+	data->supported = mmd_eee_cap_to_ethtool_sup_t(ret);
+
+	/* Get advertisement EEE */
+	ret = rtl_get_eee_adv(tp);
+	if (ret < 0)
+		goto out;
+	data->advertised = mmd_eee_adv_to_ethtool_adv_t(ret);
+	data->eee_enabled = !!data->advertised;
+
+	/* Get LP advertisement EEE */
+	ret = rtl_get_eee_lpadv(tp);
+	if (ret < 0)
+		goto out;
+	data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(ret);
+	data->eee_active = !!(data->advertised & data->lp_advertised);
+out:
+	pm_runtime_put_noidle(d);
+	return ret < 0 ? ret : 0;
+}
+
+static int rtl8169_set_eee(struct net_device *dev, struct ethtool_eee *data)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	struct device *d = tp_to_dev(tp);
+	int old_adv, adv = 0, cap, ret;
+
+	pm_runtime_get_noresume(d);
+
+	if (!dev->phydev || !pm_runtime_active(d)) {
+		ret = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (dev->phydev->autoneg == AUTONEG_DISABLE ||
+	    dev->phydev->duplex != DUPLEX_FULL) {
+		ret = -EPROTONOSUPPORT;
+		goto out;
+	}
+
+	/* Get Supported EEE */
+	ret = rtl_get_eee_supp(tp);
+	if (ret < 0)
+		goto out;
+	cap = ret;
+
+	ret = rtl_get_eee_adv(tp);
+	if (ret < 0)
+		goto out;
+	old_adv = ret;
+
+	if (data->eee_enabled) {
+		adv = !data->advertised ? cap :
+		      ethtool_adv_to_mmd_eee_adv_t(data->advertised) & cap;
+		/* Mask prohibited EEE modes */
+		adv &= ~dev->phydev->eee_broken_modes;
+	}
+
+	if (old_adv != adv) {
+		ret = rtl_set_eee_adv(tp, adv);
+		if (ret < 0)
+			goto out;
+
+		/* Restart autonegotiation so the new modes get sent to the
+		 * link partner.
+		 */
+		ret = phy_restart_aneg(dev->phydev);
+	}
+
+out:
+	pm_runtime_put_noidle(d);
+	return ret < 0 ? ret : 0;
+}
+
 static const struct ethtool_ops rtl8169_ethtool_ops = {
 	.get_drvinfo		= rtl8169_get_drvinfo,
 	.get_regs_len		= rtl8169_get_regs_len,
@@ -2000,6 +2166,8 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
 	.get_ethtool_stats	= rtl8169_get_ethtool_stats,
 	.get_ts_info		= ethtool_op_get_ts_info,
 	.nway_reset		= phy_ethtool_nway_reset,
+	.get_eee		= rtl8169_get_eee,
+	.set_eee		= rtl8169_set_eee,
 	.get_link_ksettings	= phy_ethtool_get_link_ksettings,
 	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
 };
@@ -2393,6 +2561,18 @@ static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val)
 		rtl_apply_firmware(tp);
 }
 
+static void rtl8168_config_eee_mac(struct rtl8169_private *tp)
+{
+	rtl_w0w1_eri(tp, 0x1b0, ERIAR_MASK_1111, 0x0003, 0x0000, ERIAR_EXGMAC);
+}
+
+static void rtl8168g_config_eee_phy(struct rtl8169_private *tp)
+{
+	phy_write(tp->phydev, 0x1f, 0x0a43);
+	phy_set_bits(tp->phydev, 0x11, BIT(4));
+	phy_write(tp->phydev, 0x1f, 0x0000);
+}
+
 static void rtl8169s_hw_phy_config(struct rtl8169_private *tp)
 {
 	static const struct phy_reg phy_reg_init[] = {
@@ -3442,13 +3622,13 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp)
 	rtl_writephy(tp, 0x14, 0x1065);
 
 	rtl8168g_disable_aldps(tp);
-
-	rtl_writephy(tp, 0x1f, 0x0000);
+	rtl8168g_config_eee_phy(tp);
 }
 
 static void rtl8168g_2_hw_phy_config(struct rtl8169_private *tp)
 {
 	rtl_apply_firmware(tp);
+	rtl8168g_config_eee_phy(tp);
 }
 
 static void rtl8168h_1_hw_phy_config(struct rtl8169_private *tp)
@@ -3554,8 +3734,7 @@ static void rtl8168h_1_hw_phy_config(struct rtl8169_private *tp)
 	rtl_writephy(tp, 0x1f, 0x0000);
 
 	rtl8168g_disable_aldps(tp);
-
-	rtl_writephy(tp, 0x1f, 0x0000);
+	rtl8168g_config_eee_phy(tp);
 }
 
 static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp)
@@ -3624,8 +3803,7 @@ static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp)
 	rtl_writephy(tp, 0x1f, 0x0000);
 
 	rtl8168g_disable_aldps(tp);
-
-	rtl_writephy(tp, 0x1f, 0x0000);
+	rtl8168g_config_eee_phy(tp);
 }
 
 static void rtl8168ep_1_hw_phy_config(struct rtl8169_private *tp)
@@ -3654,8 +3832,7 @@ static void rtl8168ep_1_hw_phy_config(struct rtl8169_private *tp)
 	rtl_writephy(tp, 0x1f, 0x0000);
 
 	rtl8168g_disable_aldps(tp);
-
-	rtl_writephy(tp, 0x1f, 0x0000);
+	rtl8168g_config_eee_phy(tp);
 }
 
 static void rtl8168ep_2_hw_phy_config(struct rtl8169_private *tp)
@@ -3733,8 +3910,7 @@ static void rtl8168ep_2_hw_phy_config(struct rtl8169_private *tp)
 	rtl_writephy(tp, 0x1f, 0x0000);
 
 	rtl8168g_disable_aldps(tp);
-
-	rtl_writephy(tp, 0x1f, 0x0000);
+	rtl8168g_config_eee_phy(tp);
 }
 
 static void rtl8102e_hw_phy_config(struct rtl8169_private *tp)
@@ -5017,6 +5193,8 @@ static void rtl_hw_start_8168g(struct rtl8169_private *tp)
 	/* Adjust EEE LED frequency */
 	RTL_W8(tp, EEE_LED, RTL_R8(tp, EEE_LED) & ~0x07);
 
+	rtl8168_config_eee_mac(tp);
+
 	rtl_w0w1_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x06, ERIAR_EXGMAC);
 	rtl_w0w1_eri(tp, 0x1b0, ERIAR_MASK_0011, 0x0000, 0x1000, ERIAR_EXGMAC);
 
@@ -5119,6 +5297,8 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private *tp)
 	/* Adjust EEE LED frequency */
 	RTL_W8(tp, EEE_LED, RTL_R8(tp, EEE_LED) & ~0x07);
 
+	rtl8168_config_eee_mac(tp);
+
 	RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN);
 	RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN);
 
@@ -5199,6 +5379,8 @@ static void rtl_hw_start_8168ep(struct rtl8169_private *tp)
 	/* Adjust EEE LED frequency */
 	RTL_W8(tp, EEE_LED, RTL_R8(tp, EEE_LED) & ~0x07);
 
+	rtl8168_config_eee_mac(tp);
+
 	rtl_w0w1_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x06, ERIAR_EXGMAC);
 
 	RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH net-next 2/2] r8169: enable EEE per default on chip versions from RTL8168g
  2019-01-25 19:37 [PATCH net-next 0/2] r8169: add EEE support for RTL8168g+ Heiner Kallweit
  2019-01-25 19:38 ` [PATCH net-next 1/2] r8169: add general EEE support for chip versions from RTL8168g Heiner Kallweit
@ 2019-01-25 19:39 ` Heiner Kallweit
  2019-01-26  6:03 ` [PATCH net-next 0/2] r8169: add EEE support for RTL8168g+ David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Heiner Kallweit @ 2019-01-25 19:39 UTC (permalink / raw)
  To: Realtek linux nic maintainers, David Miller; +Cc: netdev@vger.kernel.org

Enable EEE per default on chip versions from RTL8168g.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/net/ethernet/realtek/r8169.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index f46bf1187..9e335d2c7 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -2172,6 +2172,14 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
 	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
 };
 
+static void rtl_enable_eee(struct rtl8169_private *tp)
+{
+	int supported = rtl_get_eee_supp(tp);
+
+	if (supported > 0)
+		rtl_set_eee_adv(tp, supported);
+}
+
 static void rtl8169_get_mac_version(struct rtl8169_private *tp)
 {
 	/*
@@ -3623,12 +3631,14 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp)
 
 	rtl8168g_disable_aldps(tp);
 	rtl8168g_config_eee_phy(tp);
+	rtl_enable_eee(tp);
 }
 
 static void rtl8168g_2_hw_phy_config(struct rtl8169_private *tp)
 {
 	rtl_apply_firmware(tp);
 	rtl8168g_config_eee_phy(tp);
+	rtl_enable_eee(tp);
 }
 
 static void rtl8168h_1_hw_phy_config(struct rtl8169_private *tp)
@@ -3735,6 +3745,7 @@ static void rtl8168h_1_hw_phy_config(struct rtl8169_private *tp)
 
 	rtl8168g_disable_aldps(tp);
 	rtl8168g_config_eee_phy(tp);
+	rtl_enable_eee(tp);
 }
 
 static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp)
@@ -3804,6 +3815,7 @@ static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp)
 
 	rtl8168g_disable_aldps(tp);
 	rtl8168g_config_eee_phy(tp);
+	rtl_enable_eee(tp);
 }
 
 static void rtl8168ep_1_hw_phy_config(struct rtl8169_private *tp)
@@ -3833,6 +3845,7 @@ static void rtl8168ep_1_hw_phy_config(struct rtl8169_private *tp)
 
 	rtl8168g_disable_aldps(tp);
 	rtl8168g_config_eee_phy(tp);
+	rtl_enable_eee(tp);
 }
 
 static void rtl8168ep_2_hw_phy_config(struct rtl8169_private *tp)
@@ -3911,6 +3924,7 @@ static void rtl8168ep_2_hw_phy_config(struct rtl8169_private *tp)
 
 	rtl8168g_disable_aldps(tp);
 	rtl8168g_config_eee_phy(tp);
+	rtl_enable_eee(tp);
 }
 
 static void rtl8102e_hw_phy_config(struct rtl8169_private *tp)
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next 0/2] r8169: add EEE support for RTL8168g+
  2019-01-25 19:37 [PATCH net-next 0/2] r8169: add EEE support for RTL8168g+ Heiner Kallweit
  2019-01-25 19:38 ` [PATCH net-next 1/2] r8169: add general EEE support for chip versions from RTL8168g Heiner Kallweit
  2019-01-25 19:39 ` [PATCH net-next 2/2] r8169: enable EEE per default on " Heiner Kallweit
@ 2019-01-26  6:03 ` David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2019-01-26  6:03 UTC (permalink / raw)
  To: hkallweit1; +Cc: nic_swsd, netdev

From: Heiner Kallweit <hkallweit1@gmail.com>
Date: Fri, 25 Jan 2019 20:37:30 +0100

> This series adds general EEE support to be used with ethtool.
> In addition it implements EEE for chip versions from RTL8168g.
> The first patch leaves the default chip settings and the
> second enables EEE per default. This allows us to revert patch 2
> w/o removing EEE support completely if we should face issues with
> EEE on particular chip versions.
> 
> Unfortunately Realtek decided not to use the standard EEE MMD
> registers but to use proprietary registers. Therefore we can't
> use phylib functions like phy_ethtool_set_eee and have to
> reimplement the functionality.
> 
> Tested on a system with RTL8168g (chip version 40).

Series applied, thanks Heiner.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-01-26  6:03 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-01-25 19:37 [PATCH net-next 0/2] r8169: add EEE support for RTL8168g+ Heiner Kallweit
2019-01-25 19:38 ` [PATCH net-next 1/2] r8169: add general EEE support for chip versions from RTL8168g Heiner Kallweit
2019-01-25 19:39 ` [PATCH net-next 2/2] r8169: enable EEE per default on " Heiner Kallweit
2019-01-26  6:03 ` [PATCH net-next 0/2] r8169: add EEE support for RTL8168g+ David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).