All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC/RFT 00/23] net: ethernet: Rework EEE
@ 2023-03-27 17:01 Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 01/23] net: phy: Add phydev->eee_active to simplify adjust link callbacks Andrew Lunn
                   ` (22 more replies)
  0 siblings, 23 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

Most MAC drivers get EEE wrong. The API to the PHY is not very
obvious, which is probably why. Rework the API, pushing most of the
EEE handling into phylib core, leaving the MAC drivers to just
enable/disable support for EEE in there change_link call back, or
phylink mac_link_up callback.

MAC drivers are now expect to indicate to phylib/phylink if they
support EEE. If not, no EEE link modes are advertised. If the MAC does
support EEE, on phy_start()/phylink_start() EEE advertisement is
configured.

There is some overlap here with the addition of SMART EEE. This needs
to be solved before either patchset is merged. This patchset is also
large, so might need splitting into adding new infrastructure,
migrating MAC drivers, removing old code.

I deliberately reduced the Cc: list down to just a few developers, who
i hope can test the core and a couple of the MAC drivers, and review
if the new API makes sense, before the other MAC drivers are reviewed.

Andrew Lunn (23):
  net: phy: Add phydev->eee_active to simplify adjust link callbacks
  net: phylink: Plumb eee_active in mac_link_up call
  net: phy: Add helper to set EEE Clock stop enable bit
  net: phy: Keep track of EEE tx_lpi_enabled
  net: phy: Immediately call adjust_link if only tx_lpi_enabled changes
  net: marvell: mvneta: Simplify EEE configuration
  net: stmmac: Drop usage of phy_init_eee()
  net: stmmac: Simplify ethtool get eee
  net: lan743x: Fixup EEE
  net: fec: Move fec_enet_eee_mode_set() and helper earlier
  net: FEC: Fixup EEE
  net: genet: Fixup EEE
  net: sxgdb: Fixup EEE
  net: dsa: mt7530: Swap to using phydev->eee_active
  net: dsa: b53: Swap to using phydev->eee_active
  net: phylink: Remove unused phylink_init_eee()
  net: phy: remove unused phy_init_eee()
  net: usb: lan78xx: Fixup EEE
  net: phy: Add phy_support_eee() indicating MAC support EEE
  net: phylink: Add MAC_EEE to mac_capabilites
  net: phylink: Extend mac_capabilities in MAC drivers which support EEE
  net: phylib: call phy_support_eee() in MAC drivers which support EEE
  net: phy: Disable EEE advertisement by default

 drivers/net/dsa/b53/b53_common.c              |  8 +-
 drivers/net/dsa/b53/b53_priv.h                |  3 +-
 drivers/net/dsa/bcm_sf2.c                     |  3 +-
 drivers/net/dsa/lan9303-core.c                |  2 +-
 drivers/net/dsa/lantiq_gswip.c                |  3 +-
 drivers/net/dsa/microchip/ksz_common.c        | 10 ++-
 drivers/net/dsa/microchip/ksz_common.h        |  3 +-
 drivers/net/dsa/mt7530.c                      |  8 +-
 drivers/net/dsa/mv88e6xxx/chip.c              |  3 +-
 drivers/net/dsa/ocelot/felix.c                |  3 +-
 drivers/net/dsa/qca/ar9331.c                  |  3 +-
 drivers/net/dsa/qca/qca8k-8xxx.c              |  3 +-
 drivers/net/dsa/realtek/rtl8365mb.c           |  2 +-
 drivers/net/dsa/realtek/rtl8366rb.c           |  3 +-
 drivers/net/dsa/rzn1_a5psw.c                  |  3 +-
 drivers/net/dsa/sja1105/sja1105_main.c        |  3 +-
 drivers/net/dsa/xrs700x/xrs700x.c             |  3 +-
 drivers/net/ethernet/altera/altera_tse_main.c |  3 +-
 drivers/net/ethernet/atheros/ag71xx.c         |  3 +-
 .../net/ethernet/broadcom/genet/bcmgenet.c    | 42 +++------
 .../net/ethernet/broadcom/genet/bcmgenet.h    |  3 +-
 drivers/net/ethernet/broadcom/genet/bcmmii.c  |  3 +
 drivers/net/ethernet/cadence/macb_main.c      |  3 +-
 .../net/ethernet/freescale/dpaa2/dpaa2-mac.c  |  3 +-
 .../net/ethernet/freescale/enetc/enetc_pf.c   |  3 +-
 drivers/net/ethernet/freescale/fec_main.c     | 88 ++++++++-----------
 .../net/ethernet/freescale/fman/fman_dtsec.c  |  3 +-
 .../net/ethernet/freescale/fman/fman_memac.c  |  3 +-
 .../net/ethernet/freescale/fman/fman_tgec.c   |  3 +-
 drivers/net/ethernet/marvell/mvneta.c         | 24 ++---
 .../net/ethernet/marvell/mvpp2/mvpp2_main.c   |  5 +-
 .../ethernet/marvell/prestera/prestera_main.c |  3 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  3 +-
 .../net/ethernet/microchip/lan743x_ethtool.c  | 22 -----
 drivers/net/ethernet/microchip/lan743x_main.c |  9 ++
 .../microchip/lan966x/lan966x_phylink.c       |  3 +-
 .../microchip/sparx5/sparx5_phylink.c         |  3 +-
 drivers/net/ethernet/mscc/ocelot_net.c        |  3 +-
 .../net/ethernet/samsung/sxgbe/sxgbe_common.h |  3 -
 .../ethernet/samsung/sxgbe/sxgbe_ethtool.c    | 21 +----
 .../net/ethernet/samsung/sxgbe/sxgbe_main.c   | 39 +++-----
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  1 -
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c  |  7 --
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 13 +--
 drivers/net/ethernet/ti/am65-cpsw-nuss.c      |  3 +-
 .../net/ethernet/xilinx/xilinx_axienet_main.c |  3 +-
 drivers/net/phy/phy-c45.c                     | 11 ++-
 drivers/net/phy/phy-core.c                    | 11 +++
 drivers/net/phy/phy.c                         | 57 ++++++------
 drivers/net/phy/phy_device.c                  | 37 ++++----
 drivers/net/phy/phylink.c                     | 37 ++++----
 drivers/net/usb/asix_devices.c                |  2 +-
 drivers/net/usb/lan78xx.c                     | 38 ++++----
 include/linux/phy.h                           | 10 ++-
 include/linux/phylink.h                       | 25 +++---
 include/net/dsa.h                             |  3 +-
 net/dsa/port.c                                |  9 +-
 57 files changed, 295 insertions(+), 336 deletions(-)

-- 
2.39.2


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

* [RFC/RFT 01/23] net: phy: Add phydev->eee_active to simplify adjust link callbacks
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:54   ` Russell King (Oracle)
  2023-03-27 17:01 ` [RFC/RFT 02/23] net: phylink: Plumb eee_active in mac_link_up call Andrew Lunn
                   ` (21 subsequent siblings)
  22 siblings, 1 reply; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

MAC drivers which support EEE need to know the results of the EEE
auto-neg in order to program the hardware to perform EEE or not.  The
oddly named phy_init_eee() can be used to determine this, it returns 0
if EEE should be used, or a negative error code,
e.g. -EOPPROTONOTSUPPORT if the PHY does not support EEE or negotiate
resulted in it not being used.

However, many MAC drivers get this wrong. Add phydev->eee_active which
indicates the result of the autoneg for EEE, including if EEE is
administratively disabled with ethtool. The MAC driver can then access
this in the same way as link speed and duplex in the adjust link
callback.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
v2 Check for errors from genphy_c45_eee_is_active
---
 drivers/net/phy/phy.c | 7 +++++++
 include/linux/phy.h   | 2 ++
 2 files changed, 9 insertions(+)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 0c0df38cd1ab..68e1ce942dd6 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -928,9 +928,16 @@ static int phy_check_link_status(struct phy_device *phydev)
 	if (phydev->link && phydev->state != PHY_RUNNING) {
 		phy_check_downshift(phydev);
 		phydev->state = PHY_RUNNING;
+		err = genphy_c45_eee_is_active(phydev,
+					       NULL, NULL, NULL);
+		if (err < 0)
+			phydev->eee_active = false;
+		else
+			phydev->eee_active = err;
 		phy_link_up(phydev);
 	} else if (!phydev->link && phydev->state != PHY_NOLINK) {
 		phydev->state = PHY_NOLINK;
+		phydev->eee_active = false;
 		phy_link_down(phydev);
 	}
 
diff --git a/include/linux/phy.h b/include/linux/phy.h
index fefd5091bc24..5cc2dcb17eb0 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -577,6 +577,7 @@ struct macsec_ops;
  * @supported_eee: supported PHY EEE linkmodes
  * @advertising_eee: Currently advertised EEE linkmodes
  * @eee_enabled: Flag indicating whether the EEE feature is enabled
+ * @eee_active: EEE is active for the current link mode
  * @lp_advertising: Current link partner advertised linkmodes
  * @host_interfaces: PHY interface modes supported by host
  * @eee_broken_modes: Energy efficient ethernet modes which should be prohibited
@@ -691,6 +692,7 @@ struct phy_device {
 
 	/* Energy efficient ethernet modes which should be prohibited */
 	u32 eee_broken_modes;
+	bool eee_active;
 
 #ifdef CONFIG_LED_TRIGGER_PHY
 	struct phy_led_trigger *phy_led_triggers;
-- 
2.39.2


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

* [RFC/RFT 02/23] net: phylink: Plumb eee_active in mac_link_up call
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 01/23] net: phy: Add phydev->eee_active to simplify adjust link callbacks Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:57   ` Russell King (Oracle)
  2023-03-27 21:53   ` Russell King (Oracle)
  2023-03-27 17:01 ` [RFC/RFT 03/23] net: phy: Add helper to set EEE Clock stop enable bit Andrew Lunn
                   ` (20 subsequent siblings)
  22 siblings, 2 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

MAC drivers need to know the result of the auto negotiation of Energy
Efficient Ethernet. This is a simple boolean, it should be active or
not in the MAC. Extend the mac_link_up call to pass this.

Currently the correct value should be passed, however no MAC drivers
have been modified to actually use it. Yet.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/b53/b53_common.c              |  3 ++-
 drivers/net/dsa/b53/b53_priv.h                |  3 ++-
 drivers/net/dsa/bcm_sf2.c                     |  3 ++-
 drivers/net/dsa/lan9303-core.c                |  2 +-
 drivers/net/dsa/lantiq_gswip.c                |  3 ++-
 drivers/net/dsa/microchip/ksz_common.c        | 10 +++++----
 drivers/net/dsa/microchip/ksz_common.h        |  3 ++-
 drivers/net/dsa/mt7530.c                      |  6 ++++--
 drivers/net/dsa/mv88e6xxx/chip.c              |  3 ++-
 drivers/net/dsa/ocelot/felix.c                |  3 ++-
 drivers/net/dsa/qca/ar9331.c                  |  3 ++-
 drivers/net/dsa/qca/qca8k-8xxx.c              |  3 ++-
 drivers/net/dsa/realtek/rtl8365mb.c           |  2 +-
 drivers/net/dsa/realtek/rtl8366rb.c           |  3 ++-
 drivers/net/dsa/rzn1_a5psw.c                  |  3 ++-
 drivers/net/dsa/sja1105/sja1105_main.c        |  3 ++-
 drivers/net/dsa/xrs700x/xrs700x.c             |  3 ++-
 drivers/net/ethernet/altera/altera_tse_main.c |  3 ++-
 drivers/net/ethernet/atheros/ag71xx.c         |  3 ++-
 drivers/net/ethernet/cadence/macb_main.c      |  3 ++-
 .../net/ethernet/freescale/dpaa2/dpaa2-mac.c  |  3 ++-
 .../net/ethernet/freescale/enetc/enetc_pf.c   |  3 ++-
 .../net/ethernet/freescale/fman/fman_dtsec.c  |  3 ++-
 .../net/ethernet/freescale/fman/fman_memac.c  |  3 ++-
 .../net/ethernet/freescale/fman/fman_tgec.c   |  3 ++-
 drivers/net/ethernet/marvell/mvneta.c         |  3 ++-
 .../net/ethernet/marvell/mvpp2/mvpp2_main.c   |  5 +++--
 .../ethernet/marvell/prestera/prestera_main.c |  3 ++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  3 ++-
 .../microchip/lan966x/lan966x_phylink.c       |  3 ++-
 .../microchip/sparx5/sparx5_phylink.c         |  3 ++-
 drivers/net/ethernet/mscc/ocelot_net.c        |  3 ++-
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  3 ++-
 drivers/net/ethernet/ti/am65-cpsw-nuss.c      |  3 ++-
 .../net/ethernet/xilinx/xilinx_axienet_main.c |  3 ++-
 drivers/net/phy/phy-core.c                    | 11 ++++++++++
 drivers/net/phy/phylink.c                     | 16 +++++++++++---
 drivers/net/usb/asix_devices.c                |  2 +-
 include/linux/phy.h                           |  1 +
 include/linux/phylink.h                       | 21 +++++++++++--------
 include/net/dsa.h                             |  3 ++-
 net/dsa/port.c                                |  6 ++++--
 42 files changed, 119 insertions(+), 56 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 3464ce5e7470..aa3fd3c1b15e 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1445,7 +1445,8 @@ void b53_phylink_mac_link_up(struct dsa_switch *ds, int port,
 			     phy_interface_t interface,
 			     struct phy_device *phydev,
 			     int speed, int duplex,
-			     bool tx_pause, bool rx_pause)
+			     bool tx_pause, bool rx_pause,
+			     bool eee_active)
 {
 	struct b53_device *dev = ds->priv;
 
diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
index fdcfd5081c28..ed7d695de3ac 100644
--- a/drivers/net/dsa/b53/b53_priv.h
+++ b/drivers/net/dsa/b53/b53_priv.h
@@ -363,7 +363,8 @@ void b53_phylink_mac_link_up(struct dsa_switch *ds, int port,
 			     phy_interface_t interface,
 			     struct phy_device *phydev,
 			     int speed, int duplex,
-			     bool tx_pause, bool rx_pause);
+			     bool tx_pause, bool rx_pause,
+			     bool eee_active);
 int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
 		       struct netlink_ext_ack *extack);
 int b53_vlan_add(struct dsa_switch *ds, int port,
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index cde253d27bd0..72be649d4bc9 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -828,7 +828,8 @@ static void bcm_sf2_sw_mac_link_up(struct dsa_switch *ds, int port,
 				   phy_interface_t interface,
 				   struct phy_device *phydev,
 				   int speed, int duplex,
-				   bool tx_pause, bool rx_pause)
+				   bool tx_pause, bool rx_pause,
+				   bool eee_active)
 {
 	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
 	struct ethtool_eee *p = &priv->dev->ports[port].eee;
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index cbe831875347..e112a423f1a9 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -1307,7 +1307,7 @@ static void lan9303_phylink_mac_link_up(struct dsa_switch *ds, int port,
 					phy_interface_t interface,
 					struct phy_device *phydev, int speed,
 					int duplex, bool tx_pause,
-					bool rx_pause)
+					bool rx_pause, bool eee_active)
 {
 	struct lan9303 *chip = ds->priv;
 	u32 ctl;
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
index 3c76a1a14aee..9bd9b5f23280 100644
--- a/drivers/net/dsa/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq_gswip.c
@@ -1736,7 +1736,8 @@ static void gswip_phylink_mac_link_up(struct dsa_switch *ds, int port,
 				      phy_interface_t interface,
 				      struct phy_device *phydev,
 				      int speed, int duplex,
-				      bool tx_pause, bool rx_pause)
+				      bool tx_pause, bool rx_pause,
+				      bool eee_active)
 {
 	struct gswip_priv *priv = ds->priv;
 
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 50fd548c72d8..3886b53f77d5 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -221,7 +221,7 @@ static void ksz9477_phylink_mac_link_up(struct ksz_device *dev, int port,
 					phy_interface_t interface,
 					struct phy_device *phydev, int speed,
 					int duplex, bool tx_pause,
-					bool rx_pause);
+					bool rx_pause, bool eee_active);
 
 static const struct ksz_dev_ops ksz9477_dev_ops = {
 	.setup = ksz9477_setup,
@@ -2950,7 +2950,7 @@ static void ksz9477_phylink_mac_link_up(struct ksz_device *dev, int port,
 					phy_interface_t interface,
 					struct phy_device *phydev, int speed,
 					int duplex, bool tx_pause,
-					bool rx_pause)
+					bool rx_pause, bool eee_active)
 {
 	struct ksz_port *p;
 
@@ -2971,14 +2971,16 @@ static void ksz_phylink_mac_link_up(struct dsa_switch *ds, int port,
 				    unsigned int mode,
 				    phy_interface_t interface,
 				    struct phy_device *phydev, int speed,
-				    int duplex, bool tx_pause, bool rx_pause)
+				    int duplex, bool tx_pause, bool rx_pause,
+				    bool eee_active)
 {
 	struct ksz_device *dev = ds->priv;
 
 	if (dev->dev_ops->phylink_mac_link_up)
 		dev->dev_ops->phylink_mac_link_up(dev, port, mode, interface,
 						  phydev, speed, duplex,
-						  tx_pause, rx_pause);
+						  tx_pause, rx_pause,
+						  eee_active);
 }
 
 static int ksz_switch_detect(struct ksz_device *dev)
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index 8abecaf6089e..f190716264db 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -354,7 +354,8 @@ struct ksz_dev_ops {
 				    unsigned int mode,
 				    phy_interface_t interface,
 				    struct phy_device *phydev, int speed,
-				    int duplex, bool tx_pause, bool rx_pause);
+				    int duplex, bool tx_pause, bool rx_pause,
+				    bool eee_active);
 	void (*setup_rgmii_delay)(struct ksz_device *dev, int port);
 	int (*tc_cbs_set_cinc)(struct ksz_device *dev, int port, u32 val);
 	void (*config_cpu_port)(struct dsa_switch *ds);
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index a0d99af897ac..6c89026ec966 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2721,7 +2721,8 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
 				       phy_interface_t interface,
 				       struct phy_device *phydev,
 				       int speed, int duplex,
