Smatch report for drivers/net/phy/marvell10g.c
Marek Vasut
marek.vasut at mailbox.org
Thu Jan 1 17:54:47 CET 2026
On 8/7/25 10:36 AM, Marek Behún wrote:
> On Wed, Aug 06, 2025 at 05:36:27PM +0200, Marek Vasut wrote:
>> On 8/6/25 4:53 PM, Tom Rini wrote:
>>> On Tue, Aug 05, 2025 at 05:30:49PM +0100, Andrew Goodbody wrote:
>>>
>>>> I have these Smatch reports.
>>>>
>>>> drivers/net/phy/marvell10g.c:384 mv3310_select_mactype() warn: was ||
>>>> intended here instead of &&?
>>>> drivers/net/phy/marvell10g.c:387 mv3310_select_mactype() warn: was ||
>>>> intended here instead of &&?
>>>> drivers/net/phy/marvell10g.c:390 mv3310_select_mactype() warn: was ||
>>>> intended here instead of &&?
>>>>
>>>> Now there is obviously incorrect code there as it cannot work correctly as
>>>> is, phydev->interface cannot equal two different enums at the same time, but
>>>> simply swapping the && for || is not going to work either. Could anyone
>>>> please point me in the direction of a fix?
>>>
>>> Adding Marek as r8a779f0_spider and r8a779f4_s4sk are the only two
>>> boards which enable CONFIG_PHY_MARVELL_10G (aside, ./tools/qconfig.py -b
>>> and then ./tools/qconfig.py -f CONFIG_FOO is handy to see what boards
>>> enable a given option and helpful when get_maintainer.pl has nothing
>>> specific).
>> They use the 2xxx series PHY, so this code is avoided. However, it seems
>> even linux-next has the same behavior in .select_mactype() callback . They
>> use test_bit() in there, but otherwise also use && instead of || which looks
>> odd. Maybe that is a genuine bug which got ported over from Linux and needs
>> to be fixed both there and here ?
>
> In linux there is a bitmap of supported interface modes given to the
> function. Then for example we test whether 10gbase-r and sgmii are both
> supported by the host (SoC):
>
> ...
> else if (test_bit(PHY_INTERFACE_MODE_SGMII, interfaces) &&
> test_bit(PHY_INTERFACE_MODE_10GBASER, interfaces))
> return MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER;
> ...
>
> If both 10gbase-r and sgmii are supported by the SoC, we tell the PHY to
> use mactype 4 (MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER).
>
> Obiously this does not work in U-Boot it we translate it to
> interface == MODE_SGMII && interface == MODE_10GBASER
> since the interface variable is not a bitmap of supported interfaces,
> but rather the current interface mode (maybe from device-tree).
>
> Looking at U-Boot's marvell10g code, I also see mv_test_bit macro
> and how it is being used:
>
> #define mv_test_bit(iface, phydev) \
> ({ if ((phydev)->interface & (iface)) return 0; })
>
> mv_test_bit(PHY_INTERFACE_MODE_SGMII, phydev);
>
> This is completely wrong, since the ->interface member is not a bitmap
> (rather the currnet selected interface) nor are the PHY_INTERFACE_MODE_*
> values one-bit values.
>
> So this code will not work correctly at all in U-Boot.
>
>
> Now as to why Linux also has interfaces bitmap in addition to the current
> selected interface.
>
> The reason why in Linux we use bitmap of supported interface modes is so
> that we can select the best serdes mode switching behavior for the PHY.
>
> For example if the host only supports 10gbase-r serdes mode, then the PHY
> must always talk to the host in 10gbase-r mode, even if the RJ-45 copper
> speed was autonegotiated to lower speed (i.e. 1gbps). (There is another
> complication called rate matching that needs to be done in that case,
> but this is not important now.)
>
> If the host supports both 10gbase-r and sgmii serdes modes, we want the
> PHY to switch to sgmii if the RJ-45 speed is 1000/100/10, and to switch
> to 10gbase-r if the RJ-45 speed is 10000.
>
> The register configuring this behavior is called MACTYPE in the Marvell
> PHY.
>
> The following table shows how the PHY will change serdes mode depedning
> on the RJ-45 speed for some of the MACTYPE settings:
>
> mactype=4 mactype=6 mactype=7 mactype=0
> RJ-45 speed sds mode sds mode sds mode sds mode
> ---------------------------------------------------------
> 10/100/1000 sgmii 10gbase-r usxgmii sgmii
> 2500 2500base-x 10gbase-r usxgmii 2500base-x
> 5000 5gbase-r 10gbase-r usxgmii 5gbase-r
> 10000 10gbase-r 10gbase-r usxgmii rxaui
Thank you for the excellent detailed explanation. I have finally
submitted a fix:
https://lore.kernel.org/u-boot/20260101165317.25595-1-marek.vasut+renesas@mailbox.org/
More information about the U-Boot
mailing list