Merge branch 'next' of https://source.denx.de/u-boot/custodians/u-boot-net

- DM9000 DM support
- tftp server bug fix
- mdio ofnode support functions
- Various phy fixes and improvements.

[trini: Fixup merge conflicts in drivers/net/phy/ethernet_id.c
drivers/net/phy/phy.c include/phy.h]
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index d40ce92..33a4b6f 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -68,6 +68,11 @@
 config PHYLIB_10G
 	bool "Generic 10G PHY support"
 
+config PHY_ADIN
+	bool "Analog Devices Industrial Ethernet PHYs"
+	help
+		Add support for configuring RGMII on Analog Devices ADIN PHYs.
+
 menuconfig PHY_AQUANTIA
 	bool "Aquantia Ethernet PHYs support"
 	select PHY_GIGE
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 67ca4d3..9d87eb2 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -10,6 +10,7 @@
 
 obj-$(CONFIG_PHYLIB) += phy.o
 obj-$(CONFIG_PHYLIB_10G) += generic_10g.o
+obj-$(CONFIG_PHY_ADIN) += adin.o
 obj-$(CONFIG_PHY_AQUANTIA) += aquantia.o
 obj-$(CONFIG_PHY_ATHEROS) += atheros.o
 obj-$(CONFIG_PHY_BROADCOM) += broadcom.o
diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c
new file mode 100644
index 0000000..cff841a
--- /dev/null
+++ b/drivers/net/phy/adin.c
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0+
+/**
+ *  Driver for Analog Devices Industrial Ethernet PHYs
+ *
+ * Copyright 2019 Analog Devices Inc.
+ * Copyright 2022 Variscite Ltd.
+ */
+#include <common.h>
+#include <phy.h>
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
+
+#define PHY_ID_ADIN1300				0x0283bc30
+#define ADIN1300_EXT_REG_PTR			0x10
+#define ADIN1300_EXT_REG_DATA			0x11
+#define ADIN1300_GE_RGMII_CFG			0xff23
+#define ADIN1300_GE_RGMII_RX_MSK		GENMASK(8, 6)
+#define ADIN1300_GE_RGMII_RX_SEL(x)		\
+		FIELD_PREP(ADIN1300_GE_RGMII_RX_MSK, x)
+#define ADIN1300_GE_RGMII_GTX_MSK		GENMASK(5, 3)
+#define ADIN1300_GE_RGMII_GTX_SEL(x)		\
+		FIELD_PREP(ADIN1300_GE_RGMII_GTX_MSK, x)
+#define ADIN1300_GE_RGMII_RXID_EN		BIT(2)
+#define ADIN1300_GE_RGMII_TXID_EN		BIT(1)
+#define ADIN1300_GE_RGMII_EN			BIT(0)
+
+/* RGMII internal delay settings for rx and tx for ADIN1300 */
+#define ADIN1300_RGMII_1_60_NS			0x0001
+#define ADIN1300_RGMII_1_80_NS			0x0002
+#define	ADIN1300_RGMII_2_00_NS			0x0000
+#define	ADIN1300_RGMII_2_20_NS			0x0006
+#define	ADIN1300_RGMII_2_40_NS			0x0007
+
+/**
+ * struct adin_cfg_reg_map - map a config value to aregister value
+ * @cfg		value in device configuration
+ * @reg		value in the register
+ */
+struct adin_cfg_reg_map {
+	int cfg;
+	int reg;
+};
+
+static const struct adin_cfg_reg_map adin_rgmii_delays[] = {
+	{ 1600, ADIN1300_RGMII_1_60_NS },
+	{ 1800, ADIN1300_RGMII_1_80_NS },
+	{ 2000, ADIN1300_RGMII_2_00_NS },
+	{ 2200, ADIN1300_RGMII_2_20_NS },
+	{ 2400, ADIN1300_RGMII_2_40_NS },
+	{ },
+};
+
+static int adin_lookup_reg_value(const struct adin_cfg_reg_map *tbl, int cfg)
+{
+	size_t i;
+
+	for (i = 0; tbl[i].cfg; i++) {
+		if (tbl[i].cfg == cfg)
+			return tbl[i].reg;
+	}
+
+	return -EINVAL;
+}
+
+static u32 adin_get_reg_value(struct phy_device *phydev,
+			      const char *prop_name,
+			      const struct adin_cfg_reg_map *tbl,
+			      u32 dflt)
+{
+	u32 val;
+	int rc;
+
+	ofnode node = phy_get_ofnode(phydev);
+	if (!ofnode_valid(node)) {
+		printf("%s: failed to get node\n", __func__);
+		return -EINVAL;
+	}
+
+	if (ofnode_read_u32(node, prop_name, &val)) {
+		printf("%s: failed to find %s, using default %d\n",
+		       __func__, prop_name, dflt);
+		return dflt;
+	}
+
+	debug("%s: %s = '%d'\n", __func__, prop_name, val);
+
+	rc = adin_lookup_reg_value(tbl, val);
+	if (rc < 0) {
+		printf("%s: Unsupported value %u for %s using default (%u)\n",
+		      __func__, val, prop_name, dflt);
+		return dflt;
+	}
+
+	return rc;
+}
+
+/**
+ * adin_get_phy_mode_override - Get phy-mode override for adin PHY
+ *
+ * The function gets phy-mode string from property 'adi,phy-mode-override'
+ * and return its index in phy_interface_strings table, or -1 in error case.
+ */
+int adin_get_phy_mode_override(struct phy_device *phydev)
+{
+	ofnode node = phy_get_ofnode(phydev);
+	const char *phy_mode_override;
+	const char *prop_phy_mode_override = "adi,phy-mode-override";
+	int override_interface;
+
+	phy_mode_override = ofnode_read_string(node, prop_phy_mode_override);
+	if (!phy_mode_override)
+		return -ENODEV;
+
+	debug("%s: %s = '%s'\n",
+	      __func__, prop_phy_mode_override, phy_mode_override);
+
+	override_interface = phy_get_interface_by_name(phy_mode_override);
+
+	if (override_interface < 0)
+		printf("%s: %s = '%s' is not valid\n",
+		       __func__, prop_phy_mode_override, phy_mode_override);
+
+	return override_interface;
+}
+
+static u16 adin_ext_read(struct phy_device *phydev, const u32 regnum)
+{
+	u16 val;
+
+	phy_write(phydev, MDIO_DEVAD_NONE, ADIN1300_EXT_REG_PTR, regnum);
+	val = phy_read(phydev, MDIO_DEVAD_NONE, ADIN1300_EXT_REG_DATA);
+
+	debug("%s: adin@0x%x 0x%x=0x%x\n", __func__, phydev->addr, regnum, val);
+
+	return val;
+}
+
+static int adin_ext_write(struct phy_device *phydev, const u32 regnum, const u16 val)
+{
+	debug("%s: adin@0x%x 0x%x=0x%x\n", __func__, phydev->addr, regnum, val);
+
+	phy_write(phydev, MDIO_DEVAD_NONE, ADIN1300_EXT_REG_PTR, regnum);
+
+	return phy_write(phydev, MDIO_DEVAD_NONE, ADIN1300_EXT_REG_DATA, val);
+}
+
+static int adin_config_rgmii_mode(struct phy_device *phydev)
+{
+	u16 reg_val;
+	u32 val;
+	int phy_mode_override = adin_get_phy_mode_override(phydev);
+
+	if (phy_mode_override >= 0) {
+		phydev->interface = (phy_interface_t) phy_mode_override;
+	}
+
+	reg_val = adin_ext_read(phydev, ADIN1300_GE_RGMII_CFG);
+
+	if (!phy_interface_is_rgmii(phydev)) {
+		/* Disable RGMII */
+		reg_val &= ~ADIN1300_GE_RGMII_EN;
+		return adin_ext_write(phydev, ADIN1300_GE_RGMII_CFG, reg_val);
+	}
+
+	/* Enable RGMII */
+	reg_val |= ADIN1300_GE_RGMII_EN;
+
+	/* Enable / Disable RGMII RX Delay */
+	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+	    phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
+		reg_val |= ADIN1300_GE_RGMII_RXID_EN;
+
+		val = adin_get_reg_value(phydev, "adi,rx-internal-delay-ps",
+					 adin_rgmii_delays,
+					 ADIN1300_RGMII_2_00_NS);
+		reg_val &= ~ADIN1300_GE_RGMII_RX_MSK;
+		reg_val |= ADIN1300_GE_RGMII_RX_SEL(val);
+	} else {
+		reg_val &= ~ADIN1300_GE_RGMII_RXID_EN;
+	}
+
+	/* Enable / Disable RGMII RX Delay */
+	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
+		reg_val |= ADIN1300_GE_RGMII_TXID_EN;
+
+		val = adin_get_reg_value(phydev, "adi,tx-internal-delay-ps",
+					 adin_rgmii_delays,
+					 ADIN1300_RGMII_2_00_NS);
+		reg_val &= ~ADIN1300_GE_RGMII_GTX_MSK;
+		reg_val |= ADIN1300_GE_RGMII_GTX_SEL(val);
+	} else {
+		reg_val &= ~ADIN1300_GE_RGMII_TXID_EN;
+	}
+
+	return adin_ext_write(phydev, ADIN1300_GE_RGMII_CFG, reg_val);
+}
+
+static int adin1300_config(struct phy_device *phydev)
+{
+	int ret;
+
+	printf("ADIN1300 PHY detected at addr %d\n", phydev->addr);
+
+	ret = adin_config_rgmii_mode(phydev);
+
+	if (ret < 0)
+		return ret;
+
+	return genphy_config(phydev);
+}
+
+static struct phy_driver ADIN1300_driver =  {
+	.name = "ADIN1300",
+	.uid = PHY_ID_ADIN1300,
+	.mask = 0xffffffff,
+	.features = PHY_GBIT_FEATURES,
+	.config = adin1300_config,
+	.startup = genphy_startup,
+	.shutdown = genphy_shutdown,
+};
+
+int phy_adin_init(void)
+{
+	phy_register(&ADIN1300_driver);
+
+	return 0;
+}
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index 83075f7..7e950fe 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -305,7 +305,7 @@
 	u16 syscfg;
 	int cnt;
 	u16 start_rate;
