Merge branch 'next_net/phy_connect_dev' of https://source.denx.de/u-boot/custodians/u-boot-sh into next
diff --git a/arch/arm/dts/r7s72100-gr-peach.dts b/arch/arm/dts/r7s72100-gr-peach.dts
index fe1a4aa..70d034c 100644
--- a/arch/arm/dts/r7s72100-gr-peach.dts
+++ b/arch/arm/dts/r7s72100-gr-peach.dts
@@ -126,6 +126,8 @@
 	phy-handle = <&phy0>;
 
 	phy0: ethernet-phy@0 {
+		compatible = "ethernet-phy-id0007.c0f0",
+			     "ethernet-phy-ieee802.3-c22";
 		reg = <0>;
 
 		reset-gpios = <&port4 2 GPIO_ACTIVE_LOW>;
diff --git a/configs/grpeach_defconfig b/configs/grpeach_defconfig
index 04edcf3..36925f3 100644
--- a/configs/grpeach_defconfig
+++ b/configs/grpeach_defconfig
@@ -52,6 +52,9 @@
 # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_BITBANGMII=y
 CONFIG_BITBANGMII_MULTI=y
+CONFIG_PHY_SMSC=y
+CONFIG_PHY_ETHERNET_ID=y
+CONFIG_DM_ETH_PHY=y
 CONFIG_SH_ETHER=y
 CONFIG_PINCTRL=y
 CONFIG_DM_REGULATOR=y
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 09039a2..7d482cb 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -695,6 +695,7 @@
 config SH_ETHER
 	bool "Renesas SH Ethernet MAC"
 	select PHYLIB
+	select PHY_ETHERNET_ID
 	help
 	  This driver supports the Ethernet for Renesas SH and ARM SoCs.
 
@@ -764,6 +765,7 @@
 	bool "Renesas Ethernet AVB MAC"
 	depends on RCAR_64
 	select PHYLIB
+	select PHY_ETHERNET_ID
 	help
 	  This driver implements support for the Ethernet AVB block in
 	  Renesas M3 and H3 SoCs.
diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c
index 912d28f..e234093 100644
--- a/drivers/net/altera_tse.c
+++ b/drivers/net/altera_tse.c
@@ -430,17 +430,11 @@
 static int tse_phy_init(struct altera_tse_priv *priv, void *dev)
 {
 	struct phy_device *phydev;
-	unsigned int mask = 0xffffffff;
 
-	if (priv->phyaddr)
-		mask = 1 << priv->phyaddr;
-
-	phydev = phy_find_by_mask(priv->bus, mask);
+	phydev = phy_connect(priv->bus, -1, dev, priv->interface);
 	if (!phydev)
 		return -ENODEV;
 
-	phy_connect_dev(phydev, dev, priv->interface);
-
 	phydev->supported &= PHY_GBIT_FEATURES;
 	phydev->advertising = phydev->supported;
 
diff --git a/drivers/net/eth-phy-uclass.c b/drivers/net/eth-phy-uclass.c
index 27b7744..9d1e8d3 100644
--- a/drivers/net/eth-phy-uclass.c
+++ b/drivers/net/eth-phy-uclass.c
@@ -144,10 +144,18 @@
 	uc_priv->reset_assert_delay = dev_read_u32_default(dev, "reset-assert-us", 0);
 	uc_priv->reset_deassert_delay = dev_read_u32_default(dev, "reset-deassert-us", 0);
 
+	/* These are used by some DTs, try these as a fallback. */
+	if (!uc_priv->reset_assert_delay && !uc_priv->reset_deassert_delay) {
+		uc_priv->reset_assert_delay =
+			dev_read_u32_default(dev, "reset-delay-us", 0);
+		uc_priv->reset_deassert_delay =
+			dev_read_u32_default(dev, "reset-post-delay-us", 0);
+	}
+
 	return 0;
 }
 
-void eth_phy_reset(struct udevice *dev, int value)
+static void eth_phy_reset(struct udevice *dev, int value)
 {
 	struct eth_phy_device_priv *uc_priv = dev_get_uclass_priv(dev);
 	u32 delay;
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index 29067e9..13fad81 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -608,18 +608,16 @@
 static int ethoc_phy_init(struct ethoc *priv, void *dev)
 {
 	struct phy_device *phydev;
-	int mask = 0xffffffff;
+	int mask = -1;
 
 #ifdef CONFIG_PHY_ADDR
-	mask = 1 << CONFIG_PHY_ADDR;
+	mask = CONFIG_PHY_ADDR;
 #endif
 
-	phydev = phy_find_by_mask(priv->bus, mask);
+	phydev = phy_connect(priv->bus, mask, dev, PHY_INTERFACE_MODE_MII);
 	if (!phydev)
 		return -ENODEV;
 
-	phy_connect_dev(phydev, dev, PHY_INTERFACE_MODE_MII);
-
 	phydev->supported &= PHY_BASIC_FEATURES;
 	phydev->advertising = phydev->supported;
 
diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c
index ad7b5b8..ecf8c28 100644
--- a/drivers/net/pch_gbe.c
+++ b/drivers/net/pch_gbe.c
@@ -414,16 +414,13 @@
 	struct pch_gbe_priv *priv = dev_get_priv(dev);
 	struct eth_pdata *plat = dev_get_plat(dev);
 	struct phy_device *phydev;
-	int mask = 0xffffffff;
 
-	phydev = phy_find_by_mask(priv->bus, mask);
+	phydev = phy_connect(priv->bus, -1, dev, plat->phy_interface);
 	if (!phydev) {
 		printf("pch_gbe: cannot find the phy\n");
 		return -1;
 	}
 
-	phy_connect_dev(phydev, dev, plat->phy_interface);
-
 	phydev->supported &= PHY_GBIT_FEATURES;
 	phydev->advertising = phydev->supported;
 
diff --git a/drivers/net/phy/ethernet_id.c b/drivers/net/phy/ethernet_id.c
index a715e83..877a51c 100644
--- a/drivers/net/phy/ethernet_id.c
+++ b/drivers/net/phy/ethernet_id.c
@@ -7,6 +7,8 @@
 
 #include <common.h>
 #include <dm/device_compat.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
 #include <phy.h>
 #include <linux/delay.h>
 #include <asm/gpio.h>
@@ -17,6 +19,8 @@
 	struct phy_device *phydev;
 	struct ofnode_phandle_args phandle_args;
 	struct gpio_desc gpio;
+	const char *node_name;
+	struct udevice *pdev;
 	ofnode node;
 	u32 id, assert, deassert;
 	u16 vendor, device;
@@ -72,5 +76,18 @@
 	if (phydev)
 		phydev->node = node;
 
+	if (IS_ENABLED(CONFIG_DM_ETH_PHY) && ofnode_valid(node)) {
+		node_name = ofnode_get_name(node);
+		ret = device_bind_driver_to_node(dev, "eth_phy_generic_drv",
+						 node_name, node,
+						 &pdev);
+		if (ret)
+			return NULL;
+
+		ret = device_probe(pdev);
+		if (ret)
+			return NULL;
+	}
+
 	return phydev;
 }
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 0eeb0cb..ae21acb 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -812,8 +812,8 @@
 	return get_phy_device_by_mask(bus, phy_mask);
 }
 
-void phy_connect_dev(struct phy_device *phydev, struct udevice *dev,
-		     phy_interface_t interface)
+static void phy_connect_dev(struct phy_device *phydev, struct udevice *dev,
+			    phy_interface_t interface)
 {
 	/* Soft Reset the PHY */
 	phy_reset(phydev);
diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c
index c74c8a8..0bcd6cf 100644
--- a/drivers/net/ravb.c
+++ b/drivers/net/ravb.c
@@ -131,7 +131,6 @@
 	struct mii_dev		*bus;
 	void __iomem		*iobase;
 	struct clk_bulk		clks;
-	struct gpio_desc	reset_gpio;
 };
 
 static inline void ravb_flush_dcache(u32 addr, u32 len)
@@ -312,13 +311,6 @@
 	struct phy_device *phydev;
 	int reg;
 
-	if (dm_gpio_is_valid(&eth->reset_gpio)) {
-		dm_gpio_set_value(&eth->reset_gpio, 1);
-		mdelay(20);
-		dm_gpio_set_value(&eth->reset_gpio, 0);
-		mdelay(1);
-	}
-
 	phydev = phy_connect(eth->bus, -1, dev, pdata->phy_interface);
 	if (!phydev)
 		return -ENODEV;
@@ -503,7 +495,6 @@
 {
 	struct eth_pdata *pdata = dev_get_plat(dev);
 	struct ravb_priv *eth = dev_get_priv(dev);
-	struct ofnode_phandle_args phandle_args;
 	struct mii_dev *mdiodev;
 	void __iomem *iobase;
 	int ret;
@@ -515,17 +506,6 @@
 	if (ret < 0)
 		goto err_mdio_alloc;
 
-	ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, &phandle_args);
-	if (!ret) {
-		gpio_request_by_name_nodev(phandle_args.node, "reset-gpios", 0,
-					   &eth->reset_gpio, GPIOD_IS_OUT);
-	}
-
-	if (!dm_gpio_is_valid(&eth->reset_gpio)) {
-		gpio_request_by_name(dev, "reset-gpios", 0, &eth->reset_gpio,
-				     GPIOD_IS_OUT);
-	}
-
 	mdiodev = mdio_alloc();
 	if (!mdiodev) {
 		ret = -ENOMEM;
@@ -576,8 +556,6 @@
 	free(eth->phydev);
 	mdio_unregister(eth->bus);
 	mdio_free(eth->bus);
-	if (dm_gpio_is_valid(&eth->reset_gpio))
-		dm_gpio_free(dev, &eth->reset_gpio);
 	unmap_physmem(eth->iobase, MAP_NOCACHE);
 
 	return 0;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 8f162ca..7b1f59d 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -129,11 +129,11 @@
 	/* Check if the rx descriptor is ready */
 	invalidate_cache(port_info->rx_desc_cur, sizeof(struct rx_desc_s));
 	if (port_info->rx_desc_cur->rd0 & RD_RACT)
-		return -EINVAL;
+		return -EAGAIN;
 
 	/* Check for errors */
 	if (port_info->rx_desc_cur->rd0 & RD_RFE)
-		return -EINVAL;
+		return 0;
 
 	return port_info->rx_desc_cur->rd1 & 0xffff;
 }
@@ -142,6 +142,8 @@
 {
 	struct sh_eth_info *port_info = &eth->port_info[eth->port];
 
+	invalidate_cache(ADDR_TO_P2(port_info->rx_desc_cur->rd2), MAX_BUF_SIZE);
+
 	/* Make current descriptor available again */
 	if (port_info->rx_desc_cur->rd0 & RD_RDLE)
 		port_info->rx_desc_cur->rd0 = RD_RACT | RD_RDLE;
@@ -210,8 +212,6 @@
 		goto err;
 	}
 
-	flush_cache_wback(port_info->tx_desc_alloc, alloc_desc_size);
-
 	/* Make sure we use a P2 address (non-cacheable) */
 	port_info->tx_desc_base =
 		(struct tx_desc_s *)ADDR_TO_P2((uintptr_t)port_info->tx_desc_alloc);
@@ -229,6 +229,7 @@
 	cur_tx_desc--;
 	cur_tx_desc->td0 |= TD_TDLE;
 
+	flush_cache_wback(port_info->tx_desc_alloc, alloc_desc_size);
 	/*
 	 * Point the controller to the tx descriptor list. Must use physical
 	 * addresses
@@ -264,8 +265,6 @@
 		goto err;
 	}
 
-	flush_cache_wback(port_info->rx_desc_alloc, alloc_desc_size);
-
 	/* Make sure we use a P2 address (non-cacheable) */
 	port_info->rx_desc_base =
 		(struct rx_desc_s *)ADDR_TO_P2((uintptr_t)port_info->rx_desc_alloc);
@@ -299,6 +298,9 @@
 	cur_rx_desc--;
 	cur_rx_desc->rd0 |= RD_RDLE;
 
+	invalidate_cache(port_info->rx_buf_alloc, NUM_RX_DESC * MAX_BUF_SIZE);
+	flush_cache_wback(port_info->rx_desc_alloc, alloc_desc_size);
+
 	/* Point the controller to the rx descriptor list */
 	sh_eth_write(port_info, ADDR_TO_PHY(port_info->rx_desc_base), RDLAR);
 #if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
@@ -530,7 +532,6 @@
 	struct mii_dev		*bus;
 	phys_addr_t		iobase;
 	struct clk		clk;
-	struct gpio_desc	reset_gpio;
 };
 
 static int sh_ether_send(struct udevice *dev, void *packet, int len)
