From 39e138173ae7641e952b456d2de7ad2ac03e8d88 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 21 Nov 2025 08:40:09 -0800 Subject: net: pcs: xpcs: Fix PMA identifier handling in XPCS The XPCS driver was mangling the PMA identifier as the original code appears to have been focused on just capturing the OUI. Rather than store a mangled ID it is better to work with the actual PMA ID and instead just mask out the values that don't apply rather than shifting them and reordering them as you still don't get the original OUI for the NIC without having to bitswap the values as per the definition of the layout in IEEE 802.3-2022 22.2.4.3.1. By laying it out as it was in the hardware it is also less likely for us to have an unintentional collision as the enum values will occupy the revision number area while the OUI occupies the upper 22 bits. Signed-off-by: Alexander Duyck Link: https://patch.msgid.link/176374320920.959489.17267159479370601070.stgit@ahduyck-xeon-server.home.arpa Signed-off-by: Paolo Abeni --- include/linux/pcs/pcs-xpcs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h index e40f554ff717..4cf6bd611e5a 100644 --- a/include/linux/pcs/pcs-xpcs.h +++ b/include/linux/pcs/pcs-xpcs.h @@ -38,7 +38,7 @@ enum dw_xpcs_pma_id { DW_XPCS_PMA_GEN4_6G_ID, DW_XPCS_PMA_GEN5_10G_ID, DW_XPCS_PMA_GEN5_12G_ID, - WX_TXGBE_XPCS_PMA_10G_ID = 0x0018fc80, + WX_TXGBE_XPCS_PMA_10G_ID = 0xfc806000, }; struct dw_xpcs_info { -- cgit v1.2.3 From 3f29dd34f75a09ee7f8333305618edb44617d835 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 21 Nov 2025 08:40:16 -0800 Subject: net: pcs: xpcs: Add support for FBNIC 25G, 50G, 100G PMD The fbnic driver is planning to make use of the XPCS driver to enable support for PCS and better integration with phylink. To do this though we will need to enable several workarounds since the PMD interface for fbnic is likely to be unique since it is a mix of two different vendor products with a unique wrapper around the IP. I have generated a PHY identifier based on IEEE 802.3-2022 22.2.4.3.1 using an OUI belonging to Meta Platforms and used with our NICs. Using this we will provide it as the PMD ID via the SW based MDIO interface so that the fbnic device can be identified and necessary workarounds enabled in the XPCS driver. As an initial workaround this change adds an exception so that soft_reset is not set when the driver is initially bound to the PCS. In addition I have added logic to integrate the PMD Rx signal detect state into the link state for the PCS. With this we can avoid the link coming up too soon on the FBNIC PMD and as a result of it being in the training state so we can avoid link flaps. Signed-off-by: Alexander Duyck Link: https://patch.msgid.link/176374321695.959489.6648161125012056619.stgit@ahduyck-xeon-server.home.arpa Signed-off-by: Paolo Abeni --- drivers/net/pcs/pcs-xpcs.c | 24 ++++++++++++++++++++++-- include/linux/pcs/pcs-xpcs.h | 2 ++ 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c index a94a7cb93664..9679f2b35a44 100644 --- a/drivers/net/pcs/pcs-xpcs.c +++ b/drivers/net/pcs/pcs-xpcs.c @@ -597,7 +597,26 @@ static int xpcs_c45_read_pcs_speed(struct dw_xpcs *xpcs, static int xpcs_resolve_pma(struct dw_xpcs *xpcs, struct phylink_link_state *state) { - int err = 0; + int pmd_rxdet, err = 0; + + /* The Meta Platforms FBNIC PMD will go into a training state for + * about 4 seconds when the link first comes up. During this time the + * PCS link will bounce. To avoid reporting link up too soon we include + * the PMD state provided by the driver. + */ + if (xpcs->info.pma == MP_FBNIC_XPCS_PMA_100G_ID) { + pmd_rxdet = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_PMA_RXDET); + if (pmd_rxdet < 0) { + state->link = false; + return pmd_rxdet; + } + + /* Verify Rx lanes are trained before reporting link up */ + if (!(pmd_rxdet & MDIO_PMD_RXDET_GLOBAL)) { + state->link = false; + return 0; + } + } state->pause = MLO_PAUSE_TX | MLO_PAUSE_RX; state->duplex = DUPLEX_FULL; @@ -1591,7 +1610,8 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev) xpcs_get_interfaces(xpcs, xpcs->pcs.supported_interfaces); - if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) + if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID || + xpcs->info.pma == MP_FBNIC_XPCS_PMA_100G_ID) xpcs->pcs.poll = false; else xpcs->need_reset = true; diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h index 4cf6bd611e5a..36073f7b6bb4 100644 --- a/include/linux/pcs/pcs-xpcs.h +++ b/include/linux/pcs/pcs-xpcs.h @@ -39,6 +39,8 @@ enum dw_xpcs_pma_id { DW_XPCS_PMA_GEN5_10G_ID, DW_XPCS_PMA_GEN5_12G_ID, WX_TXGBE_XPCS_PMA_10G_ID = 0xfc806000, + /* Meta Platforms OUI 88:25:08, model 0, revision 0 */ + MP_FBNIC_XPCS_PMA_100G_ID = 0x46904000, }; struct dw_xpcs_info { -- cgit v1.2.3