net: question on Liquidio II link speed management code, i suspect it's a bit incomplete

Florian Heigl <[email protected]> Tue, 31 Mar 2026 11:35:59 +0200
Newsgroups gmane.linux.newbie
Message-ID <[email protected]>
I=E2=80=99m trying to wrap my head around the link speed setting =
mechanism for the Cavium LiquidIO II / CN23XX NICs. I have a few of =
those for playing around and try to make them more accessible for =
others.

I=E2=80=99m on Alpine Linux edge, running 6.18.19

The card defaults to 25gbit, and when I try to set the link speed from =
ethtool it doesn=E2=80=99t work.
"Changing speed is not supported=E2=80=9C in dmesg and in ethtool =
it=E2=80=99ll say

tschike:/tmp# ethtool -s eth0 speed 10000
netlink error: link settings update failed
netlink error: Not supported

that was odd since I can find that that support IS in the kernel.

https://lists.openwall.net/netdev/2018/05/08/21



Today I was looking at this again, and specifically at how the flag =
no_speed_setting comes into existence.
I found that happens in lio.core.c (drivers/net/cavium/liquidio):

specifically here
                        var =3D be32_to_cpu((__force __be32)resp->speed)
if that sends back a ffff it=E2=80=99ll end up at the default link speed =
and deny setting it.


=
https://gist.github.com/FlorianHeigl/de72c603b1579dd94dc9ecbeb290a36c?perm=
alink_comment_id=3D6068358#gistcomment-6068358

I got the strong suspicion that the code for that decision making is =
incomplete.
common scenarios:
- if the card has link at 10g, it=E2=80=99ll send 10g, and you=E2=80=99ll =
be able to switch link speed via ethtool
- if the card has link at 25g, it=E2=80=99ll send 25g, and you=E2=80=99ll =
be able to switch link speed via ethtool
- if the card has a 10g cable and tries to talk 25g it will not have a =
link and no idea what to do.

>i think it the driver then ends up with no negotiated speed state,
and in that situation, with the current implementation you can never set =
the right speed<
this would explain the actual behaviour I see, and it would explain it =
better than just looking for
differences between the old SDK and fresher in-kernel code.
the supported link modes in ethtool are also =E2=80=9Ewrong" (only shows =
25g, should show 10g, 25g)



i=E2=80=99m just not sure how to prove it from the code. I can point at =
three relevant opcodes in liquidio_common.h


#define OPCODE_NIC_UBOOT_CTL           0x17
#define   SEAPI_CMD_SPEED_SET           0x2
#define   SEAPI_CMD_SPEED_GET           0x3

but IDK what really happens when it queries the that resp->speed thing =
(i=E2=80=99m not a dev, obviously)

I=E2=80=99ll test with a different u-boot version but the kernel side is =
far above my head.
some other dumb tests I can imagine are changing it to always select 10g =
or overriding the =E2=80=9Affff=E2=80=98 return.
it just feels like piking at things blindly. I=E2=80=99d like to know if =
that even has a point.
if someone tells me no that logic flaw you imagine doesn=E2=80=99t exist =
then I can avoid a lot of frustrating tests.
I don=E2=80=99t have a 25g DAC or SFP that the card accepts, so I =
can=E2=80=99t even test by just connecting it to itself.



tl;dr
I think driver only allows the card to change the link speed when it=E2=80=
=99s not really important to be able to
I think the supported link speeds are reported wrong
if someone with a bigger brain or more practice could look at the logic =
and see if my suspicions hold up, or tell me a reasonable next step to =
take?