-				       bool tx_pause, bool rx_pause)
+				       bool tx_pause, bool rx_pause,
+				       bool eee_active)
 {
 	struct mt7530_priv *priv = ds->priv;
 	u32 mcr;
@@ -2806,7 +2807,8 @@ mt7531_cpu_port_config(struct dsa_switch *ds, int port)
 	mt753x_phylink_pcs_link_up(&priv->pcs[port].pcs, MLO_AN_FIXED,
 				   interface, speed, DUPLEX_FULL);
 	mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
-				   speed, DUPLEX_FULL, true, true);
+				   speed, DUPLEX_FULL, true, true,
+				   false);
 
 	return 0;
 }
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index b73d1d6747b7..7591f33b5993 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -932,7 +932,8 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
 				  unsigned int mode, phy_interface_t interface,
 				  struct phy_device *phydev,
 				  int speed, int duplex,
-				  bool tx_pause, bool rx_pause)
+				  bool tx_pause, bool rx_pause,
+				  bool eee_active)
 {
 	struct mv88e6xxx_chip *chip = ds->priv;
 	const struct mv88e6xxx_ops *ops;
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index 6dcebcfd71e7..63cd8ea4c22f 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -1099,7 +1099,8 @@ static void felix_phylink_mac_link_up(struct dsa_switch *ds, int port,
 				      phy_interface_t interface,
 				      struct phy_device *phydev,
 				      int speed, int duplex,
-				      bool tx_pause, bool rx_pause)
+				      bool tx_pause, bool rx_pause,
+				      bool eee_active)
 {
 	struct ocelot *ocelot = ds->priv;
 	struct felix *felix = ocelot_to_felix(ocelot);
diff --git a/drivers/net/dsa/qca/ar9331.c b/drivers/net/dsa/qca/ar9331.c
index e7b98b864fa1..c3f831a6b9a7 100644
--- a/drivers/net/dsa/qca/ar9331.c
+++ b/drivers/net/dsa/qca/ar9331.c
@@ -560,7 +560,8 @@ static void ar9331_sw_phylink_mac_link_up(struct dsa_switch *ds, int port,
 					  phy_interface_t interface,
 					  struct phy_device *phydev,
 					  int speed, int duplex,
-					  bool tx_pause, bool rx_pause)
+					  bool tx_pause, bool rx_pause,
+					  bool eee_active)
 {
 	struct ar9331_sw_priv *priv = (struct ar9331_sw_priv *)ds->priv;
 	struct ar9331_sw_port *p = &priv->port[port];
diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
index 62810903f1b3..a7f9fcbf896d 100644
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
@@ -1424,7 +1424,8 @@ qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
 static void
 qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode,
 			  phy_interface_t interface, struct phy_device *phydev,
-			  int speed, int duplex, bool tx_pause, bool rx_pause)
+			  int speed, int duplex, bool tx_pause, bool rx_pause,
+			  bool eee_active)
 {
 	struct qca8k_priv *priv = ds->priv;
 	u32 reg;
diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
index 41ea3b5a42b1..34b5bbfe60bb 100644
--- a/drivers/net/dsa/realtek/rtl8365mb.c
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
@@ -1113,7 +1113,7 @@ static void rtl8365mb_phylink_mac_link_up(struct dsa_switch *ds, int port,
 					  phy_interface_t interface,
 					  struct phy_device *phydev, int speed,
 					  int duplex, bool tx_pause,
-					  bool rx_pause)
+					  bool rx_pause, bool eee_active)
 {
 	struct realtek_priv *priv = ds->priv;
 	struct rtl8365mb_port *p;
diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
index 25f88022b9e4..3d1982bc8748 100644
--- a/drivers/net/dsa/realtek/rtl8366rb.c
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
@@ -1052,7 +1052,8 @@ static enum dsa_tag_protocol rtl8366_get_tag_protocol(struct dsa_switch *ds,
 static void
 rtl8366rb_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode,
 		      phy_interface_t interface, struct phy_device *phydev,
-		      int speed, int duplex, bool tx_pause, bool rx_pause)
+		      int speed, int duplex, bool tx_pause, bool rx_pause,
+		      bool eee_active)
 {
 	struct realtek_priv *priv = ds->priv;
 	int ret;
diff --git a/drivers/net/dsa/rzn1_a5psw.c b/drivers/net/dsa/rzn1_a5psw.c
index 919027cf2012..d9d35258b9a5 100644
--- a/drivers/net/dsa/rzn1_a5psw.c
+++ b/drivers/net/dsa/rzn1_a5psw.c
@@ -251,7 +251,8 @@ static void a5psw_phylink_mac_link_up(struct dsa_switch *ds, int port,
 				      unsigned int mode,
 				      phy_interface_t interface,
 				      struct phy_device *phydev, int speed,
-				      int duplex, bool tx_pause, bool rx_pause)
+				      int duplex, bool tx_pause, bool rx_pause,
+				      bool eee_active)
 {
 	u32 cmd_cfg = A5PSW_CMD_CFG_RX_ENA | A5PSW_CMD_CFG_TX_ENA |
 		      A5PSW_CMD_CFG_TX_CRC_APPEND;
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index b70dcf32a26d..5475e81a4f4c 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1380,7 +1380,8 @@ static void sja1105_mac_link_up(struct dsa_switch *ds, int port,
 				phy_interface_t interface,
 				struct phy_device *phydev,
 				int speed, int duplex,
-				bool tx_pause, bool rx_pause)
+				bool tx_pause, bool rx_pause,
+				bool eee_active)
 {
 	struct sja1105_private *priv = ds->priv;
 
diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c
index fa622639d640..f6ca6360b517 100644
--- a/drivers/net/dsa/xrs700x/xrs700x.c
+++ b/drivers/net/dsa/xrs700x/xrs700x.c
@@ -470,7 +470,8 @@ static void xrs700x_mac_link_up(struct dsa_switch *ds, int port,
 				unsigned int mode, phy_interface_t interface,
 				struct phy_device *phydev,
 				int speed, int duplex,
-				bool tx_pause, bool rx_pause)
+				bool tx_pause, bool rx_pause,
+				bool eee_active)
 {
 	struct xrs700x *priv = ds->priv;
 	unsigned int val;
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c
index 66e3af73ec41..cbd8c067163a 100644
--- a/drivers/net/ethernet/altera/altera_tse_main.c
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -1060,7 +1060,8 @@ static void alt_tse_mac_link_down(struct phylink_config *config,
 static void alt_tse_mac_link_up(struct phylink_config *config,
 				struct phy_device *phy, unsigned int mode,
 				phy_interface_t interface, int speed,
-				int duplex, bool tx_pause, bool rx_pause)
+				int duplex, bool tx_pause, bool rx_pause,
+				bool eee_active)
 {
 	struct net_device *ndev = to_net_dev(config->dev);
 	struct altera_tse_private *priv = netdev_priv(ndev);
diff --git a/drivers/net/ethernet/atheros/ag71xx.c b/drivers/net/ethernet/atheros/ag71xx.c
index ff1a5edf8df1..0e077342dc0e 100644
--- a/drivers/net/ethernet/atheros/ag71xx.c
+++ b/drivers/net/ethernet/atheros/ag71xx.c
@@ -1036,7 +1036,8 @@ static void ag71xx_mac_link_up(struct phylink_config *config,
 			       struct phy_device *phy,
 			       unsigned int mode, phy_interface_t interface,
 			       int speed, int duplex,
-			       bool tx_pause, bool rx_pause)
+			       bool tx_pause, bool rx_pause,
+			       bool eee_active)
 {
 	struct ag71xx *ag = netdev_priv(to_net_dev(config->dev));
 	u32 cfg1, cfg2;
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index f77bd1223c8f..26e53125fb78 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -719,7 +719,8 @@ static void macb_mac_link_up(struct phylink_config *config,
 			     struct phy_device *phy,
 			     unsigned int mode, phy_interface_t interface,
 			     int speed, int duplex,
-			     bool tx_pause, bool rx_pause)
+			     bool tx_pause, bool rx_pause,
+			     bool eee_active)
 {
 	struct net_device *ndev = to_net_dev(config->dev);
 	struct macb *bp = netdev_priv(ndev);
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
index b1871e6c4006..8451fa6fb011 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
@@ -189,7 +189,8 @@ static void dpaa2_mac_link_up(struct phylink_config *config,
 			      struct phy_device *phy,
 			      unsigned int mode, phy_interface_t interface,
 			      int speed, int duplex,
-			      bool tx_pause, bool rx_pause)
+			      bool tx_pause, bool rx_pause,
+			      bool eee_active)
 {
 	struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
 	struct dpmac_link_state *dpmac_state = &mac->state;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index 7cd22d370caa..7defd16c84dc 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -1017,7 +1017,8 @@ static void enetc_force_rgmii_mac(struct enetc_si *si, int speed, int duplex)
 static void enetc_pl_mac_link_up(struct phylink_config *config,
 				 struct phy_device *phy, unsigned int mode,
 				 phy_interface_t interface, int speed,
-				 int duplex, bool tx_pause, bool rx_pause)
+				 int duplex, bool tx_pause, bool rx_pause,
+				 bool eee_active)
 {
 	struct enetc_pf *pf = phylink_to_enetc_pf(config);
 	u32 pause_off_thresh = 0, pause_on_thresh = 0;
diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.c b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
index d528ca681b6f..89510aed4aad 100644
--- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
@@ -928,7 +928,8 @@ static void dtsec_mac_config(struct phylink_config *config, unsigned int mode,
 
 static void dtsec_link_up(struct phylink_config *config, struct phy_device *phy,
 			  unsigned int mode, phy_interface_t interface,
-			  int speed, int duplex, bool tx_pause, bool rx_pause)
+			  int speed, int duplex, bool tx_pause, bool rx_pause,
+			  bool eee_active)
 {
 	struct mac_device *mac_dev = fman_config_to_mac(config);
 	struct fman_mac *dtsec = mac_dev->fman_mac;
diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c
index 625c79d5636f..f247d205da4f 100644
--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
@@ -712,7 +712,8 @@ static void memac_mac_config(struct phylink_config *config, unsigned int mode,
 
 static void memac_link_up(struct phylink_config *config, struct phy_device *phy,
 			  unsigned int mode, phy_interface_t interface,
-			  int speed, int duplex, bool tx_pause, bool rx_pause)
+			  int speed, int duplex, bool tx_pause, bool rx_pause,
+			  bool eee_active)
 {
 	struct mac_device *mac_dev = fman_config_to_mac(config);
 	struct fman_mac *memac = mac_dev->fman_mac;
diff --git a/drivers/net/ethernet/freescale/fman/fman_tgec.c b/drivers/net/ethernet/freescale/fman/fman_tgec.c
index c2261d26db5b..a8655d155382 100644
--- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
+++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c
@@ -438,7 +438,8 @@ static void tgec_mac_config(struct phylink_config *config, unsigned int mode,
 
 static void tgec_link_up(struct phylink_config *config, struct phy_device *phy,
 			 unsigned int mode, phy_interface_t interface,
-			 int speed, int duplex, bool tx_pause, bool rx_pause)
+			 int speed, int duplex, bool tx_pause, bool rx_pause,
+			 bool eee_active)
 {
 	struct mac_device *mac_dev = fman_config_to_mac(config);
 	struct fman_mac *tgec = mac_dev->fman_mac;
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 0e39d199ff06..cebd3848a228 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -4178,7 +4178,8 @@ static void mvneta_mac_link_up(struct phylink_config *config,
 			       struct phy_device *phy,
 			       unsigned int mode, phy_interface_t interface,
 			       int speed, int duplex,
-			       bool tx_pause, bool rx_pause)
+			       bool tx_pause, bool rx_pause,
+			       bool eee_active)
 {
 	struct net_device *ndev = to_net_dev(config->dev);
 	struct mvneta_port *pp = netdev_priv(ndev);
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index adc953611913..860f43e8c4e4 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -6517,7 +6517,8 @@ static void mvpp2_mac_link_up(struct phylink_config *config,
 			      struct phy_device *phy,
 			      unsigned int mode, phy_interface_t interface,
 			      int speed, int duplex,
-			      bool tx_pause, bool rx_pause)
+			      bool tx_pause, bool rx_pause,
+			      bool eee_active)
 {
 	struct mvpp2_port *port = mvpp2_phylink_to_port(config);
 	u32 val;
@@ -6655,7 +6656,7 @@ static void mvpp2_acpi_start(struct mvpp2_port *port)
 			 port->phy_interface);
 	mvpp2_mac_link_up(&port->phylink_config, NULL,
 			  MLO_AN_INBAND, port->phy_interface,
-			  SPEED_UNKNOWN, DUPLEX_UNKNOWN, false, false);
+			  SPEED_UNKNOWN, DUPLEX_UNKNOWN, false, false, false);
 }
 
 /* In order to ensure backward compatibility for ACPI, check if the port
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_main.c b/drivers/net/ethernet/marvell/prestera/prestera_main.c
index 9d504142e51a..5f5bc3bac4c7 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_main.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c
@@ -265,7 +265,8 @@ static void prestera_mac_link_up(struct phylink_config *config,
 				 struct phy_device *phy,
 				 unsigned int mode, phy_interface_t interface,
 				 int speed, int duplex,
-				 bool tx_pause, bool rx_pause)
+				 bool tx_pause, bool rx_pause,
+				 bool eee_active)
 {
 }
 
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 4403d3bbfd4d..9f25aac84703 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -717,7 +717,8 @@ static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
 static void mtk_mac_link_up(struct phylink_config *config,
 			    struct phy_device *phy,
 			    unsigned int mode, phy_interface_t interface,
-			    int speed, int duplex, bool tx_pause, bool rx_pause)
+			    int speed, int duplex, bool tx_pause, bool rx_pause,
+			    bool eee_active)
 {
 	struct mtk_mac *mac = container_of(config, struct mtk_mac,
 					   phylink_config);
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c b/drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c
index c5f9803e6e63..01188b6870f8 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c
@@ -48,7 +48,8 @@ static void lan966x_phylink_mac_link_up(struct phylink_config *config,
 					unsigned int mode,
 					phy_interface_t interface,
 					int speed, int duplex,
-					bool tx_pause, bool rx_pause)
+					bool tx_pause, bool rx_pause,
+					bool eee_active)
 {
 	struct lan966x_port *port = netdev_priv(to_net_dev(config->dev));
 	struct lan966x_port_config *port_config = &port->config;
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
index bb97d27a1da4..e5895be3d722 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
@@ -47,7 +47,8 @@ static void sparx5_phylink_mac_link_up(struct phylink_config *config,
 				       unsigned int mode,
 				       phy_interface_t interface,
 				       int speed, int duplex,
-				       bool tx_pause, bool rx_pause)
+				       bool tx_pause, bool rx_pause,
+				       bool eee_active)
 {
 	struct sparx5_port *port = netdev_priv(to_net_dev(config->dev));
 	struct sparx5_port_config conf;
diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
index 21a87a3fc556..574c147009b1 100644
--- a/drivers/net/ethernet/mscc/ocelot_net.c
+++ b/drivers/net/ethernet/mscc/ocelot_net.c
@@ -1699,7 +1699,8 @@ static void vsc7514_phylink_mac_link_up(struct phylink_config *config,
 					unsigned int link_an_mode,
 					phy_interface_t interface,
 					int speed, int duplex,
-					bool tx_pause, bool rx_pause)
+					bool tx_pause, bool rx_pause,
+					bool eee_active)
 {
 	struct net_device *ndev = to_net_dev(config->dev);
 	struct ocelot_port_private *priv = netdev_priv(ndev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 17310ade88dd..c76160b0e635 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -983,7 +983,8 @@ static void stmmac_mac_link_up(struct phylink_config *config,
 			       struct phy_device *phy,
 			       unsigned int mode, phy_interface_t interface,
 			       int speed, int duplex,
-			       bool tx_pause, bool rx_pause)
+			       bool tx_pause, bool rx_pause,
+			       bool eee_active)
 {
 	struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
 	u32 old_ctrl, ctrl;
diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
index 9ddb79776c88..f154bbed7af6 100644
--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
@@ -1534,7 +1534,8 @@ static void am65_cpsw_nuss_mac_link_down(struct phylink_config *config, unsigned
 
 static void am65_cpsw_nuss_mac_link_up(struct phylink_config *config, struct phy_device *phy,
 				       unsigned int mode, phy_interface_t interface, int speed,
-				       int duplex, bool tx_pause, bool rx_pause)
+				       int duplex, bool tx_pause, bool rx_pause,
+				       bool eee_active)
 {
 	struct am65_cpsw_slave_data *slave = container_of(config, struct am65_cpsw_slave_data,
 							  phylink_config);
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 3e310b55bce2..59e4d70f53d1 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -1696,7 +1696,8 @@ static void axienet_mac_link_up(struct phylink_config *config,
 				struct phy_device *phy,
 				unsigned int mode, phy_interface_t interface,
 				int speed, int duplex,
-				bool tx_pause, bool rx_pause)
+				bool tx_pause, bool rx_pause,
+				bool eee_active)
 {
 	struct net_device *ndev = to_net_dev(config->dev);
 	struct axienet_local *lp = netdev_priv(ndev);
diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
index a64186dc53f8..3680f845e43e 100644
--- a/drivers/net/phy/phy-core.c
+++ b/drivers/net/phy/phy-core.c
@@ -76,6 +76,17 @@ const char *phy_duplex_to_str(unsigned int duplex)
 }
 EXPORT_SYMBOL_GPL(phy_duplex_to_str);
 
+/**
+ * phy_eee_active_to_str - Return string describing eee_active
+ *
+ * @eee_active: EEE active setting to describe
+ */
+const char *phy_eee_active_to_str(bool eee_active)
+{
+	return (eee_active ? "EEE Active" : "EEE Inactive");
+}
+EXPORT_SYMBOL_GPL(phy_eee_active_to_str);
+
 /**
  * phy_rate_matching_to_str - Return a string describing the rate matching
  *
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index f7da96f0c75b..2d1e1cda9f42 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1142,6 +1142,7 @@ static void phylink_mac_pcs_get_state(struct phylink *pl,
 		state->speed = SPEED_UNKNOWN;
 		state->duplex = DUPLEX_UNKNOWN;
 		state->pause = MLO_PAUSE_NONE;
+		state->eee_active = false;
 	} else {
 		state->speed =  pl->link_config.speed;
 		state->duplex = pl->link_config.duplex;
@@ -1223,10 +1224,12 @@ static void phylink_link_up(struct phylink *pl,
 	struct net_device *ndev = pl->netdev;
 	int speed, duplex;
 	bool rx_pause;
+	bool eee_active;
 
 	speed = link_state.speed;
 	duplex = link_state.duplex;
 	rx_pause = !!(link_state.pause & MLO_PAUSE_RX);
+	eee_active = link_state.eee_active;
 
 	switch (link_state.rate_matching) {
 	case RATE_MATCH_PAUSE:
@@ -1257,7 +1260,8 @@ static void phylink_link_up(struct phylink *pl,
 
 	pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode,
 				 pl->cur_interface, speed, duplex,
-				 !!(link_state.pause & MLO_PAUSE_TX), rx_pause);
+				 !!(link_state.pause & MLO_PAUSE_TX), rx_pause,
+				 eee_active);
 
 	if (ndev)
 		netif_carrier_on(ndev);
@@ -1529,6 +1533,7 @@ struct phylink *phylink_create(struct phylink_config *config,
 	pl->link_config.pause = MLO_PAUSE_AN;
 	pl->link_config.speed = SPEED_UNKNOWN;
 	pl->link_config.duplex = DUPLEX_UNKNOWN;
+	pl->link_config.eee_active = false;
 	pl->mac_ops = mac_ops;
 	__set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
 	timer_setup(&pl->link_poll, phylink_fixed_poll, 0);
@@ -1593,6 +1598,7 @@ static void phylink_phy_change(struct phy_device *phydev, bool up)
 	mutex_lock(&pl->state_mutex);
 	pl->phy_state.speed = phydev->speed;
 	pl->phy_state.duplex = phydev->duplex;
+	pl->phy_state.eee_active = phydev->eee_active;
 	pl->phy_state.rate_matching = phydev->rate_matching;
 	pl->phy_state.pause = MLO_PAUSE_NONE;
 	if (tx_pause)
@@ -1605,12 +1611,13 @@ static void phylink_phy_change(struct phy_device *phydev, bool up)
 
 	phylink_run_resolve(pl);
 
-	phylink_dbg(pl, "phy link %s %s/%s/%s/%s/%s\n", up ? "up" : "down",
+	phylink_dbg(pl, "phy link %s %s/%s/%s/%s/%s/%s\n", up ? "up" : "down",
 		    phy_modes(phydev->interface),
 		    phy_speed_to_str(phydev->speed),
 		    phy_duplex_to_str(phydev->duplex),
 		    phy_rate_matching_to_str(phydev->rate_matching),
-		    phylink_pause_to_str(pl->phy_state.pause));
+		    phylink_pause_to_str(pl->phy_state.pause),
+		    phy_eee_active_to_str(phydev->eee_active));
 }
 
 static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
@@ -1684,6 +1691,7 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
 	pl->phy_state.pause = MLO_PAUSE_NONE;
 	pl->phy_state.speed = SPEED_UNKNOWN;
 	pl->phy_state.duplex = DUPLEX_UNKNOWN;
+	pl->phy_state.eee_active = false;
 	pl->phy_state.rate_matching = RATE_MATCH_NONE;
 	linkmode_copy(pl->supported, supported);
 	linkmode_copy(pl->link_config.advertising, config.advertising);
@@ -2929,6 +2937,7 @@ static int phylink_sfp_config_phy(struct phylink *pl, u8 mode,
 	config.interface = PHY_INTERFACE_MODE_NA;
 	config.speed = SPEED_UNKNOWN;
 	config.duplex = DUPLEX_UNKNOWN;
+	config.eee_active = false;
 	config.pause = MLO_PAUSE_AN;
 
 	/* Ignore errors if we're expecting a PHY to attach later */
@@ -2997,6 +3006,7 @@ static int phylink_sfp_config_optical(struct phylink *pl)
 	linkmode_copy(config.advertising, pl->sfp_support);
 	config.speed = SPEED_UNKNOWN;
 	config.duplex = DUPLEX_UNKNOWN;
+	config.eee_active = false;
 	config.pause = MLO_PAUSE_AN;
 
 	/* For all the interfaces that are supported, reduce the sfp_support
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
index f7cff58fe044..0c1e54c41f3a 100644
--- a/drivers/net/usb/asix_devices.c
+++ b/drivers/net/usb/asix_devices.c
@@ -759,7 +759,7 @@ static void ax88772_mac_link_up(struct phylink_config *config,
 			       struct phy_device *phy,
 			       unsigned int mode, phy_interface_t interface,
 			       int speed, int duplex,
-			       bool tx_pause, bool rx_pause)
+			       bool tx_pause, bool rx_pause, bool eee_active)
 {
 	struct usbnet *dev = netdev_priv(to_net_dev(config->dev));
 	u16 m = AX_MEDIUM_AC | AX_MEDIUM_RE;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 5cc2dcb17eb0..2508f1d99777 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1080,6 +1080,7 @@ struct phy_fixup {
 
 const char *phy_speed_to_str(int speed);
 const char *phy_duplex_to_str(unsigned int duplex);
+const char *phy_eee_active_to_str(bool eee_active);
 const char *phy_rate_matching_to_str(int rate_matching);
 
 int phy_interface_num_ports(phy_interface_t interface);
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 9ff56b050584..ef09b3b7e471 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -88,6 +88,7 @@ static inline bool phylink_autoneg_inband(unsigned int mode)
  * @speed: link speed, one of the SPEED_* constants.
  * @duplex: link duplex mode, one of DUPLEX_* constants.
  * @pause: link pause state, described by MLO_PAUSE_* constants.
+ * @eee_active: true if EEE should be active
  * @rate_matching: rate matching being performed, one of the RATE_MATCH_*
  *   constants. If rate matching is taking place, then the speed/duplex of
  *   the medium link mode (@speed and @duplex) and the speed/duplex of the phy
@@ -105,6 +106,7 @@ struct phylink_link_state {
 	int rate_matching;
 	unsigned int link:1;
 	unsigned int an_complete:1;
+	unsigned int eee_active:1;
 };
 
 enum phylink_op_type {
@@ -175,7 +177,7 @@ struct phylink_mac_ops {
 	void (*mac_link_up)(struct phylink_config *config,
 			    struct phy_device *phy, unsigned int mode,
 			    phy_interface_t interface, int speed, int duplex,
-			    bool tx_pause, bool rx_pause);
+			    bool tx_pause, bool rx_pause, bool eee_active);
 };
 
 #if 0 /* For kernel-doc purposes only. */
@@ -408,27 +410,28 @@ void mac_link_down(struct phylink_config *config, unsigned int mode,
  * @duplex: link duplex
  * @tx_pause: link transmit pause enablement status
  * @rx_pause: link receive pause enablement status
+ * @eee_active: EEE should be enabled
  *
  * Configure the MAC for an established link.
  *
- * @speed, @duplex, @tx_pause and @rx_pause indicate the finalised link
- * settings, and should be used to configure the MAC block appropriately
- * where these settings are not automatically conveyed from the PCS block,
- * or if in-band negotiation (as defined by phylink_autoneg_inband(@mode))
- * is disabled.
+ * @speed, @duplex, @tx_pause, @rx_pause and @eee_active indicate the
+ * finalised link settings, and should be used to configure the MAC block
+ * appropriately where these settings are not automatically conveyed from
+ * the PCS block, or if in-band negotiation (as defined by
+ * phylink_autoneg_inband(@mode)) is disabled.
  *
  * Note that when 802.3z in-band negotiation is in use, it is possible
  * that the user wishes to override the pause settings, and this should
  * be allowed when considering the implementation of this method.
  *
  * If in-band negotiation mode is disabled, allow the link to come up. If
- * @phy is non-%NULL, configure Energy Efficient Ethernet by calling
- * phy_init_eee() and perform appropriate MAC configuration for EEE.
+ * eee_active is true enable the LPI timer for Energy Efficient Ethernet.
  * Interface type selection must be done in mac_config().
  */
 void mac_link_up(struct phylink_config *config, struct phy_device *phy,
 		 unsigned int mode, phy_interface_t interface,
-		 int speed, int duplex, bool tx_pause, bool rx_pause);
+		 int speed, int duplex, bool tx_pause, bool rx_pause,
+	         bool eee_active);
 #endif
 
 struct phylink_pcs_ops;
diff --git a/include/net/dsa.h b/include/net/dsa.h
index a15f17a38eca..a680ecb66ad9 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -894,7 +894,8 @@ struct dsa_switch_ops {
 				       phy_interface_t interface,
 				       struct phy_device *phydev,
 				       int speed, int duplex,
-				       bool tx_pause, bool rx_pause);
+				       bool tx_pause, bool rx_pause,
+				       bool eee_active);
 	void	(*phylink_fixed_state)(struct dsa_switch *ds, int port,
 				       struct phylink_link_state *state);
 	/*
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 67ad1adec2a2..44c923b568ed 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -1650,7 +1650,8 @@ static void dsa_port_phylink_mac_link_up(struct phylink_config *config,
 					 unsigned int mode,
 					 phy_interface_t interface,
 					 int speed, int duplex,
-					 bool tx_pause, bool rx_pause)
+					 bool tx_pause, bool rx_pause,
+					 bool eee_active)
 {
 	struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
 	struct dsa_switch *ds = dp->ds;
@@ -1662,7 +1663,8 @@ static void dsa_port_phylink_mac_link_up(struct phylink_config *config,
 	}
 
 	ds->ops->phylink_mac_link_up(ds, dp->index, mode, interface, phydev,
-				     speed, duplex, tx_pause, rx_pause);
+				     speed, duplex, tx_pause, rx_pause,
+				     eee_active);
 }
 
 static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
-- 
2.39.2


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

* [RFC/RFT 03/23] net: phy: Add helper to set EEE Clock stop enable bit
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 01/23] net: phy: Add phydev->eee_active to simplify adjust link callbacks Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 02/23] net: phylink: Plumb eee_active in mac_link_up call Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:58   ` Russell King (Oracle)
  2023-03-28  5:03   ` Oleksij Rempel
  2023-03-27 17:01 ` [RFC/RFT 04/23] net: phy: Keep track of EEE tx_lpi_enabled Andrew Lunn
                   ` (19 subsequent siblings)
  22 siblings, 2 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

The MAC driver can request that the PHY stops the clock during EEE
LPI. This has normally been does as part of phy_init_eee(), however
that function is overly complex and often wrongly used. Add a
standalone helper, to aid removing phy_init_eee().

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
v2: Add missing EXPORT_SYMBOL_GPL
---
 drivers/net/phy/phy.c | 20 ++++++++++++++++++++
 include/linux/phy.h   |  1 +
 2 files changed, 21 insertions(+)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 68e1ce942dd6..d3d6ff4ed488 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1503,6 +1503,26 @@ void phy_mac_interrupt(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(phy_mac_interrupt);
 
+/**
+ * phy_eee_clk_stop_enable - Clock should stop during LIP
+ * @phydev: target phy_device struct
+ *
+ * Description: Program the MMD register 3.0 setting the "Clock stop enable"
+ * bit.
+ */
+int phy_eee_clk_stop_enable(struct phy_device *phydev)
+{
+	int ret;
+
+	mutex_lock(&phydev->lock);
+	ret = phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
+			       MDIO_PCS_CTRL1_CLKSTOP_EN);
+	mutex_unlock(&phydev->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(phy_eee_clk_stop_enable);
+
 /**
  * phy_init_eee - init and check the EEE feature
  * @phydev: target phy_device struct
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 2508f1d99777..12addd1c29f2 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1846,6 +1846,7 @@ int phy_unregister_fixup_for_id(const char *bus_id);
 int phy_unregister_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask);
 
 int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable);
+int phy_eee_clk_stop_enable(struct phy_device *phydev);
 int phy_get_eee_err(struct phy_device *phydev);
 int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data);
 int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data);
-- 
2.39.2


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

* [RFC/RFT 04/23] net: phy: Keep track of EEE tx_lpi_enabled
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (2 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 03/23] net: phy: Add helper to set EEE Clock stop enable bit Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:58   ` Russell King (Oracle)
  2023-03-27 17:01 ` [RFC/RFT 05/23] net: phy: Immediately call adjust_link if only tx_lpi_enabled changes Andrew Lunn
                   ` (18 subsequent siblings)
  22 siblings, 1 reply; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

Have phylib keep track of the EEE tx_lpi_enabled configuration.  This
simplifies the MAC drivers, in that they don't need to store it.

Future patches to phylib will also make use of this information to
further simplify the MAC drivers.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/phy/phy.c | 5 ++++-
 include/linux/phy.h   | 2 ++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index d3d6ff4ed488..7d9205c3f235 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1585,7 +1585,7 @@ EXPORT_SYMBOL(phy_get_eee_err);
  * @data: ethtool_eee data
  *
  * Description: it reportes the Supported/Advertisement/LP Advertisement
- * capabilities.
+ * capabilities, etc.
  */
 int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data)
 {
@@ -1596,6 +1596,7 @@ int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data)
 
 	mutex_lock(&phydev->lock);
 	ret = genphy_c45_ethtool_get_eee(phydev, data);
+	data->tx_lpi_enabled = phydev->tx_lpi_enabled;
 	mutex_unlock(&phydev->lock);
 
 	return ret;
@@ -1618,6 +1619,8 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
 
 	mutex_lock(&phydev->lock);
 	ret = genphy_c45_ethtool_set_eee(phydev, data);
+	if (!ret)
+		phydev->tx_lpi_enabled = data->tx_lpi_enabled;
 	mutex_unlock(&phydev->lock);
 
 	return ret;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 12addd1c29f2..f746d0b10e68 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -578,6 +578,7 @@ struct macsec_ops;
  * @advertising_eee: Currently advertised EEE linkmodes
  * @eee_enabled: Flag indicating whether the EEE feature is enabled
  * @eee_active: EEE is active for the current link mode
+ * @tx_lpi_enabled: EEE should send LPI
  * @lp_advertising: Current link partner advertised linkmodes
  * @host_interfaces: PHY interface modes supported by host
  * @eee_broken_modes: Energy efficient ethernet modes which should be prohibited
@@ -693,6 +694,7 @@ struct phy_device {
 	/* Energy efficient ethernet modes which should be prohibited */
 	u32 eee_broken_modes;
 	bool eee_active;
+	bool tx_lpi_enabled;
 
 #ifdef CONFIG_LED_TRIGGER_PHY
 	struct phy_led_trigger *phy_led_triggers;
-- 
2.39.2


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

* [RFC/RFT 05/23] net: phy: Immediately call adjust_link if only tx_lpi_enabled changes
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (3 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 04/23] net: phy: Keep track of EEE tx_lpi_enabled Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 18:02   ` Russell King (Oracle)
  2023-03-27 17:01 ` [RFC/RFT 06/23] net: marvell: mvneta: Simplify EEE configuration Andrew Lunn
                   ` (17 subsequent siblings)
  22 siblings, 1 reply; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

The MAC driver changes its EEE hardware configuration in its
adjust_link callback. This is called when auto-neg completes. If
set_eee is called with a change to tx_lpi_enabled which does not
trigger an auto-neg, it is necessary to call the adjust_link callback
so that the MAC is reconfigured to take this change into account.

When setting phydev->eee_active, take tx_lpi_enabled into account, so
the MAC drivers don't need to consider tx_lpi_enabled.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/phy/phy-c45.c | 11 ++++++++---
 drivers/net/phy/phy.c     | 15 ++++++++++++---
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c
index fee514b96ab1..84e859eae64b 100644
--- a/drivers/net/phy/phy-c45.c
+++ b/drivers/net/phy/phy-c45.c
@@ -1431,6 +1431,8 @@ EXPORT_SYMBOL(genphy_c45_ethtool_get_eee);
  *
  * Description: it reportes the Supported/Advertisement/LP Advertisement
  * capabilities.
+ * Returns either error code, 0 if there was no change, or positive if
+ * there was a change which triggered auto-neg.
  */
 int genphy_c45_ethtool_set_eee(struct phy_device *phydev,
 			       struct ethtool_eee *data)
@@ -1464,9 +1466,12 @@ int genphy_c45_ethtool_set_eee(struct phy_device *phydev,
 	ret = genphy_c45_an_config_eee_aneg(phydev);
 	if (ret < 0)
 		return ret;
-	if (ret > 0)
-		return phy_restart_aneg(phydev);
-
+	if (ret > 0) {
+		ret = phy_restart_aneg(phydev);
+		if (ret < 0)
+			return ret;
+		return 1;
+	}
 	return 0;
 }
 EXPORT_SYMBOL(genphy_c45_ethtool_set_eee);
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 7d9205c3f235..b074ac5d1de1 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -933,7 +933,7 @@ static int phy_check_link_status(struct phy_device *phydev)
 		if (err < 0)
 			phydev->eee_active = false;
 		else
-			phydev->eee_active = err;
+			phydev->eee_active = (err & phydev->tx_lpi_enabled);
 		phy_link_up(phydev);
 	} else if (!phydev->link && phydev->state != PHY_NOLINK) {
 		phydev->state = PHY_NOLINK;
@@ -1619,11 +1619,20 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
 
 	mutex_lock(&phydev->lock);
 	ret = genphy_c45_ethtool_set_eee(phydev, data);
-	if (!ret)
+	if (ret >= 0) {
+		if (ret == 0) {
+			/* auto-neg not triggered */
+			if (phydev->tx_lpi_enabled != data->tx_lpi_enabled) {
+				phydev->tx_lpi_enabled = data->tx_lpi_enabled;
+				if (phydev->link)
+					phy_link_up(phydev);
+			}
+		}
 		phydev->tx_lpi_enabled = data->tx_lpi_enabled;
+	}
 	mutex_unlock(&phydev->lock);
 
-	return ret;
+	return (ret < 0 ? ret : 0);
 }
 EXPORT_SYMBOL(phy_ethtool_set_eee);
 
-- 
2.39.2


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

* [RFC/RFT 06/23] net: marvell: mvneta: Simplify EEE configuration
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (4 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 05/23] net: phy: Immediately call adjust_link if only tx_lpi_enabled changes Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 07/23] net: stmmac: Drop usage of phy_init_eee() Andrew Lunn
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

phylib already does most of the work. It will track eee_enabled,
eee_active and tx_lpi_enabled and correctly set them in the
ethtool_get_eee callback.

Replace the call to phy_init_eee() by looking at the value of
eee_active passed to the function.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
v2: Use eee_active parameter, which is race free.
    Remove handling of tx_lpi_enabled, leave it to phylib.
---
 drivers/net/ethernet/marvell/mvneta.c | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index cebd3848a228..c7d53fc774c3 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -536,10 +536,6 @@ struct mvneta_port {
 	struct mvneta_bm_pool *pool_short;
 	int bm_win_id;
 
-	bool eee_enabled;
-	bool eee_active;
-	bool tx_lpi_enabled;
-
 	u64 ethtool_stats[ARRAY_SIZE(mvneta_statistics)];
 
 	u32 indir[MVNETA_RSS_LU_TABLE_SIZE];
@@ -4170,7 +4166,6 @@ static void mvneta_mac_link_down(struct phylink_config *config,
 		mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
 	}
 
-	pp->eee_active = false;
 	mvneta_set_eee(pp, false);
 }
 
@@ -4222,10 +4217,8 @@ static void mvneta_mac_link_up(struct phylink_config *config,
 
 	mvneta_port_up(pp);
 
-	if (phy && pp->eee_enabled) {
-		pp->eee_active = phy_init_eee(phy, false) >= 0;
-		mvneta_set_eee(pp, pp->eee_active && pp->tx_lpi_enabled);
-	}
+	if (phy)
+		mvneta_set_eee(pp, eee_active);
 }
 
 static const struct phylink_mac_ops mvneta_phylink_ops = {
@@ -5029,9 +5022,6 @@ static int mvneta_ethtool_get_eee(struct net_device *dev,
 
 	lpi_ctl0 = mvreg_read(pp, MVNETA_LPI_CTRL_0);
 
-	eee->eee_enabled = pp->eee_enabled;
-	eee->eee_active = pp->eee_active;
-	eee->tx_lpi_enabled = pp->tx_lpi_enabled;
 	eee->tx_lpi_timer = (lpi_ctl0) >> 8; // * scale;
 
 	return phylink_ethtool_get_eee(pp->phylink, eee);
@@ -5054,11 +5044,6 @@ static int mvneta_ethtool_set_eee(struct net_device *dev,
 	lpi_ctl0 |= eee->tx_lpi_timer << 8;
 	mvreg_write(pp, MVNETA_LPI_CTRL_0, lpi_ctl0);
 
-	pp->eee_enabled = eee->eee_enabled;
-	pp->tx_lpi_enabled = eee->tx_lpi_enabled;
-
-	mvneta_set_eee(pp, eee->tx_lpi_enabled && eee->eee_enabled);
-
 	return phylink_ethtool_set_eee(pp->phylink, eee);
 }
 
-- 
2.39.2


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

* [RFC/RFT 07/23] net: stmmac: Drop usage of phy_init_eee()
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (5 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 06/23] net: marvell: mvneta: Simplify EEE configuration Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 08/23] net: stmmac: Simplify ethtool get eee Andrew Lunn
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

Replace this method by looking at the eee_active member of the phydev
structure. Additionally, call the phy_eee_clk_stop_enable() if the
platform indicates the clock should be stopped while LPI is active.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c76160b0e635..c0ce3b2c8d7b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1081,8 +1081,9 @@ static void stmmac_mac_link_up(struct phylink_config *config,
 
 	stmmac_mac_set(priv, priv->ioaddr, true);
 	if (phy && priv->dma_cap.eee) {
-		priv->eee_active =
-			phy_init_eee(phy, !priv->plat->rx_clk_runs_in_lpi) >= 0;
+		priv->eee_active = phy->eee_active;
+		if (!priv->plat->rx_clk_runs_in_lpi)
+			phy_eee_clk_stop_enable(phy);
 		priv->eee_enabled = stmmac_eee_init(priv);
 		priv->tx_lpi_enabled = priv->eee_enabled;
 		stmmac_set_eee_pls(priv, priv->hw, true);
-- 
2.39.2


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

* [RFC/RFT 08/23] net: stmmac: Simplify ethtool get eee
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (6 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 07/23] net: stmmac: Drop usage of phy_init_eee() Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 09/23] net: lan743x: Fixup EEE Andrew Lunn
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

phylink_ethtool_get_eee() fills in eee_enabled, eee_active and
tx_lpi_enabled.  So there is no need for the MAC driver to do it as
well.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h         | 1 -
 drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 7 -------
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c    | 2 --
 3 files changed, 10 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 3d15e1e92e18..a0f6e58fc622 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -253,7 +253,6 @@ struct stmmac_priv {
 	int eee_enabled;
 	int eee_active;
 	int tx_lpi_timer;
-	int tx_lpi_enabled;
 	int eee_tw_timer;
 	bool eee_sw_timer_en;
 	unsigned int mode;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 35c8dd92d369..fd97cdbb6797 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -782,10 +782,7 @@ static int stmmac_ethtool_op_get_eee(struct net_device *dev,
 	if (!priv->dma_cap.eee)
 		return -EOPNOTSUPP;
 
-	edata->eee_enabled = priv->eee_enabled;
-	edata->eee_active = priv->eee_active;
 	edata->tx_lpi_timer = priv->tx_lpi_timer;
-	edata->tx_lpi_enabled = priv->tx_lpi_enabled;
 
 	return phylink_ethtool_get_eee(priv->phylink, edata);
 }
@@ -799,10 +796,6 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
 	if (!priv->dma_cap.eee)
 		return -EOPNOTSUPP;
 
-	if (priv->tx_lpi_enabled != edata->tx_lpi_enabled)
-		netdev_warn(priv->dev,
-			    "Setting EEE tx-lpi is not supported\n");
-
 	if (!edata->eee_enabled)
 		stmmac_disable_eee_mode(priv);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c0ce3b2c8d7b..12cf6674909c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -971,7 +971,6 @@ static void stmmac_mac_link_down(struct phylink_config *config,
 
 	stmmac_mac_set(priv, priv->ioaddr, false);
 	priv->eee_active = false;
-	priv->tx_lpi_enabled = false;
 	priv->eee_enabled = stmmac_eee_init(priv);
 	stmmac_set_eee_pls(priv, priv->hw, false);
 
@@ -1085,7 +1084,6 @@ static void stmmac_mac_link_up(struct phylink_config *config,
 		if (!priv->plat->rx_clk_runs_in_lpi)
 			phy_eee_clk_stop_enable(phy);
 		priv->eee_enabled = stmmac_eee_init(priv);
-		priv->tx_lpi_enabled = priv->eee_enabled;
 		stmmac_set_eee_pls(priv, priv->hw, true);
 	}
 
-- 
2.39.2


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

* [RFC/RFT 09/23] net: lan743x: Fixup EEE
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (7 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 08/23] net: stmmac: Simplify ethtool get eee Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 10/23] net: fec: Move fec_enet_eee_mode_set() and helper earlier Andrew Lunn
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

The enabling/disabling of EEE in the MAC should happen as a result of
auto negotiation. So move the enable/disable into
lan743x_phy_link_status_change() which gets called by phylib when
there is a change in link status.

lan743x_ethtool_set_eee() now just programs the hardware with the LTI
timer value, and passed everything else to phylib, so it can correctly
setup the PHY.

lan743x_ethtool_get_eee() relies on phylib doing most of the work, the
MAC driver just adds the LTI timer value.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 .../net/ethernet/microchip/lan743x_ethtool.c  | 22 -------------------
 drivers/net/ethernet/microchip/lan743x_main.c |  7 ++++++
 2 files changed, 7 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.c b/drivers/net/ethernet/microchip/lan743x_ethtool.c
index 2db5949b4c7e..da2f1110e0db 100644
--- a/drivers/net/ethernet/microchip/lan743x_ethtool.c
+++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c
@@ -1073,16 +1073,10 @@ static int lan743x_ethtool_get_eee(struct net_device *netdev,
 
 	buf = lan743x_csr_read(adapter, MAC_CR);
 	if (buf & MAC_CR_EEE_EN_) {
-		eee->eee_enabled = true;
-		eee->eee_active = !!(eee->advertised & eee->lp_advertised);
-		eee->tx_lpi_enabled = true;
 		/* EEE_TX_LPI_REQ_DLY & tx_lpi_timer are same uSec unit */
 		buf = lan743x_csr_read(adapter, MAC_EEE_TX_LPI_REQ_DLY_CNT);
 		eee->tx_lpi_timer = buf;
 	} else {
-		eee->eee_enabled = false;
-		eee->eee_active = false;
-		eee->tx_lpi_enabled = false;
 		eee->tx_lpi_timer = 0;
 	}
 
@@ -1095,7 +1089,6 @@ static int lan743x_ethtool_set_eee(struct net_device *netdev,
 	struct lan743x_adapter *adapter;
 	struct phy_device *phydev;
 	u32 buf = 0;
-	int ret = 0;
 
 	if (!netdev)
 		return -EINVAL;
@@ -1112,23 +1105,8 @@ static int lan743x_ethtool_set_eee(struct net_device *netdev,
 	}
 
 	if (eee->eee_enabled) {
-		ret = phy_init_eee(phydev, false);
-		if (ret) {
-			netif_err(adapter, drv, adapter->netdev,
-				  "EEE initialization failed\n");
-			return ret;
-		}
-
 		buf = (u32)eee->tx_lpi_timer;
 		lan743x_csr_write(adapter, MAC_EEE_TX_LPI_REQ_DLY_CNT, buf);
-
-		buf = lan743x_csr_read(adapter, MAC_CR);
-		buf |= MAC_CR_EEE_EN_;
-		lan743x_csr_write(adapter, MAC_CR, buf);
-	} else {
-		buf = lan743x_csr_read(adapter, MAC_CR);
-		buf &= ~MAC_CR_EEE_EN_;
-		lan743x_csr_write(adapter, MAC_CR, buf);
 	}
 
 	return phy_ethtool_set_eee(phydev, eee);
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
index 957d96a91a8a..7986f8fcf7d3 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -1457,6 +1457,13 @@ static void lan743x_phy_link_status_change(struct net_device *netdev)
 		    phydev->interface == PHY_INTERFACE_MODE_1000BASEX ||
 		    phydev->interface == PHY_INTERFACE_MODE_2500BASEX)
 			lan743x_sgmii_config(adapter);
+
+		data = lan743x_csr_read(adapter, MAC_CR);
+		if (phydev->eee_active)
+			data |=  MAC_CR_EEE_EN_;
+		else
+			data &= ~MAC_CR_EEE_EN_;
+		lan743x_csr_write(adapter, MAC_CR, data);
 	}
 }
 
-- 
2.39.2


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

* [RFC/RFT 10/23] net: fec: Move fec_enet_eee_mode_set() and helper earlier
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (8 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 09/23] net: lan743x: Fixup EEE Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 11/23] net: FEC: Fixup EEE Andrew Lunn
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

FEC is about to get its EEE code re-written. To allow this, move
fec_enet_eee_mode_set() before fec_enet_adjust_link() which will
need to call it.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/ethernet/freescale/fec_main.c | 79 ++++++++++++-----------
 1 file changed, 40 insertions(+), 39 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index f3b16a6673e2..462755f5d33e 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1919,6 +1919,46 @@ static int fec_get_mac(struct net_device *ndev)
 /*
  * Phy section
  */
+
+/* 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, false);
+		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 void fec_enet_adjust_link(struct net_device *ndev)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
@@ -3057,45 +3097,6 @@ 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, false);
-		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)
 {
-- 
2.39.2


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

* [RFC/RFT 11/23] net: FEC: Fixup EEE
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (9 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 10/23] net: fec: Move fec_enet_eee_mode_set() and helper earlier Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 12/23] net: genet: " Andrew Lunn
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

The enabling/disabling of EEE in the MAC should happen as a result of
auto negotiation. So move the enable/disable into
fec_enet_adjust_link() which gets called by phylib when there is a
change in link status.

fec_enet_set_eee() now just stores away the LTI timer value.
Everything else is passed to phylib, so it can correctly setup the
PHY.

fec_enet_get_eee() relies on phylib doing most of the work,
the MAC driver just adds the LTI timer value.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
v2: Only call fec_enet_eee_mode_set for those that support EEE
---
 drivers/net/ethernet/freescale/fec_main.c | 28 ++++-------------------
 1 file changed, 4 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 462755f5d33e..fda1f9ff32b9 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1930,18 +1930,13 @@ static int fec_enet_us_to_tx_cycle(struct net_device *ndev, int us)
 	return us * (fep->clk_ref_rate / 1000) / 1000;
 }
 
-static int fec_enet_eee_mode_set(struct net_device *ndev, bool enable)
+static int fec_enet_eee_mode_set(struct net_device *ndev, bool eee_active)
 {
 	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, false);
-		if (ret)
-			return ret;
 
+	if (eee_active) {
 		sleep_cycle = fec_enet_us_to_tx_cycle(ndev, p->tx_lpi_timer);
 		wake_cycle = sleep_cycle;
 	} else {
@@ -1949,10 +1944,6 @@ static int fec_enet_eee_mode_set(struct net_device *ndev, bool enable)
 		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);
 
@@ -1997,6 +1988,8 @@ static void fec_enet_adjust_link(struct net_device *ndev)
 			netif_tx_unlock_bh(ndev);
 			napi_enable(&fep->napi);
 		}
+		if (fep->quirks & FEC_QUIRK_HAS_EEE)
+			fec_enet_eee_mode_set(ndev, phy_dev->eee_active);
 	} else {
 		if (fep->link) {
 			napi_disable(&fep->napi);
@@ -3109,10 +3102,7 @@ fec_enet_get_eee(struct net_device *ndev, struct ethtool_eee *edata)
 	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);
 }
@@ -3122,7 +3112,6 @@ 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;
@@ -3132,15 +3121,6 @@ fec_enet_set_eee(struct net_device *ndev, struct ethtool_eee *edata)
 
 	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);
 }
 
-- 
2.39.2


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

* [RFC/RFT 12/23] net: genet: Fixup EEE
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (10 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 11/23] net: FEC: Fixup EEE Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 13/23] net: sxgdb: " Andrew Lunn
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

The enabling/disabling of EEE in the MAC should happen as a result of
auto negotiation. So move the enable/disable into bcmgenet_mii_setup()
which gets called by phylib when there is a change in link status.

bcmgenet_set_eee() now just writes the LTI timer value to the
hardware.  Everything else is passed to phylib, so it can correctly
setup the PHY.

bcmgenet_get_eee() relies on phylib doing most of the work, the MAC
driver just adds the LTI timer value from hardware.

The call to bcmgenet_eee_enable_set() in the resume function has been
removed. There is both unconditional calls to phy_init_hw() and
genphy_config_aneg, and a call to phy_resume(). As a result, the PHY
is going to perform auto-neg, and then it completes
bcmgenet_mii_setup() will be called, which will set the hardware to
the correct EEE mode.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 .../net/ethernet/broadcom/genet/bcmgenet.c    | 42 +++++--------------
 .../net/ethernet/broadcom/genet/bcmgenet.h    |  3 +-
 drivers/net/ethernet/broadcom/genet/bcmmii.c  |  1 +
 3 files changed, 12 insertions(+), 34 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index d937daa8ee88..035486304e31 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1272,19 +1272,21 @@ static void bcmgenet_get_ethtool_stats(struct net_device *dev,
 	}
 }
 
-static void bcmgenet_eee_enable_set(struct net_device *dev, bool enable)
+void bcmgenet_eee_enable_set(struct net_device *dev, bool eee_active)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
-	u32 off = priv->hw_params->tbuf_offset + TBUF_ENERGY_CTRL;
+	u32 off;
 	u32 reg;
 
-	if (enable && !priv->clk_eee_enabled) {
+	off = priv->hw_params->tbuf_offset + TBUF_ENERGY_CTRL;
+
+	if (eee_active && !priv->clk_eee_enabled) {
 		clk_prepare_enable(priv->clk_eee);
 		priv->clk_eee_enabled = true;
 	}
 
 	reg = bcmgenet_umac_readl(priv, UMAC_EEE_CTRL);
-	if (enable)
+	if (eee_active)
 		reg |= EEE_EN;
 	else
 		reg &= ~EEE_EN;
@@ -1292,7 +1294,7 @@ static void bcmgenet_eee_enable_set(struct net_device *dev, bool enable)
 
 	/* Enable EEE and switch to a 27Mhz clock automatically */
 	reg = bcmgenet_readl(priv->base + off);
-	if (enable)
+	if (eee_active)
 		reg |= TBUF_EEE_EN | TBUF_PM_EN;
 	else
 		reg &= ~(TBUF_EEE_EN | TBUF_PM_EN);
@@ -1300,25 +1302,21 @@ static void bcmgenet_eee_enable_set(struct net_device *dev, bool enable)
 
 	/* Do the same for thing for RBUF */
 	reg = bcmgenet_rbuf_readl(priv, RBUF_ENERGY_CTRL);
-	if (enable)
+	if (eee_active)
 		reg |= RBUF_EEE_EN | RBUF_PM_EN;
 	else
 		reg &= ~(RBUF_EEE_EN | RBUF_PM_EN);
 	bcmgenet_rbuf_writel(priv, reg, RBUF_ENERGY_CTRL);
 
-	if (!enable && priv->clk_eee_enabled) {
+	if (!eee_active && priv->clk_eee_enabled) {
 		clk_disable_unprepare(priv->clk_eee);
 		priv->clk_eee_enabled = false;
 	}
-
-	priv->eee.eee_enabled = enable;
-	priv->eee.eee_active = enable;
 }
 
 static int bcmgenet_get_eee(struct net_device *dev, struct ethtool_eee *e)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
-	struct ethtool_eee *p = &priv->eee;
 
 	if (GENET_IS_V1(priv))
 		return -EOPNOTSUPP;
@@ -1326,8 +1324,6 @@ static int bcmgenet_get_eee(struct net_device *dev, struct ethtool_eee *e)
 	if (!dev->phydev)
 		return -ENODEV;
 
-	e->eee_enabled = p->eee_enabled;
-	e->eee_active = p->eee_active;
 	e->tx_lpi_timer = bcmgenet_umac_readl(priv, UMAC_EEE_LPI_TIMER);
 
 	return phy_ethtool_get_eee(dev->phydev, e);
@@ -1336,8 +1332,6 @@ static int bcmgenet_get_eee(struct net_device *dev, struct ethtool_eee *e)
 static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_eee *e)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
-	struct ethtool_eee *p = &priv->eee;
-	int ret = 0;
 
 	if (GENET_IS_V1(priv))
 		return -EOPNOTSUPP;
@@ -1345,20 +1339,7 @@ static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_eee *e)
 	if (!dev->phydev)
 		return -ENODEV;
 
-	p->eee_enabled = e->eee_enabled;
-
-	if (!p->eee_enabled) {
-		bcmgenet_eee_enable_set(dev, false);
-	} else {
-		ret = phy_init_eee(dev->phydev, false);
-		if (ret) {
-			netif_err(priv, hw, dev, "EEE initialization failed\n");
-			return ret;
-		}
-
-		bcmgenet_umac_writel(priv, e->tx_lpi_timer, UMAC_EEE_LPI_TIMER);
-		bcmgenet_eee_enable_set(dev, true);
-	}
+	bcmgenet_umac_writel(priv, e->tx_lpi_timer, UMAC_EEE_LPI_TIMER);
 
 	return phy_ethtool_set_eee(dev->phydev, e);
 }
@@ -4278,9 +4259,6 @@ static int bcmgenet_resume(struct device *d)
 	if (!device_may_wakeup(d))
 		phy_resume(dev->phydev);
 
-	if (priv->eee.eee_enabled)
-		bcmgenet_eee_enable_set(dev, true);
-
 	bcmgenet_netif_start(dev);
 
 	netif_device_attach(dev);
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index 946f6e283c4e..8c9643ec738c 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -644,8 +644,6 @@ struct bcmgenet_priv {
 	bool wol_active;
 
 	struct bcmgenet_mib_counters mib;
-
-	struct ethtool_eee eee;
 };
 
 #define GENET_IO_MACRO(name, offset)					\
@@ -703,4 +701,5 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
 void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
 			       enum bcmgenet_power_mode mode);
 
+void bcmgenet_eee_enable_set(struct net_device *dev, bool eee_active);
 #endif /* __BCMGENET_H__ */
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
index be042905ada2..6c39839762a7 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -100,6 +100,7 @@ void bcmgenet_mii_setup(struct net_device *dev)
 
 	if (phydev->link) {
 		bcmgenet_mac_config(dev);
+		bcmgenet_eee_enable_set(dev, phydev->eee_active);
 	} else {
 		reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
 		reg &= ~RGMII_LINK;
-- 
2.39.2


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

* [RFC/RFT 13/23] net: sxgdb: Fixup EEE
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (11 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 12/23] net: genet: " Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 14/23] net: dsa: mt7530: Swap to using phydev->eee_active Andrew Lunn
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

The enabling/disabling of EEE in the MAC should happen as a result of
auto negotiation. So rework sxgbe_eee_adjust() to take the result of
negotiation into account.

sxgbe_set_eee() now just stores LTI timer value. Everything else is
passed to phylib, so it can correctly setup the PHY.

sxgbe_get_eee() relies on phylib doing most of the work, the MAC
driver just adds the LTI timer value.

The hw_cap.eee is now used to control timers, rather than eee_enabled,
which was wrongly being set based on the value of phy_init_eee()
before auto-neg even completed.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 .../net/ethernet/samsung/sxgbe/sxgbe_common.h |  3 --
 .../ethernet/samsung/sxgbe/sxgbe_ethtool.c    | 21 ++---------
 .../net/ethernet/samsung/sxgbe/sxgbe_main.c   | 36 ++++++-------------
 3 files changed, 12 insertions(+), 48 deletions(-)

diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h
index 0f45107db8dd..c25588b90a13 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h
@@ -502,8 +502,6 @@ struct sxgbe_priv_data {
 	struct timer_list eee_ctrl_timer;
 	bool tx_path_in_lpi_mode;
 	int lpi_irq;
-	int eee_enabled;
-	int eee_active;
 	int tx_lpi_timer;
 };
 
@@ -528,5 +526,4 @@ int sxgbe_restore(struct net_device *ndev);
 const struct sxgbe_mtl_ops *sxgbe_get_mtl_ops(void);
 
 void sxgbe_disable_eee_mode(struct sxgbe_priv_data * const priv);
-bool sxgbe_eee_init(struct sxgbe_priv_data * const priv);
 #endif /* __SXGBE_COMMON_H__ */
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
index 8ba017ec9849..e7128864a3ef 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
@@ -140,8 +140,6 @@ static int sxgbe_get_eee(struct net_device *dev,
 	if (!priv->hw_cap.eee)
 		return -EOPNOTSUPP;
 
-	edata->eee_enabled = priv->eee_enabled;
-	edata->eee_active = priv->eee_active;
 	edata->tx_lpi_timer = priv->tx_lpi_timer;
 
 	return phy_ethtool_get_eee(dev->phydev, edata);
@@ -152,22 +150,7 @@ static int sxgbe_set_eee(struct net_device *dev,
 {
 	struct sxgbe_priv_data *priv = netdev_priv(dev);
 
-	priv->eee_enabled = edata->eee_enabled;
-
-	if (!priv->eee_enabled) {
-		sxgbe_disable_eee_mode(priv);
-	} else {
-		/* We are asking for enabling the EEE but it is safe
-		 * to verify all by invoking the eee_init function.
-		 * In case of failure it will return an error.
-		 */
-		priv->eee_enabled = sxgbe_eee_init(priv);
-		if (!priv->eee_enabled)
-			return -EOPNOTSUPP;
-
-		/* Do not change tx_lpi_timer in case of failure */
-		priv->tx_lpi_timer = edata->tx_lpi_timer;
-	}
+	priv->tx_lpi_timer = edata->tx_lpi_timer;
 
 	return phy_ethtool_set_eee(dev->phydev, edata);
 }
@@ -230,7 +213,7 @@ static void sxgbe_get_ethtool_stats(struct net_device *dev,
 	int i;
 	char *p;
 
-	if (priv->eee_enabled) {
+	if (dev->phydev->eee_active) {
 		int val = phy_get_eee_err(dev->phydev);
 
 		if (val)
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
index 9664f029fa16..cf549a524674 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
@@ -119,18 +119,10 @@ static void sxgbe_eee_ctrl_timer(struct timer_list *t)
  *  phy can also manage EEE, so enable the LPI state and start the timer
  *  to verify if the tx path can enter in LPI state.
  */
-bool sxgbe_eee_init(struct sxgbe_priv_data * const priv)
+static void sxgbe_eee_init(struct sxgbe_priv_data * const priv)
 {
-	struct net_device *ndev = priv->dev;
-	bool ret = false;
-
 	/* MAC core supports the EEE feature. */
 	if (priv->hw_cap.eee) {
-		/* Check if the PHY supports EEE */
-		if (phy_init_eee(ndev->phydev, true))
-			return false;
-
-		priv->eee_active = 1;
 		timer_setup(&priv->eee_ctrl_timer, sxgbe_eee_ctrl_timer, 0);
 		priv->eee_ctrl_timer.expires = SXGBE_LPI_TIMER(eee_timer);
 		add_timer(&priv->eee_ctrl_timer);
@@ -140,23 +132,15 @@ bool sxgbe_eee_init(struct sxgbe_priv_data * const priv)
 					     priv->tx_lpi_timer);
 
 		pr_info("Energy-Efficient Ethernet initialized\n");
-
-		ret = true;
 	}
-
-	return ret;
 }
 
-static void sxgbe_eee_adjust(const struct sxgbe_priv_data *priv)
+static void sxgbe_eee_adjust(const struct sxgbe_priv_data *priv,
+			     bool eee_active)
 {
-	struct net_device *ndev = priv->dev;
-
-	/* When the EEE has been already initialised we have to
-	 * modify the PLS bit in the LPI ctrl & status reg according
-	 * to the PHY link status. For this reason.
-	 */
-	if (priv->eee_enabled)
-		priv->hw->mac->set_eee_pls(priv->ioaddr, ndev->phydev->link);
+	if (priv->hw_cap.eee)
+		priv->hw->mac->set_eee_pls(priv->ioaddr, eee_active);
+	phy_eee_clk_stop_enable(priv->dev->phydev);
 }
 
 /**
@@ -250,7 +234,7 @@ static void sxgbe_adjust_link(struct net_device *dev)
 		phy_print_status(phydev);
 
 	/* Alter the MAC settings for EEE */
-	sxgbe_eee_adjust(priv);
+	sxgbe_eee_adjust(priv, phydev->eee_active);
 }
 
 /**
@@ -803,7 +787,7 @@ static void sxgbe_tx_all_clean(struct sxgbe_priv_data * const priv)
 		sxgbe_tx_queue_clean(tqueue);
 	}
 
-	if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) {
+	if (priv->hw_cap.eee && !priv->tx_path_in_lpi_mode) {
 		sxgbe_enable_eee_mode(priv);
 		mod_timer(&priv->eee_ctrl_timer, SXGBE_LPI_TIMER(eee_timer));
 	}
@@ -1181,7 +1165,7 @@ static int sxgbe_open(struct net_device *dev)
 	}
 
 	priv->tx_lpi_timer = SXGBE_DEFAULT_LPI_TIMER;
-	priv->eee_enabled = sxgbe_eee_init(priv);
+	sxgbe_eee_init(priv);
 
 	napi_enable(&priv->napi);
 	netif_start_queue(dev);
@@ -1208,7 +1192,7 @@ static int sxgbe_release(struct net_device *dev)
 {
 	struct sxgbe_priv_data *priv = netdev_priv(dev);
 
-	if (priv->eee_enabled)
+	if (priv->hw_cap.eee)
 		del_timer_sync(&priv->eee_ctrl_timer);
 
 	/* Stop and disconnect the PHY */
-- 
2.39.2


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

* [RFC/RFT 14/23] net: dsa: mt7530: Swap to using phydev->eee_active
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (12 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 13/23] net: sxgdb: " Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 15/23] net: dsa: b53: " Andrew Lunn
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

Rather than calling phy_init_eee() retrieve the same information from
within the phydev structure.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mt7530.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 6c89026ec966..40b86999f543 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2754,7 +2754,7 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
 			mcr |= PMCR_RX_FC_EN;
 	}
 
-	if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, false) >= 0) {
+	if (mode == MLO_AN_PHY && phydev && phydev->eee_active) {
 		switch (speed) {
 		case SPEED_1000:
 			mcr |= PMCR_FORCE_EEE1G;
-- 
2.39.2


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

* [RFC/RFT 15/23] net: dsa: b53: Swap to using phydev->eee_active
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (13 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 14/23] net: dsa: mt7530: Swap to using phydev->eee_active Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 16/23] net: phylink: Remove unused phylink_init_eee() Andrew Lunn
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

Rather than calling phy_init_eee() retrieve the same information from
within the phydev structure.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/b53/b53_common.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index aa3fd3c1b15e..dfa4968c1820 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -2219,10 +2219,7 @@ EXPORT_SYMBOL(b53_eee_enable_set);
  */
 int b53_eee_init(struct dsa_switch *ds, int port, struct phy_device *phy)
 {
-	int ret;
-
-	ret = phy_init_eee(phy, false);
-	if (ret)
+	if (!phy->eee_active)
 		return 0;
 
 	b53_eee_enable_set(ds, port, true);
-- 
2.39.2


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

* [RFC/RFT 16/23] net: phylink: Remove unused phylink_init_eee()
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (14 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 15/23] net: dsa: b53: " Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 17/23] net: phy: remove unused phy_init_eee() Andrew Lunn
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

This is not used in tree, and the phylib equivalent phy_init_eee() is
about to be removed.

Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/phy/phylink.c | 18 ------------------
 include/linux/phylink.h   |  1 -
 2 files changed, 19 deletions(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 2d1e1cda9f42..2e9ce6862042 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -2507,24 +2507,6 @@ int phylink_get_eee_err(struct phylink *pl)
 }
 EXPORT_SYMBOL_GPL(phylink_get_eee_err);
 
-/**
- * phylink_init_eee() - init and check the EEE features
- * @pl: a pointer to a &struct phylink returned from phylink_create()
- * @clk_stop_enable: allow PHY to stop receive clock
- *
- * Must be called either with RTNL held or within mac_link_up()
- */
-int phylink_init_eee(struct phylink *pl, bool clk_stop_enable)
-{
-	int ret = -EOPNOTSUPP;
-
-	if (pl->phydev)
-		ret = phy_init_eee(pl->phydev, clk_stop_enable);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(phylink_init_eee);
-
 /**
  * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters
  * @pl: a pointer to a &struct phylink returned from phylink_create()
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index ef09b3b7e471..6eee6194b5ab 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -604,7 +604,6 @@ void phylink_ethtool_get_pauseparam(struct phylink *,
 int phylink_ethtool_set_pauseparam(struct phylink *,
 				   struct ethtool_pauseparam *);
 int phylink_get_eee_err(struct phylink *);
-int phylink_init_eee(struct phylink *, bool);
 int phylink_ethtool_get_eee(struct phylink *, struct ethtool_eee *);
 int phylink_ethtool_set_eee(struct phylink *, struct ethtool_eee *);
 int phylink_mii_ioctl(struct phylink *, struct ifreq *, int);
-- 
2.39.2


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

* [RFC/RFT 17/23] net: phy: remove unused phy_init_eee()
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (15 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 16/23] net: phylink: Remove unused phylink_init_eee() Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 18/23] net: usb: lan78xx: Fixup EEE Andrew Lunn
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

There are no users left of phy_init_eee(), and it is often wrongly
used. So remove it.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/phy/phy.c | 34 ----------------------------------
 include/linux/phy.h   |  1 -
 2 files changed, 35 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index b074ac5d1de1..3d12a46f7a4c 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1523,40 +1523,6 @@ int phy_eee_clk_stop_enable(struct phy_device *phydev)
 }
 EXPORT_SYMBOL_GPL(phy_eee_clk_stop_enable);
 
-/**
- * phy_init_eee - init and check the EEE feature
- * @phydev: target phy_device struct
- * @clk_stop_enable: PHY may stop the clock during LPI
- *
- * Description: it checks if the Energy-Efficient Ethernet (EEE)
- * is supported by looking at the MMD registers 3.20 and 7.60/61
- * and it programs the MMD register 3.0 setting the "Clock stop enable"
- * bit if required.
- */
-int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
-{
-	int ret;
-
-	if (!phydev->drv)
-		return -EIO;
-
-	ret = genphy_c45_eee_is_active(phydev, NULL, NULL, NULL);
-	if (ret < 0)
-		return ret;
-	if (!ret)
-		return -EPROTONOSUPPORT;
-
-	if (clk_stop_enable)
-		/* Configure the PHY to stop receiving xMII
-		 * clock while it is signaling LPI.
-		 */
-		ret = phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
-				       MDIO_PCS_CTRL1_CLKSTOP_EN);
-
-	return ret < 0 ? ret : 0;
-}
-EXPORT_SYMBOL(phy_init_eee);
-
 /**
  * phy_get_eee_err - report the EEE wake error count
  * @phydev: target phy_device struct
diff --git a/include/linux/phy.h b/include/linux/phy.h
index f746d0b10e68..9769021b1aa7 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1847,7 +1847,6 @@ int phy_unregister_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask);
 int phy_unregister_fixup_for_id(const char *bus_id);
 int phy_unregister_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask);
 
-int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable);
 int phy_eee_clk_stop_enable(struct phy_device *phydev);
 int phy_get_eee_err(struct phy_device *phydev);
 int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data);
-- 
2.39.2


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

* [RFC/RFT 18/23] net: usb: lan78xx: Fixup EEE
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (16 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 17/23] net: phy: remove unused phy_init_eee() Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 20:56   ` kernel test robot
  2023-03-27 17:01 ` [RFC/RFT 19/23] net: phy: Add phy_support_eee() indicating MAC support EEE Andrew Lunn
                   ` (4 subsequent siblings)
  22 siblings, 1 reply; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

The enabling/disabling of EEE in the MAC should happen as a result of
auto negotiation. So move the enable/disable into
lan783xx_phy_link_status_change() which gets called by phylib when
there is a change in link status.

lan78xx_set_eee() now just programs the hardware with the LTI
timer value, and passed everything else to phylib, so it can correctly
setup the PHY.

lan743x_get_eee() relies on phylib doing most of the work, the
MAC driver just adds the LTI timer value.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/usb/lan78xx.c | 36 ++++++++++++++----------------------
 1 file changed, 14 insertions(+), 22 deletions(-)

diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index c458c030fadf..3f12b67d7444 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -1690,17 +1690,10 @@ static int lan78xx_get_eee(struct net_device *net, struct ethtool_eee *edata)
 
 	ret = lan78xx_read_reg(dev, MAC_CR, &buf);
 	if (buf & MAC_CR_EEE_EN_) {
-		edata->eee_enabled = true;
-		edata->eee_active = !!(edata->advertised &
-				       edata->lp_advertised);
-		edata->tx_lpi_enabled = true;
 		/* EEE_TX_LPI_REQ_DLY & tx_lpi_timer are same uSec unit */
 		ret = lan78xx_read_reg(dev, EEE_TX_LPI_REQ_DLY, &buf);
 		edata->tx_lpi_timer = buf;
 	} else {
-		edata->eee_enabled = false;
-		edata->eee_active = false;
-		edata->tx_lpi_enabled = false;
 		edata->tx_lpi_timer = 0;
 	}
 
@@ -1721,24 +1714,16 @@ static int lan78xx_set_eee(struct net_device *net, struct ethtool_eee *edata)
 	if (ret < 0)
 		return ret;
 
-	if (edata->eee_enabled) {
-		ret = lan78xx_read_reg(dev, MAC_CR, &buf);
-		buf |= MAC_CR_EEE_EN_;
-		ret = lan78xx_write_reg(dev, MAC_CR, buf);
-
-		phy_ethtool_set_eee(net->phydev, edata);
-
-		buf = (u32)edata->tx_lpi_timer;
-		ret = lan78xx_write_reg(dev, EEE_TX_LPI_REQ_DLY, buf);
-	} else {
-		ret = lan78xx_read_reg(dev, MAC_CR, &buf);
-		buf &= ~MAC_CR_EEE_EN_;
-		ret = lan78xx_write_reg(dev, MAC_CR, buf);
-	}
+	ret = phy_ethtool_set_eee(net->phydev, edata);
+	if (ret < 0)
+		goto out;
 
+	buf = (u32)edata->tx_lpi_timer;
+	ret = lan78xx_write_reg(dev, EEE_TX_LPI_REQ_DLY, buf);
+out:
 	usb_autopm_put_interface(dev->intf);
 
-	return 0;
+	return ret;
 }
 
 static u32 lan78xx_get_link(struct net_device *net)
@@ -2114,8 +2099,15 @@ static void lan78xx_remove_mdio(struct lan78xx_net *dev)
 
 static void lan78xx_link_status_change(struct net_device *net)
 {
+	struct lan78xx_net *dev = netdev_priv(net);
 	struct phy_device *phydev = net->phydev;
 
+	if (phydev->eee_active)
+		data |=  MAC_CR_EEE_EN_;
+	else
+		data &= ~MAC_CR_EEE_EN_;
+	lan78xx_write_reg(dev, MAC_CR, data);
+
 	phy_print_status(phydev);
 }
 
-- 
2.39.2


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

* [RFC/RFT 19/23] net: phy: Add phy_support_eee() indicating MAC support EEE
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (17 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 18/23] net: usb: lan78xx: Fixup EEE Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:01 ` [RFC/RFT 20/23] net: phylink: Add MAC_EEE to mac_capabilites Andrew Lunn
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

In order for EEE to operate, both the MAC and the PHY need to support
it, similar to how pause works. Copy the pause concept and add the
call phy_support_eee() which the MAC makes after connecting the PHY to
indicate it supports EEE. phylib will then advertise EEE when auto-neg
is performed.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/phy/phy_device.c | 16 ++++++++++++++++
 include/linux/phy.h          |  3 ++-
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index c0760cbf534b..30f07623637b 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -2760,6 +2760,22 @@ void phy_advertise_supported(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(phy_advertise_supported);
 
+/**
+ * phy_support_eee - Enable support of EEE
+ * @phydev: target phy_device struct
+ *
+ * Description: Called by the MAC to indicate is supports Energy
+ * Efficient Ethernet. This should be called before phy_start() in
+ * order that EEE is negotiated when the link comes up as part of
+ * phy_start().
+ */
+void phy_support_eee(struct phy_device *phydev)
+{
+	linkmode_copy(phydev->advertising_eee, phydev->supported_eee);
+	phydev->tx_lpi_enabled = true;
+}
+EXPORT_SYMBOL(phy_support_eee);
+
 /**
  * phy_support_sym_pause - Enable support of symmetrical pause
  * @phydev: target phy_device struct
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 9769021b1aa7..b8c489f2b4f2 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -683,7 +683,7 @@ struct phy_device {
 	__ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising);
 	/* used with phy_speed_down */
 	__ETHTOOL_DECLARE_LINK_MODE_MASK(adv_old);
-	/* used for eee validation */
+	/* used for eee validation and configuration*/
 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported_eee);
 	__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising_eee);
 	bool eee_enabled;
@@ -1823,6 +1823,7 @@ void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode);
 void phy_advertise_supported(struct phy_device *phydev);
 void phy_support_sym_pause(struct phy_device *phydev);
 void phy_support_asym_pause(struct phy_device *phydev);
+void phy_support_eee(struct phy_device *phydev);
 void phy_set_sym_pause(struct phy_device *phydev, bool rx, bool tx,
 		       bool autoneg);
 void phy_set_asym_pause(struct phy_device *phydev, bool rx, bool tx);
-- 
2.39.2


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

* [RFC/RFT 20/23] net: phylink: Add MAC_EEE to mac_capabilites
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (18 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 19/23] net: phy: Add phy_support_eee() indicating MAC support EEE Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 21:59   ` Russell King (Oracle)
  2023-03-27 17:01 ` [RFC/RFT 21/23] net: phylink: Extend mac_capabilities in MAC drivers which support EEE Andrew Lunn
                   ` (2 subsequent siblings)
  22 siblings, 1 reply; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

If the MAC supports Energy Efficient Ethernet, it should indicate this
by setting the MAC_EEE bit in the config.mac_capabilities
bitmap. phylink will then enable EEE in the PHY, if it supports it.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/phy/phylink.c | 3 +++
 include/linux/phylink.h   | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 2e9ce6862042..192f9d13d3d1 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1637,6 +1637,9 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
 	 */
 	phy_support_asym_pause(phy);
 
+	if (pl->config->mac_capabilities & MAC_EEE)
+		phy_support_eee(phy);
+
 	memset(&config, 0, sizeof(config));
 	linkmode_copy(supported, phy->supported);
 	linkmode_copy(config.advertising, phy->advertising);
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 6eee6194b5ab..beac34b71343 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -72,6 +72,9 @@ enum {
 	MAC_100000FD	= BIT(16),
 	MAC_200000FD	= BIT(17),
 	MAC_400000FD	= BIT(18),
+	/* MAC_EEE indicates that the MAC is Energy Efficient capable
+	   and that the PHY should negotiate its use, if possible */
+	MAC_EEE		= BIT(31),
 };
 
 static inline bool phylink_autoneg_inband(unsigned int mode)
-- 
2.39.2


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

* [RFC/RFT 21/23] net: phylink: Extend mac_capabilities in MAC drivers which support EEE
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (19 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 20/23] net: phylink: Add MAC_EEE to mac_capabilites Andrew Lunn
@ 2023-03-27 17:01 ` Andrew Lunn
  2023-03-27 17:02 ` [RFC/RFT 22/23] net: phylib: call phy_support_eee() " Andrew Lunn
  2023-03-27 17:02 ` [RFC/RFT 23/23] net: phy: Disable EEE advertisement by default Andrew Lunn
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:01 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

For MAC drivers making use of phylink, and which support EEE, set the
MAC_EEE bit in the mac_capabilities.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/ethernet/marvell/mvneta.c             | 2 +-
 drivers/net/ethernet/microchip/lan743x_main.c     | 2 ++
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 +++
 net/dsa/port.c                                    | 3 +++
 4 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index c7d53fc774c3..9560a627fb78 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -5444,7 +5444,7 @@ static int mvneta_probe(struct platform_device *pdev)
 
 	pp->phylink_config.dev = &dev->dev;
 	pp->phylink_config.type = PHYLINK_NETDEV;
-	pp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_10 |
+	pp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_EEE | MAC_10 |
 		MAC_100 | MAC_1000FD | MAC_2500FD;
 
 	phy_interface_set_rgmii(pp->phylink_config.supported_interfaces);
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
index 7986f8fcf7d3..ad76be484536 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -1543,6 +1543,8 @@ static int lan743x_phy_open(struct lan743x_adapter *adapter)
 	phy->fc_request_control = (FLOW_CTRL_RX | FLOW_CTRL_TX);
 	phy->fc_autoneg = phydev->autoneg;
 
+	phy_support_eee(phydev);
+
 	phy_start(phydev);
 	phy_start_aneg(phydev);
 	phy_attached_info(phydev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 12cf6674909c..90aa602647ed 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1233,6 +1233,9 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 			~(MAC_10HD | MAC_100HD | MAC_1000HD);
 	priv->phylink_config.mac_managed_pm = true;
 
+	if (priv->dma_cap.eee)
+		priv->phylink_config.mac_capabilities |= MAC_EEE;
+
 	phylink = phylink_create(&priv->phylink_config, fwnode,
 				 mode, &stmmac_phylink_mac_ops);
 	if (IS_ERR(phylink))
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 44c923b568ed..0d1bff988059 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -1698,6 +1698,9 @@ int dsa_port_phylink_create(struct dsa_port *dp)
 	if (ds->ops->phylink_get_caps)
 		ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
 
+	if (ds->ops->set_mac_eee && ds->ops->get_mac_eee)
+		dp->pl_config.mac_capabilities |= MAC_EEE;
+
 	pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
 			    mode, &dsa_port_phylink_mac_ops);
 	if (IS_ERR(pl)) {
-- 
2.39.2


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

* [RFC/RFT 22/23] net: phylib: call phy_support_eee() in MAC drivers which support EEE
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (20 preceding siblings ...)
  2023-03-27 17:01 ` [RFC/RFT 21/23] net: phylink: Extend mac_capabilities in MAC drivers which support EEE Andrew Lunn
@ 2023-03-27 17:02 ` Andrew Lunn
  2023-03-27 17:02 ` [RFC/RFT 23/23] net: phy: Disable EEE advertisement by default Andrew Lunn
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:02 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

For MAC drivers making use of phylib, and which support EEE, call
phy_support_eee() before starting the PHY.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/ethernet/broadcom/genet/bcmmii.c    | 2 ++
 drivers/net/ethernet/freescale/fec_main.c       | 3 +++
 drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 3 +++
 drivers/net/usb/lan78xx.c                       | 2 ++
 4 files changed, 10 insertions(+)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
index 6c39839762a7..4175042865ec 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -376,6 +376,8 @@ int bcmgenet_mii_probe(struct net_device *dev)
 		}
 	}
 
