mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-02 14:34:13 -04:00
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: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -50,7 +50,6 @@ struct dw_xpcs;
|
||||
|
||||
struct phylink_pcs *xpcs_to_phylink_pcs(struct dw_xpcs *xpcs);
|
||||
int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface);
|
||||
void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces);
|
||||
int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
|
||||
int enable);
|
||||
struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr);
|
||||
|
||||
@@ -393,6 +393,8 @@ struct phylink_pcs_ops;
|
||||
|
||||
/**
|
||||
* struct phylink_pcs - PHYLINK PCS instance
|
||||
* @supported_interfaces: describing which PHY_INTERFACE_MODE_xxx
|
||||
* are supported by this PCS.
|
||||
* @ops: a pointer to the &struct phylink_pcs_ops structure
|
||||
* @phylink: pointer to &struct phylink_config
|
||||
* @neg_mode: provide PCS neg mode via "mode" argument
|
||||
@@ -409,6 +411,7 @@ struct phylink_pcs_ops;
|
||||
* the PCS driver.
|
||||
*/
|
||||
struct phylink_pcs {
|
||||
DECLARE_PHY_INTERFACE_MASK(supported_interfaces);
|
||||
const struct phylink_pcs_ops *ops;
|
||||
struct phylink *phylink;
|
||||
bool neg_mode;
|
||||
|
||||
Reference in New Issue
Block a user