Commit 7c7ea705 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-pcs-add-supported_interfaces-bitmap-for-pcs'

Russell King says:

====================
net: pcs: add supported_interfaces bitmap for PCS

This series adds supported_interfaces for PCS, which gives MAC code
a way to determine the interface modes that the PCS supports without
having to implement functions such as xpcs_get_interfaces(), or
workarounds such as in

 https://lore.kernel.org/20241213090526.71516-3-maxime.chevallier@bootlin.com

Patch 1 adds the new bitmask to struct phylink_pcs, and code within
phylink to validate that the PCS returned by the MAC driver supports
the interface mode - but only if this bitmask is non-empty.

Patch 2 through 4 fills in the interface modes for XPCS, Mediatek LynxI
and Lynx PCS.

Patch 5 adds support to stmmac to make use of this bitmask when filling
in phylink_config.supported_interfaces, eliminating the call to
xpcs_get_interfaces.

As xpcs_get_interfaces() is now unused outside of pcs-xpcs.c, patch 6
makes this function static and removes it from the header file.
====================

Link: https://patch.msgid.link/Z3fG9oTY9F9fCYHv@shell.armlinux.org.uk


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 4475d561 2410719c
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -1203,6 +1203,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
	struct stmmac_mdio_bus_data *mdio_bus_data;
	int mode = priv->plat->phy_interface;
	struct fwnode_handle *fwnode;
	struct phylink_pcs *pcs;
	struct phylink *phylink;

	priv->phylink_config.dev = &priv->dev->dev;
@@ -1224,8 +1225,14 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)

	/* If we have an xpcs, it defines which PHY interfaces are supported. */
	if (priv->hw->xpcs)
		xpcs_get_interfaces(priv->hw->xpcs,
				    priv->phylink_config.supported_interfaces);
		pcs = xpcs_to_phylink_pcs(priv->hw->xpcs);
	else
		pcs = priv->hw->phylink_pcs;

	if (pcs)
		phy_interface_or(priv->phylink_config.supported_interfaces,
				 priv->phylink_config.supported_interfaces,
				 pcs->supported_interfaces);

	fwnode = priv->plat->port_node;
	if (!fwnode)
+13 −0
Original line number Diff line number Diff line
@@ -334,9 +334,19 @@ static const struct phylink_pcs_ops lynx_pcs_phylink_ops = {
	.pcs_link_up = lynx_pcs_link_up,
};

static const phy_interface_t lynx_interfaces[] = {
	PHY_INTERFACE_MODE_SGMII,
	PHY_INTERFACE_MODE_QSGMII,
	PHY_INTERFACE_MODE_1000BASEX,
	PHY_INTERFACE_MODE_2500BASEX,
	PHY_INTERFACE_MODE_10GBASER,
	PHY_INTERFACE_MODE_USXGMII,
};

static struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio)
{
	struct lynx_pcs *lynx;
	int i;

	lynx = kzalloc(sizeof(*lynx), GFP_KERNEL);
	if (!lynx)
@@ -348,6 +358,9 @@ static struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio)
	lynx->pcs.neg_mode = true;
	lynx->pcs.poll = true;

	for (i = 0; i < ARRAY_SIZE(lynx_interfaces); i++)
		__set_bit(lynx_interfaces[i], lynx->pcs.supported_interfaces);

	return lynx_to_phylink_pcs(lynx);
}

+4 −0
Original line number Diff line number Diff line
@@ -307,6 +307,10 @@ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
	mpcs->pcs.poll = true;
	mpcs->interface = PHY_INTERFACE_MODE_NA;

	__set_bit(PHY_INTERFACE_MODE_SGMII, mpcs->pcs.supported_interfaces);
	__set_bit(PHY_INTERFACE_MODE_1000BASEX, mpcs->pcs.supported_interfaces);
	__set_bit(PHY_INTERFACE_MODE_2500BASEX, mpcs->pcs.supported_interfaces);

	return &mpcs->pcs;
}
EXPORT_SYMBOL(mtk_pcs_lynxi_create);
+3 −2
Original line number Diff line number Diff line
@@ -594,14 +594,13 @@ static unsigned int xpcs_inband_caps(struct phylink_pcs *pcs,
	}
}

void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces)
static void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces)
{
	const struct dw_xpcs_compat *compat;

	for (compat = xpcs->desc->compat; compat->supported; compat++)
		__set_bit(compat->interface, interfaces);
}
EXPORT_SYMBOL_GPL(xpcs_get_interfaces);

int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable)
{
@@ -1446,6 +1445,8 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev)
	if (ret)
		goto out_clear_clks;

	xpcs_get_interfaces(xpcs, xpcs->pcs.supported_interfaces);

	if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID)
		xpcs->pcs.poll = false;
	else
+11 −0
Original line number Diff line number Diff line
@@ -691,6 +691,17 @@ static int phylink_validate_mac_and_pcs(struct phylink *pl,
			return -EINVAL;
		}

		/* Ensure that this PCS supports the interface which the MAC
		 * returned it for. It is an error for the MAC to return a PCS
		 * that does not support the interface mode.
		 */
		if (!phy_interface_empty(pcs->supported_interfaces) &&
		    !test_bit(state->interface, pcs->supported_interfaces)) {
			phylink_err(pl, "MAC returned PCS which does not support %s\n",
				    phy_modes(state->interface));
			return -EINVAL;
		}

		/* Validate the link parameters with the PCS */
		if (pcs->ops->pcs_validate) {
			ret = pcs->ops->pcs_validate(pcs, supported, state);
Loading