+	phy_support_eee(dev->phydev);
+
 	/* Configure port multiplexer based on what the probed PHY device since
 	 * reading the 'max-speed' property determines the maximum supported
 	 * PHY speed which is needed for bcmgenet_mii_config() to configure
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index fda1f9ff32b9..09c55430c614 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2348,6 +2348,9 @@ static int fec_enet_mii_probe(struct net_device *ndev)
 	else
 		phy_set_max_speed(phy_dev, 100);
 
+	if (fep->quirks & FEC_QUIRK_HAS_EEE)
+		phy_support_eee(phy_dev);
+
 	fep->link = 0;
 	fep->full_duplex = 0;
 
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
index cf549a524674..060280c4bc0a 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
@@ -286,6 +286,9 @@ static int sxgbe_init_phy(struct net_device *ndev)
 		return -ENODEV;
 	}
 
+	if (priv->hw_cap.eee)
+		phy_support_eee(phydev);
+
 	netdev_dbg(ndev, "%s: attached to PHY (UID 0x%x) Link = %d\n",
 		   __func__, phydev->phy_id, phydev->link);
 
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 3f12b67d7444..9b4a33f8e3b2 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -2400,6 +2400,8 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
 	mii_adv_to_linkmode_adv_t(fc, mii_adv);
 	linkmode_or(phydev->advertising, fc, phydev->advertising);
 
+	phy_support_eee(phydev);
+
 	if (phydev->mdio.dev.of_node) {
 		u32 reg;
 		int len;
-- 
2.39.2


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

* [RFC/RFT 23/23] net: phy: Disable EEE advertisement by default
  2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
                   ` (21 preceding siblings ...)
  2023-03-27 17:02 ` [RFC/RFT 22/23] net: phylib: call phy_support_eee() " Andrew Lunn
@ 2023-03-27 17:02 ` Andrew Lunn
  22 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 17:02 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Heiner Kallweit, Russell King, Oleksij Rempel,
	Andrew Lunn

EEE should only be advertised if the MAC supports it. Clear
advertising_eee by default. If the MAC indicates it supports EEE by
calling phy_support_eee() advertising_eee will be set to
supported_eee. When the PHY is started, EEE registers will then be
configured.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/phy/phy_device.c | 21 ++++-----------------
 1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 30f07623637b..d571738be3d8 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -3153,24 +3153,11 @@ static int phy_probe(struct device *dev)
 	of_set_phy_supported(phydev);
 	phy_advertise_supported(phydev);
 
-	/* Get PHY default EEE advertising modes and handle them as potentially
-	 * safe initial configuration.
+	/* Clear EEE advertising until the MAC indicates it also
+	   supports EEE.
 	 */
