Subject: Re: [PATCH] net: phy: phy_remove_link_mode should not advertise new modes

From: Andrew Lunn <[email-masked]>
Date: Wed, 15 Jul 2020 21:27:22 +0200

On Tue, Jul 14, 2020 at 10:25:42AM +0200, Helmut Grohne wrote:
> When doing "ip link set dev ... up" for a ksz9477 backed link,
> ksz9477_phy_setup is called and it calls phy_remove_link_mode to remove
> 1000baseT HDX. During phy_remove_link_mode, phy_advertise_supported is
> called.
> 
> If one wants to advertise fewer modes than the supported ones, one
> usually reduces the advertised link modes before upping the link (e.g.
> by passing an appropriate .link file to udev).  However upping
> overrwrites the advertised link modes due to the call to
> phy_advertise_supported reverting to the supported link modes.
> 
> It seems unintentional to have phy_remove_link_mode enable advertising
> bits and it does not match its description in any way. Instead of
> calling phy_advertise_supported, we should simply clear the link mode to
> be removed from both supported and advertising.

We have two different reasons for removing link modes.

1) The PHY cannot support a link mode. E.g.

static int bcm84881_get_features(struct phy_device *phydev)
{
        int ret;

        ret = genphy_c45_pma_read_abilities(phydev);
        if (ret)
                return ret;

        /* Although the PHY sets bit 1.11.8, it does not support 10M modes */
        linkmode_clear_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
                           phydev->supported);
        linkmode_clear_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
                           phydev->supported);

        return 0;
}

This is done very early on, as part of probing the PHY. This is done
before supported is copied into advertised towards the end of the PHYs
probe.

2) The MAC does not support a link mode. It uses
phy_remove_link_mode() to remove a link mode. There are two different
times this can be done:

a) As part of open(), the PHY is connected to the MAC. Since the PHY
is not connected to the MAC until you open it, you cannot use ethtool
to change the advertised modes until you have opened it. Hence user
space cannot of removed anything and you don't need to worry about
this copy.

b) As part of the MAC drivers probe, the PHY is connected to the MAC.
In this case, ethtool can be used by userspace to remove link
modes. But the MAC driver should of already removed the modes it does
not support, directly after connecting the PHY to the MAC in its probe
function. So advertising and supported at the same already.

The key point here is ksz9477_phy_setup(), and how it breaks this
model. It is called from ksz_enable_port(). That is called via
dsa_port_enable() in dsa_slave_open(). But the PHY was connected to
the MAC during probe of the MAC. So we have a bad mix of a) and b),
which is leading to your problem. You need to fix the switch driver so
it cleanly does b), removes the link mode early on before the user has
chance to use ethtool.

       Andrew