aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/phy
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-04-15 08:09:52 -0400
committerTom Rini <trini@konsulko.com>2022-04-15 08:10:32 -0400
commit7f418ea59852945eeb9e5d2555d306f09643d555 (patch)
tree069dbaf3a1f62b68251189e9acdbd9affcbd98c5 /drivers/net/phy
parent239fe55a6ce516f329687c0680428ca2acfc73ca (diff)
parent0154e6de37e8bbaac837939391f6d4a8f0b3fd18 (diff)
downloadu-boot-7f418ea59852945eeb9e5d2555d306f09643d555.zip
u-boot-7f418ea59852945eeb9e5d2555d306f09643d555.tar.gz
u-boot-7f418ea59852945eeb9e5d2555d306f09643d555.tar.bz2
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]
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/Kconfig5
-rw-r--r--drivers/net/phy/Makefile1
-rw-r--r--drivers/net/phy/adin.c228
-rw-r--r--drivers/net/phy/aquantia.c2
-rw-r--r--drivers/net/phy/atheros.c2
-rw-r--r--drivers/net/phy/dp83867.c9
-rw-r--r--drivers/net/phy/ethernet_id.c4
-rw-r--r--drivers/net/phy/phy.c120
-rw-r--r--drivers/net/phy/xilinx_gmii2rgmii.c14
9 files changed, 295 insertions, 90 deletions
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 @@ endif # MV88E61XX_SWITCH
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_MV88E6352_SWITCH) += mv88e6352.o
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 @@ struct {
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 @@ static int ar803x_of_init(struct phy_device *phydev)
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 @@ static int dp83867_of_init(struct phy_device *phydev)
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_of_init(struct phy_device *phydev)
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 @@ static int dp83867_config(struct phy_device *phydev)
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 @@ struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev,
}
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 @@ int phy_init(void)
#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 @@ static int phy_probe(struct phy_device *phydev)
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 @@ static struct phy_driver *get_phy_driver(struct phy_device *phydev,
}
/* 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 @@ struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
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 @@ struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
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 @@ int __weak get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
}
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 @@ static struct phy_device *create_phy_by_mask(struct mii_dev *bus,
/* 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 @@ next:
}
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 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
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 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
* 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 @@ int phy_reset(struct phy_device *phydev)
#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 @@ int miiphy_reset(const char *devname, unsigned char addr)
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 @@ struct phy_device *phy_find_by_mask(struct mii_dev *bus, uint phy_mask,
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 @@ void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev)
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 @@ static struct phy_device *phy_connect_gmii2rgmii(struct mii_dev *bus,
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 @@ static struct phy_device *phy_connect_gmii2rgmii(struct mii_dev *bus,
*/
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 @@ struct phy_device *phy_connect(struct mii_dev *bus, int addr,
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 @@ int phy_shutdown(struct phy_device *phydev)
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 @@ static int xilinxgmiitorgmii_config(struct phy_device *phydev)
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 @@ static int xilinxgmiitorgmii_config(struct phy_device *phydev)
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 @@ static int xilinxgmiitorgmii_probe(struct phy_device *phydev)
{
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;