Re: [PATCH v3 1/5] net: macb: add phylink support

From: Russell King - ARM Linux admin
Date: Fri Jun 21 2019 - 09:29:25 EST


On Fri, Jun 21, 2019 at 09:34:44AM +0100, Parshuram Thombare wrote:
> @@ -438,115 +439,145 @@ static void macb_set_tx_clk(struct clk *clk, int speed, struct net_device *dev)
> netdev_err(dev, "adjusting tx_clk failed.\n");
> }
>
> -static void macb_handle_link_change(struct net_device *dev)
> +static void gem_phylink_validate(struct phylink_config *pl_config,
> + unsigned long *supported,
> + struct phylink_link_state *state)
> {
> - struct macb *bp = netdev_priv(dev);
> - struct phy_device *phydev = dev->phydev;
> - unsigned long flags;
> - int status_change = 0;
> + struct net_device *netdev = to_net_dev(pl_config->dev);
> + struct macb *bp = netdev_priv(netdev);
> + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
> +
> + switch (state->interface) {
> + case PHY_INTERFACE_MODE_GMII:
> + case PHY_INTERFACE_MODE_RGMII:
> + if (bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE) {
> + phylink_set(mask, 1000baseT_Full);
> + phylink_set(mask, 1000baseX_Full);
> + if (!(bp->caps & MACB_CAPS_NO_GIGABIT_HALF)) {
> + phylink_set(mask, 1000baseT_Half);
> + phylink_set(mask, 1000baseT_Half);
> + }
> + }
> + /* fallthrough */
> + case PHY_INTERFACE_MODE_MII:
> + case PHY_INTERFACE_MODE_RMII:
> + phylink_set(mask, 10baseT_Half);
> + phylink_set(mask, 10baseT_Full);
> + phylink_set(mask, 100baseT_Half);
> + phylink_set(mask, 100baseT_Full);
> + break;
> + default:
> + break;

PHY_INTERFACE_MODE_NA is used to ascertain the _full_ set of support
from the MAC irrespective of interface mode, so that (eg) SFPs can
select an appropriate interface mode from the subset of capabililties
supported by the SFP and MAC.

Also note this behaviour for MACs that support switching between
2500BASE-X and 1000BASE-X (which are fixed speed BASE-X):

static void mvneta_validate(struct net_device *ndev, unsigned long *supported,
struct phylink_link_state *state)
{
...
/* Half-duplex at speeds higher than 100Mbit is unsupported */
if (pp->comphy || state->interface != PHY_INTERFACE_MODE_2500BASEX) {
phylink_set(mask, 1000baseT_Full);
phylink_set(mask, 1000baseX_Full);
}
if (pp->comphy || state->interface == PHY_INTERFACE_MODE_2500BASEX) {
phylink_set(mask, 2500baseT_Full);
phylink_set(mask, 2500baseX_Full);
}

The idea here is that _if_ we have a comphy, we can reprogram the comphy
to select between 1G and 2.5G speeds. So we offer both 1G and 2.5G
capabilities irrespective of interface mode.

When the interface type is set in mvneta_mac_config(), the comphy is
configured for the link mode, including setting the link speed to either
1.25Gbaud or 3.125Gbaud.

So, the speed of the serdes lane is determined by the selected
PHY_INTERFACE_MODE.

There is additional logic in the mvneta_validate() method to deal with
the selection of 1G and 2.5G modes for BASE-X:

/* We can only operate at 2500BaseX or 1000BaseX. If requested
* to advertise both, only report advertising at 2500BaseX.
*/
phylink_helper_basex_speed(state);

What this does is clear state->advertising, ensuring that only one of
2500BASE_X or 1000BASE_X is shown, and also sets state->interface in
the validate callback accordingly to select the interface mode.

--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up