[PATCH v5 6/8] net: pch_gbe: Add PHY reset and MAC address fallback for RISC-V

Uros Stajic
2025-12-24T16:42:10Z

From: Chao-ying Fu <cfu@mips.com>

Add optional PHY reset support via GPIO defined in the device tree.

Improve robustness by handling probe errors and falling back to the
environment-provided MAC address if no hardware MAC is found.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
board/mips/boston-riscv/Kconfig | 4 ++++
drivers/net/pch_gbe.c | 37 +++++++++++++++++++++++++++++++--
drivers/net/pch_gbe.h | 1 +
3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/board/mips/boston-riscv/Kconfig b/board/mips/boston-riscv/Kconfig
index 68c5fc50489..4d55d96603e 100644
--- a/board/mips/boston-riscv/Kconfig
+++ b/board/mips/boston-riscv/Kconfig
@@ -40,4 +40,8 @@ config PHY_REALTEK
bool
default y

+config TFTP_FILE_NAME_MAX_LEN
+ int "Maximum length of TFTP file name"
+ default 256
+
endif
diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c
index adeca3d040d..dea8ab828ac 100644
--- a/drivers/net/pch_gbe.c
+++ b/drivers/net/pch_gbe.c
@@ -7,6 +7,7 @@

#include <cpu_func.h>
#include <dm.h>
+#include <env.h>
#include <errno.h>
#include <log.h>
#include <malloc.h>
@@ -15,6 +16,7 @@
#include <miiphy.h>
#include <linux/delay.h>
#include "pch_gbe.h"
+#include <asm/gpio.h>

#if !defined(CONFIG_PHYLIB)
# error "PCH Gigabit Ethernet driver requires PHYLIB - missing CONFIG_PHYLIB"
@@ -33,6 +35,13 @@ static void pch_gbe_mac_read(struct pch_gbe_regs *mac_regs, u8 *addr)
macid_lo = readl(&mac_regs->mac_adr[0].low) & 0xffff;
debug("pch_gbe: macid_hi %#x macid_lo %#x\n", macid_hi, macid_lo);

+ if (!macid_lo && !macid_hi) {
+ if (eth_env_get_enetaddr("ethaddr", addr))
+ return;
+
+ printf("No MAC found in either EG20T H/W or environment");
+ }
+
addr[0] = (u8)(macid_hi & 0xff);
addr[1] = (u8)((macid_hi >> 8) & 0xff);
addr[2] = (u8)((macid_hi >> 16) & 0xff);
@@ -74,6 +83,14 @@ static int pch_gbe_reset(struct udevice *dev)
priv->rx_idx = 0;
priv->tx_idx = 0;

+ if (dm_gpio_is_valid(&priv->gpio_phy_reset)) {
+ /* Reset the PHY */
+ dm_gpio_set_value(&priv->gpio_phy_reset, 1);
+ udelay(15000);
+ dm_gpio_set_value(&priv->gpio_phy_reset, 0);
+ udelay(5000);
+ }
+
writel(PCH_GBE_ALL_RST, &mac_regs->reset);

/*
@@ -450,6 +467,11 @@ static int pch_gbe_probe(struct udevice *dev)
plat->iobase = (ulong)iobase;
priv->mac_regs = (struct pch_gbe_regs *)iobase;

+ err = gpio_request_by_name(dev, "phy-reset-gpios", 0,
+ &priv->gpio_phy_reset, GPIOD_IS_OUT);
+ if (err && (err != -ENOENT))
+ return err;
+
/* Read MAC address from SROM and initialize dev->enetaddr with it */
pch_gbe_mac_read(priv->mac_regs, plat->enetaddr);

@@ -459,9 +481,17 @@ static int pch_gbe_probe(struct udevice *dev)

err = pch_gbe_reset(dev);
if (err)
- return err;
+ goto out_err;
+
+ err = pch_gbe_phy_init(dev);
+ if (err)
+ goto out_err;

- return pch_gbe_phy_init(dev);
+ return 0;
+out_err:
+ if (dm_gpio_is_valid(&priv->gpio_phy_reset))
+ dm_gpio_free(dev, &priv->gpio_phy_reset);
+ return err;
}

static int pch_gbe_remove(struct udevice *dev)
@@ -472,6 +502,9 @@ static int pch_gbe_remove(struct udevice *dev)
mdio_unregister(priv->bus);
mdio_free(priv->bus);

+ if (dm_gpio_is_valid(&priv->gpio_phy_reset))
+ dm_gpio_free(dev, &priv->gpio_phy_reset);
+
return 0;
}

diff --git a/drivers/net/pch_gbe.h b/drivers/net/pch_gbe.h
index 7e0fdbfd5a3..dcbb94094bc 100644
--- a/drivers/net/pch_gbe.h
+++ b/drivers/net/pch_gbe.h
@@ -292,6 +292,7 @@ struct pch_gbe_priv {
struct udevice *dev;
int rx_idx;
int tx_idx;
+ struct gpio_desc gpio_phy_reset;
};

#endif /* _PCH_GBE_H_ */
--
2.34.1