diff mbox series

[net-next,3/9] net: phy: c45: don't accept disabled EEE modes in genphy_c45_ethtool_set_eee

Message ID 5964fa47-2eff-4968-894c-0b7f487d820c@gmail.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series net: phy: improve phylib EEE handling | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1 this patch: 1
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 7 of 7 maintainers
netdev/build_clang success Errors and warnings before: 2 this patch: 2
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 1 this patch: 1
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 11 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 35 this patch: 35
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2025-01-11--15-00 (tests: 883)

Commit Message

Heiner Kallweit Jan. 11, 2025, 9:06 a.m. UTC
Link modes in phydev->eee_disabled_modes are filtered out by
genphy_c45_write_eee_adv() and won't be advertised. Therefore
don't accept such modes from userspace.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/net/phy/phy-c45.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Russell King (Oracle) Jan. 11, 2025, 9:21 a.m. UTC | #1
On Sat, Jan 11, 2025 at 10:06:02AM +0100, Heiner Kallweit wrote:
> Link modes in phydev->eee_disabled_modes are filtered out by
> genphy_c45_write_eee_adv() and won't be advertised. Therefore
> don't accept such modes from userspace.

Why do we need this? Surely if the MAC doesn't support modes, then they
should be filtered out of phydev->supported_eee so that userspace knows
that the mode is not supported by the network interface as a whole, just
like we do for phydev->supported.

That would give us the checking here.
Heiner Kallweit Jan. 11, 2025, 9:44 a.m. UTC | #2
On 11.01.2025 10:21, Russell King (Oracle) wrote:
> On Sat, Jan 11, 2025 at 10:06:02AM +0100, Heiner Kallweit wrote:
>> Link modes in phydev->eee_disabled_modes are filtered out by
>> genphy_c45_write_eee_adv() and won't be advertised. Therefore
>> don't accept such modes from userspace.
> 
> Why do we need this? Surely if the MAC doesn't support modes, then they
> should be filtered out of phydev->supported_eee so that userspace knows
> that the mode is not supported by the network interface as a whole, just
> like we do for phydev->supported.
> 
> That would give us the checking here.
> 
Removing EEE modes to be disabled from supported_eee is problematic
because of how genphy_c45_write_eee_adv() works.

Let's say we have a 2.5Gbps PHY and want to disable EEE at 2.5Gbps. If we
remove 2.5Gbps from supported_eee, then the following check is false:
if (linkmode_intersects(phydev->supported_eee, PHY_EEE_CAP2_FEATURES))
What would result in the 2.5Gbps mode not getting disabled.
Russell King (Oracle) Jan. 11, 2025, 10:01 a.m. UTC | #3
On Sat, Jan 11, 2025 at 10:44:25AM +0100, Heiner Kallweit wrote:
> On 11.01.2025 10:21, Russell King (Oracle) wrote:
> > On Sat, Jan 11, 2025 at 10:06:02AM +0100, Heiner Kallweit wrote:
> >> Link modes in phydev->eee_disabled_modes are filtered out by
> >> genphy_c45_write_eee_adv() and won't be advertised. Therefore
> >> don't accept such modes from userspace.
> > 
> > Why do we need this? Surely if the MAC doesn't support modes, then they
> > should be filtered out of phydev->supported_eee so that userspace knows
> > that the mode is not supported by the network interface as a whole, just
> > like we do for phydev->supported.
> > 
> > That would give us the checking here.
> > 
> Removing EEE modes to be disabled from supported_eee is problematic
> because of how genphy_c45_write_eee_adv() works.
> 
> Let's say we have a 2.5Gbps PHY and want to disable EEE at 2.5Gbps. If we
> remove 2.5Gbps from supported_eee, then the following check is false:
> if (linkmode_intersects(phydev->supported_eee, PHY_EEE_CAP2_FEATURES))
> What would result in the 2.5Gbps mode not getting disabled.

