[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID:
<176133845391.2245037.2378678349333571121.stgit@ahduyck-xeon-server.home.arpa>
Date: Fri, 24 Oct 2025 13:40:53 -0700
From: Alexander Duyck <alexander.duyck@...il.com>
To: netdev@...r.kernel.org
Cc: kuba@...nel.org, kernel-team@...a.com, andrew+netdev@...n.ch,
hkallweit1@...il.com, linux@...linux.org.uk, pabeni@...hat.com,
davem@...emloft.net
Subject: [net-next PATCH 3/8] net: phy: Add 25G-CR, 50G-CR,
100G-CR2 support to C45 genphy
From: Alexander Duyck <alexanderduyck@...com>
Add support for 25G-CR, 50G-CR, 50G-CR2, and 100G-CR2 the c45 genphy. Note
that 3 of the 4 are IEEE compliant so they are a direct copy from the
clause 45 specification, the only exception to this is 50G-CR2 which is
part of the Ethernet Consortium specification which never referenced how to
handle this in the MDIO registers.
Since 50GBase-CR2 isn't an IEEE standard it doesn't have a value in the
extended capabilities registers. To account for that I am adding a define
that is aliasing the 100GBase-CR4 to represent it as that is the media type
used to carry data for 50R2, it is just that the PHY is carrying two 2 with
2 lanes each over the 4 lane cable. For now I am representing it with ctrl1
set to 50G and ctrl2 being set to 100R4, and using the 100R4 capability to
identify if it is supported or not.
Signed-off-by: Alexander Duyck <alexanderduyck@...com>
---
drivers/net/phy/phy-c45.c | 114 +++++++++++++++++++++++++++++++++++++++++++++
include/uapi/linux/mdio.h | 34 +++++++++++++
2 files changed, 147 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c
index 4210863c1b6e..65d6f45c898d 100644
--- a/drivers/net/phy/phy-c45.c
+++ b/drivers/net/phy/phy-c45.c
@@ -161,6 +161,38 @@ int genphy_c45_pma_setup_forced(struct phy_device *phydev)
/* Assume 10Gbase-T */
ctrl2 |= MDIO_PMA_CTRL2_10GBT;
break;
+ case SPEED_25000:
+ ctrl1 |= MDIO_CTRL1_SPEED25G;
+ /* Assume 25Gbase-CR */
+ ctrl2 |= MDIO_PMA_CTRL2_25GBCR;
+ break;
+ case SPEED_50000:
+ ctrl1 |= MDIO_CTRL1_SPEED50G;
+ /* There are currently 2 supported modes for 50G.
+ * The first is 50Gbase-CR which is in the IEEE standard.
+ * The second is 50Gbase-CR2 which isn't. It is intended
+ * to piggy-back on 100Gbase-CR4 and only use 2 lanes, so
+ * we can use the interface type to identify which is which.
+ */
+ if (phydev->interface == PHY_INTERFACE_MODE_50GBASER)
+ ctrl2 |= MDIO_PMA_CTRL2_50GBCR;
+ else if (phydev->interface == PHY_INTERFACE_MODE_LAUI)
+ ctrl2 |= MDIO_PMA_CTRL2_50GBCR2;
+ else
+ return -EINVAL;
+ break;
+ case SPEED_100000:
+ ctrl1 |= MDIO_CTRL1_SPEED100G;
+ /* For now we only have support for 2 lane devices, so
+ * 100Gbase-CR2 is the limit. We might look at enabling
+ * 100Gbase-CR4 in the future with additional devices to
+ * test this code on.
+ */
+ if (phydev->interface == PHY_INTERFACE_MODE_100GBASEP)
+ ctrl2 |= MDIO_PMA_CTRL2_100GBCR2;
+ else
+ return -EINVAL;
+ break;
default:
return -EINVAL;
}
@@ -958,6 +990,34 @@ int genphy_c45_an_config_eee_aneg(struct phy_device *phydev)
}
EXPORT_SYMBOL_GPL(genphy_c45_an_config_eee_aneg);
+static int genphy_c45_pma_40_100g_read_abilities(struct phy_device *phydev)
+{
+ int val;
+
+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
+ MDIO_PMA_40G_EXTABLE);
+ if (val < 0)
+ return val;
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_40G_EXTABLE_100GBCR4);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_40G_EXTABLE_50GBCR2);
+
+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
+ MDIO_PMA_100G_EXTABLE);
+ if (val < 0)
+ return val;
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_100G_EXTABLE_100GBCR2);
+
+ return 0;
+}
+
static int genphy_c45_pma_ng_read_abilities(struct phy_device *phydev)
{
int val;
@@ -978,6 +1038,22 @@ static int genphy_c45_pma_ng_read_abilities(struct phy_device *phydev)
return 0;
}
+static int genphy_c45_pma_25g_read_abilities(struct phy_device *phydev)
+{
+ int val;
+
+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
+ MDIO_PMA_25G_EXTABLE);
+ if (val < 0)
+ return val;
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_25G_EXTABLE_25GBCR);
+
+ return 0;
+}
+
/**
* genphy_c45_pma_baset1_read_abilities - read supported baset1 link modes from PMA
* @phydev: target phy_device struct
@@ -1016,6 +1092,22 @@ int genphy_c45_pma_baset1_read_abilities(struct phy_device *phydev)
}
EXPORT_SYMBOL_GPL(genphy_c45_pma_baset1_read_abilities);
+static int genphy_c45_pma_50g_read_abilities(struct phy_device *phydev)
+{
+ int val;
+
+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
+ MDIO_PMA_50G_EXTABLE);
+ if (val < 0)
+ return val;
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_50G_EXTABLE_50GBCR);
+
+ return 0;
+}
+
/**
* genphy_c45_pma_read_ext_abilities - read supported link modes from PMA
* @phydev: target phy_device struct
@@ -1064,18 +1156,40 @@ int genphy_c45_pma_read_ext_abilities(struct phy_device *phydev)
phydev->supported,
val & MDIO_PMA_EXTABLE_10BT);
+ if (val & MDIO_PMA_EXTABLE_40_100G) {
+ err = genphy_c45_pma_40_100g_read_abilities(phydev);
+ if (err < 0)
+ return err;
+ }
+
if (val & MDIO_PMA_EXTABLE_NBT) {
err = genphy_c45_pma_ng_read_abilities(phydev);
if (err < 0)
return err;
}
+ if (val & MDIO_PMA_EXTABLE_25G) {
+ err = genphy_c45_pma_25g_read_abilities(phydev);
+ if (err < 0)
+ return err;
+ }
+
if (val & MDIO_PMA_EXTABLE_BT1) {
err = genphy_c45_pma_baset1_read_abilities(phydev);
if (err < 0)
return err;
}
+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_EXTABLE2);
+ if (val < 0)
+ return val;
+
+ if (val & MDIO_PMA_EXTABLE2_50G) {
+ err = genphy_c45_pma_50g_read_abilities(phydev);
+ if (err < 0)
+ return err;
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(genphy_c45_pma_read_ext_abilities);
diff --git a/include/uapi/linux/mdio.h b/include/uapi/linux/mdio.h
index ff8b6423bd1e..8f9a4328daf9 100644
--- a/include/uapi/linux/mdio.h
+++ b/include/uapi/linux/mdio.h
@@ -41,15 +41,20 @@
#define MDIO_PMA_TXDIS 9 /* 10G PMA/PMD transmit disable */
#define MDIO_PMA_RXDET 10 /* 10G PMA/PMD receive signal detect */
#define MDIO_PMA_EXTABLE 11 /* 10G PMA/PMD extended ability */
+#define MDIO_PMA_40G_EXTABLE 13 /* 40G/100G PMA/PMD extended ability */
#define MDIO_PKGID1 14 /* Package identifier */
#define MDIO_PKGID2 15
#define MDIO_AN_ADVERTISE 16 /* AN advertising (base page) */
#define MDIO_AN_LPA 19 /* AN LP abilities (base page) */
+#define MDIO_PMA_25G_EXTABLE 19 /* 25G PMA/PMD extended ability */
#define MDIO_PCS_EEE_ABLE 20 /* EEE Capability register */
+#define MDIO_PMA_50G_EXTABLE 20 /* 50G PMA/PMD extended ability */
#define MDIO_PCS_EEE_ABLE2 21 /* EEE Capability register 2 */
#define MDIO_PMA_NG_EXTABLE 21 /* 2.5G/5G PMA/PMD extended ability */
#define MDIO_PCS_EEE_WK_ERR 22 /* EEE wake error counter */
#define MDIO_PHYXS_LNSTAT 24 /* PHY XGXS lane state */
+#define MDIO_PMA_EXTABLE2 25 /* PMA/PMD extended ability 2 */
+#define MDIO_PMA_100G_EXTABLE 26 /* 40G/100G PMA/PMD extended ability 2 */
#define MDIO_AN_EEE_ADV 60 /* EEE advertisement */
#define MDIO_AN_EEE_LPABLE 61 /* EEE link partner ability */
#define MDIO_AN_EEE_ADV2 62 /* EEE advertisement 2 */
@@ -187,9 +192,18 @@
#define MDIO_PMA_CTRL2_1000BKX 0x000d /* 1000BASE-KX type */
#define MDIO_PMA_CTRL2_100BTX 0x000e /* 100BASE-TX type */
#define MDIO_PMA_CTRL2_10BT 0x000f /* 10BASE-T type */
+#define MDIO_PMA_CTRL2_100GBCR4 0x002e /* 100GBASE-CR4 type */
+/* 50GBase-CR2 isn't an IEEE media type, as such there isn't a defined
+ * value for it. However as it is meant to be a reuse of 100GBase-CR4 we
+ * will reuse the value here so that both report the same value.
+ */
+#define MDIO_PMA_CTRL2_50GBCR2 MDIO_PMA_CTRL2_100GBCR4
#define MDIO_PMA_CTRL2_2_5GBT 0x0030 /* 2.5GBaseT type */
#define MDIO_PMA_CTRL2_5GBT 0x0031 /* 5GBaseT type */
+#define MDIO_PMA_CTRL2_25GBCR 0x0038 /* 25GBASE-CR type */
#define MDIO_PMA_CTRL2_BASET1 0x003D /* BASE-T1 type */
+#define MDIO_PMA_CTRL2_50GBCR 0x0041 /* 50GBASE-CR type */
+#define MDIO_PMA_CTRL2_100GBCR2 0x0049 /* 100GBASE-CR2 type */
#define MDIO_PCS_CTRL2_TYPE 0x0003 /* PCS type selection */
#define MDIO_PCS_CTRL2_10GBR 0x0000 /* 10GBASE-R type */
#define MDIO_PCS_CTRL2_10GBX 0x0001 /* 10GBASE-X type */
@@ -233,7 +247,7 @@
#define MDIO_PMD_RXDET_2 0x0008 /* PMD RX signal detect 2 */
#define MDIO_PMD_RXDET_3 0x0010 /* PMD RX signal detect 3 */
-/* Extended abilities register. */
+/* PMA/PMD extended ability register. */
#define MDIO_PMA_EXTABLE_10GCX4 0x0001 /* 10GBASE-CX4 ability */
#define MDIO_PMA_EXTABLE_10GBLRM 0x0002 /* 10GBASE-LRM ability */
#define MDIO_PMA_EXTABLE_10GBT 0x0004 /* 10GBASE-T ability */
@@ -243,9 +257,14 @@
#define MDIO_PMA_EXTABLE_1000BKX 0x0040 /* 1000BASE-KX ability */
#define MDIO_PMA_EXTABLE_100BTX 0x0080 /* 100BASE-TX ability */
#define MDIO_PMA_EXTABLE_10BT 0x0100 /* 10BASE-T ability */
+#define MDIO_PMA_EXTABLE_40_100G 0x0400 /* 40G/100G ability */
#define MDIO_PMA_EXTABLE_BT1 0x0800 /* BASE-T1 ability */
+#define MDIO_PMA_EXTABLE_25G 0x1000 /* 25G ability */
#define MDIO_PMA_EXTABLE_NBT 0x4000 /* 2.5/5GBASE-T ability */
+/* PMA/PMD extended ability 2 register. */
+#define MDIO_PMA_EXTABLE2_50G 0x0001 /* 50G ability */
+
/* AN Clause 73 linkword */
#define MDIO_AN_C73_0_S_MASK GENMASK(4, 0)
#define MDIO_AN_C73_0_E_MASK GENMASK(9, 5)
@@ -436,10 +455,23 @@
/* AN MultiGBASE-T AN control 2 */
#define MDIO_AN_THP_BP2_5GT 0x0008 /* 2.5GT THP bypass request */
+/* 40G/100G PMA/PMD Extended ability register */
+#define MDIO_PMA_40G_EXTABLE_100GBCR4 0x4000 /* 100GBASE-CR4 ability */
+#define MDIO_PMA_40G_EXTABLE_50GBCR2 MDIO_PMA_40G_EXTABLE_100GBCR4
+
+/* 25G PMA/PMD Extended ability register */
+#define MDIO_PMA_25G_EXTABLE_25GBCR 0x0008 /* 25GBASE-CR ability */
+
+/* 50G PMA/PMD Extended ability register */
+#define MDIO_PMA_50G_EXTABLE_50GBCR 0x0002 /* 50GBASE-CR ability */
+
/* 2.5G/5G Extended abilities register. */
#define MDIO_PMA_NG_EXTABLE_2_5GBT 0x0001 /* 2.5GBASET ability */
#define MDIO_PMA_NG_EXTABLE_5GBT 0x0002 /* 5GBASET ability */
+/* 40G/100G PMA/PMD Extended ability 2 register */
+#define MDIO_PMA_100G_EXTABLE_100GBCR2 0x0100 /* 100GBASE-CR2 ability */
+
/* LASI RX_ALARM control/status registers. */
#define MDIO_PMA_LASI_RX_PHYXSLFLT 0x0001 /* PHY XS RX local fault */
#define MDIO_PMA_LASI_RX_PCSLFLT 0x0008 /* PCS RX local fault */
Powered by blists - more mailing lists