-} aquantia_syscfg[PHY_INTERFACE_MODE_COUNT] = {
+} aquantia_syscfg[PHY_INTERFACE_MODE_MAX] = {
 	[PHY_INTERFACE_MODE_SGMII] =      {0x04b, AQUANTIA_VND1_GSYSCFG_1G,
 					   AQUANTIA_VND1_GSTART_RATE_1G},
 	[PHY_INTERFACE_MODE_2500BASEX]  = {0x144, AQUANTIA_VND1_GSYSCFG_2_5G,
diff --git a/drivers/net/phy/atheros.c b/drivers/net/phy/atheros.c
index f922fec..fa1fe08 100644
--- a/drivers/net/phy/atheros.c
+++ b/drivers/net/phy/atheros.c
@@ -199,7 +199,7 @@
 
 	node = phy_get_ofnode(phydev);
 	if (!ofnode_valid(node))
-		return -EINVAL;
+		return 0;
 
 	priv = malloc(sizeof(*priv));
 	if (!priv)
diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
index eada454..3d86263 100644
--- a/drivers/net/phy/dp83867.c
+++ b/drivers/net/phy/dp83867.c
@@ -158,7 +158,7 @@
 
 	node = phy_get_ofnode(phydev);
 	if (!ofnode_valid(node))
-		return -EINVAL;
+		return 0;
 
 	/* Optional configuration */
 	ret = ofnode_read_u32(node, "ti,clk-output-sel",
@@ -266,7 +266,7 @@
 static int dp83867_config(struct phy_device *phydev)
 {
 	struct dp83867_private *dp83867;
-	unsigned int val, delay, cfg2;
+	int val, delay, cfg2;
 	int ret, bs;
 
 	dp83867 = (struct dp83867_private *)phydev->priv;
@@ -291,8 +291,11 @@
 
 	if (phy_interface_is_rgmii(phydev)) {
 		val = phy_read(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL);
-		if (val < 0)
+		if (val < 0) {
+			ret = val;
 			goto err_out;
+		}
+
 		val &= ~DP83867_PHYCR_FIFO_DEPTH_MASK;
 		val |= (dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT);
 
diff --git a/drivers/net/phy/ethernet_id.c b/drivers/net/phy/ethernet_id.c
index 1a78a75..8864f99 100644
--- a/drivers/net/phy/ethernet_id.c
+++ b/drivers/net/phy/ethernet_id.c
@@ -12,7 +12,7 @@
 #include <asm/gpio.h>
 
 struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev,
-				      int phyaddr, phy_interface_t interface)
+				      int phyaddr)
 {
 	struct phy_device *phydev;
 	struct ofnode_phandle_args phandle_args;
@@ -68,7 +68,7 @@
 	}
 
 	id =  vendor << 16 | device;
-	phydev = phy_device_create(bus, phyaddr, id, false, interface);
+	phydev = phy_device_create(bus, phyaddr, id, false);
 	if (phydev)
 		phydev->node = node;
 
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 3672262..1121b99 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -490,6 +490,9 @@
 #ifdef CONFIG_MV88E61XX_SWITCH
 	phy_mv88e61xx_init();
 #endif
+#ifdef CONFIG_PHY_ADIN
+	phy_adin_init();
+#endif
 #ifdef CONFIG_PHY_AQUANTIA
 	phy_aquantia_init();
 #endif
@@ -635,18 +638,17 @@
 	return err;
 }
 
-static struct phy_driver *generic_for_interface(phy_interface_t interface)
+static struct phy_driver *generic_for_phy(struct phy_device *phydev)
 {
 #ifdef CONFIG_PHYLIB_10G
-	if (is_10g_interface(interface))
+	if (phydev->is_c45)
 		return &gen10g_driver;
 #endif
 
 	return &genphy_driver;
 }
 
-static struct phy_driver *get_phy_driver(struct phy_device *phydev,
-					 phy_interface_t interface)
+static struct phy_driver *get_phy_driver(struct phy_device *phydev)
 {
 	struct list_head *entry;
 	int phy_id = phydev->phy_id;
@@ -659,12 +661,11 @@
 	}
 
 	/* If we made it here, there's no driver for this PHY */
-	return generic_for_interface(interface);
+	return generic_for_phy(phydev);
 }
 
 struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
-				     u32 phy_id, bool is_c45,
-				     phy_interface_t interface)
+				     u32 phy_id, bool is_c45)
 {
 	struct phy_device *dev;
 
@@ -683,7 +684,7 @@
 
 	dev->duplex = -1;
 	dev->link = 0;
-	dev->interface = interface;
+	dev->interface = PHY_INTERFACE_MODE_NA;
 
 #ifdef CONFIG_DM_ETH
 	dev->node = ofnode_null();
@@ -696,7 +697,7 @@
 	dev->is_c45 = is_c45;
 	dev->bus = bus;
 
-	dev->drv = get_phy_driver(dev, interface);
+	dev->drv = get_phy_driver(dev);
 
 	if (phy_probe(dev)) {
 		printf("%s, PHY probe failed\n", __func__);
@@ -745,8 +746,7 @@
 }
 
 static struct phy_device *create_phy_by_mask(struct mii_dev *bus,
-					     uint phy_mask, int devad,
-					     phy_interface_t interface)
+					     uint phy_mask, int devad)
 {
 	u32 phy_id = 0xffffffff;
 	bool is_c45;
@@ -767,8 +767,7 @@
 		/* If the PHY ID is mostly f's, we didn't find anything */
 		if (r == 0 && (phy_id & 0x1fffffff) != 0x1fffffff) {
 			is_c45 = (devad == MDIO_DEVAD_NONE) ? false : true;
-			return phy_device_create(bus, addr, phy_id, is_c45,
-						 interface);
+			return phy_device_create(bus, addr, phy_id, is_c45);
 		}
 next:
 		phy_mask &= ~(1 << addr);
@@ -777,25 +776,22 @@
 }
 
 static struct phy_device *search_for_existing_phy(struct mii_dev *bus,
-						  uint phy_mask,
-						  phy_interface_t interface)
+						  uint phy_mask)
 {
 	/* If we have one, return the existing device, with new interface */
 	while (phy_mask) {
 		int addr = ffs(phy_mask) - 1;
 
-		if (bus->phymap[addr]) {
-			bus->phymap[addr]->interface = interface;
+		if (bus->phymap[addr])
 			return bus->phymap[addr];
-		}
+
 		phy_mask &= ~(1 << addr);
 	}
 	return NULL;
 }
 
 static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