Ok. Do we at least remove the broken modes from the supported mask
reported to userspace?
Heiner Kallweit Jan. 11, 2025, 1:19 p.m. UTC | #4
On 11.01.2025 11:01, Russell King (Oracle) wrote:
> On Sat, Jan 11, 2025 at 10:44:25AM +0100, Heiner Kallweit wrote:
>> On 11.01.2025 10:21, Russell King (Oracle) wrote:
>>> On Sat, Jan 11, 2025 at 10:06:02AM +0100, Heiner Kallweit wrote:
>>>> Link modes in phydev->eee_disabled_modes are filtered out by
>>>> genphy_c45_write_eee_adv() and won't be advertised. Therefore
>>>> don't accept such modes from userspace.
>>>
>>> Why do we need this? Surely if the MAC doesn't support modes, then they
>>> should be filtered out of phydev->supported_eee so that userspace knows
>>> that the mode is not supported by the network interface as a whole, just
>>> like we do for phydev->supported.
>>>
>>> That would give us the checking here.
>>>
>> Removing EEE modes to be disabled from supported_eee is problematic
>> because of how genphy_c45_write_eee_adv() works.
>>
>> Let's say we have a 2.5Gbps PHY and want to disable EEE at 2.5Gbps. If we
>> remove 2.5Gbps from supported_eee, then the following check is false:
>> if (linkmode_intersects(phydev->supported_eee, PHY_EEE_CAP2_FEATURES))
>> What would result in the 2.5Gbps mode not getting disabled.
> 
> Ok. Do we at least remove the broken modes from the supported mask
> reported to userspace?
> 
I think that's something we could do in addition, to provide a hint to the
user about unavailable modes. It wouldn't remove the need for the check here.
ethtool doesn't check the advertisement against the supported modes.
And even if it would, we must not rely on input from user space being sane.
Russell King (Oracle) Jan. 11, 2025, 3:13 p.m. UTC | #5
On Sat, Jan 11, 2025 at 02:19:04PM +0100, Heiner Kallweit wrote:
> On 11.01.2025 11:01, Russell King (Oracle) wrote:
> > On Sat, Jan 11, 2025 at 10:44:25AM +0100, Heiner Kallweit wrote:
> >> On 11.01.2025 10:21, Russell King (Oracle) wrote:
> >>> On Sat, Jan 11, 2025 at 10:06:02AM +0100, Heiner Kallweit wrote:
> >>>> Link modes in phydev->eee_disabled_modes are filtered out by
> >>>> genphy_c45_write_eee_adv() and won't be advertised. Therefore
> >>>> don't accept such modes from userspace.
> >>>
> >>> Why do we need this? Surely if the MAC doesn't support modes, then they
> >>> should be filtered out of phydev->supported_eee so that userspace knows
> >>> that the mode is not supported by the network interface as a whole, just
> >>> like we do for phydev->supported.
> >>>
> >>> That would give us the checking here.
> >>>
> >> Removing EEE modes to be disabled from supported_eee is problematic
> >> because of how genphy_c45_write_eee_adv() works.
> >>
> >> Let's say we have a 2.5Gbps PHY and want to disable EEE at 2.5Gbps. If we
> >> remove 2.5Gbps from supported_eee, then the following check is false:
> >> if (linkmode_intersects(phydev->supported_eee, PHY_EEE_CAP2_FEATURES))
> >> What would result in the 2.5Gbps mode not getting disabled.
> > 
> > Ok. Do we at least remove the broken modes from the supported mask
> > reported to userspace?
> > 
> I think that's something we could do in addition, to provide a hint to the
> user about unavailable modes. It wouldn't remove the need for the check here.
> ethtool doesn't check the advertisement against the supported modes.
> And even if it would, we must not rely on input from user space being sane.

I disagree with some of this. Userspace should expect:

- read current settings
- copy supported modes to advertised modes
- write current settings

to work. If it fails, then how does ethtool, or even the user, work out
which link modes are actually supported or not.

If we're introducing a failure on the "disabled" modes, then that is
a user-breaking change, and we need to avoid that. The current code
silently ignored the broken modes, your new code would error out on
the above action - and that's a bug.
Heiner Kallweit Jan. 11, 2025, 3:33 p.m. UTC | #6
On 11.01.2025 16:13, Russell King (Oracle) wrote:
> On Sat, Jan 11, 2025 at 02:19:04PM +0100, Heiner Kallweit wrote:
>> On 11.01.2025 11:01, Russell King (Oracle) wrote:
>>> On Sat, Jan 11, 2025 at 10:44:25AM +0100, Heiner Kallweit wrote:
>>>> On 11.01.2025 10:21, Russell King (Oracle) wrote:
>>>>> On Sat, Jan 11, 2025 at 10:06:02AM +0100, Heiner Kallweit wrote:
>>>>>> Link modes in phydev->eee_disabled_modes are filtered out by
>>>>>> genphy_c45_write_eee_adv() and won't be advertised. Therefore
>>>>>> don't accept such modes from userspace.
>>>>>
>>>>> Why do we need this? Surely if the MAC doesn't support modes, then they
>>>>> should be filtered out of phydev->supported_eee so that userspace knows
>>>>> that the mode is not supported by the network interface as a whole, just
>>>>> like we do for phydev->supported.
>>>>>
>>>>> That would give us the checking here.
>>>>>
>>>> Removing EEE modes to be disabled from supported_eee is problematic
>>>> because of how genphy_c45_write_eee_adv() works.
>>>>
>>>> Let's say we have a 2.5Gbps PHY and want to disable EEE at 2.5Gbps. If we
>>>> remove 2.5Gbps from supported_eee, then the following check is false:
>>>> if (linkmode_intersects(phydev->supported_eee, PHY_EEE_CAP2_FEATURES))
>>>> What would result in the 2.5Gbps mode not getting disabled.
>>>
>>> Ok. Do we at least remove the broken modes from the supported mask
>>> reported to userspace?
>>>
>> I think that's something we could do in addition, to provide a hint to the
>> user about unavailable modes. It wouldn't remove the need for the check here.
>> ethtool doesn't check the advertisement against the supported modes.
>> And even if it would, we must not rely on input from user space being sane.
> 
> I disagree with some of this. Userspace should expect:
> 
> - read current settings
> - copy supported modes to advertised modes
> - write current settings
> 
> to work. If it fails, then how does ethtool, or even the user, work out
> which link modes are actually supported or not.
> 
> If we're introducing a failure on the "disabled" modes, then that is
> a user-breaking change, and we need to avoid that. The current code
> silently ignored the broken modes, your new code would error out on
> the above action - and that's a bug.
> 
OK, then I think what we can/should do:
- filter out disabled EEE modes when populating data->supported in
  genphy_c45_ethtool_get_eee
