+From c04ade27cb7b952b6b9b9a0efa0a6129cc63f2ae Mon Sep 17 00:00:00 2001
+From: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Date: Wed, 17 Aug 2022 14:32:54 +0200
+Subject: [PATCH] net: phy: Add helper to derive the number of ports from a phy
+ mode
+
+Some phy modes such as QSGMII multiplex several MAC<->PHY links on one
+single physical interface. QSGMII used to be the only one supported, but
+other modes such as QUSGMII also carry multiple links.
+
+This helper allows getting the number of links that are multiplexed
+on a given interface.
+
+Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/phy-core.c | 52 ++++++++++++++++++++++++++++++++++++++
+ include/linux/phy.h | 2 ++
+ 2 files changed, 54 insertions(+)
+
+--- a/drivers/net/phy/phy-core.c
++++ b/drivers/net/phy/phy-core.c
+@@ -74,6 +74,58 @@ const char *phy_duplex_to_str(unsigned i
+ }
+ EXPORT_SYMBOL_GPL(phy_duplex_to_str);
+
++/**
++ * phy_interface_num_ports - Return the number of links that can be carried by
++ * a given MAC-PHY physical link. Returns 0 if this is
++ * unknown, the number of links else.
++ *
++ * @interface: The interface mode we want to get the number of ports
++ */
++int phy_interface_num_ports(phy_interface_t interface)
++{
++ switch (interface) {
++ case PHY_INTERFACE_MODE_NA:
++ return 0;
++ case PHY_INTERFACE_MODE_INTERNAL:
++ case PHY_INTERFACE_MODE_MII:
++ case PHY_INTERFACE_MODE_GMII:
++ case PHY_INTERFACE_MODE_TBI:
++ case PHY_INTERFACE_MODE_REVMII:
++ case PHY_INTERFACE_MODE_RMII:
++ case PHY_INTERFACE_MODE_REVRMII:
++ case PHY_INTERFACE_MODE_RGMII:
++ case PHY_INTERFACE_MODE_RGMII_ID:
++ case PHY_INTERFACE_MODE_RGMII_RXID:
++ case PHY_INTERFACE_MODE_RGMII_TXID:
++ case PHY_INTERFACE_MODE_RTBI:
++ case PHY_INTERFACE_MODE_XGMII:
++ case PHY_INTERFACE_MODE_XLGMII:
++ case PHY_INTERFACE_MODE_MOCA:
++ case PHY_INTERFACE_MODE_TRGMII:
++ case PHY_INTERFACE_MODE_USXGMII:
++ case PHY_INTERFACE_MODE_SGMII:
++ case PHY_INTERFACE_MODE_SMII:
++ case PHY_INTERFACE_MODE_1000BASEX:
++ case PHY_INTERFACE_MODE_2500BASEX:
++ case PHY_INTERFACE_MODE_5GBASER:
++ case PHY_INTERFACE_MODE_10GBASER:
++ case PHY_INTERFACE_MODE_25GBASER:
++ case PHY_INTERFACE_MODE_10GKR:
++ case PHY_INTERFACE_MODE_100BASEX:
++ case PHY_INTERFACE_MODE_RXAUI:
++ case PHY_INTERFACE_MODE_XAUI:
++ return 1;
++ case PHY_INTERFACE_MODE_QSGMII:
++ case PHY_INTERFACE_MODE_QUSGMII:
++ return 4;
++ case PHY_INTERFACE_MODE_MAX:
++ WARN_ONCE(1, "PHY_INTERFACE_MODE_MAX isn't a valid interface mode");
++ return 0;
++ }
++ return 0;
++}
++EXPORT_SYMBOL_GPL(phy_interface_num_ports);
++
+ /* A mapping of all SUPPORTED settings to speed/duplex. This table
+ * must be grouped by speed and sorted in descending match priority
+ * - iow, descending speed.
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -964,6 +964,8 @@ struct phy_fixup {
+ const char *phy_speed_to_str(int speed);
+ const char *phy_duplex_to_str(unsigned int duplex);
+
++int phy_interface_num_ports(phy_interface_t interface);
++
+ /* A structure for mapping a particular speed and duplex
+ * combination to a particular SUPPORTED and ADVERTISED value
+ */