From: Chao-ying Fu <c...@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 <c...@mips.com> Signed-off-by: Uros Stajic <uros.sta...@htecgroup.com> --- board/mips/boston-riscv/Kconfig | 4 ++++ drivers/net/pch_gbe.c | 36 +++++++++++++++++++++++++++++++-- drivers/net/pch_gbe.h | 1 + net/eth-uclass.c | 2 ++ 4 files changed, 41 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..0970a2dd8ba 100644 --- a/drivers/net/pch_gbe.c +++ b/drivers/net/pch_gbe.c @@ -14,6 +14,7 @@ #include <pci.h> #include <miiphy.h> #include <linux/delay.h> +#include <asm/gpio.h> #include "pch_gbe.h" #if !defined(CONFIG_PHYLIB) @@ -33,6 +34,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 +82,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 +466,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 +480,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 +501,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_ */ diff --git a/net/eth-uclass.c b/net/eth-uclass.c index 5555f82f23e..c82e8b0a523 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -461,6 +461,8 @@ int eth_rx(void) eth_get_ops(current)->free_pkt(current, packet, ret); if (ret <= 0) break; + if (net_state == NETLOOP_FAIL) + break; } if (ret == -EAGAIN) ret = 0; -- 2.34.1