@@ -555,15 +556,13 @@
 		*packetp = packet;
 
 		return len;
-	} else {
-		len = 0;
-
-		/* Restart the receiver if disabled */
-		if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
-			sh_eth_write(port_info, EDRRR_R, EDRRR);
-
-		return -EAGAIN;
 	}
+
+	/* Restart the receiver if disabled */
+	if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
+		sh_eth_write(port_info, EDRRR_R, EDRRR);
+
+	return len;
 }
 
 static int sh_ether_free_pkt(struct udevice *dev, uchar *packet, int length)
@@ -601,14 +600,11 @@
 	int ret = 0;
 	struct sh_eth_info *port_info = &eth->port_info[eth->port];
 	struct phy_device *phydev;
-	int mask = 0xffffffff;
 
-	phydev = phy_find_by_mask(priv->bus, mask);
+	phydev = phy_connect(priv->bus, -1, dev, pdata->phy_interface);
 	if (!phydev)
 		return -ENODEV;
 
-	phy_connect_dev(phydev, dev, pdata->phy_interface);
-
 	port_info->phydev = phydev;
 	phy_config(phydev);
 
@@ -653,7 +649,6 @@
 	struct eth_pdata *pdata = dev_get_plat(udev);
 	struct sh_ether_priv *priv = dev_get_priv(udev);
 	struct sh_eth_dev *eth = &priv->shdev;
