diff mbox series

[V1,4/5] net: fec: add eee mode tx lpi support

Message ID 20210709075355.27218-5-qiangqing.zhang@nxp.com
State Superseded
Headers show
Series net: fec: add support for i.MX8MQ and i.MX8QM | expand

Commit Message

Joakim Zhang July 9, 2021, 7:53 a.m. UTC
From: Fugang Duan <fugang.duan@nxp.com>

The i.MX8MQ ENET version support IEEE802.3az eee mode, add
eee mode tx lpi enable to support ethtool interface.

usage:
1. set sleep and wake timer to 5ms:
ethtool --set-eee eth0 eee on tx-lpi on tx-timer 5000
2. check the eee mode:
~# ethtool --show-eee eth0
EEE Settings for eth0:
        EEE status: enabled - active
        Tx LPI: 5000 (us)
        Supported EEE link modes:  100baseT/Full
                                   1000baseT/Full
        Advertised EEE link modes:  100baseT/Full
                                    1000baseT/Full
        Link partner advertised EEE link modes:  100baseT/Full

Note: For realtime case and IEEE1588 ptp case, it should disable
EEE mode.

Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
---
 drivers/net/ethernet/freescale/fec.h      |  6 ++
 drivers/net/ethernet/freescale/fec_main.c | 89 +++++++++++++++++++++++
 2 files changed, 95 insertions(+)

Comments

Guenter Roeck Aug. 9, 2021, 1:40 a.m. UTC | #1
On Fri, Jul 09, 2021 at 03:53:54PM +0800, Joakim Zhang wrote:
> From: Fugang Duan <fugang.duan@nxp.com>
> 
> The i.MX8MQ ENET version support IEEE802.3az eee mode, add
> eee mode tx lpi enable to support ethtool interface.
> 
> usage:
> 1. set sleep and wake timer to 5ms:
> ethtool --set-eee eth0 eee on tx-lpi on tx-timer 5000
> 2. check the eee mode:
> ~# ethtool --show-eee eth0
> EEE Settings for eth0:
>         EEE status: enabled - active
>         Tx LPI: 5000 (us)
>         Supported EEE link modes:  100baseT/Full
>                                    1000baseT/Full
>         Advertised EEE link modes:  100baseT/Full
>                                     1000baseT/Full
>         Link partner advertised EEE link modes:  100baseT/Full
> 
> Note: For realtime case and IEEE1588 ptp case, it should disable
> EEE mode.
> 
> Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
> Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>

This patch results in:

drivers/net/ethernet/freescale/fec_main.c: In function 'fec_enet_eee_mode_set':
drivers/net/ethernet/freescale/fec_main.c:2801:40: error: 'FEC_LPI_SLEEP' undeclared
drivers/net/ethernet/freescale/fec_main.c:2802:39: error: 'FEC_LPI_WAKE' undeclared

when building m68k:m5272c3_defconfig.

Guenter
Joakim Zhang Aug. 9, 2021, 5:11 a.m. UTC | #2
Hi Guenter,

> -----Original Message-----

> From: Guenter Roeck <groeck7@gmail.com> On Behalf Of Guenter Roeck

> Sent: 2021年8月9日 9:41

> To: Joakim Zhang <qiangqing.zhang@nxp.com>

> Cc: davem@davemloft.net; kuba@kernel.org; robh+dt@kernel.org;

> andrew@lunn.ch; netdev@vger.kernel.org; devicetree@vger.kernel.org;

> linux-kernel@vger.kernel.org; dl-linux-imx <linux-imx@nxp.com>

> Subject: Re: [PATCH V1 4/5] net: fec: add eee mode tx lpi support

> 

> On Fri, Jul 09, 2021 at 03:53:54PM +0800, Joakim Zhang wrote:

> > From: Fugang Duan <fugang.duan@nxp.com>

> >

> > The i.MX8MQ ENET version support IEEE802.3az eee mode, add eee mode tx

> > lpi enable to support ethtool interface.

> >

> > usage:

> > 1. set sleep and wake timer to 5ms:

> > ethtool --set-eee eth0 eee on tx-lpi on tx-timer 5000 2. check the eee

> > mode:

> > ~# ethtool --show-eee eth0

> > EEE Settings for eth0:

> >         EEE status: enabled - active

> >         Tx LPI: 5000 (us)

> >         Supported EEE link modes:  100baseT/Full

> >                                    1000baseT/Full

> >         Advertised EEE link modes:  100baseT/Full

> >                                     1000baseT/Full

> >         Link partner advertised EEE link modes:  100baseT/Full

> >

> > Note: For realtime case and IEEE1588 ptp case, it should disable EEE

> > mode.

> >

> > Signed-off-by: Fugang Duan <fugang.duan@nxp.com>

> > Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>

> 

> This patch results in:

> 

> drivers/net/ethernet/freescale/fec_main.c: In function

> 'fec_enet_eee_mode_set':

> drivers/net/ethernet/freescale/fec_main.c:2801:40: error: 'FEC_LPI_SLEEP'

> undeclared

> drivers/net/ethernet/freescale/fec_main.c:2802:39: error: 'FEC_LPI_WAKE'

> undeclared

> 

> when building m68k:m5272c3_defconfig.


I just sent to patch to fix this build issue, sorry for this inconvenience.

Best Regards,
Joakim Zhang
> Guenter
diff mbox series

Patch

diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index c1f93aa79d63..0a741bc440e4 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -77,6 +77,8 @@ 
 #define FEC_R_DES_ACTIVE_2	0x1e8 /* Rx descriptor active for ring 2 */
 #define FEC_X_DES_ACTIVE_2	0x1ec /* Tx descriptor active for ring 2 */
 #define FEC_QOS_SCHEME		0x1f0 /* Set multi queues Qos scheme */
+#define FEC_LPI_SLEEP		0x1f4 /* Set IEEE802.3az LPI Sleep Ts time */
+#define FEC_LPI_WAKE		0x1f8 /* Set IEEE802.3az LPI Wake Tw time */
 #define FEC_MIIGSK_CFGR		0x300 /* MIIGSK Configuration reg */
 #define FEC_MIIGSK_ENR		0x308 /* MIIGSK Enable reg */
 
@@ -602,6 +604,10 @@  struct fec_enet_private {
 	unsigned int tx_time_itr;
 	unsigned int itr_clk_rate;
 
+	/* tx lpi eee mode */
+	struct ethtool_eee eee;
+	unsigned int clk_ref_rate;
+
 	u32 rx_copybreak;
 
 	/* ptp clock period in ns*/
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index dd0b8715e84e..24082b3f2118 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2722,6 +2722,92 @@  static int fec_enet_set_tunable(struct net_device *netdev,
 	return ret;
 }
 
+/* LPI Sleep Ts count base on tx clk (clk_ref).
+ * The lpi sleep cnt value = X us / (cycle_ns).
+ */
+static int fec_enet_us_to_tx_cycle(struct net_device *ndev, int us)
+{
+	struct fec_enet_private *fep = netdev_priv(ndev);
+
+	return us * (fep->clk_ref_rate / 1000) / 1000;
+}
+
+static int fec_enet_eee_mode_set(struct net_device *ndev, bool enable)
+{
+	struct fec_enet_private *fep = netdev_priv(ndev);
+	struct ethtool_eee *p = &fep->eee;
+	unsigned int sleep_cycle, wake_cycle;
+	int ret = 0;
+
+	if (enable) {
+		ret = phy_init_eee(ndev->phydev, 0);
+		if (ret)
+			return ret;
+
+		sleep_cycle = fec_enet_us_to_tx_cycle(ndev, p->tx_lpi_timer);
+		wake_cycle = sleep_cycle;
+	} else {
+		sleep_cycle = 0;
+		wake_cycle = 0;
+	}
+
+	p->tx_lpi_enabled = enable;
+	p->eee_enabled = enable;
+	p->eee_active = enable;
+
+	writel(sleep_cycle, fep->hwp + FEC_LPI_SLEEP);
+	writel(wake_cycle, fep->hwp + FEC_LPI_WAKE);
+
+	return 0;
+}
+
+static int
+fec_enet_get_eee(struct net_device *ndev, struct ethtool_eee *edata)
+{
+	struct fec_enet_private *fep = netdev_priv(ndev);
+	struct ethtool_eee *p = &fep->eee;
+
+	if (!(fep->quirks & FEC_QUIRK_HAS_EEE))
+		return -EOPNOTSUPP;
+
+	if (!netif_running(ndev))
+		return -ENETDOWN;
+
+	edata->eee_enabled = p->eee_enabled;
+	edata->eee_active = p->eee_active;
+	edata->tx_lpi_timer = p->tx_lpi_timer;
+	edata->tx_lpi_enabled = p->tx_lpi_enabled;
+
+	return phy_ethtool_get_eee(ndev->phydev, edata);
+}
+
+static int
+fec_enet_set_eee(struct net_device *ndev, struct ethtool_eee *edata)
+{
+	struct fec_enet_private *fep = netdev_priv(ndev);
+	struct ethtool_eee *p = &fep->eee;
+	int ret = 0;
+
+	if (!(fep->quirks & FEC_QUIRK_HAS_EEE))
+		return -EOPNOTSUPP;
+
+	if (!netif_running(ndev))
+		return -ENETDOWN;
+
+	p->tx_lpi_timer = edata->tx_lpi_timer;
+
+	if (!edata->eee_enabled || !edata->tx_lpi_enabled ||
+	    !edata->tx_lpi_timer)
+		ret = fec_enet_eee_mode_set(ndev, false);
+	else
+		ret = fec_enet_eee_mode_set(ndev, true);
+
+	if (ret)
+		return ret;
+
+	return phy_ethtool_set_eee(ndev->phydev, edata);
+}
+
 static void
 fec_enet_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
 {
@@ -2782,6 +2868,8 @@  static const struct ethtool_ops fec_enet_ethtool_ops = {
 	.set_tunable		= fec_enet_set_tunable,
 	.get_wol		= fec_enet_get_wol,
 	.set_wol		= fec_enet_set_wol,
+	.get_eee		= fec_enet_get_eee,
+	.set_eee		= fec_enet_set_eee,
 	.get_link_ksettings	= phy_ethtool_get_link_ksettings,
 	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
 	.self_test		= net_selftest,
@@ -3722,6 +3810,7 @@  fec_probe(struct platform_device *pdev)
 	fep->clk_ref = devm_clk_get(&pdev->dev, "enet_clk_ref");
 	if (IS_ERR(fep->clk_ref))
 		fep->clk_ref = NULL;
+	fep->clk_ref_rate = clk_get_rate(fep->clk_ref);
 
 	fep->bufdesc_ex = fep->quirks & FEC_QUIRK_HAS_BUFDESC_EX;
 	fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp");