All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Russell King (Oracle)" <linux@armlinux.org.uk>
To: Sean Anderson <sean.anderson@seco.com>
Cc: netdev@vger.kernel.org, Andrew Lunn <andrew@lunn.ch>,
	Heiner Kallweit <hkallweit1@gmail.com>,
	Alexandru Marginean <alexandru.marginean@nxp.com>,
	Paolo Abeni <pabeni@redhat.com>,
	"David S . Miller" <davem@davemloft.net>,
	linux-kernel@vger.kernel.org, Vladimir Oltean <olteanv@gmail.com>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>
Subject: Re: [PATCH v2 07/11] net: phylink: Adjust link settings based on rate adaptation
Date: Wed, 20 Jul 2022 19:32:41 +0100	[thread overview]
Message-ID: <YthKSYje5e+swg08@shell.armlinux.org.uk> (raw)
In-Reply-To: <YtelzB1uO0zACa42@shell.armlinux.org.uk>

On Wed, Jul 20, 2022 at 07:50:52AM +0100, Russell King (Oracle) wrote:
> We can do that by storing the PHY rate adaption state, and processing
> that in phylink_link_up().

Something like this? I haven't included the IPG (open loop) stuff in
this - I think when we come to implement that, we need a new mac
method to call to set the IPG just before calling mac_link_up().
Something like:

 void mac_set_ipg(struct phylink_config *config, int packet_speed,
		  int interface_speed);

Note that we also have PCS that do rate adaption too, and I think
fitting those in with the code below may be easier than storing the
media and phy interface speed/duplex separately.

A few further question though - does rate adaption make sense with
interface modes that can already natively handle the different speeds,
such as SGMII, RGMII, USXGMII, etc?

 drivers/net/phy/phylink.c | 103 ++++++++++++++++++++++++++++++++++++++++++++--
 include/linux/phylink.h   |   1 +
 2 files changed, 100 insertions(+), 4 deletions(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 9bd69328dc4d..c89eb74458cd 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -994,23 +994,105 @@ static const char *phylink_pause_to_str(int pause)
 	}
 }
 
+static int phylink_interface_max_speed(phy_interface_t interface)
+{
+	switch (interface) {
+	case PHY_INTERFACE_MODE_100BASEX:
+	case PHY_INTERFACE_MODE_REVRMII:
+	case PHY_INTERFACE_MODE_RMII:
+	case PHY_INTERFACE_MODE_SMII:
+	case PHY_INTERFACE_MODE_REVMII:
+	case PHY_INTERFACE_MODE_MII:
+		return SPEED_100;
+
+	case PHY_INTERFACE_MODE_TBI:
+	case PHY_INTERFACE_MODE_MOCA:
+	case PHY_INTERFACE_MODE_RTBI:
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_1000BASEKX:
+	case PHY_INTERFACE_MODE_TRGMII:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_QSGMII:
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_GMII:
+		return SPEED_1000;
+
+	case PHY_INTERFACE_MODE_2500BASEX:
+		return SPEED_2500;
+
+	case PHY_INTERFACE_MODE_5GBASER:
+		return SPEED_5000;
+
+	case PHY_INTERFACE_MODE_XGMII:
+	case PHY_INTERFACE_MODE_RXAUI:
+	case PHY_INTERFACE_MODE_XAUI:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_10GKR:
+	case PHY_INTERFACE_MODE_USXGMII:
+		return SPEED_10000;
+
+	case PHY_INTERFACE_MODE_25GBASER:
+		return SPEED_25000;
+
+	case PHY_INTERFACE_MODE_XLGMII:
+		return SPEED_40000;
+
+	case PHY_INTERFACE_MODE_INTERNAL:
+		/* Rate adaption is probably not supported */
+		return 0;
+
+	case PHY_INTERFACE_MODE_NA:
+	case PHY_INTERFACE_MODE_MAX:
+		return SPEED_UNKNOWN;
+	}
+}
+
 static void phylink_link_up(struct phylink *pl,
 			    struct phylink_link_state link_state)
 {
 	struct net_device *ndev = pl->netdev;
+	int speed, duplex;
+	bool rx_pause;
+
+	speed = link_state.speed;
+	duplex = link_state.duplex;
+	rx_pause = !!(link_state.pause & MLO_PAUSE_RX);
+
+	switch (state->rate_adaption) {
+	case RATE_ADAPT_PAUSE:
+		/* The PHY is doing rate adaption from the media rate (in
+		 * the link_state) to the interface speed, and will send
+		 * pause frames to the MAC to limit its transmission speed.
+		 */
+		speed = phylink_interface_max_speed(link_state.interface);
+		duplex = DUPLEX_FULL;
+		rx_pause = true;
+		break;
+
+	case RATE_ADAPT_CRS:
+		/* The PHY is doing rate adaption from the media rate (in
+		 * the link_state) to the interface speed, and will cause
+		 * collisions to the MAC to limit its transmission speed.
+		 */
+		speed = phylink_interface_max_speed(link_state.interface);
+		duplex = DUPLEX_HALF;
+		break;
+	}
 
 	pl->cur_interface = link_state.interface;
 
 	if (pl->pcs && pl->pcs->ops->pcs_link_up)
 		pl->pcs->ops->pcs_link_up(pl->pcs, pl->cur_link_an_mode,
-					 pl->cur_interface,
-					 link_state.speed, link_state.duplex);
+					 pl->cur_interface, speed, duplex);
 
 	pl->mac_ops->mac_link_up(pl->config, pl->phydev,
 				 pl->cur_link_an_mode, pl->cur_interface,
-				 link_state.speed, link_state.duplex,
+				 speed, duplex,
 				 !!(link_state.pause & MLO_PAUSE_TX),
-				 !!(link_state.pause & MLO_PAUSE_RX));
+				 rx_pause);
 
 	if (ndev)
 		netif_carrier_on(ndev);
