From a05c0d17321e09353bb4a5b993f8d4579f1696c8 Mon Sep 17 00:00:00 2001 From: Mikhail Kshevetskiy Date: Sun, 15 Mar 2026 10:47:55 +0300 Subject: [PATCH 01/18] net: airoha: probe airoha switch mdio on airoha_eth probing Airoha switch mdio maybe used not only by GDM1, but also by other GDM ports (ex: as21xxx phy connected to GDM2 port). So it's better probe airoha switch mdio a bit early in the airoha_eth_probe() code. Also remove useless eth_phy_set_mdio_bus() call and related code. Signed-off-by: Mikhail Kshevetskiy --- drivers/net/airoha_eth.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/drivers/net/airoha_eth.c b/drivers/net/airoha_eth.c index f60405392b6..84ee9b2ad76 100644 --- a/drivers/net/airoha_eth.c +++ b/drivers/net/airoha_eth.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -909,6 +908,11 @@ static int airoha_eth_probe(struct udevice *dev) if (ret) return ret; + if (eth->switch_mdio_dev) { + if (!device_probe(eth->switch_mdio_dev)) + debug("Warning: failed to probe airoha switch mdio\n"); + } + ofnode_for_each_subnode(node, dev_ofnode(dev)) { if (!ofnode_device_is_compatible(node, "airoha,eth-mac")) continue; @@ -935,8 +939,6 @@ static int airoha_eth_port_probe(struct udevice *dev) { struct airoha_eth *eth = (void *)dev_get_driver_data(dev); struct airoha_gdm_port *port = dev_get_priv(dev); - struct mdio_perdev_priv *pdata; - struct mii_dev *mdio_bus; int ret; port->qdma = ð->qdma[0]; @@ -945,7 +947,6 @@ static int airoha_eth_port_probe(struct udevice *dev) if (ret) return ret; - mdio_bus = NULL; if (port->id > 1) { #if defined(CONFIG_PCS_AIROHA) ret = airoha_pcs_init(dev); @@ -953,24 +954,11 @@ static int airoha_eth_port_probe(struct udevice *dev) return ret; port->phydev = dm_eth_phy_connect(dev); - if (port->phydev) - mdio_bus = port->phydev->bus; #else return -EINVAL; #endif - } else { - if (eth->switch_mdio_dev && - !device_probe(eth->switch_mdio_dev)) { - pdata = dev_get_uclass_priv(eth->switch_mdio_dev); - mdio_bus = pdata->mii_bus; - } } -#ifdef CONFIG_DM_ETH_PHY - if (!IS_ERR_OR_NULL(mdio_bus)) - eth_phy_set_mdio_bus(dev, mdio_bus); -#endif - return 0; } From ac91f1a8ad59ce899ba2c46407a48a989eab3744 Mon Sep 17 00:00:00 2001 From: Mikhail Kshevetskiy Date: Sun, 15 Mar 2026 10:47:56 +0300 Subject: [PATCH 02/18] net: pcs-airoha: unify code using SCU regmap helper Use common code to get CHIP_SCU registers instead of driver one. Signed-off-by: Mikhail Kshevetskiy --- drivers/net/airoha/pcs-airoha-common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/airoha/pcs-airoha-common.c b/drivers/net/airoha/pcs-airoha-common.c index 2e5cb085498..1263092fcdd 100644 --- a/drivers/net/airoha/pcs-airoha-common.c +++ b/drivers/net/airoha/pcs-airoha-common.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include "pcs-airoha.h" @@ -755,7 +755,7 @@ static int airoha_pcs_probe(struct udevice *dev) return PTR_ERR(priv->xfi_ana); /* SCU is used to toggle XFI or HSGMII in global SoC registers */ - priv->scu = syscon_regmap_lookup_by_phandle(dev, "airoha,scu"); + priv->scu = airoha_get_scu_regmap(); if (IS_ERR(priv->scu)) return PTR_ERR(priv->scu); From 6dae594af33197e28a2c21e137e67b7cd1bde67d Mon Sep 17 00:00:00 2001 From: Mikhail Kshevetskiy Date: Sun, 15 Mar 2026 10:47:57 +0300 Subject: [PATCH 03/18] net: pcs-airoha: fix allyesconfig building Airoha PCS driver depends on ARCH_AIROHA, so it should not be built by allyesconfig configuration. Signed-off-by: Mikhail Kshevetskiy --- drivers/net/airoha/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/airoha/Kconfig b/drivers/net/airoha/Kconfig index 8c2d6db92fa..d0c007ced80 100644 --- a/drivers/net/airoha/Kconfig +++ b/drivers/net/airoha/Kconfig @@ -6,6 +6,7 @@ config PCS_AIROHA config PCS_AIROHA_AN7581 bool "Airoha AN7581 PCS driver" + depends on ARCH_AIROHA select PCS_AIROHA help This module provides helper to phylink for managing the Airoha From 6b5d2990f4951dc832cc162790a8baea5a8715ce Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 16 Mar 2026 19:24:23 -0600 Subject: [PATCH 04/18] net: Rework some symbol dependencies As exposed by "make randconfig", we have a few dependency issues with some network drivers: - Both HIFEMAC_ETH and HIGMACV300_ETH functionally require both DM and OF_CONTROL. Further, HIFEMAC_ETH needs DM_CLK not just CLK to be selected. - BNXT_ETH deals with it's PCI requirement in a backwards way. The symbol PCI_INIT_R is board specific, PCI alone is required to build. Signed-off-by: Tom Rini --- drivers/net/Kconfig | 3 +++ drivers/net/bnxt/Kconfig | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index cd07b117a5f..02063ce3aa9 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -979,7 +979,9 @@ source "drivers/net/mtk_eth/Kconfig" config HIFEMAC_ETH bool "HiSilicon Fast Ethernet Controller" + depends on DM && OF_CONTROL select CLK + select DM_CLK select DM_RESET select PHYLIB help @@ -996,6 +998,7 @@ config HIFEMAC_MDIO config HIGMACV300_ETH bool "HiSilicon Gigabit Ethernet Controller" + depends on DM && OF_CONTROL select DM_RESET select PHYLIB help diff --git a/drivers/net/bnxt/Kconfig b/drivers/net/bnxt/Kconfig index 6ff3ffa137b..e25ed479678 100644 --- a/drivers/net/bnxt/Kconfig +++ b/drivers/net/bnxt/Kconfig @@ -1,6 +1,6 @@ config BNXT_ETH bool "BNXT PCI support" - select PCI_INIT_R + depends on PCI help This driver implements support for bnxt pci controller driver of ethernet class. From 6e30330d7ac1b708772b1f5c2afae4bbec7c9678 Mon Sep 17 00:00:00 2001 From: Boon Khai Ng Date: Thu, 12 Mar 2026 19:22:46 +0800 Subject: [PATCH 05/18] net: dwc_eth_xgmac: Move DMA reset and pad calibration after PHY init - Move DMA software reset and pad calibration in xgmac_start() to occur after the PHY is initialized and connected. - This ensures the PHY is ready before performing these operations, which is necessary for proper recovery after reboot. This change fixes issues where the PHY did not recover from power-down state after a Linux reboot, for the board using Micrel KSZ90x1 PHY. Signed-off-by: Boon Khai Ng --- drivers/net/dwc_eth_xgmac.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/dwc_eth_xgmac.c b/drivers/net/dwc_eth_xgmac.c index 458b87af7a2..2ab5ec5f0d9 100644 --- a/drivers/net/dwc_eth_xgmac.c +++ b/drivers/net/dwc_eth_xgmac.c @@ -497,20 +497,6 @@ static int xgmac_start(struct udevice *dev) xgmac->reg_access_ok = true; - ret = wait_for_bit_le32(&xgmac->dma_regs->mode, - XGMAC_DMA_MODE_SWR, false, - xgmac->config->swr_wait, false); - if (ret) { - pr_err("%s XGMAC_DMA_MODE_SWR stuck: %d\n", dev->name, ret); - goto err_stop_resets; - } - - ret = xgmac->config->ops->xgmac_calibrate_pads(dev); - if (ret < 0) { - pr_err("%s xgmac_calibrate_pads() failed: %d\n", dev->name, ret); - goto err_stop_resets; - } - /* * if PHY was already connected and configured, * don't need to reconnect/reconfigure again @@ -559,6 +545,20 @@ static int xgmac_start(struct udevice *dev) goto err_shutdown_phy; } + ret = wait_for_bit_le32(&xgmac->dma_regs->mode, + XGMAC_DMA_MODE_SWR, false, + xgmac->config->swr_wait, false); + if (ret) { + pr_err("%s XGMAC_DMA_MODE_SWR stuck: %d\n", dev->name, ret); + goto err_stop_resets; + } + + ret = xgmac->config->ops->xgmac_calibrate_pads(dev); + if (ret < 0) { + pr_err("%s xgmac_calibrate_pads() failed: %d\n", dev->name, ret); + goto err_stop_resets; + } + /* Configure MTL */ /* Enable Store and Forward mode for TX */ From a40defd46a636fcdb38a5cfe4a354ace1730dbe1 Mon Sep 17 00:00:00 2001 From: Boon Khai Ng Date: Thu, 12 Mar 2026 19:22:47 +0800 Subject: [PATCH 06/18] phy: micrel: ksz90x1: Issue PHY soft reset during configuration - Add a call to phy_reset() in ksz9031_config() to ensure the PHY is properly reset during initialization. - This clears the power-down bit and ensures the PHY recovers correctly after Linux reboot. Tested on Agilex5 hardware with KSZ90X1 PHY. Signed-off-by: Boon Khai Ng --- drivers/net/phy/micrel_ksz90x1.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/phy/micrel_ksz90x1.c b/drivers/net/phy/micrel_ksz90x1.c index f357e0f1c77..1a7116f4ddd 100644 --- a/drivers/net/phy/micrel_ksz90x1.c +++ b/drivers/net/phy/micrel_ksz90x1.c @@ -407,6 +407,9 @@ static int ksz9031_config(struct phy_device *phydev) if (ret) return ret; + /* soft reset */ + phy_reset(phydev); + ksz90x1_workaround_asymmetric_pause(phydev); /* add an option to disable the gigabit feature of this PHY */ From 803e5cc5f9dd47b4f4361270831dd02737657b47 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Fri, 20 Mar 2026 14:53:27 -0600 Subject: [PATCH 07/18] net: Rework dependencies around NET/NET_LWIP and NETDEVICES Functionally, both networking stacks require DM_ETH. This is because they both also require some networking devices to be enabled. Express this more correctly by having both NET and NET_LWIP select NETDEVICES. In turn NETDEVICES no longer depends on NET or NET_LWIP as it's not prompted anymore. Signed-off-by: Tom Rini Reviewed-by: Jerome Forissier --- Kconfig | 4 ++-- drivers/net/Kconfig | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Kconfig b/Kconfig index 1679bba5d75..24d238f96df 100644 --- a/Kconfig +++ b/Kconfig @@ -804,14 +804,14 @@ config NO_NET config NET bool "Legacy U-Boot networking stack" - imply NETDEVICES + select NETDEVICES help Include networking support with U-Boot's internal implementation of the TCP/IP protocol stack. config NET_LWIP bool "Use lwIP for networking stack" - imply NETDEVICES + select NETDEVICES help Include networking support based on the lwIP (lightweight IP) TCP/IP stack (https://nongnu.org/lwip). This is a replacement for diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 02063ce3aa9..9d4e9f06970 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -90,9 +90,10 @@ config DSA_SANDBOX Ethernet device used as DSA master, to test DSA class code, including exported DSA API and datapath processing of Ethernet traffic. -menuconfig NETDEVICES - bool "Network device support" - depends on NET || NET_LWIP +menu "Network device support" + +config NETDEVICES + bool select DM_ETH help You must select Y to enable any network device support @@ -1106,3 +1107,5 @@ source "drivers/net/pfe_eth/Kconfig" source "drivers/net/fsl-mc/Kconfig" endif # NETDEVICES + +endmenu From 078e2663e44ae36a66d4f4cd9b6506689e328633 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Fri, 20 Mar 2026 14:53:29 -0600 Subject: [PATCH 08/18] net: lwip: nfs: Add missing dependency In order to use NFS with lwIP we need to select PROT_UDP_LWIP. Signed-off-by: Tom Rini Reviewed-by: Jerome Forissier --- cmd/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/Kconfig b/cmd/Kconfig index a96d6472359..08af0003a9f 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2229,6 +2229,7 @@ config CMD_MDIO config CMD_NFS bool "nfs" + select PROT_UDP_LWIP if NET_LWIP help Boot image via network using NFS protocol. From fd6e3d34097f9fbe268aa56a50fecc013f4d07a3 Mon Sep 17 00:00:00 2001 From: Pranav Tilak Date: Mon, 23 Mar 2026 15:14:14 +0530 Subject: [PATCH 09/18] net: lwip: nfs: fix buffer overflow when using symlinks When resolving a symlink, nfs_path points into a heap allocated buffer which is just large enough to hold the original path with no extra space. If the symlink target name is longer than the original filename, the write goes beyond the end of the buffer corrupting heap memory. Fix this by ensuring nfs_path always points to a buffer large enough to accommodate the resolved symlink path. Fixes: 230cf3bc2776 ("net: lwip: nfs: Port the NFS code to work with lwIP") Signed-off-by: Pranav Tilak Acked-by: Jerome Forissier Reviewed-by: Jerome Forissier --- net/lwip/nfs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/lwip/nfs.c b/net/lwip/nfs.c index c3b819a091e..9e6b801e465 100644 --- a/net/lwip/nfs.c +++ b/net/lwip/nfs.c @@ -114,8 +114,10 @@ static int nfs_loop(struct udevice *udev, ulong addr, char *fname, if (!netif) return -1; - nfs_filename = nfs_basename(fname); - nfs_path = nfs_dirname(fname); + strlcpy(nfs_path_buff, fname, sizeof(nfs_path_buff)); + + nfs_filename = nfs_basename(nfs_path_buff); + nfs_path = nfs_dirname(nfs_path_buff); printf("Using %s device\n", udev->name); From 9d0b1838044616d4bbe7b5c7815d43d70888719f Mon Sep 17 00:00:00 2001 From: Javen Xu Date: Tue, 17 Mar 2026 15:24:56 +0800 Subject: [PATCH 10/18] rtl8169: add support for RTL8125d This patch adds support for RTL8125d. Its chip version is 0x6a. Signed-off-by: Javen Xu [jf: add missing comma] Signed-off-by: Jerome Forissier --- drivers/net/rtl8169.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index edcae88a3fc..5b093623619 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -270,6 +270,7 @@ static struct { {"RTL-8100e", 0x32, 0xff7e1880,}, {"RTL-8168h/8111h", 0x54, 0xff7e1880,}, {"RTL-8125B", 0x64, 0xff7e1880,}, + {"RTL-8125d", 0x6a, 0xff7e5880,}, }; enum _DescStatusBit { From 66da793b69cbc3cced046c93e9882b249a30a5c6 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 23 Mar 2026 13:52:53 -0600 Subject: [PATCH 11/18] net: cmd: Correct dependencies for CMD_PXE The CMD_PXE functionality can only build with CMD_TFTPBOOT enabled (or we get undefined references to do_tftpb), so express this dependency in Kconfig. Signed-off-by: Tom Rini --- cmd/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index 08af0003a9f..3fd426d3d44 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2314,7 +2314,7 @@ config WGET_BUILTIN_CACERT_PATH config CMD_PXE bool "pxe" select PXE_UTILS - imply CMD_TFTPBOOT + select CMD_TFTPBOOT help Boot image via network using PXE protocol From 2edd015cd578dd6e157499e6bd55082637f72bf3 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 23 Mar 2026 13:53:00 -0600 Subject: [PATCH 12/18] net: Correct dependencies for HIFEMAC_ETH The HIFEMAC_ETH functionality can only work with both DM_ETH_PHY and DM_MDIO enabled (it calls one of the functions that requires both), so express this dependency in Kconfig. Signed-off-by: Tom Rini --- drivers/net/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9d4e9f06970..ed07e286676 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -983,6 +983,8 @@ config HIFEMAC_ETH depends on DM && OF_CONTROL select CLK select DM_CLK + select DM_ETH_PHY + select DM_MDIO select DM_RESET select PHYLIB help From b3e303b60f39149085a21d7c4bbc5138d4506a70 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 25 Mar 2026 02:06:47 +0100 Subject: [PATCH 13/18] cmd: dhcp: Select CMD_BOOTP The DHCP command depends on bootp_reset() function, which is implemented only if CMD_BOOTP is enabled. Select CMD_BOOTP to satisfy the dependency. Signed-off-by: Marek Vasut Reviewed-by: Tom Rini Reviewed-by: Heiko Schocher Reviewed-by: Kory Maincent --- cmd/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/Kconfig b/cmd/Kconfig index 3fd426d3d44..81c64d9ba85 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2195,6 +2195,7 @@ endif # if NET config CMD_DHCP bool "dhcp" select PROT_DHCP_LWIP if NET_LWIP + select CMD_BOOTP help Boot image via network using DHCP/TFTP protocol From d63e58c5f030785c17607f00cbec354e6d84e733 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 25 Mar 2026 02:07:12 +0100 Subject: [PATCH 14/18] net: bootp: Drop unused code This code is surely unused and there are not even commented out references to the function name. Drop the code. Signed-off-by: Marek Vasut Reviewed-by: Heiko Schocher Reviewed-by: Kory Maincent Reviewed-by: Ilias Apalodimas --- net/bootp.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/net/bootp.c b/net/bootp.c index 1d905a01a47..8976936b184 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -87,23 +87,6 @@ static u8 dhcp_option_overload; #define OVERLOAD_SNAME 2 static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip, unsigned src, unsigned len); - -/* For Debug */ -#if 0 -static char *dhcpmsg2str(int type) -{ - switch (type) { - case 1: return "DHCPDISCOVER"; break; - case 2: return "DHCPOFFER"; break; - case 3: return "DHCPREQUEST"; break; - case 4: return "DHCPDECLINE"; break; - case 5: return "DHCPACK"; break; - case 6: return "DHCPNACK"; break; - case 7: return "DHCPRELEASE"; break; - default: return "UNKNOWN/INVALID MSG TYPE"; break; - } -} -#endif #endif static void bootp_add_id(ulong id) From 1fc34e1bb8c727354b5f5f908ecefadbd6fe1d6b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 25 Mar 2026 02:09:05 +0100 Subject: [PATCH 15/18] net: rswitch: Avoid NULL pointer dereference during PHY access At the very early stage when PHY ID is being auto-detected, the PHY device is not yet instantiated and rswitch_etha .phydev is still NULL. Add missing check for this condition and perform C22 fallback access in this PHY ID auto-detection case. Signed-off-by: Marek Vasut --- drivers/net/rswitch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/rswitch.c b/drivers/net/rswitch.c index 801c22bbdc7..c51908ed8f3 100644 --- a/drivers/net/rswitch.c +++ b/drivers/net/rswitch.c @@ -482,7 +482,7 @@ static int rswitch_mii_read_c45(struct mii_dev *miidev, int phyad, int devad, in /* Access PHY register */ if (devad != MDIO_DEVAD_NONE) /* Definitelly C45 */ val = rswitch_mii_access_c45(etha_mii, true, phyad, devad, regad, 0); - else if (etha->phydev->is_c45) /* C22 access to C45 PHY */ + else if (etha->phydev && etha->phydev->is_c45) /* C22 access to C45 PHY */ val = rswitch_mii_access_c45(etha_mii, true, phyad, 1, regad, 0); else val = rswitch_mii_access_c22(etha_mii, true, phyad, regad, 0); @@ -516,7 +516,7 @@ int rswitch_mii_write_c45(struct mii_dev *miidev, int phyad, int devad, int rega /* Access PHY register */ if (devad != MDIO_DEVAD_NONE) /* Definitelly C45 */ rswitch_mii_access_c45(etha_mii, false, phyad, devad, regad, data); - else if (etha->phydev->is_c45) /* C22 access to C45 PHY */ + else if (etha->phydev && etha->phydev->is_c45) /* C22 access to C45 PHY */ rswitch_mii_access_c45(etha_mii, false, phyad, 1, regad, data); else rswitch_mii_access_c22(etha_mii, false, phyad, regad, data); From 44c7f95987e36de3e034051ed3bbf07c91a8fc16 Mon Sep 17 00:00:00 2001 From: Pranav Sanwal Date: Thu, 26 Mar 2026 16:11:58 +0530 Subject: [PATCH 16/18] net: lwip: tftp: update image_load_addr after successful transfer do_tftpb() parses the load address into a local variable laddr but never updates the global image_load_addr. Commands that rely on image_load_addr as their default address (e.g. 'bmp info') therefore operate on the wrong address when called without an explicit argument after tftpboot. Update image_load_addr to laddr only on a successful transfer, so that it accurately reflects where data was actually loaded. Fixes: 4d4d7838127e ("net: lwip: add TFTP support and tftpboot command") Signed-off-by: Pranav Sanwal Reviewed-by: Jerome Forissier --- net/lwip/tftp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c index 5c3becc68c6..7f3b28b8507 100644 --- a/net/lwip/tftp.c +++ b/net/lwip/tftp.c @@ -368,6 +368,8 @@ int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (tftp_loop(eth_get_dev(), laddr, fname, srvip, port) < 0) ret = CMD_RET_FAILURE; + else + image_load_addr = laddr; out: if (arg != net_boot_file_name) free(arg); From 8f6077a8b8edbfe3af1be8a7024392e2056ddbfe Mon Sep 17 00:00:00 2001 From: Pranav Tilak Date: Wed, 25 Mar 2026 16:36:34 +0100 Subject: [PATCH 17/18] net: phy: dp83867: reset PHY on init to ensure clean state After a warm reboot, the PHY is left in power-down state (BMCR_PDOWN set) causing auto-negotiation to timeout when running the dhcp command. Fix this by calling phy_reset() in dp83867_config() which brings the PHY to a known clean state. The existing DP83867_SW_RESTART is removed as it is redundant after phy_reset(). Fixes: 721aed79126b ("net: phy: Add support for Texas Instruments DP83867") Signed-off-by: Pranav Tilak Signed-off-by: Michal Simek --- drivers/net/phy/dp83867.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index 772cde1c520..7ce03b59b6a 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -257,14 +257,14 @@ static int dp83867_config(struct phy_device *phydev) dp83867 = (struct dp83867_private *)phydev->priv; - ret = dp83867_of_init(phydev); + /* Reset PHY to clear any stale state after warm reboot */ + ret = phy_reset(phydev); if (ret) return ret; - /* Restart the PHY. */ - val = phy_read(phydev, MDIO_DEVAD_NONE, DP83867_CTRL); - phy_write(phydev, MDIO_DEVAD_NONE, DP83867_CTRL, - val | DP83867_SW_RESTART); + ret = dp83867_of_init(phydev); + if (ret) + return ret; /* Mode 1 or 2 workaround */ if (dp83867->rxctrl_strap_quirk) { From d1f8719e5163c3aceef501283f29d928f19e546f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 25 Mar 2026 02:10:43 +0100 Subject: [PATCH 18/18] net: rswitch: Remap CPU to bus addresses using dev_phys_to_bus() Use dev_phys_to_bus() to convert CPU addresses of DMA descriptors into bus addresses of DMA descriptors. This is necessary on hardware which does not have 1:1 mapping between CPU and memory addressed by the DMA. This has no impact on other hardware which does not need this conversion. Signed-off-by: Marek Vasut --- drivers/net/rswitch.c | 80 ++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/drivers/net/rswitch.c b/drivers/net/rswitch.c index c51908ed8f3..52fc3edd4e0 100644 --- a/drivers/net/rswitch.c +++ b/drivers/net/rswitch.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include #define RSWITCH_SLEEP_US 1000 #define RSWITCH_TIMEOUT_US 1000000 @@ -587,9 +589,11 @@ static void rswitch_bat_desc_init(struct rswitch_port_priv *priv) rswitch_flush_dcache((uintptr_t)priv->bat_desc, desc_size); } -static void rswitch_tx_desc_init(struct rswitch_port_priv *priv) +static void rswitch_tx_desc_init(struct udevice *dev) { + struct rswitch_port_priv *priv = dev_get_priv(dev); const u32 desc_size = RSWITCH_NUM_TX_DESC * sizeof(struct rswitch_desc); + dma_addr_t tx_desc_ba; u64 tx_desc_addr; int i; @@ -603,21 +607,25 @@ static void rswitch_tx_desc_init(struct rswitch_port_priv *priv) /* Mark the end of the descriptors */ priv->tx_desc[RSWITCH_NUM_TX_DESC - 1].die_dt = DT_LINKFIX; tx_desc_addr = (uintptr_t)priv->tx_desc; - priv->tx_desc[RSWITCH_NUM_TX_DESC - 1].dptrl = lower_32_bits(tx_desc_addr); - priv->tx_desc[RSWITCH_NUM_TX_DESC - 1].dptrh = upper_32_bits(tx_desc_addr); + tx_desc_ba = dev_phys_to_bus(dev, (phys_addr_t)tx_desc_addr); + + priv->tx_desc[RSWITCH_NUM_TX_DESC - 1].dptrl = lower_32_bits(tx_desc_ba); + priv->tx_desc[RSWITCH_NUM_TX_DESC - 1].dptrh = upper_32_bits(tx_desc_ba); rswitch_flush_dcache(tx_desc_addr, desc_size); /* Point the controller to the TX descriptor list */ priv->bat_desc[RSWITCH_TX_CHAIN_INDEX].die_dt = DT_LINKFIX; - priv->bat_desc[RSWITCH_TX_CHAIN_INDEX].dptrl = lower_32_bits(tx_desc_addr); - priv->bat_desc[RSWITCH_TX_CHAIN_INDEX].dptrh = upper_32_bits(tx_desc_addr); + priv->bat_desc[RSWITCH_TX_CHAIN_INDEX].dptrl = lower_32_bits(tx_desc_ba); + priv->bat_desc[RSWITCH_TX_CHAIN_INDEX].dptrh = upper_32_bits(tx_desc_ba); rswitch_flush_dcache((uintptr_t)&priv->bat_desc[RSWITCH_TX_CHAIN_INDEX], sizeof(struct rswitch_desc)); } -static void rswitch_rx_desc_init(struct rswitch_port_priv *priv) +static void rswitch_rx_desc_init(struct udevice *dev) { + struct rswitch_port_priv *priv = dev_get_priv(dev); const u32 desc_size = RSWITCH_NUM_RX_DESC * sizeof(struct rswitch_rxdesc); + dma_addr_t packet_ba, next_rx_desc_ba, rx_desc_ba; int i; u64 packet_addr; u64 next_rx_desc_addr; @@ -631,26 +639,29 @@ static void rswitch_rx_desc_init(struct rswitch_port_priv *priv) priv->rx_desc[i].data.die_dt = DT_FEMPTY; priv->rx_desc[i].data.info_ds = PKTSIZE_ALIGN; packet_addr = (uintptr_t)priv->rx_desc[i].packet; - priv->rx_desc[i].data.dptrl = lower_32_bits(packet_addr); - priv->rx_desc[i].data.dptrh = upper_32_bits(packet_addr); + packet_ba = dev_phys_to_bus(dev, (phys_addr_t)packet_addr); + priv->rx_desc[i].data.dptrl = lower_32_bits(packet_ba); + priv->rx_desc[i].data.dptrh = upper_32_bits(packet_ba); priv->rx_desc[i].link.die_dt = DT_LINKFIX; next_rx_desc_addr = (uintptr_t)&priv->rx_desc[i + 1]; - priv->rx_desc[i].link.dptrl = lower_32_bits(next_rx_desc_addr); - priv->rx_desc[i].link.dptrh = upper_32_bits(next_rx_desc_addr); + next_rx_desc_ba = dev_phys_to_bus(dev, (phys_addr_t)next_rx_desc_addr); + priv->rx_desc[i].link.dptrl = lower_32_bits(next_rx_desc_ba); + priv->rx_desc[i].link.dptrh = upper_32_bits(next_rx_desc_ba); } /* Mark the end of the descriptors */ priv->rx_desc[RSWITCH_NUM_RX_DESC - 1].link.die_dt = DT_LINKFIX; rx_desc_addr = (uintptr_t)priv->rx_desc; - priv->rx_desc[RSWITCH_NUM_RX_DESC - 1].link.dptrl = lower_32_bits(rx_desc_addr); - priv->rx_desc[RSWITCH_NUM_RX_DESC - 1].link.dptrh = upper_32_bits(rx_desc_addr); + rx_desc_ba = dev_phys_to_bus(dev, (phys_addr_t)rx_desc_addr); + priv->rx_desc[RSWITCH_NUM_RX_DESC - 1].link.dptrl = lower_32_bits(rx_desc_ba); + priv->rx_desc[RSWITCH_NUM_RX_DESC - 1].link.dptrh = upper_32_bits(rx_desc_ba); rswitch_flush_dcache(rx_desc_addr, desc_size); /* Point the controller to the rx descriptor list */ priv->bat_desc[RSWITCH_RX_CHAIN_INDEX].die_dt = DT_LINKFIX; - priv->bat_desc[RSWITCH_RX_CHAIN_INDEX].dptrl = lower_32_bits(rx_desc_addr); - priv->bat_desc[RSWITCH_RX_CHAIN_INDEX].dptrh = upper_32_bits(rx_desc_addr); + priv->bat_desc[RSWITCH_RX_CHAIN_INDEX].dptrl = lower_32_bits(rx_desc_ba); + priv->bat_desc[RSWITCH_RX_CHAIN_INDEX].dptrh = upper_32_bits(rx_desc_ba); rswitch_flush_dcache((uintptr_t)&priv->bat_desc[RSWITCH_RX_CHAIN_INDEX], sizeof(struct rswitch_desc)); } @@ -741,9 +752,11 @@ static int rswitch_gwca_axi_ram_reset(struct rswitch_gwca *gwca) RSWITCH_SLEEP_US, RSWITCH_TIMEOUT_US); } -static int rswitch_gwca_init(struct rswitch_port_priv *priv) +static int rswitch_gwca_init(struct udevice *dev) { + struct rswitch_port_priv *priv = dev_get_priv(dev); struct rswitch_gwca *gwca = &priv->gwca; + dma_addr_t bat_desc_ba; int ret; ret = rswitch_gwca_change_mode(priv, GWMC_OPC_DISABLE); @@ -765,9 +778,11 @@ static int rswitch_gwca_init(struct rswitch_port_priv *priv) /* Setting flow */ writel(GWVCC_VEM_SC_TAG, gwca->addr + GWVCC); writel(0, gwca->addr + GWTTFC); - writel(upper_32_bits((uintptr_t)priv->bat_desc) & GWDCBAC0_DCBAUP, + + bat_desc_ba = dev_phys_to_bus(dev, (phys_addr_t)(priv->bat_desc)); + writel(upper_32_bits(bat_desc_ba) & GWDCBAC0_DCBAUP, gwca->addr + GWDCBAC0 + priv->drv_data->gwdcbac_offset); - writel(lower_32_bits((uintptr_t)priv->bat_desc), + writel(lower_32_bits(bat_desc_ba), gwca->addr + GWDCBAC1 + priv->drv_data->gwdcbac_offset); writel(GWDCC_DQT | GWDCC_BALR, gwca->addr + GWDCC(RSWITCH_TX_CHAIN_INDEX)); writel(GWDCC_BALR, gwca->addr + GWDCC(RSWITCH_RX_CHAIN_INDEX)); @@ -844,8 +859,9 @@ static int rswitch_etha_init(struct rswitch_port_priv *priv) return 0; } -static int rswitch_init(struct rswitch_port_priv *priv) +static int rswitch_start(struct udevice *dev) { + struct rswitch_port_priv *priv = dev_get_priv(dev); struct rswitch_etha *etha = &priv->etha; int ret; @@ -875,8 +891,8 @@ static int rswitch_init(struct rswitch_port_priv *priv) return ret; rswitch_bat_desc_init(priv); - rswitch_tx_desc_init(priv); - rswitch_rx_desc_init(priv); + rswitch_tx_desc_init(dev); + rswitch_rx_desc_init(dev); rswitch_clock_enable(priv); @@ -886,7 +902,7 @@ static int rswitch_init(struct rswitch_port_priv *priv) rswitch_mfwd_init(priv); - ret = rswitch_gwca_init(priv); + ret = rswitch_gwca_init(dev); if (ret) return ret; @@ -897,23 +913,12 @@ static int rswitch_init(struct rswitch_port_priv *priv) return 0; } -static int rswitch_start(struct udevice *dev) -{ - struct rswitch_port_priv *priv = dev_get_priv(dev); - int ret; - - ret = rswitch_init(priv); - if (ret) - return ret; - - return 0; -} - #define RSWITCH_TX_TIMEOUT_MS 1000 static int rswitch_send(struct udevice *dev, void *packet, int len) { struct rswitch_port_priv *priv = dev_get_priv(dev); struct rswitch_desc *desc = &priv->tx_desc[priv->tx_desc_index]; + dma_addr_t bpacket = dev_phys_to_bus(dev, (phys_addr_t)packet); struct rswitch_gwca *gwca = &priv->gwca; u32 gwtrc_index, start; @@ -923,8 +928,8 @@ static int rswitch_send(struct udevice *dev, void *packet, int len) memset(desc, 0x0, sizeof(*desc)); desc->die_dt = DT_FSINGLE; desc->info_ds = len; - desc->dptrl = lower_32_bits((uintptr_t)packet); - desc->dptrh = upper_32_bits((uintptr_t)packet); + desc->dptrl = lower_32_bits(bpacket); + desc->dptrh = upper_32_bits(bpacket); rswitch_flush_dcache((uintptr_t)desc, sizeof(*desc)); /* Start transmission */ @@ -954,6 +959,7 @@ static int rswitch_recv(struct udevice *dev, int flags, uchar **packetp) { struct rswitch_port_priv *priv = dev_get_priv(dev); struct rswitch_rxdesc *desc = &priv->rx_desc[priv->rx_desc_index]; + dma_addr_t dpacket; u8 *packet; int len; @@ -963,7 +969,9 @@ static int rswitch_recv(struct udevice *dev, int flags, uchar **packetp) return -EAGAIN; len = desc->data.info_ds & RX_DS; - packet = (u8 *)(((uintptr_t)(desc->data.dptrh) << 32) | (uintptr_t)desc->data.dptrl); + dpacket = ((u64)(desc->data.dptrh) << 32) | (u64)(desc->data.dptrl); + packet = (u8 *)(uintptr_t)dev_bus_to_phys(dev, dpacket); + rswitch_invalidate_dcache((uintptr_t)packet, len); *packetp = packet;