- silently filter out disabled EEE modes from user space provided
  EEE advertisement in genphy_c45_ethtool_set_eee
Andrew Lunn Jan. 11, 2025, 5:31 p.m. UTC | #7
> > I disagree with some of this. Userspace should expect:
> > 
> > - read current settings
> > - copy supported modes to advertised modes
> > - write current settings
> > 
> > to work. If it fails, then how does ethtool, or even the user, work out
> > which link modes are actually supported or not.
> > 
> > If we're introducing a failure on the "disabled" modes, then that is
> > a user-breaking change, and we need to avoid that. The current code
> > silently ignored the broken modes, your new code would error out on
> > the above action - and that's a bug.
> > 
> OK, then I think what we can/should do:
> - filter out disabled EEE modes when populating data->supported in
>   genphy_c45_ethtool_get_eee
> - silently filter out disabled EEE modes from user space provided
>   EEE advertisement in genphy_c45_ethtool_set_eee

Ideally, the kAPI should work just the same as normal advertised
modes. The read API returns what can actually be used, and write API
expects a subset of that.

But maybe we have too much history and cannot enforce the subset
without regressions, we just silently ignore the extra modes?

It might be too much plumbing, but it would be nice to include an
extack saying some modes have been ignored? I _think_ extack can be
used without an error.

	Andrew
Heiner Kallweit Jan. 11, 2025, 5:52 p.m. UTC | #8
On 11.01.2025 18:31, Andrew Lunn wrote:
>>> I disagree with some of this. Userspace should expect:
>>>
>>> - read current settings
>>> - copy supported modes to advertised modes
>>> - write current settings
>>>
>>> to work. If it fails, then how does ethtool, or even the user, work out
>>> which link modes are actually supported or not.
>>>
>>> If we're introducing a failure on the "disabled" modes, then that is
>>> a user-breaking change, and we need to avoid that. The current code
>>> silently ignored the broken modes, your new code would error out on
>>> the above action - and that's a bug.
>>>
>> OK, then I think what we can/should do:
>> - filter out disabled EEE modes when populating data->supported in
>>   genphy_c45_ethtool_get_eee
>> - silently filter out disabled EEE modes from user space provided
>>   EEE advertisement in genphy_c45_ethtool_set_eee
> 
> Ideally, the kAPI should work just the same as normal advertised
> modes. The read API returns what can actually be used, and write API
> expects a subset of that.
> 
> But maybe we have too much history and cannot enforce the subset
> without regressions, we just silently ignore the extra modes?
> 
> It might be too much plumbing, but it would be nice to include an
> extack saying some modes have been ignored? I _think_ extack can be
> used without an error.
> 
Nice idea, this could be done as a follow-up. I'll have a look into this.

> 	Andrew
> 
Heiner
> 
> 
>
diff mbox series

Patch

diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c
index 468d24611..b566faba9 100644
--- a/drivers/net/phy/phy-c45.c
+++ b/drivers/net/phy/phy-c45.c
@@ -1559,6 +1559,11 @@  int genphy_c45_ethtool_set_eee(struct phy_device *phydev,
 				phydev_warn(phydev, "At least some EEE link modes are not supported.\n");
 				return -EINVAL;
 			}
+			linkmode_and(tmp, adv, phydev->eee_disabled_modes);
+			if (!linkmode_empty(tmp)) {
+				phydev_warn(phydev, "At least some EEE link modes are disabled.\n");
+				return -EINVAL;
+			}
 			linkmode_copy(phydev->advertising_eee, adv);
 		} else if (linkmode_empty(phydev->advertising_eee)) {
 			phy_advertise_eee_all(phydev);