-	struct ofnode_phandle_args phandle_args;
 	struct mii_dev *mdiodev;
 	int ret;
 
@@ -664,18 +659,6 @@
 	if (ret < 0)
 		return ret;
 #endif
-
-	ret = dev_read_phandle_with_args(udev, "phy-handle", NULL, 0, 0, &phandle_args);
-	if (!ret) {
-		gpio_request_by_name_nodev(phandle_args.node, "reset-gpios", 0,
-					   &priv->reset_gpio, GPIOD_IS_OUT);
-	}
-
-	if (!dm_gpio_is_valid(&priv->reset_gpio)) {
-		gpio_request_by_name(udev, "reset-gpios", 0, &priv->reset_gpio,
-				     GPIOD_IS_OUT);
-	}
-
 	mdiodev = mdio_alloc();
 	if (!mdiodev) {
 		ret = -ENOMEM;
@@ -738,9 +721,6 @@
 	mdio_unregister(priv->bus);
 	mdio_free(priv->bus);
 
-	if (dm_gpio_is_valid(&priv->reset_gpio))
-		dm_gpio_free(udev, &priv->reset_gpio);
-
 	return 0;
 }
 
diff --git a/drivers/net/sni_ave.c b/drivers/net/sni_ave.c
index 014b070..f5a0d80 100644
--- a/drivers/net/sni_ave.c
+++ b/drivers/net/sni_ave.c
@@ -391,14 +391,12 @@
 static int ave_phy_init(struct ave_private *priv, void *dev)
 {
 	struct phy_device *phydev;
-	int mask = GENMASK(31, 0), ret;
+	int ret;
 
-	phydev = phy_find_by_mask(priv->bus, mask);
+	phydev = phy_connect(priv->bus, -1, dev, priv->phy_mode);
 	if (!phydev)
 		return -ENODEV;
 
-	phy_connect_dev(phydev, dev, priv->phy_mode);
-
 	phydev->supported &= PHY_GBIT_FEATURES;
 	if (priv->max_speed) {
 		ret = phy_set_supported(phydev, priv->max_speed);
diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c
index ad9e1ab..4c90d4b 100644
--- a/drivers/net/sunxi_emac.c
+++ b/drivers/net/sunxi_emac.c
@@ -248,10 +248,10 @@
 
 static int sunxi_emac_init_phy(struct emac_eth_dev *priv, void *dev)
 {
-	int ret, mask = 0xffffffff;
+	int ret, mask = -1;
 
 #ifdef CONFIG_PHY_ADDR
-	mask = 1 << CONFIG_PHY_ADDR;
+	mask = CONFIG_PHY_ADDR;
 #endif
 
 	priv->bus = mdio_alloc();
@@ -269,11 +269,10 @@
 	if (ret)
 		return ret;
 
-	priv->phydev = phy_find_by_mask(priv->bus, mask);
+	priv->phydev = phy_connect(priv->bus, mask, dev, PHY_INTERFACE_MODE_MII);
 	if (!priv->phydev)
 		return -ENODEV;
 
-	phy_connect_dev(priv->phydev, dev, PHY_INTERFACE_MODE_MII);
 	phy_config(priv->phydev);
 
 	return 0;
diff --git a/include/phy.h b/include/phy.h
index 247223d..f023a3c 100644
--- a/include/phy.h
+++ b/include/phy.h
@@ -224,15 +224,6 @@
 #endif
 
 /**
- * phy_connect_dev() - Associates the given pair of PHY and Ethernet devices
- * @phydev:	PHY device
- * @dev:	Ethernet device
- * @interface:	type of MAC-PHY interface
- */
-void phy_connect_dev(struct phy_device *phydev, struct udevice *dev,
-		     phy_interface_t interface);
-
-/**
  * phy_connect() - Creates a PHY device for the Ethernet interface
  * Creates a PHY device for the PHY at the given address, if one doesn't exist
  * already, and associates it with the Ethernet device.