-						 uint phy_mask,
-						 phy_interface_t interface)
+						 uint phy_mask)
 {
 	struct phy_device *phydev;
 	int devad[] = {
@@ -811,13 +807,12 @@
 	int i, devad_cnt;
 
 	devad_cnt = sizeof(devad)/sizeof(int);
-	phydev = search_for_existing_phy(bus, phy_mask, interface);
+	phydev = search_for_existing_phy(bus, phy_mask);
 	if (phydev)
 		return phydev;
 	/* try different access clauses  */
 	for (i = 0; i < devad_cnt; i++) {
-		phydev = create_phy_by_mask(bus, phy_mask,
-					    devad[i], interface);
+		phydev = create_phy_by_mask(bus, phy_mask, devad[i]);
 		if (IS_ERR(phydev))
 			return NULL;
 		if (phydev)
@@ -845,10 +840,9 @@
  * Description: Reads the ID registers of the PHY at @addr on the
  *   @bus, then allocates and returns the phy_device to represent it.
  */
-static struct phy_device *get_phy_device(struct mii_dev *bus, int addr,
-					 phy_interface_t interface)
+static struct phy_device *get_phy_device(struct mii_dev *bus, int addr)
 {
-	return get_phy_device_by_mask(bus, 1 << addr, interface);
+	return get_phy_device_by_mask(bus, 1 << addr);
 }
 
 int phy_reset(struct phy_device *phydev)
@@ -862,7 +856,7 @@
 
 #ifdef CONFIG_PHYLIB_10G
 	/* If it's 10G, we need to issue reset through one of the MMDs */
-	if (is_10g_interface(phydev->interface)) {
+	if (phydev->is_c45) {
 		if (!phydev->mmds)
 			gen10g_discover_mmds(phydev);
 
@@ -907,18 +901,12 @@
 	struct mii_dev *bus = miiphy_get_dev_by_name(devname);
 	struct phy_device *phydev;
 
-	/*
-	 * miiphy_reset was only used on standard PHYs, so we'll fake it here.
-	 * If later code tries to connect with the right interface, this will
-	 * be corrected by get_phy_device in phy_connect()
-	 */
-	phydev = get_phy_device(bus, addr, PHY_INTERFACE_MODE_MII);
+	phydev = get_phy_device(bus, addr);
 
 	return phy_reset(phydev);
 }
 
-struct phy_device *phy_find_by_mask(struct mii_dev *bus, uint phy_mask,
-				    phy_interface_t interface)
+struct phy_device *phy_find_by_mask(struct mii_dev *bus, uint phy_mask)
 {
 	/* Reset the bus */
 	if (bus->reset) {
@@ -928,13 +916,15 @@
 		mdelay(15);
 	}
 
-	return get_phy_device_by_mask(bus, phy_mask, interface);
+	return get_phy_device_by_mask(bus, phy_mask);
 }
 
 #ifdef CONFIG_DM_ETH
-void phy_connect_dev(struct phy_device *phydev, struct udevice *dev)
+void phy_connect_dev(struct phy_device *phydev, struct udevice *dev,
+		     phy_interface_t interface)
 #else
-void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev)
+void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev,
+		     phy_interface_t interface)
 #endif
 {
 	/* Soft Reset the PHY */
@@ -945,13 +935,14 @@
 		       phydev->dev->name, dev->name);
 	}
 	phydev->dev = dev;
-	debug("%s connected to %s\n", dev->name, phydev->drv->name);
+	phydev->interface = interface;
+	debug("%s connected to %s mode %s\n", dev->name, phydev->drv->name,
+	      phy_string_for_interface(interface));
 }
 
 #ifdef CONFIG_PHY_XILINX_GMII2RGMII
 static struct phy_device *phy_connect_gmii2rgmii(struct mii_dev *bus,
-						 struct udevice *dev,
-						 phy_interface_t interface)
+						 struct udevice *dev)
 {
 	struct phy_device *phydev = NULL;
 	ofnode node;
@@ -960,8 +951,7 @@
 		node = ofnode_by_compatible(node, "xlnx,gmii-to-rgmii-1.0");
 		if (ofnode_valid(node)) {
 			phydev = phy_device_create(bus, 0,
-						   PHY_GMII2RGMII_ID, false,
-						   interface);
+						   PHY_GMII2RGMII_ID, false);
 			if (phydev)
 				phydev->node = node;
 			break;
@@ -985,41 +975,31 @@
  */
 struct phy_device *fixed_phy_create(ofnode node)
 {
-	phy_interface_t interface = PHY_INTERFACE_MODE_NONE;
 	struct phy_device *phydev;
-	const char *if_str;
 	ofnode subnode;
 
-	if_str = ofnode_read_string(node, "phy-mode");
-	if (!if_str) {
-		if_str = ofnode_read_string(node, "phy-interface-type");
-	}
-	if (if_str) {
-		interface = phy_get_interface_by_name(if_str);
-	}
-
 	subnode = ofnode_find_subnode(node, "fixed-link");
 	if (!ofnode_valid(subnode)) {
 		return NULL;
 	}
 
-	phydev = phy_device_create(NULL, 0, PHY_FIXED_ID, false, interface);
+	phydev = phy_device_create(NULL, 0, PHY_FIXED_ID, false);
 	if (phydev)
 		phydev->node = subnode;
 
+	phydev->interface = ofnode_read_phy_mode(node);
+
 	return phydev;
 }
 
 static struct phy_device *phy_connect_fixed(struct mii_dev *bus,
-					    struct udevice *dev,
-					    phy_interface_t interface)
+					    struct udevice *dev)
 {
 	ofnode node = dev_ofnode(dev), subnode;
 	struct phy_device *phydev = NULL;
 
 	if (ofnode_phy_is_fixed_link(node, &subnode)) {
-		phydev = phy_device_create(bus, 0, PHY_FIXED_ID,
-					   false, interface);
+		phydev = phy_device_create(bus, 0, PHY_FIXED_ID, false);
 		if (phydev)
 			phydev->node = subnode;
 	}
@@ -1042,29 +1022,29 @@
 	uint mask = (addr >= 0) ? (1 << addr) : 0xffffffff;
 
 #ifdef CONFIG_PHY_FIXED
-	phydev = phy_connect_fixed(bus, dev, interface);
+	phydev = phy_connect_fixed(bus, dev);
 #endif
 
 #ifdef CONFIG_PHY_NCSI
 	if (!phydev)
-		phydev = phy_device_create(bus, 0, PHY_NCSI_ID, false, interface);
+		phydev = phy_device_create(bus, 0, PHY_NCSI_ID, false);
 #endif
 
 #ifdef CONFIG_PHY_ETHERNET_ID
 	if (!phydev)
-		phydev = phy_connect_phy_id(bus, dev, addr, interface);
+		phydev = phy_connect_phy_id(bus, dev, addr);
 #endif
 
 #ifdef CONFIG_PHY_XILINX_GMII2RGMII
 	if (!phydev)
-		phydev = phy_connect_gmii2rgmii(bus, dev, interface);
+		phydev = phy_connect_gmii2rgmii(bus, dev);
 #endif
 
 	if (!phydev)
-		phydev = phy_find_by_mask(bus, mask, interface);
+		phydev = phy_find_by_mask(bus, mask);
 
 	if (phydev)
-		phy_connect_dev(phydev, dev);
+		phy_connect_dev(phydev, dev, interface);
 	else
 		printf("Could not get PHY for %s: addr %d\n", bus->name, addr);
 	return phydev;
@@ -1102,18 +1082,6 @@
 	return 0;
 }
 
