From ea65363d578ffb3b7ee33ae5039f46167ac49914 Mon Sep 17 00:00:00 2001 From: "Daniel P. Carvalho" Date: Sat, 3 Oct 2026 21:45:00 -0300 Subject: [PATCH] arch/mips/pic32mz: keep the PHY auto-negotiation enabled. After a successful auto-negotiation, pic32mz_phyinit() called pic32mz_phymode() with the negotiated speed and duplex. That function clears MII_MCR_ANENABLE, so the PHY stayed in a forced mode. The link keeps working until the cable is removed, but on reconnection the PHY no longer negotiates and, against an auto-negotiating partner, the link stays down (seen with a LAN8720A: MCR 0x2100, MSR without link status). Only force the mode when CONFIG_PIC32MZ_PHY_AUTONEG is not selected. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Daniel P. Carvalho --- arch/mips/src/pic32mz/pic32mz_ethernet.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/arch/mips/src/pic32mz/pic32mz_ethernet.c b/arch/mips/src/pic32mz/pic32mz_ethernet.c index 130d71bc528..bcdc9f4b151 100644 --- a/arch/mips/src/pic32mz/pic32mz_ethernet.c +++ b/arch/mips/src/pic32mz/pic32mz_ethernet.c @@ -488,8 +488,9 @@ static uint16_t pic32mz_phyread(uint8_t phyaddr, uint8_t regaddr); static inline int pic32mz_phyreset(uint8_t phyaddr); # ifdef CONFIG_PIC32MZ_PHY_AUTONEG static inline int pic32mz_phyautoneg(uint8_t phyaddr); -# endif +# else static int pic32mz_phymode(uint8_t phyaddr, uint8_t mode); +# endif static inline int pic32mz_phyinit(struct pic32mz_driver_s *priv); #else # define pic32mz_phyinit(priv) @@ -2829,7 +2830,7 @@ static inline int pic32mz_phyautoneg(uint8_t phyaddr) * ****************************************************************************/ -#ifdef PIC32MZ_HAVE_PHY +#if defined(PIC32MZ_HAVE_PHY) && !defined(CONFIG_PIC32MZ_PHY_AUTONEG) static int pic32mz_phymode(uint8_t phyaddr, uint8_t mode) { int32_t timeout; @@ -2914,7 +2915,7 @@ static inline int pic32mz_phyinit(struct pic32mz_driver_s *priv) unsigned int phyaddr; uint16_t phyreg; uint32_t regval; - int ret; + int ret = OK; #if CONFIG_PIC32MZ_FMIIEN == 0 /* Set the RMII operation mode. This usually requires access to a vendor @@ -3181,11 +3182,16 @@ static inline int pic32mz_phyinit(struct pic32mz_driver_s *priv) (priv->pd_mode & PIC32MZ_DUPLEX_MASK) == PIC32MZ_DUPLEX_FULL ?"full" : "half"); - /* Disable auto-configuration. Set the fixed speed/duplex mode. - * (probably more than little redundant). +#ifndef CONFIG_PIC32MZ_PHY_AUTONEG + /* Set the fixed speed/duplex mode (again). With auto-negotiation, the + * negotiated mode is not forced: auto-negotiation stays enabled so that + * the PHY negotiates again when the cable is reconnected. Forcing the + * mode would leave the link down against an auto-negotiating partner. */ ret = pic32mz_phymode(phyaddr, priv->pd_mode); +#endif + pic32mz_showmii(phyaddr, "After final configuration"); return ret; }