@@ -1102,6 +1184,17 @@ static void phylink_resolve(struct work_struct *w)
 				}
 				link_state.interface = pl->phy_state.interface;
 
+				/* If we are doing rate adaption, then the
+				 * media speed/duplex has to come from the PHY.
+				 */
+				if (pl->phy_state.rate_adaption) {
+					link_state.rate_adaption =
+						pl->phy_state.rate_adaption;
+					link_state.speed = pl->phy_state.speed;
+					link_state.duplex =
+						pl->phy_state.duplex;
+				}
+
 				/* If we have a PHY, we need to update with
 				 * the PHY flow control bits.
 				 */
@@ -1337,6 +1430,7 @@ static void phylink_phy_change(struct phy_device *phydev, bool up)
 	pl->phy_state.speed = phydev->speed;
 	pl->phy_state.duplex = phydev->duplex;
 	pl->phy_state.pause = MLO_PAUSE_NONE;
+	pl->phy_state.rate_adaption = phydev->rate_adaption;
 	if (tx_pause)
 		pl->phy_state.pause |= MLO_PAUSE_TX;
 	if (rx_pause)
@@ -1414,6 +1508,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.rate_adaption = RATE_ADAPT_NONE;
 	linkmode_copy(pl->supported, supported);
 	linkmode_copy(pl->link_config.advertising, config.advertising);
 
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 6d06896fc20d..65301e7961b0 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -70,6 +70,7 @@ struct phylink_link_state {
 	int speed;
 	int duplex;
 	int pause;
+	int rate_adaption;
 	unsigned int link:1;
 	unsigned int an_enabled:1;
 	unsigned int an_complete:1;

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

  reply	other threads:[~2022-07-20 18:32 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-19 23:49 [PATCH v2 00/11] net: phy: Add support for rate adaptation Sean Anderson
2022-07-19 23:49 ` [PATCH v2 01/11] net: dpaa: Fix <1G ethernet on LS1046ARDB Sean Anderson
2022-07-21 12:34   ` Camelia Alexandra Groza
2022-07-19 23:49 ` [PATCH v2 02/11] net: phy: Add 1000BASE-KX interface mode Sean Anderson
2022-07-19 23:49 ` [PATCH v2 03/11] net: phylink: Export phylink_caps_to_linkmodes Sean Anderson
2022-07-19 23:49 ` [PATCH v2 04/11] net: phylink: Generate caps and convert to linkmodes separately Sean Anderson
2022-07-19 23:49 ` [PATCH v2 05/11] net: phy: Add support for rate adaptation Sean Anderson
2022-07-19 23:49 ` [PATCH v2 06/11] net: phylink: Support differing link/interface speed/duplex Sean Anderson
2022-07-20  6:43   ` Russell King (Oracle)
2022-07-21 16:15     ` Sean Anderson
2022-07-21 16:40       ` Andrew Lunn
2022-07-19 23:49 ` [PATCH v2 07/11] net: phylink: Adjust link settings based on rate adaptation Sean Anderson
2022-07-20  6:50   ` Russell King (Oracle)
2022-07-20 18:32     ` Russell King (Oracle) [this message]
2022-07-21 21:48       ` Sean Anderson
2022-07-22  8:45         ` Russell King (Oracle)
2022-07-21 16:24     ` Sean Anderson
2022-07-20  9:08   ` kernel test robot
2022-07-20  9:28   ` kernel test robot
2022-07-19 23:49 ` [PATCH v2 08/11] net: phylink: Adjust advertisement " Sean Anderson
2022-07-20  7:08   ` Russell King (Oracle)
2022-07-21 16:55     ` Sean Anderson
2022-07-21 18:04       ` Russell King (Oracle)
2022-07-21 18:36         ` Andrew Lunn
2022-07-21 19:02           ` Dave Taht
2022-07-21 19:24           ` Sean Anderson
2022-07-21 21:06           ` Russell King (Oracle)
2022-07-19 23:49 ` [PATCH v2 09/11] [RFC] net: phylink: Add support for CRS-based " Sean Anderson
2022-07-19 23:50 ` [PATCH v2 10/11] net: phy: aquantia: Add some additional phy interfaces Sean Anderson
2022-07-20 11:35   ` Russell King (Oracle)
2022-07-21 17:15     ` Sean Anderson
2022-07-19 23:50 ` [PATCH v2 11/11] net: phy: aquantia: Add support for rate adaptation Sean Anderson
2022-07-20 12:03 ` [PATCH v2 00/11] net: phy: " Russell King (Oracle)
2022-07-21 17:40   ` Sean Anderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YthKSYje5e+swg08@shell.armlinux.org.uk \
    --to=linux@armlinux.org.uk \
    --cc=alexandru.marginean@nxp.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=hkallweit1@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=pabeni@redhat.com \
    --cc=sean.anderson@seco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.