-	err = genphy_c45_read_eee_adv(phydev, phydev->advertising_eee);
-	if (err)
-		goto out;
-
-	/* There is no "enabled" flag. If PHY is advertising, assume it is
-	 * kind of enabled.
-	 */
-	phydev->eee_enabled = !linkmode_empty(phydev->advertising_eee);
-
-	/* Some PHYs may advertise, by default, not support EEE modes. So,
-	 * we need to clean them.
-	 */
-	if (phydev->eee_enabled)
-		linkmode_and(phydev->advertising_eee, phydev->supported_eee,
-			     phydev->advertising_eee);
+	linkmode_zero(phydev->advertising_eee);
+	phydev->eee_enabled = false;
 
 	/* Get the EEE modes we want to prohibit. We will ask
 	 * the PHY stop advertising these mode later on
-- 
2.39.2


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

* Re: [RFC/RFT 01/23] net: phy: Add phydev->eee_active to simplify adjust link callbacks
  2023-03-27 17:01 ` [RFC/RFT 01/23] net: phy: Add phydev->eee_active to simplify adjust link callbacks Andrew Lunn
@ 2023-03-27 17:54   ` Russell King (Oracle)
  0 siblings, 0 replies; 38+ messages in thread
From: Russell King (Oracle) @ 2023-03-27 17:54 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, Florian Fainelli, Heiner Kallweit, Oleksij Rempel

On Mon, Mar 27, 2023 at 07:01:39PM +0200, Andrew Lunn wrote:
> MAC drivers which support EEE need to know the results of the EEE
> auto-neg in order to program the hardware to perform EEE or not.  The
> oddly named phy_init_eee() can be used to determine this, it returns 0
> if EEE should be used, or a negative error code,
> e.g. -EOPPROTONOTSUPPORT if the PHY does not support EEE or negotiate
> resulted in it not being used.
> 
> However, many MAC drivers get this wrong. Add phydev->eee_active which
> indicates the result of the autoneg for EEE, including if EEE is
> administratively disabled with ethtool. The MAC driver can then access
> this in the same way as link speed and duplex in the adjust link
> callback.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>

Thanks!

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

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

* Re: [RFC/RFT 02/23] net: phylink: Plumb eee_active in mac_link_up call
  2023-03-27 17:01 ` [RFC/RFT 02/23] net: phylink: Plumb eee_active in mac_link_up call Andrew Lunn
@ 2023-03-27 17:57   ` Russell King (Oracle)
  2023-03-27 21:53   ` Russell King (Oracle)
  1 sibling, 0 replies; 38+ messages in thread
From: Russell King (Oracle) @ 2023-03-27 17:57 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, Florian Fainelli, Heiner Kallweit, Oleksij Rempel

On Mon, Mar 27, 2023 at 07:01:40PM +0200, Andrew Lunn wrote:
> MAC drivers need to know the result of the auto negotiation of Energy
> Efficient Ethernet. This is a simple boolean, it should be active or
> not in the MAC. Extend the mac_link_up call to pass this.
> 
> Currently the correct value should be passed, however no MAC drivers
> have been modified to actually use it. Yet.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>

Thanks!

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

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

* Re: [RFC/RFT 03/23] net: phy: Add helper to set EEE Clock stop enable bit
  2023-03-27 17:01 ` [RFC/RFT 03/23] net: phy: Add helper to set EEE Clock stop enable bit Andrew Lunn
@ 2023-03-27 17:58   ` Russell King (Oracle)
  2023-03-28  5:03   ` Oleksij Rempel
  1 sibling, 0 replies; 38+ messages in thread
From: Russell King (Oracle) @ 2023-03-27 17:58 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, Florian Fainelli, Heiner Kallweit, Oleksij Rempel

On Mon, Mar 27, 2023 at 07:01:41PM +0200, Andrew Lunn wrote:
> The MAC driver can request that the PHY stops the clock during EEE
> LPI. This has normally been does as part of phy_init_eee(), however
> that function is overly complex and often wrongly used. Add a
> standalone helper, to aid removing phy_init_eee().
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>

Thanks!

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

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

* Re: [RFC/RFT 04/23] net: phy: Keep track of EEE tx_lpi_enabled
  2023-03-27 17:01 ` [RFC/RFT 04/23] net: phy: Keep track of EEE tx_lpi_enabled Andrew Lunn
@ 2023-03-27 17:58   ` Russell King (Oracle)
  0 siblings, 0 replies; 38+ messages in thread
From: Russell King (Oracle) @ 2023-03-27 17:58 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, Florian Fainelli, Heiner Kallweit, Oleksij Rempel

On Mon, Mar 27, 2023 at 07:01:42PM +0200, Andrew Lunn wrote:
> Have phylib keep track of the EEE tx_lpi_enabled configuration.  This
> simplifies the MAC drivers, in that they don't need to store it.
> 
> Future patches to phylib will also make use of this information to
> further simplify the MAC drivers.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>

Thanks!

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

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

* Re: [RFC/RFT 05/23] net: phy: Immediately call adjust_link if only tx_lpi_enabled changes
  2023-03-27 17:01 ` [RFC/RFT 05/23] net: phy: Immediately call adjust_link if only tx_lpi_enabled changes Andrew Lunn
@ 2023-03-27 18:02   ` Russell King (Oracle)
  2023-03-27 22:13     ` Andrew Lunn
  0 siblings, 1 reply; 38+ messages in thread
From: Russell King (Oracle) @ 2023-03-27 18:02 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, Florian Fainelli, Heiner Kallweit, Oleksij Rempel

On Mon, Mar 27, 2023 at 07:01:43PM +0200, Andrew Lunn wrote:
> The MAC driver changes its EEE hardware configuration in its
> adjust_link callback. This is called when auto-neg completes. If
> set_eee is called with a change to tx_lpi_enabled which does not
> trigger an auto-neg, it is necessary to call the adjust_link callback
> so that the MAC is reconfigured to take this change into account.
> 
> When setting phydev->eee_active, take tx_lpi_enabled into account, so
> the MAC drivers don't need to consider tx_lpi_enabled.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Hmm..

> @@ -1619,11 +1619,20 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
>  
>  	mutex_lock(&phydev->lock);
>  	ret = genphy_c45_ethtool_set_eee(phydev, data);
> -	if (!ret)
> +	if (ret >= 0) {
> +		if (ret == 0) {
> +			/* auto-neg not triggered */
> +			if (phydev->tx_lpi_enabled != data->tx_lpi_enabled) {
> +				phydev->tx_lpi_enabled = data->tx_lpi_enabled;
> +				if (phydev->link)
> +					phy_link_up(phydev);
> +			}
> +		}
>  		phydev->tx_lpi_enabled = data->tx_lpi_enabled;

So we set eee_active depending on tx_lpi_enabled:

> +			phydev->eee_active = (err & phydev->tx_lpi_enabled);

However, if tx_lpi_enabled changes state in this function, we don't
update phydev->eee_active, but it's phydev->eee_active that gets
passed back to MAC drivers. Is that intentional?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

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

* Re: [RFC/RFT 18/23] net: usb: lan78xx: Fixup EEE
  2023-03-27 17:01 ` [RFC/RFT 18/23] net: usb: lan78xx: Fixup EEE Andrew Lunn
@ 2023-03-27 20:56   ` kernel test robot
  0 siblings, 0 replies; 38+ messages in thread
From: kernel test robot @ 2023-03-27 20:56 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: oe-kbuild-all

Hi Andrew,

[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on net-next/main]
[also build test ERROR on next-20230327]
[cannot apply to horms-ipvs/master net/main linus/master v6.3-rc4]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andrew-Lunn/net-phy-Add-phydev-eee_active-to-simplify-adjust-link-callbacks/20230328-011028
patch link:    https://lore.kernel.org/r/20230327170201.2036708-19-andrew%40lunn.ch
patch subject: [RFC/RFT 18/23] net: usb: lan78xx: Fixup EEE
config: riscv-allmodconfig (https://download.01.org/0day-ci/archive/20230328/202303280408.oSjPt0Zb-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/1c73847c47808e1b064f8520dda3d05868e771eb
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Andrew-Lunn/net-phy-Add-phydev-eee_active-to-simplify-adjust-link-callbacks/20230328-011028
        git checkout 1c73847c47808e1b064f8520dda3d05868e771eb
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=riscv olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/net/usb/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202303280408.oSjPt0Zb-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/net/usb/lan78xx.c: In function 'lan78xx_link_status_change':
>> drivers/net/usb/lan78xx.c:2106:17: error: 'data' undeclared (first use in this function); did you mean '_data'?
    2106 |                 data |=  MAC_CR_EEE_EN_;
         |                 ^~~~
         |                 _data
   drivers/net/usb/lan78xx.c:2106:17: note: each undeclared identifier is reported only once for each function it appears in


vim +2106 drivers/net/usb/lan78xx.c

  2099	
  2100	static void lan78xx_link_status_change(struct net_device *net)
  2101	{
  2102		struct lan78xx_net *dev = netdev_priv(net);
  2103		struct phy_device *phydev = net->phydev;
  2104	
  2105		if (phydev->eee_active)
> 2106			data |=  MAC_CR_EEE_EN_;
  2107		else
  2108			data &= ~MAC_CR_EEE_EN_;
  2109		lan78xx_write_reg(dev, MAC_CR, data);
  2110	
  2111		phy_print_status(phydev);
  2112	}
  2113	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

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

* Re: [RFC/RFT 02/23] net: phylink: Plumb eee_active in mac_link_up call
  2023-03-27 17:01 ` [RFC/RFT 02/23] net: phylink: Plumb eee_active in mac_link_up call Andrew Lunn
  2023-03-27 17:57   ` Russell King (Oracle)
@ 2023-03-27 21:53   ` Russell King (Oracle)
  2023-03-27 22:45     ` Andrew Lunn
  1 sibling, 1 reply; 38+ messages in thread
From: Russell King (Oracle) @ 2023-03-27 21:53 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, Florian Fainelli, Heiner Kallweit, Oleksij Rempel

Hi Andrew,

Thinking about this more having read the follow-on patches, I retract
my r-b tag, because there is an issue that needs solving.

On Mon, Mar 27, 2023 at 07:01:40PM +0200, Andrew Lunn wrote:
> @@ -1257,7 +1260,8 @@ static void phylink_link_up(struct phylink *pl,
>  
>  	pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode,
>  				 pl->cur_interface, speed, duplex,
> -				 !!(link_state.pause & MLO_PAUSE_TX), rx_pause);
> +				 !!(link_state.pause & MLO_PAUSE_TX), rx_pause,
> +				 eee_active);

In one of your later patches, you have phylib call phy_link_up() when
the state changes as a result of configuration. That will cause
phy_link_change(), which will update phylink's stored link state, and
trigger phylink to re-resolve the link.

However, phylink guarantees that mac_link_up() will only be called
if mac_link_down() was previously called. This will *not* cause
mac_link_up() to be called.

Moreover, we don't want mac_link_up() to be called because the link
hasn't gone down and to do so will violate that guarantee that
phylink makes to MAC drivers.

So, I don't think this is going to work fully as seems to be intended,
if I'm understanding things correctly.

Maybe we should have a new mac_set_eee() method which we can call
when the EEE state changes? Would we need to call it with the LPI
delay parameter and wheneever that changes, or should we rely on
the MAC to do that? What if the LPI parameter is dependent on the
speed the MAC is operating? Just brain-storming...

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

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

* Re: [RFC/RFT 20/23] net: phylink: Add MAC_EEE to mac_capabilites
  2023-03-27 17:01 ` [RFC/RFT 20/23] net: phylink: Add MAC_EEE to mac_capabilites Andrew Lunn
@ 2023-03-27 21:59   ` Russell King (Oracle)
  2023-03-27 22:15     ` Andrew Lunn
  0 siblings, 1 reply; 38+ messages in thread
From: Russell King (Oracle) @ 2023-03-27 21:59 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, Florian Fainelli, Heiner Kallweit, Oleksij Rempel

On Mon, Mar 27, 2023 at 07:01:58PM +0200, Andrew Lunn wrote:
> If the MAC supports Energy Efficient Ethernet, it should indicate this
> by setting the MAC_EEE bit in the config.mac_capabilities
> bitmap. phylink will then enable EEE in the PHY, if it supports it.

I know it will be a larger patch, but I would prefer to add it after
MAC_ASYM_PAUSE and shuffle the speeds up. I'm sure network speeds will
continue to increase, resulting in more bits added in the future.

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

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

* Re: [RFC/RFT 05/23] net: phy: Immediately call adjust_link if only tx_lpi_enabled changes
  2023-03-27 18:02   ` Russell King (Oracle)
