Re: [PATCH v2 net] Add genphy_c45_config_aneg() function to phy-c45.c

From: Heiner Kallweit
Date: Wed Aug 21 2019 - 12:56:09 EST


On 21.08.2019 17:37, Andrew Lunn wrote:
> On Wed, Aug 21, 2019 at 11:00:46AM +0000, Marco Hartmann wrote:
>> Commit 34786005eca3 ("net: phy: prevent PHYs w/o Clause 22 regs from calling
>> genphy_config_aneg") introduced a check that aborts phy_config_aneg()
>> if the phy is a C45 phy.
>> This causes phy_state_machine() to call phy_error() so that the phy
>> ends up in PHY_HALTED state.
>>
>> Instead of returning -EOPNOTSUPP, call genphy_c45_config_aneg()
>> (analogous to the C22 case) so that the state machine can run
>> correctly.
>>
>> genphy_c45_config_aneg() closely resembles mv3310_config_aneg()
>> in drivers/net/phy/marvell10g.c, excluding vendor specific
>> configurations for 1000BaseT.
>
>> +/**
>> + * genphy_c45_config_aneg - restart auto-negotiation or forced setup
>> + * @phydev: target phy_device struct
>> + *
>> + * Description: If auto-negotiation is enabled, we configure the
>> + * advertising, and then restart auto-negotiation. If it is not
>> + * enabled, then we force a configuration.
>> + */
>> +int genphy_c45_config_aneg(struct phy_device *phydev)
>> +{
>> + bool changed = false;
>> + int ret;
>> +
>> + if (phydev->autoneg == AUTONEG_DISABLE)
>> + return genphy_c45_pma_setup_forced(phydev);
>> +
>> + ret = genphy_c45_an_config_aneg(phydev);
>> + if (ret < 0)
>> + return ret;
>> + if (ret > 0)
>> + changed = true;
>> +
>> + return genphy_c45_check_and_restart_aneg(phydev, changed);
>> +}
>> +EXPORT_SYMBOL_GPL(genphy_c45_config_aneg);
>
> The vendor parts for 1000BaseT makes this interesting. Do we expect to
> see an C45 PHYs which don't support 1000BaseT? I think that
> unlikely. So all C45 PHYs are going to implement their own config_aneg
> callback so they can set their vendor registers for 1000BaseT.
>
>> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
>> index f3adea9ef400..74c4e15ebe52 100644
>> --- a/drivers/net/phy/phy.c
>> +++ b/drivers/net/phy/phy.c
>> @@ -507,7 +507,7 @@ static int phy_config_aneg(struct phy_device *phydev)
>> * allowed to call genphy_config_aneg()
>> */
>> if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0)))
>> - return -EOPNOTSUPP;
>> + return genphy_c45_config_aneg(phydev);
>>
>> return genphy_config_aneg(phydev);
>
> So here we should be calling the driver config_aneg function. It can
> then call genphy_c45_config_aneg(phydev) to do the generic parts.
>
> Heiner, what do you think?
>
As you say, C45 doesn't cover 1000BaseT, therefore for this mode a
vendor-specific part is needed in the PHY driver always.
That's the reason why genphy_c45_an_config_aneg is meant to be used
within a PHY drivers config_aneg callback implementation, and why
we don't have a generic C45 config_aneg function yet.

Use case for the new function could be cases where 1000BaseT support
isn't needed, and it could serve as a fallback if there's no
dedicated PHY driver yet e.g. for a new chip.

> Andrew
>
Heiner