diff mbox series

[v2,net] net: phy: broadcom: Correct BCM5221 PHY model detection failure

Message ID 20250317063452.3072784-1-JJLIU0@nuvoton.com (mailing list archive)
State New
Delegated to: Netdev Maintainers
Headers show
Series [v2,net] net: phy: broadcom: Correct BCM5221 PHY model detection failure | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 10 of 10 maintainers
netdev/build_clang success Errors and warnings before: 0 this patch: 0
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 Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 24 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest pending net-next-2025-03-17--09-00 (tests: 0)

Commit Message

Jim Liu March 17, 2025, 6:34 a.m. UTC
Use "BRCM_PHY_MODEL" can be applied to the entire 5221 family of PHYs.

Fixes: 3abbd0699b67 ("net: phy: broadcom: add support for BCM5221 phy")
Signed-off-by: Jim Liu <jim.t90615@gmail.com>
---
v2: 
   - add target tree
   - add maintainer in mail thread
   - modify checkpatch warning
---
 drivers/net/phy/broadcom.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

Russell King (Oracle) March 17, 2025, 10:24 a.m. UTC | #1
On Mon, Mar 17, 2025 at 02:34:52PM +0800, Jim Liu wrote:
> Use "BRCM_PHY_MODEL" can be applied to the entire 5221 family of PHYs.
> 
> Fixes: 3abbd0699b67 ("net: phy: broadcom: add support for BCM5221 phy")
> Signed-off-by: Jim Liu <jim.t90615@gmail.com>

Looking at BRCM_PHY_MODEL() and BRCM_PHY_REV(), I think there's more
issues with this driver. E.g.:

#define BRCM_PHY_MODEL(phydev) \
        ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)

#define BRCM_PHY_REV(phydev) \
        ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask))

