net: stmmac: convert to phylink_get_linkmodes()

Add the MAC speed, duplex and pause capabilities to the phylink_config
structure, and switch stmmac_validate() to use phylink_get_linkmodes()
to generate the mask of supported ethtool link modes.

Tested-by: Wong Vee Khee <vee.khee.wong@linux.intel.com> # Intel EHL            Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Russell King (Oracle) 2022-01-26 10:26:00 +00:00 коммит произвёл David S. Miller
Родитель be6ec5b702
Коммит 92c3807b9a
1 изменённых файлов: 42 добавлений и 83 удалений

Просмотреть файл

@ -942,95 +942,22 @@ static void stmmac_validate(struct phylink_config *config,
{
struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
__ETHTOOL_DECLARE_LINK_MODE_MASK(mac_supported) = { 0, };
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
int tx_cnt = priv->plat->tx_queues_to_use;
int max_speed = priv->plat->max_speed;
phylink_set(mac_supported, 10baseT_Half);
phylink_set(mac_supported, 10baseT_Full);
phylink_set(mac_supported, 100baseT_Half);
phylink_set(mac_supported, 100baseT_Full);
phylink_set(mac_supported, 1000baseT_Half);
phylink_set(mac_supported, 1000baseT_Full);
phylink_set(mac_supported, 1000baseKX_Full);
/* This is very similar to phylink_generic_validate() except that
* we always use PHY_INTERFACE_MODE_INTERNAL to get all capabilities.
* This is because we don't always have config->supported_interfaces
* populated (only when we have the XPCS.)
*
* When we do have an XPCS, we could pass state->interface, as XPCS
* limits to a subset of the ethtool link modes allowed here.
*/
phylink_set(mac_supported, Autoneg);
phylink_set(mac_supported, Pause);
phylink_set(mac_supported, Asym_Pause);
phylink_set_port_modes(mac_supported);
/* Cut down 1G if asked to */
if ((max_speed > 0) && (max_speed < 1000)) {
phylink_set(mask, 1000baseT_Full);
phylink_set(mask, 1000baseX_Full);
} else if (priv->plat->has_gmac4) {
if (!max_speed || max_speed >= 2500) {
phylink_set(mac_supported, 2500baseT_Full);
phylink_set(mac_supported, 2500baseX_Full);
}
} else if (priv->plat->has_xgmac) {
if (!max_speed || (max_speed >= 2500)) {
phylink_set(mac_supported, 2500baseT_Full);
phylink_set(mac_supported, 2500baseX_Full);
}
if (!max_speed || (max_speed >= 5000)) {
phylink_set(mac_supported, 5000baseT_Full);
}
if (!max_speed || (max_speed >= 10000)) {
phylink_set(mac_supported, 10000baseSR_Full);
phylink_set(mac_supported, 10000baseLR_Full);
phylink_set(mac_supported, 10000baseER_Full);
phylink_set(mac_supported, 10000baseLRM_Full);
phylink_set(mac_supported, 10000baseT_Full);
phylink_set(mac_supported, 10000baseKX4_Full);
phylink_set(mac_supported, 10000baseKR_Full);
}
if (!max_speed || (max_speed >= 25000)) {
phylink_set(mac_supported, 25000baseCR_Full);
phylink_set(mac_supported, 25000baseKR_Full);
phylink_set(mac_supported, 25000baseSR_Full);
}
if (!max_speed || (max_speed >= 40000)) {
phylink_set(mac_supported, 40000baseKR4_Full);
phylink_set(mac_supported, 40000baseCR4_Full);
phylink_set(mac_supported, 40000baseSR4_Full);
phylink_set(mac_supported, 40000baseLR4_Full);
}
if (!max_speed || (max_speed >= 50000)) {
phylink_set(mac_supported, 50000baseCR2_Full);
phylink_set(mac_supported, 50000baseKR2_Full);
phylink_set(mac_supported, 50000baseSR2_Full);
phylink_set(mac_supported, 50000baseKR_Full);
phylink_set(mac_supported, 50000baseSR_Full);
phylink_set(mac_supported, 50000baseCR_Full);
phylink_set(mac_supported, 50000baseLR_ER_FR_Full);
phylink_set(mac_supported, 50000baseDR_Full);
}
if (!max_speed || (max_speed >= 100000)) {
phylink_set(mac_supported, 100000baseKR4_Full);
phylink_set(mac_supported, 100000baseSR4_Full);
phylink_set(mac_supported, 100000baseCR4_Full);
phylink_set(mac_supported, 100000baseLR4_ER4_Full);
phylink_set(mac_supported, 100000baseKR2_Full);
phylink_set(mac_supported, 100000baseSR2_Full);
phylink_set(mac_supported, 100000baseCR2_Full);
phylink_set(mac_supported, 100000baseLR2_ER2_FR2_Full);
phylink_set(mac_supported, 100000baseDR2_Full);
}
}
/* Half-Duplex can only work with single queue */
if (tx_cnt > 1) {
phylink_set(mask, 10baseT_Half);
phylink_set(mask, 100baseT_Half);
phylink_set(mask, 1000baseT_Half);
}
phylink_get_linkmodes(mac_supported, PHY_INTERFACE_MODE_INTERNAL,
config->mac_capabilities);
linkmode_and(supported, supported, mac_supported);
linkmode_andnot(supported, supported, mask);
linkmode_and(state->advertising, state->advertising, mac_supported);
linkmode_andnot(state->advertising, state->advertising, mask);
/* If PCS is supported, check which modes it supports. */
if (priv->hw->xpcs)
@ -1253,6 +1180,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
{
struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
struct fwnode_handle *fwnode = of_fwnode_handle(priv->plat->phylink_node);
int max_speed = priv->plat->max_speed;
int mode = priv->plat->phy_interface;
struct phylink *phylink;
@ -1266,6 +1194,37 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
if (!fwnode)
fwnode = dev_fwnode(priv->device);
priv->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
MAC_10 | MAC_100;
if (!max_speed || max_speed >= 1000)
priv->phylink_config.mac_capabilities |= MAC_1000;
if (priv->plat->has_gmac4) {
if (!max_speed || max_speed >= 2500)
priv->phylink_config.mac_capabilities |= MAC_2500FD;
} else if (priv->plat->has_xgmac) {
if (!max_speed || max_speed >= 2500)
priv->phylink_config.mac_capabilities |= MAC_2500FD;
if (!max_speed || max_speed >= 5000)
priv->phylink_config.mac_capabilities |= MAC_5000FD;
if (!max_speed || max_speed >= 10000)
priv->phylink_config.mac_capabilities |= MAC_10000FD;
if (!max_speed || max_speed >= 25000)
priv->phylink_config.mac_capabilities |= MAC_25000FD;
if (!max_speed || max_speed >= 40000)
priv->phylink_config.mac_capabilities |= MAC_40000FD;
if (!max_speed || max_speed >= 50000)
priv->phylink_config.mac_capabilities |= MAC_50000FD;
if (!max_speed || max_speed >= 100000)
priv->phylink_config.mac_capabilities |= MAC_100000FD;
}
/* Half-Duplex can only work with single queue */
if (priv->plat->tx_queues_to_use > 1)
priv->phylink_config.mac_capabilities &=
~(MAC_10HD | MAC_100HD | MAC_1000HD);
phylink = phylink_create(&priv->phylink_config, fwnode,
mode, &stmmac_phylink_mac_ops);
if (IS_ERR(phylink))