@ 2023-03-27 22:13     ` Andrew Lunn
  0 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 22:13 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: netdev, Florian Fainelli, Heiner Kallweit, Oleksij Rempel

On Mon, Mar 27, 2023 at 07:02:01PM +0100, Russell King (Oracle) wrote:
> On Mon, Mar 27, 2023 at 07:01:43PM +0200, Andrew Lunn wrote:
> > The MAC driver changes its EEE hardware configuration in its
> > adjust_link callback. This is called when auto-neg completes. If
> > set_eee is called with a change to tx_lpi_enabled which does not
> > trigger an auto-neg, it is necessary to call the adjust_link callback
> > so that the MAC is reconfigured to take this change into account.
> > 
> > When setting phydev->eee_active, take tx_lpi_enabled into account, so
> > the MAC drivers don't need to consider tx_lpi_enabled.
> > 
> > Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> 
> Hmm..
> 
> > @@ -1619,11 +1619,20 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
> >  
> >  	mutex_lock(&phydev->lock);
> >  	ret = genphy_c45_ethtool_set_eee(phydev, data);
> > -	if (!ret)
> > +	if (ret >= 0) {
> > +		if (ret == 0) {
> > +			/* auto-neg not triggered */
> > +			if (phydev->tx_lpi_enabled != data->tx_lpi_enabled) {
> > +				phydev->tx_lpi_enabled = data->tx_lpi_enabled;
> > +				if (phydev->link)
> > +					phy_link_up(phydev);
> > +			}
> > +		}
> >  		phydev->tx_lpi_enabled = data->tx_lpi_enabled;
> 
> So we set eee_active depending on tx_lpi_enabled:
> 
> > +			phydev->eee_active = (err & phydev->tx_lpi_enabled);
> 
> However, if tx_lpi_enabled changes state in this function, we don't
> update phydev->eee_active, but it's phydev->eee_active that gets
> passed back to MAC drivers. Is that intentional?

No, that is a bug. I don't think phy_check_link_status() can be called
here, since we might not be in state RUNNING. So a bit of refactoring
is required to add a function which can update phydev->eee_active.

Thanks
	Andrew

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

* Re: [RFC/RFT 20/23] net: phylink: Add MAC_EEE to mac_capabilites
  2023-03-27 21:59   ` Russell King (Oracle)