#define PHY_ID_BCM50610                 0x0143bd60
#define PHY_ID_BCM50610M                0x0143bd70

        if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
             BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
            BRCM_PHY_REV(phydev) >= 0x3) {

and from the PHY driver table:

        .phy_id         = PHY_ID_BCM50610,
        .phy_id_mask    = 0xfffffff0,

        .phy_id         = PHY_ID_BCM50610M,
        .phy_id_mask    = 0xfffffff0,

BRCM_PHY_REV() looks at _this_ .phy_id in the table, and tries to match
it against the revision field bits 0-3 being >= 3 - but as we can see,
this field is set to the defined value which has bits 0-3 always as
zero. So, this if() statement is always false.

So, BRCM_PHY_REV() should be:

#define BRCM_PHY_REV(phydev) \
	((phydev)->phy_id & ~(phydev)->drv->phy_id_mask)


Next, I question why BRCM_PHY_MODEL() exists in the first place.
phydev->drv->phy_id is initialised to the defined value(s), and then
we end up doing:

	(phydev->drv->phy_id & phydev->drv->phy_id_mask) ==
		one-of-those-defined-values

which is pointless, because we know that what is in phydev->drv->phy_id
/is/ one-of-those-defined-values.

Therefore, I would suggest:

#define BRCM_PHY_MODEL(phydev) ((phydev)->drv->phy_id)

is entirely sufficient, and with such a simple definition, I question
the value of BRCM_PHY_MODEL() existing.
Florian Fainelli March 17, 2025, 1:18 p.m. UTC | #2
On 3/17/2025 3:24 AM, Russell King (Oracle) wrote:
> On Mon, Mar 17, 2025 at 02:34:52PM +0800, Jim Liu wrote:
>> Use "BRCM_PHY_MODEL" can be applied to the entire 5221 family of PHYs.
>>
>> Fixes: 3abbd0699b67 ("net: phy: broadcom: add support for BCM5221 phy")
>> Signed-off-by: Jim Liu <jim.t90615@gmail.com>
> 
> Looking at BRCM_PHY_MODEL() and BRCM_PHY_REV(), I think there's more
> issues with this driver. E.g.:
> 
> #define BRCM_PHY_MODEL(phydev) \
>          ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
> 
> #define BRCM_PHY_REV(phydev) \
>          ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask))
> 
> #define PHY_ID_BCM50610                 0x0143bd60
> #define PHY_ID_BCM50610M                0x0143bd70
> 
>          if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
>               BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
>              BRCM_PHY_REV(phydev) >= 0x3) {
> 
> and from the PHY driver table:
> 
>          .phy_id         = PHY_ID_BCM50610,
>          .phy_id_mask    = 0xfffffff0,
> 
>          .phy_id         = PHY_ID_BCM50610M,
>          .phy_id_mask    = 0xfffffff0,
> 
> BRCM_PHY_REV() looks at _this_ .phy_id in the table, and tries to match
> it against the revision field bits 0-3 being >= 3 - but as we can see,
> this field is set to the defined value which has bits 0-3 always as
> zero. So, this if() statement is always false.
> 
> So, BRCM_PHY_REV() should be:
> 
> #define BRCM_PHY_REV(phydev) \
> 	((phydev)->phy_id & ~(phydev)->drv->phy_id_mask)
> 
> 
> Next, I question why BRCM_PHY_MODEL() exists in the first place.
> phydev->drv->phy_id is initialised to the defined value(s), and then
> we end up doing:
> 
> 	(phydev->drv->phy_id & phydev->drv->phy_id_mask) ==
> 		one-of-those-defined-values
> 
> which is pointless, because we know that what is in phydev->drv->phy_id
> /is/ one-of-those-defined-values.
> 
> Therefore, I would suggest:
> 
> #define BRCM_PHY_MODEL(phydev) ((phydev)->drv->phy_id)
> 
> is entirely sufficient, and with such a simple definition, I question
> the value of BRCM_PHY_MODEL() existing.

If I were to make a guess, BRCM_PHY_MODEL() might have existed to ease 
the porting of a non-Linux PHY driver to a Linux PHY driver environment 
at a time where the subsystem was not as mature as it is now.

In the interest of a targeted bug fix, I would be keen on taking this 
patch in its current form and follow up in net next with a removal of 
BRCM_PHY_MODEL() later on.
Russell King (Oracle) March 17, 2025, 1:29 p.m. UTC | #3
On Mon, Mar 17, 2025 at 06:18:17AM -0700, Florian Fainelli wrote:
> On 3/17/2025 3:24 AM, Russell King (Oracle) wrote:
> > On Mon, Mar 17, 2025 at 02:34:52PM +0800, Jim Liu wrote:
> > > Use "BRCM_PHY_MODEL" can be applied to the entire 5221 family of PHYs.
> > > 
> > > Fixes: 3abbd0699b67 ("net: phy: broadcom: add support for BCM5221 phy")
> > > Signed-off-by: Jim Liu <jim.t90615@gmail.com>
> > 
> > Looking at BRCM_PHY_MODEL() and BRCM_PHY_REV(), I think there's more
> > issues with this driver. E.g.:
> > 
> > #define BRCM_PHY_MODEL(phydev) \
> >          ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
> > 
> > #define BRCM_PHY_REV(phydev) \
> >          ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask))
> > 
> > #define PHY_ID_BCM50610                 0x0143bd60
> > #define PHY_ID_BCM50610M                0x0143bd70
> > 
> >          if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
> >               BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
> >              BRCM_PHY_REV(phydev) >= 0x3) {
> > 
> > and from the PHY driver table:
> > 
> >          .phy_id         = PHY_ID_BCM50610,
> >          .phy_id_mask    = 0xfffffff0,
> > 
> >          .phy_id         = PHY_ID_BCM50610M,
> >          .phy_id_mask    = 0xfffffff0,
> > 
> > BRCM_PHY_REV() looks at _this_ .phy_id in the table, and tries to match
> > it against the revision field bits 0-3 being >= 3 - but as we can see,
> > this field is set to the defined value which has bits 0-3 always as
> > zero. So, this if() statement is always false.
> > 
> > So, BRCM_PHY_REV() should be:
> > 
> > #define BRCM_PHY_REV(phydev) \
> > 	((phydev)->phy_id & ~(phydev)->drv->phy_id_mask)
> > 
> > 
> > Next, I question why BRCM_PHY_MODEL() exists in the first place.
> > phydev->drv->phy_id is initialised to the defined value(s), and then
> > we end up doing:
> > 
> > 	(phydev->drv->phy_id & phydev->drv->phy_id_mask) ==
> > 		one-of-those-defined-values
> > 
> > which is pointless, because we know that what is in phydev->drv->phy_id
> > /is/ one-of-those-defined-values.
> > 
> > Therefore, I would suggest:
> > 
> > #define BRCM_PHY_MODEL(phydev) ((phydev)->drv->phy_id)
> > 
> > is entirely sufficient, and with such a simple definition, I question
> > the value of BRCM_PHY_MODEL() existing.
> 
> If I were to make a guess, BRCM_PHY_MODEL() might have existed to ease the
> porting of a non-Linux PHY driver to a Linux PHY driver environment at a
> time where the subsystem was not as mature as it is now.
> 
> In the interest of a targeted bug fix, I would be keen on taking this patch
> in its current form and follow up in net next with a removal of
> BRCM_PHY_MODEL() later on.

Note that commit 32e5a8d651c0 ("tg3 / broadcom: Add code to disable rxc
refclk") is still wrong (which introduced BRCM_PHY_REV().)

Given its age, I would suggest that the commit I reference above was
not properly tested, and *possibly* fixing the bug might actually
cause a regression on TG3.

Also, the original commit description (which references RXC) which is
supposed to be synchronous to the received data, but the code talks
about CLK125 which is *technically* a different clock.

We know that the current driver logic works, even though it doesn't
do what the original author of the code wanted it to do.

Taking these three points together, I don't think it would be wise
to fix the logical error (and actually test the revision field).
Instead, I think getting rid of the always-false if() and simplifying
the code would be better to avoid causing a possible regression on
TG3.
diff mbox series

Patch

diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 22edb7e4c1a1..3529289e9d13 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -859,7 +859,7 @@  static int brcm_fet_config_init(struct phy_device *phydev)
 		return reg;
 
 	/* Unmask events we are interested in and mask interrupts globally. */
-	if (phydev->phy_id == PHY_ID_BCM5221)
+	if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM5221)
 		reg = MII_BRCM_FET_IR_ENABLE |
 		      MII_BRCM_FET_IR_MASK;
 	else
@@ -888,7 +888,7 @@  static int brcm_fet_config_init(struct phy_device *phydev)
 		return err;
 	}
 
-	if (phydev->phy_id != PHY_ID_BCM5221) {
+	if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM5221) {
 		/* Set the LED mode */
 		reg = __phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4);
 		if (reg < 0) {
@@ -1009,7 +1009,7 @@  static int brcm_fet_suspend(struct phy_device *phydev)
 		return err;
 	}
 
-	if (phydev->phy_id == PHY_ID_BCM5221)
+	if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM5221)
 		/* Force Low Power Mode with clock enabled */
 		reg = BCM5221_SHDW_AM4_EN_CLK_LPM | BCM5221_SHDW_AM4_FORCE_LPM;
 	else