-int phy_get_interface_by_name(const char *str)
-{
-	int i;
-
-	for (i = 0; i < PHY_INTERFACE_MODE_COUNT; i++) {
-		if (!strcmp(str, phy_interface_strings[i]))
-			return i;
-	}
-
-	return -1;
-}
-
 /**
  * phy_modify - Convenience function for modifying a given PHY register
  * @phydev: the phy_device struct
diff --git a/drivers/net/phy/xilinx_gmii2rgmii.c b/drivers/net/phy/xilinx_gmii2rgmii.c
index 635c057..7376283 100644
--- a/drivers/net/phy/xilinx_gmii2rgmii.c
+++ b/drivers/net/phy/xilinx_gmii2rgmii.c
@@ -26,6 +26,11 @@
 
 	debug("%s\n", __func__);
 
+	if (phydev->interface != PHY_INTERFACE_MODE_GMII) {
+		printf("Incorrect interface type\n");
+		return -EINVAL;
+	}
+
 	if (!ofnode_valid(node))
 		return -EINVAL;
 
@@ -37,13 +42,13 @@
 
 	ext_phyaddr = ofnode_read_u32_default(phandle.node, "reg", -1);
 	ext_phydev = phy_find_by_mask(phydev->bus,
-				      1 << ext_phyaddr,
-				      PHY_INTERFACE_MODE_RGMII);
+				      1 << ext_phyaddr);
 	if (!ext_phydev) {
 		printf("%s, No external phy device found\n", __func__);
 		return -EINVAL;
 	}
 
+	ext_phydev->interface = PHY_INTERFACE_MODE_RGMII;
 	ext_phydev->node = phandle.node;
 	phydev->priv = ext_phydev;
 
@@ -114,11 +119,6 @@
 {
 	debug("%s\n", __func__);
 
-	if (phydev->interface != PHY_INTERFACE_MODE_GMII) {
-		printf("Incorrect interface type\n");
-		return -EINVAL;
-	}
-
 	phydev->flags |= PHY_FLAG_BROKEN_RESET;
 
 	return 0;