Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <alexanderduyck@fb.com>
Link: https://patch.msgid.link/176374321695.959489.6648161125012056619.stgit@ahduyck-xeon-server.home.arpa
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Alexander Duyck and committed by
Paolo Abeni
3f29dd34 39e13817

+24 -2
+22 -2
drivers/net/pcs/pcs-xpcs.c
··· 597 597 static int xpcs_resolve_pma(struct dw_xpcs *xpcs, 598 598 struct phylink_link_state *state) 599 599 { 600 - int err = 0; 600 + int pmd_rxdet, err = 0; 601 + 602 + /* The Meta Platforms FBNIC PMD will go into a training state for 603 + * about 4 seconds when the link first comes up. During this time the 604 + * PCS link will bounce. To avoid reporting link up too soon we include 605 + * the PMD state provided by the driver. 606 + */ 607 + if (xpcs->info.pma == MP_FBNIC_XPCS_PMA_100G_ID) { 608 + pmd_rxdet = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_PMA_RXDET); 609 + if (pmd_rxdet < 0) { 610 + state->link = false; 611 + return pmd_rxdet; 612 + } 613 + 614 + /* Verify Rx lanes are trained before reporting link up */ 615 + if (!(pmd_rxdet & MDIO_PMD_RXDET_GLOBAL)) { 616 + state->link = false; 617 + return 0; 618 + } 619 + } 601 620 602 621 state->pause = MLO_PAUSE_TX | MLO_PAUSE_RX; 603 622 state->duplex = DUPLEX_FULL; ··· 1610 1591 1611 1592 xpcs_get_interfaces(xpcs, xpcs->pcs.supported_interfaces); 1612 1593 1613 - if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) 1594 + if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID || 1595 + xpcs->info.pma == MP_FBNIC_XPCS_PMA_100G_ID) 1614 1596 xpcs->pcs.poll = false; 1615 1597 else 1616 1598 xpcs->need_reset = true;
+2
include/linux/pcs/pcs-xpcs.h
··· 39 39 DW_XPCS_PMA_GEN5_10G_ID, 40 40 DW_XPCS_PMA_GEN5_12G_ID, 41 41 WX_TXGBE_XPCS_PMA_10G_ID = 0xfc806000, 42 + /* Meta Platforms OUI 88:25:08, model 0, revision 0 */ 43 + MP_FBNIC_XPCS_PMA_100G_ID = 0x46904000, 42 44 }; 43 45 44 46 struct dw_xpcs_info {