@ 2023-03-27 22:15     ` Andrew Lunn
  0 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 22:15 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: netdev, Florian Fainelli, Heiner Kallweit, Oleksij Rempel

On Mon, Mar 27, 2023 at 10:59:51PM +0100, Russell King (Oracle) wrote:
> On Mon, Mar 27, 2023 at 07:01:58PM +0200, Andrew Lunn wrote:
> > If the MAC supports Energy Efficient Ethernet, it should indicate this
> > by setting the MAC_EEE bit in the config.mac_capabilities
> > bitmap. phylink will then enable EEE in the PHY, if it supports it.
> 
> I know it will be a larger patch, but I would prefer to add it after
> MAC_ASYM_PAUSE and shuffle the speeds up. I'm sure network speeds will
> continue to increase, resulting in more bits added in the future.

O.K, i can make the new symbol BIT(2).

Thanks
	Andrew

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

* Re: [RFC/RFT 02/23] net: phylink: Plumb eee_active in mac_link_up call
  2023-03-27 21:53   ` Russell King (Oracle)
@ 2023-03-27 22:45     ` Andrew Lunn
  0 siblings, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-27 22:45 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: netdev, Florian Fainelli, Heiner Kallweit, Oleksij Rempel

On Mon, Mar 27, 2023 at 10:53:36PM +0100, Russell King (Oracle) wrote:
> Hi Andrew,
> 
> Thinking about this more having read the follow-on patches, I retract
> my r-b tag, because there is an issue that needs solving.
> 
> On Mon, Mar 27, 2023 at 07:01:40PM +0200, Andrew Lunn wrote:
> > @@ -1257,7 +1260,8 @@ static void phylink_link_up(struct phylink *pl,
> >  
> >  	pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode,
> >  				 pl->cur_interface, speed, duplex,
> > -				 !!(link_state.pause & MLO_PAUSE_TX), rx_pause);
> > +				 !!(link_state.pause & MLO_PAUSE_TX), rx_pause,
> > +				 eee_active);
> 
> In one of your later patches, you have phylib call phy_link_up() when
> the state changes as a result of configuration. That will cause
> phy_link_change(), which will update phylink's stored link state, and
> trigger phylink to re-resolve the link.
> 
> However, phylink guarantees that mac_link_up() will only be called
> if mac_link_down() was previously called. This will *not* cause
> mac_link_up() to be called.

Ah, O.K.

> 
> Moreover, we don't want mac_link_up() to be called because the link
> hasn't gone down and to do so will violate that guarantee that
> phylink makes to MAC drivers.

O.K. I don't think phylib makes the same guarantee.

> So, I don't think this is going to work fully as seems to be intended,
> if I'm understanding things correctly.

You are correct. If the EEE configuration is changed and an auto-neg
is not required, i was not intending to force an autoneg so the link
goes down and up again.

> Maybe we should have a new mac_set_eee() method which we can call
> when the EEE state changes? Would we need to call it with the LPI
> delay parameter and wheneever that changes, or should we rely on
> the MAC to do that?

For the current hardware, the MAC gets all the parameters passed as
part of the ethtool set call. They write the delay parameters to
hardware. And then there is one bit to enable/disable the us of EEE.
So the mac_set_eee() callback should only need to pass a boolean.

>What if the LPI parameter is dependent on the
> speed the MAC is operating? Just brain-storming...

None of the current hardware needs that. And we only need to call
mac_set_eee() when the link is up, so the MAC probably knows the link
speed one way or another.

I will rework this code with a new callback.

  Andrew

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

* Re: [RFC/RFT 03/23] net: phy: Add helper to set EEE Clock stop enable bit
  2023-03-27 17:01 ` [RFC/RFT 03/23] net: phy: Add helper to set EEE Clock stop enable bit Andrew Lunn
  2023-03-27 17:58   ` Russell King (Oracle)
@ 2023-03-28  5:03   ` Oleksij Rempel
  2023-03-28  5:13     ` Oleksij Rempel
  2023-03-28 12:09     ` Andrew Lunn
  1 sibling, 2 replies; 38+ messages in thread
From: Oleksij Rempel @ 2023-03-28  5:03 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, Florian Fainelli, Heiner Kallweit, Russell King

On Mon, Mar 27, 2023 at 07:01:41PM +0200, Andrew Lunn wrote:
> The MAC driver can request that the PHY stops the clock during EEE
> LPI. This has normally been does as part of phy_init_eee(), however
> that function is overly complex and often wrongly used. Add a
> standalone helper, to aid removing phy_init_eee().
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> v2: Add missing EXPORT_SYMBOL_GPL
> ---
>  drivers/net/phy/phy.c | 20 ++++++++++++++++++++
>  include/linux/phy.h   |  1 +
>  2 files changed, 21 insertions(+)
> 
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index 68e1ce942dd6..d3d6ff4ed488 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -1503,6 +1503,26 @@ void phy_mac_interrupt(struct phy_device *phydev)
>  }
>  EXPORT_SYMBOL(phy_mac_interrupt);
>  
> +/**
> + * phy_eee_clk_stop_enable - Clock should stop during LIP
> + * @phydev: target phy_device struct
> + *
> + * Description: Program the MMD register 3.0 setting the "Clock stop enable"
> + * bit.


> + */
> +int phy_eee_clk_stop_enable(struct phy_device *phydev)

this function should go to drivers/net/phy/phy-c45.c
and renamed to genphy_c45_eee_clk_stop_enable()
> +{
> +	int ret;
> +
> +	mutex_lock(&phydev->lock);

	/* IEEE 802.3-2018 45.2.3.1.4 Clock stop enable (3.0.10) */

> +	ret = phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
> +			       MDIO_PCS_CTRL1_CLKSTOP_EN);

It would be better to write it conditionally. Only if EEE is supported
and only if this bit is supported as well. Support is indicated by the
IEEE 802.3:2018 - 45.2.3.2.6 Clock stop capable (3.1.6)

It looks like there are other registers for same functionality too but
other types of PHYs:
45.2.4.1.4 Clock stop enable (4.0.10)
45.2.4.2.6 Clock stop capable (4.1.6)
45.2.5.1.4 Clock stop enable (5.0.10)
45.2.5.2.6 Clock stop capable (5.1.6)

If I see it correctly, Clock-stop is possible only for GMII/RGMII.
Integrated PHYs or EEE capable PHYs with RMII do not support it.
For example KSZ8091RNA with RMII:
https://ww1.microchip.com/downloads/en/DeviceDoc/KSZ8091RNA-RND-10BASE-T-100BASE-TX-PHY-with-RMII-and-EEE-Support-DS00002298B.pdf
KSZ9477 switch with integrated PHYs:
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/KSZ9477S-Data-Sheet-DS00002392C.pdf

> +	mutex_unlock(&phydev->lock);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(phy_eee_clk_stop_enable);
> +
>  /**
>   * phy_init_eee - init and check the EEE feature
>   * @phydev: target phy_device struct
> diff --git a/include/linux/phy.h b/include/linux/phy.h
> index 2508f1d99777..12addd1c29f2 100644
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
> @@ -1846,6 +1846,7 @@ int phy_unregister_fixup_for_id(const char *bus_id);
>  int phy_unregister_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask);
>  
>  int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable);
> +int phy_eee_clk_stop_enable(struct phy_device *phydev);
>  int phy_get_eee_err(struct phy_device *phydev);
>  int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data);
>  int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data);
> -- 
> 2.39.2
> 
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* Re: [RFC/RFT 03/23] net: phy: Add helper to set EEE Clock stop enable bit
  2023-03-28  5:03   ` Oleksij Rempel
@ 2023-03-28  5:13     ` Oleksij Rempel
  2023-03-28 12:09     ` Andrew Lunn
  1 sibling, 0 replies; 38+ messages in thread
From: Oleksij Rempel @ 2023-03-28  5:13 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, Florian Fainelli, Heiner Kallweit, Russell King

On Tue, Mar 28, 2023 at 07:03:27AM +0200, Oleksij Rempel wrote:
> On Mon, Mar 27, 2023 at 07:01:41PM +0200, Andrew Lunn wrote:
> > The MAC driver can request that the PHY stops the clock during EEE
> > LPI. This has normally been does as part of phy_init_eee(), however
> > that function is overly complex and often wrongly used. Add a
> > standalone helper, to aid removing phy_init_eee().
> > 
> > Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> > ---
> > v2: Add missing EXPORT_SYMBOL_GPL
> > ---
> >  drivers/net/phy/phy.c | 20 ++++++++++++++++++++
> >  include/linux/phy.h   |  1 +
> >  2 files changed, 21 insertions(+)
> > 
> > diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> > index 68e1ce942dd6..d3d6ff4ed488 100644
> > --- a/drivers/net/phy/phy.c
> > +++ b/drivers/net/phy/phy.c
> > @@ -1503,6 +1503,26 @@ void phy_mac_interrupt(struct phy_device *phydev)
> >  }
> >  EXPORT_SYMBOL(phy_mac_interrupt);
> >  
> > +/**
> > + * phy_eee_clk_stop_enable - Clock should stop during LIP
> > + * @phydev: target phy_device struct
> > + *
> > + * Description: Program the MMD register 3.0 setting the "Clock stop enable"
> > + * bit.
> 
> 
> > + */
> > +int phy_eee_clk_stop_enable(struct phy_device *phydev)
> 
> this function should go to drivers/net/phy/phy-c45.c
> and renamed to genphy_c45_eee_clk_stop_enable()
> > +{
> > +	int ret;
> > +
> > +	mutex_lock(&phydev->lock);
> 
> 	/* IEEE 802.3-2018 45.2.3.1.4 Clock stop enable (3.0.10) */
> 
> > +	ret = phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
> > +			       MDIO_PCS_CTRL1_CLKSTOP_EN);
> 
> It would be better to write it conditionally. Only if EEE is supported
> and only if this bit is supported as well. Support is indicated by the
> IEEE 802.3:2018 - 45.2.3.2.6 Clock stop capable (3.1.6)
> 
> It looks like there are other registers for same functionality too but
> other types of PHYs:
> 45.2.4.1.4 Clock stop enable (4.0.10)
> 45.2.4.2.6 Clock stop capable (4.1.6)
> 45.2.5.1.4 Clock stop enable (5.0.10)
> 45.2.5.2.6 Clock stop capable (5.1.6)
> 
> If I see it correctly, Clock-stop is possible only for GMII/RGMII.
> Integrated PHYs or EEE capable PHYs with RMII do not support it.
> For example KSZ8091RNA with RMII:
> https://ww1.microchip.com/downloads/en/DeviceDoc/KSZ8091RNA-RND-10BASE-T-100BASE-TX-PHY-with-RMII-and-EEE-Support-DS00002298B.pdf
> KSZ9477 switch with integrated PHYs:
> https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/KSZ9477S-Data-Sheet-DS00002392C.pdf

One more PHY, with RGMII support, but without clock-stop, which is
probably indicated by 3.1.6 bit.
https://ww1.microchip.com/downloads/aemDocuments/documents/AERO/ProductDocuments/DataSheets/VSC8540ET_Extended_Temperature_Single_Port_Fast_Ethernet_Copper_PHY_DS60001648.pdf

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* Re: [RFC/RFT 03/23] net: phy: Add helper to set EEE Clock stop enable bit
  2023-03-28  5:03   ` Oleksij Rempel
  2023-03-28  5:13     ` Oleksij Rempel
@ 2023-03-28 12:09     ` Andrew Lunn
  1 sibling, 0 replies; 38+ messages in thread
From: Andrew Lunn @ 2023-03-28 12:09 UTC (permalink / raw)
  To: Oleksij Rempel; +Cc: netdev, Florian Fainelli, Heiner Kallweit, Russell King

> > + */
> > +int phy_eee_clk_stop_enable(struct phy_device *phydev)
> 
> this function should go to drivers/net/phy/phy-c45.c
> and renamed to genphy_c45_eee_clk_stop_enable()
> > +{
> > +	int ret;
> > +
> > +	mutex_lock(&phydev->lock);
> 
> 	/* IEEE 802.3-2018 45.2.3.1.4 Clock stop enable (3.0.10) */
> 
> > +	ret = phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
> > +			       MDIO_PCS_CTRL1_CLKSTOP_EN);
> 
> It would be better to write it conditionally. Only if EEE is supported
> and only if this bit is supported as well. Support is indicated by the
> IEEE 802.3:2018 - 45.2.3.2.6 Clock stop capable (3.1.6)

O.K, i was too lazy. I just took the existing code in phy_eee_init()
and moved it here. I can rework it as requested.

> It looks like there are other registers for same functionality too but
> other types of PHYs:
> 45.2.4.1.4 Clock stop enable (4.0.10)
> 45.2.4.2.6 Clock stop capable (4.1.6)
> 45.2.5.1.4 Clock stop enable (5.0.10)
> 45.2.5.2.6 Clock stop capable (5.1.6)
> 
> If I see it correctly, Clock-stop is possible only for GMII/RGMII.
> Integrated PHYs or EEE capable PHYs with RMII do not support it.

For the existing code, it is up to the MAC to decide if the clock
should be stopped. It is not clear why, but we do see some MACs where
the DMA engine stops working when the clock is stopped. So i don't
want to be overly eager to stop clocks and introduce regressions.  So
i will keep with just one clock above. But make it conditional on the
capability.

	Andrew


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

end of thread, other threads:[~2023-03-28 12:09 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-27 17:01 [RFC/RFT 00/23] net: ethernet: Rework EEE Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 01/23] net: phy: Add phydev->eee_active to simplify adjust link callbacks Andrew Lunn
2023-03-27 17:54   ` Russell King (Oracle)
2023-03-27 17:01 ` [RFC/RFT 02/23] net: phylink: Plumb eee_active in mac_link_up call Andrew Lunn
2023-03-27 17:57   ` Russell King (Oracle)
2023-03-27 21:53   ` Russell King (Oracle)
2023-03-27 22:45     ` Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 03/23] net: phy: Add helper to set EEE Clock stop enable bit Andrew Lunn
2023-03-27 17:58   ` Russell King (Oracle)
2023-03-28  5:03   ` Oleksij Rempel
2023-03-28  5:13     ` Oleksij Rempel
2023-03-28 12:09     ` Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 04/23] net: phy: Keep track of EEE tx_lpi_enabled Andrew Lunn
2023-03-27 17:58   ` Russell King (Oracle)
2023-03-27 17:01 ` [RFC/RFT 05/23] net: phy: Immediately call adjust_link if only tx_lpi_enabled changes Andrew Lunn
2023-03-27 18:02   ` Russell King (Oracle)
2023-03-27 22:13     ` Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 06/23] net: marvell: mvneta: Simplify EEE configuration Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 07/23] net: stmmac: Drop usage of phy_init_eee() Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 08/23] net: stmmac: Simplify ethtool get eee Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 09/23] net: lan743x: Fixup EEE Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 10/23] net: fec: Move fec_enet_eee_mode_set() and helper earlier Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 11/23] net: FEC: Fixup EEE Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 12/23] net: genet: " Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 13/23] net: sxgdb: " Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 14/23] net: dsa: mt7530: Swap to using phydev->eee_active Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 15/23] net: dsa: b53: " Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 16/23] net: phylink: Remove unused phylink_init_eee() Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 17/23] net: phy: remove unused phy_init_eee() Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 18/23] net: usb: lan78xx: Fixup EEE Andrew Lunn
2023-03-27 20:56   ` kernel test robot
2023-03-27 17:01 ` [RFC/RFT 19/23] net: phy: Add phy_support_eee() indicating MAC support EEE Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 20/23] net: phylink: Add MAC_EEE to mac_capabilites Andrew Lunn
2023-03-27 21:59   ` Russell King (Oracle)
2023-03-27 22:15     ` Andrew Lunn
2023-03-27 17:01 ` [RFC/RFT 21/23] net: phylink: Extend mac_capabilities in MAC drivers which support EEE Andrew Lunn
2023-03-27 17:02 ` [RFC/RFT 22/23] net: phylib: call phy_support_eee() " Andrew Lunn
2023-03-27 17:02 ` [RFC/RFT 23/23] net: phy: Disable EEE advertisement by default Andrew Lunn

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.