From 4f6746dc7f7f1691dfdc73a69831e61c9507708f Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Fri, 8 Feb 2019 17:25:06 +0000 Subject: net: phy: Add generic helpers to access MMD PHY registers Two new helper functions (phy_read_mmd() and phy_write_mmd()) are added to allow access to the MMD PHY registers. The MMD PHY registers can be accessed by several means: 1. Using two new MMD access function hooks in the PHY driver. These functions can be implemented when the PHY driver does not support the standard IEEE Compatible clause 45 access mechanism described in clause 22 or if the PHY uses its own non-standard access mechanism. 2. Direct access for C45 PHYs and C22 PHYs when accessing the reachable DEVADs. 3. The standard clause 45 access extensions to the MMD registers through the indirection registers (clause 22) in all the other cases. Signed-off-by: Carlo Caione Acked-by: Joe Hershberger --- drivers/net/phy/phy.c | 4 +++ include/phy.h | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 4e8d2943ee..9c3e037682 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -549,6 +549,10 @@ int phy_register(struct phy_driver *drv) drv->readext += gd->reloc_off; if (drv->writeext) drv->writeext += gd->reloc_off; + if (drv->read_mmd) + drv->read_mmd += gd->reloc_off; + if (drv->write_mmd) + drv->write_mmd += gd->reloc_off; #endif return 0; } diff --git a/include/phy.h b/include/phy.h index f23ca63f3b..d01435d1aa 100644 --- a/include/phy.h +++ b/include/phy.h @@ -101,6 +101,14 @@ struct phy_driver { int (*readext)(struct phy_device *phydev, int addr, int devad, int reg); int (*writeext)(struct phy_device *phydev, int addr, int devad, int reg, u16 val); + + /* Phy specific driver override for reading a MMD register */ + int (*read_mmd)(struct phy_device *phydev, int devad, int reg); + + /* Phy specific driver override for writing a MMD register */ + int (*write_mmd)(struct phy_device *phydev, int devad, int reg, + u16 val); + struct list_head list; }; @@ -165,6 +173,68 @@ static inline int phy_write(struct phy_device *phydev, int devad, int regnum, return bus->write(bus, phydev->addr, devad, regnum, val); } +static inline void phy_mmd_start_indirect(struct phy_device *phydev, int devad, + int regnum) +{ + /* Write the desired MMD Devad */ + phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL, devad); + + /* Write the desired MMD register address */ + phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, regnum); + + /* Select the Function : DATA with no post increment */ + phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL, + (devad | MII_MMD_CTRL_NOINCR)); +} + +static inline int phy_read_mmd(struct phy_device *phydev, int devad, + int regnum) +{ + struct phy_driver *drv = phydev->drv; + + if (regnum > (u16)~0 || devad > 32) + return -EINVAL; + + /* driver-specific access */ + if (drv->read_mmd) + return drv->read_mmd(phydev, devad, regnum); + + /* direct C45 / C22 access */ + if ((drv->features & PHY_10G_FEATURES) == PHY_10G_FEATURES || + devad == MDIO_DEVAD_NONE || !devad) + return phy_read(phydev, devad, regnum); + + /* indirect C22 access */ + phy_mmd_start_indirect(phydev, devad, regnum); + + /* Read the content of the MMD's selected register */ + return phy_read(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA); +} + +static inline int phy_write_mmd(struct phy_device *phydev, int devad, + int regnum, u16 val) +{ + struct phy_driver *drv = phydev->drv; + + if (regnum > (u16)~0 || devad > 32) + return -EINVAL; + + /* driver-specific access */ + if (drv->write_mmd) + return drv->write_mmd(phydev, devad, regnum, val); + + /* direct C45 / C22 access */ + if ((drv->features & PHY_10G_FEATURES) == PHY_10G_FEATURES || + devad == MDIO_DEVAD_NONE || !devad) + return phy_write(phydev, devad, regnum, val); + + /* indirect C22 access */ + phy_mmd_start_indirect(phydev, devad, regnum); + + /* Write the data into MMD's selected register */ + return phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, val); +} + #ifdef CONFIG_PHYLIB_10G extern struct phy_driver gen10g_driver; -- cgit v1.2.3 From 4c29dc1863e4f739ec2f496352935fd37c123553 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Fri, 8 Feb 2019 17:25:07 +0000 Subject: net: phy: ti: use generic helpers to access MMD registers Now that generic helpers are available, use those instead of relying on ti specific functions. Signed-off-by: Carlo Caione Signed-off-by: Vladimir Oltean Acked-by: Joe Hershberger --- drivers/net/phy/ti.c | 130 ++++++++++----------------------------------------- 1 file changed, 25 insertions(+), 105 deletions(-) diff --git a/drivers/net/phy/ti.c b/drivers/net/phy/ti.c index 6db6edd0d0..6ac890a7f5 100644 --- a/drivers/net/phy/ti.c +++ b/drivers/net/phy/ti.c @@ -73,16 +73,6 @@ #define MII_DP83867_CFG2_SPEEDOPT_INTLOW 0x2000 #define MII_DP83867_CFG2_MASK 0x003F -#define MII_MMD_CTRL 0x0d /* MMD Access Control Register */ -#define MII_MMD_DATA 0x0e /* MMD Access Data Register */ - -/* MMD Access Control register fields */ -#define MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/ -#define MII_MMD_CTRL_ADDR 0x0000 /* Address */ -#define MII_MMD_CTRL_NOINCR 0x4000 /* no post increment */ -#define MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */ -#define MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */ - /* User setting - can be taken from DTS */ #define DEFAULT_RX_ID_DELAY DP83867_RGMIIDCTL_2_25_NS #define DEFAULT_TX_ID_DELAY DP83867_RGMIIDCTL_2_75_NS @@ -116,88 +106,20 @@ struct dp83867_private { int clk_output_sel; }; -/** - * phy_read_mmd_indirect - reads data from the MMD registers - * @phydev: The PHY device bus - * @prtad: MMD Address - * @devad: MMD DEVAD - * @addr: PHY address on the MII bus - * - * Description: it reads data from the MMD registers (clause 22 to access to - * clause 45) of the specified phy address. - * To read these registers we have: - * 1) Write reg 13 // DEVAD - * 2) Write reg 14 // MMD Address - * 3) Write reg 13 // MMD Data Command for MMD DEVAD - * 3) Read reg 14 // Read MMD data - */ -int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, - int devad, int addr) -{ - int value = -1; - - /* Write the desired MMD Devad */ - phy_write(phydev, addr, MII_MMD_CTRL, devad); - - /* Write the desired MMD register address */ - phy_write(phydev, addr, MII_MMD_DATA, prtad); - - /* Select the Function : DATA with no post increment */ - phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR)); - - /* Read the content of the MMD's selected register */ - value = phy_read(phydev, addr, MII_MMD_DATA); - return value; -} - -/** - * phy_write_mmd_indirect - writes data to the MMD registers - * @phydev: The PHY device - * @prtad: MMD Address - * @devad: MMD DEVAD - * @addr: PHY address on the MII bus - * @data: data to write in the MMD register - * - * Description: Write data from the MMD registers of the specified - * phy address. - * To write these registers we have: - * 1) Write reg 13 // DEVAD - * 2) Write reg 14 // MMD Address - * 3) Write reg 13 // MMD Data Command for MMD DEVAD - * 3) Write reg 14 // Write MMD data - */ -void phy_write_mmd_indirect(struct phy_device *phydev, int prtad, - int devad, int addr, u32 data) -{ - /* Write the desired MMD Devad */ - phy_write(phydev, addr, MII_MMD_CTRL, devad); - - /* Write the desired MMD register address */ - phy_write(phydev, addr, MII_MMD_DATA, prtad); - - /* Select the Function : DATA with no post increment */ - phy_write(phydev, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR)); - - /* Write the data into MMD's selected register */ - phy_write(phydev, addr, MII_MMD_DATA, data); -} - static int dp83867_config_port_mirroring(struct phy_device *phydev) { struct dp83867_private *dp83867 = (struct dp83867_private *)phydev->priv; u16 val; - val = phy_read_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR, - phydev->addr); + val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4); if (dp83867->port_mirroring == DP83867_PORT_MIRRORING_EN) val |= DP83867_CFG4_PORT_MIRROR_EN; else val &= ~DP83867_CFG4_PORT_MIRROR_EN; - phy_write_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR, - phydev->addr, val); + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, val); return 0; } @@ -257,13 +179,13 @@ static int dp83867_of_init(struct phy_device *phydev) /* Clock output selection if muxing property is set */ if (dp83867->clk_output_sel != DP83867_CLK_O_SEL_REF_CLK) { - val = phy_read_mmd_indirect(phydev, DP83867_IO_MUX_CFG, - DP83867_DEVADDR, phydev->addr); + val = phy_read_mmd(phydev, DP83867_DEVADDR, + DP83867_IO_MUX_CFG); val &= ~DP83867_IO_MUX_CFG_CLK_O_SEL_MASK; val |= (dp83867->clk_output_sel << DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT); - phy_write_mmd_indirect(phydev, DP83867_IO_MUX_CFG, - DP83867_DEVADDR, phydev->addr, val); + phy_write_mmd(phydev, DP83867_DEVADDR, + DP83867_IO_MUX_CFG, val); } return 0; @@ -308,11 +230,11 @@ static int dp83867_config(struct phy_device *phydev) /* Mode 1 or 2 workaround */ if (dp83867->rxctrl_strap_quirk) { - val = phy_read_mmd_indirect(phydev, DP83867_CFG4, - DP83867_DEVADDR, phydev->addr); + val = phy_read_mmd(phydev, DP83867_DEVADDR, + DP83867_CFG4); val &= ~BIT(7); - phy_write_mmd_indirect(phydev, DP83867_CFG4, - DP83867_DEVADDR, phydev->addr, val); + phy_write_mmd(phydev, DP83867_DEVADDR, + DP83867_CFG4, val); } if (phy_interface_is_rgmii(phydev)) { @@ -332,8 +254,8 @@ static int dp83867_config(struct phy_device *phydev) * register's bit 11 (marked as RESERVED). */ - bs = phy_read_mmd_indirect(phydev, DP83867_STRAP_STS1, - DP83867_DEVADDR, phydev->addr); + bs = phy_read_mmd(phydev, DP83867_DEVADDR, + DP83867_STRAP_STS1); val = phy_read(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL); if (bs & DP83867_STRAP_STS1_RESERVED) { val &= ~DP83867_PHYCR_RESERVED_MASK; @@ -354,8 +276,8 @@ static int dp83867_config(struct phy_device *phydev) MII_DP83867_CFG2_SPEEDOPT_INTLOW); phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_CFG2, cfg2); - phy_write_mmd_indirect(phydev, DP83867_RGMIICTL, - DP83867_DEVADDR, phydev->addr, 0x0); + phy_write_mmd(phydev, DP83867_DEVADDR, + DP83867_RGMIICTL, 0x0); phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL, DP83867_PHYCTRL_SGMIIEN | @@ -367,8 +289,8 @@ static int dp83867_config(struct phy_device *phydev) } if (phy_interface_is_rgmii(phydev)) { - val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL, - DP83867_DEVADDR, phydev->addr); + val = phy_read_mmd(phydev, DP83867_DEVADDR, + DP83867_RGMIICTL); if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) val |= (DP83867_RGMII_TX_CLK_DELAY_EN | @@ -380,26 +302,24 @@ static int dp83867_config(struct phy_device *phydev) if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) val |= DP83867_RGMII_RX_CLK_DELAY_EN; - phy_write_mmd_indirect(phydev, DP83867_RGMIICTL, - DP83867_DEVADDR, phydev->addr, val); + phy_write_mmd(phydev, DP83867_DEVADDR, + DP83867_RGMIICTL, val); delay = (dp83867->rx_id_delay | (dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT)); - phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL, - DP83867_DEVADDR, phydev->addr, delay); + phy_write_mmd(phydev, DP83867_DEVADDR, + DP83867_RGMIIDCTL, delay); if (dp83867->io_impedance >= 0) { - val = phy_read_mmd_indirect(phydev, - DP83867_IO_MUX_CFG, - DP83867_DEVADDR, - phydev->addr); + val = phy_read_mmd(phydev, + DP83867_DEVADDR, + DP83867_IO_MUX_CFG); val &= ~DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL; val |= dp83867->io_impedance & DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL; - phy_write_mmd_indirect(phydev, DP83867_IO_MUX_CFG, - DP83867_DEVADDR, phydev->addr, - val); + phy_write_mmd(phydev, DP83867_DEVADDR, + DP83867_IO_MUX_CFG, val); } } -- cgit v1.2.3 From e55047ec51a662c12ed53ff543ec7cdf158b2137 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Fri, 8 Feb 2019 17:25:08 +0000 Subject: cmd: mdio: Switch to generic helpers when accessing the registers Switch to use the generic helpers to access the MMD registers so that we can used the same command also for C45 PHYs, C22 PHYs with direct and indirect access and PHYs implementing a custom way to access the registers. Signed-off-by: Carlo Caione Acked-by: Joe Hershberger --- cmd/mdio.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/cmd/mdio.c b/cmd/mdio.c index 184868063a..efe8c9ef09 100644 --- a/cmd/mdio.c +++ b/cmd/mdio.c @@ -39,21 +39,24 @@ static int extract_range(char *input, int *plo, int *phi) return 0; } -static int mdio_write_ranges(struct phy_device *phydev, struct mii_dev *bus, +static int mdio_write_ranges(struct mii_dev *bus, int addrlo, int addrhi, int devadlo, int devadhi, int reglo, int reghi, unsigned short data, int extended) { + struct phy_device *phydev; int addr, devad, reg; int err = 0; for (addr = addrlo; addr <= addrhi; addr++) { + phydev = bus->phymap[addr]; + for (devad = devadlo; devad <= devadhi; devad++) { for (reg = reglo; reg <= reghi; reg++) { if (!extended) - err = bus->write(bus, addr, devad, - reg, data); + err = phy_write_mmd(phydev, devad, + reg, data); else err = phydev->drv->writeext(phydev, addr, devad, reg, data); @@ -68,15 +71,17 @@ err_out: return err; } -static int mdio_read_ranges(struct phy_device *phydev, struct mii_dev *bus, +static int mdio_read_ranges(struct mii_dev *bus, int addrlo, int addrhi, int devadlo, int devadhi, int reglo, int reghi, int extended) { int addr, devad, reg; + struct phy_device *phydev; printf("Reading from bus %s\n", bus->name); for (addr = addrlo; addr <= addrhi; addr++) { + phydev = bus->phymap[addr]; printf("PHY at address %x:\n", addr); for (devad = devadlo; devad <= devadhi; devad++) { @@ -84,7 +89,7 @@ static int mdio_read_ranges(struct phy_device *phydev, struct mii_dev *bus, int val; if (!extended) - val = bus->read(bus, addr, devad, reg); + val = phy_read_mmd(phydev, devad, reg); else val = phydev->drv->readext(phydev, addr, devad, reg); @@ -222,14 +227,14 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) bus = phydev->bus; extended = 1; } else { - return -1; + return CMD_RET_FAILURE; } if (!phydev->drv || (!phydev->drv->writeext && (op[0] == 'w')) || (!phydev->drv->readext && (op[0] == 'r'))) { puts("PHY does not have extended functions\n"); - return -1; + return CMD_RET_FAILURE; } } } @@ -242,13 +247,13 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (pos > 1) if (extract_reg_range(argv[pos--], &devadlo, &devadhi, ®lo, ®hi)) - return -1; + return CMD_RET_FAILURE; default: if (pos > 1) if (extract_phy_range(&argv[2], pos - 1, &bus, &phydev, &addrlo, &addrhi)) - return -1; + return CMD_RET_FAILURE; break; } @@ -264,12 +269,12 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) switch (op[0]) { case 'w': - mdio_write_ranges(phydev, bus, addrlo, addrhi, devadlo, devadhi, + mdio_write_ranges(bus, addrlo, addrhi, devadlo, devadhi, reglo, reghi, data, extended); break; case 'r': - mdio_read_ranges(phydev, bus, addrlo, addrhi, devadlo, devadhi, + mdio_read_ranges(bus, addrlo, addrhi, devadlo, devadhi, reglo, reghi, extended); break; } -- cgit v1.2.3 From d47cfdbd315297af73746462599b0c81dac6054a Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Thu, 24 Jan 2019 08:54:37 +0000 Subject: net: phy: realtek: Introduce quirk to mark RXC not stoppable When EEE is supported by the PHY and the driver allows it, libphy in the kernel is configuring the PHY to stop receiving the xMII clock while it is signaling LPI. While this (usually) works fine in the kernel this is causing issues in U-Boot when rebooting from the linux kernel with this bit set (without having the possibility to reset the PHY) where the PHY suddenly stops working. A new quirk is introduced to unconditionally reset this bit. If the quirk is not enabled using the proper configuration symbol, the PHY state is not changed. Signed-off-by: Carlo Caione Acked-by: Joe Hershberger --- drivers/net/phy/Kconfig | 20 ++++++++++++++++++++ drivers/net/phy/realtek.c | 19 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 3dc0822d9c..631b52b1cf 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -202,6 +202,26 @@ config RTL8211X_PHY_FORCE_MASTER If unsure, say N. +config RTL8211F_PHY_FORCE_EEE_RXC_ON + bool "Ethernet PHY RTL8211F: do not stop receiving the xMII clock during LPI" + depends on PHY_REALTEK + default n + help + The IEEE 802.3az-2010 (EEE) standard provides a protocol to coordinate + transitions to/from a lower power consumption level (Low Power Idle + mode) based on link utilization. When no packets are being + transmitted, the system goes to Low Power Idle mode to save power. + + Under particular circumstances this setting can cause issues where + the PHY is unable to transmit or receive any packet when in LPI mode. + The problem is caused when the PHY is configured to stop receiving + the xMII clock while it is signaling LPI. For some PHYs the bit + configuring this behavior is set by the Linux kernel, causing the + issue in U-Boot on reboot if the PHY retains the register value. + + Default n, which means that the PHY state is not changed. To work + around the issues, change this setting to y. + config PHY_SMSC bool "Microchip(SMSC) Ethernet PHYs support" diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index dd45e11b3a..8f1d759632 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -12,6 +12,7 @@ #define PHY_RTL8211x_FORCE_MASTER BIT(1) #define PHY_RTL8211E_PINE64_GIGABIT_FIX BIT(2) +#define PHY_RTL8211F_FORCE_EEE_RXC_ON BIT(3) #define PHY_AUTONEGOTIATE_TIMEOUT 5000 @@ -102,6 +103,15 @@ static int rtl8211e_probe(struct phy_device *phydev) return 0; } +static int rtl8211f_probe(struct phy_device *phydev) +{ +#ifdef CONFIG_RTL8211F_PHY_FORCE_EEE_RXC_ON + phydev->flags |= PHY_RTL8211F_FORCE_EEE_RXC_ON; +#endif + + return 0; +} + /* RealTek RTL8211x */ static int rtl8211x_config(struct phy_device *phydev) { @@ -151,6 +161,14 @@ static int rtl8211f_config(struct phy_device *phydev) { u16 reg; + if (phydev->flags & PHY_RTL8211F_FORCE_EEE_RXC_ON) { + unsigned int reg; + + reg = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1); + reg &= ~MDIO_PCS_CTRL1_CLKSTOP_EN; + phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, reg); + } + phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); phy_write(phydev, MDIO_DEVAD_NONE, @@ -360,6 +378,7 @@ static struct phy_driver RTL8211F_driver = { .uid = 0x1cc916, .mask = 0xffffff, .features = PHY_GBIT_FEATURES, + .probe = &rtl8211f_probe, .config = &rtl8211f_config, .startup = &rtl8211f_startup, .shutdown = &genphy_shutdown, -- cgit v1.2.3 From 4b0880d66baa1b96c6293051a03af0ad1bee7cb0 Mon Sep 17 00:00:00 2001 From: Pankaj Bansal Date: Fri, 8 Feb 2019 08:46:11 +0000 Subject: drivers: net: ldpaa_eth: fix resource leak if an error occurs in ldpaa_eth_init, need to free all resources before returning the error. Threfore, free net_dev before returning from ldpaa_eth_init. Signed-off-by: Pankaj Bansal Acked-by: Joe Hershberger --- drivers/net/ldpaa_eth/ldpaa_eth.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 73b7ba29df..34253e3924 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -1074,6 +1074,7 @@ int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if) priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv)); if (!priv) { printf("ldpaa_eth_priv malloc() failed\n"); + free(net_dev); return -ENOMEM; } memset(priv, 0, sizeof(struct ldpaa_eth_priv)); -- cgit v1.2.3 From 63200d8457209783300bf44a200298e12d23bf2d Mon Sep 17 00:00:00 2001 From: Murali Karicheri Date: Mon, 25 Feb 2019 15:27:33 -0500 Subject: ARM: k2g-gp-evm: update to rgmii pinmux configuration This patch updates pinmux configuration for K2G GP EVM based on data generated by the pinmux tool at https://dev.ti.com/pinmux/app.html#/default Signed-off-by: Murali Karicheri Reviewed-by: Lokesh Vutla Acked-by: Joe Hershberger --- board/ti/ks2_evm/mux-k2g.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/board/ti/ks2_evm/mux-k2g.h b/board/ti/ks2_evm/mux-k2g.h index 89c49f9e4f..3f57739fff 100644 --- a/board/ti/ks2_evm/mux-k2g.h +++ b/board/ti/ks2_evm/mux-k2g.h @@ -126,22 +126,22 @@ struct pin_cfg k2g_evm_pin_cfg[] = { { 71, MODE(0) }, /* MMC1POW TP124 */ /* EMAC */ - { 79, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD1 */ - { 78, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD2 */ + { 72, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXC */ { 77, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD3 */ + { 78, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD2 */ + { 79, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD1 */ { 80, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD0 */ - { 94, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD0 */ - { 93, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD1 */ - { 92, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD2 */ - { 91, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD3 */ + { 81, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXCTL */ { 85, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXC */ + { 91, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD3 */ + { 92, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD2 */ + { 93, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD1 */ + { 94, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD0 */ { 95, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXCTL */ - { 72, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXC */ - { 81, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXCTL */ /* MDIO */ - { 99, BUFFER_CLASS_B | PIN_PDIS | MODE(0) }, /* MDIO_CLK */ { 98, BUFFER_CLASS_B | PIN_PDIS | MODE(0) }, /* MDIO_DATA */ + { 99, BUFFER_CLASS_B | PIN_PDIS | MODE(0) }, /* MDIO_CLK */ /* PWM */ { 73, MODE(4) }, /* SOC_EHRPWM3A */ -- cgit v1.2.3 From 89bf9f1162d7420e8b41ad729608add8f0cdc83b Mon Sep 17 00:00:00 2001 From: Murali Karicheri Date: Mon, 25 Feb 2019 15:27:34 -0500 Subject: ARM: k2g-ice: Add pinmux support for rgmii interface This add pinmux configuration for rgmii interface so that network driver can be supported on K2G ICE boards. The pinmux configurations for this are generated using the pinmux tool at https://dev.ti.com/pinmux/app.html#/default As this required some BUFFER_CLASS definitions, same is re-used from the linux defnitions in include/dt-bindings/pinctrl/keystone.h Signed-off-by: Murali Karicheri Reviewed-by: Lokesh Vutla Acked-by: Joe Hershberger --- board/ti/ks2_evm/mux-k2g.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/board/ti/ks2_evm/mux-k2g.h b/board/ti/ks2_evm/mux-k2g.h index 3f57739fff..6aa785ea42 100644 --- a/board/ti/ks2_evm/mux-k2g.h +++ b/board/ti/ks2_evm/mux-k2g.h @@ -350,22 +350,22 @@ struct pin_cfg k2g_ice_evm_pin_cfg[] = { { 135, MODE(0) }, /* SOC_QSPI_CSN0 */ /* EMAC */ - { 79, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD1 */ - { 78, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD2 */ + { 72, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXC */ { 77, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD3 */ + { 78, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD2 */ + { 79, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD1 */ { 80, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXD0 */ - { 94, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD0 */ - { 93, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD1 */ - { 92, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD2 */ - { 91, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD3 */ + { 81, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXCTL */ { 85, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXC */ + { 91, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD3 */ + { 92, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD2 */ + { 93, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD1 */ + { 94, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXD0 */ { 95, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_TXCTL */ - { 72, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXC */ - { 81, BUFFER_CLASS_D | PIN_PDIS | MODE(1) }, /* RGMII_RXCTL */ /* MDIO */ - { 99, BUFFER_CLASS_B | PIN_PDIS | MODE(0) }, /* MDIO_CLK */ { 98, BUFFER_CLASS_B | PIN_PDIS | MODE(0) }, /* MDIO_DATA */ + { 99, BUFFER_CLASS_B | PIN_PDIS | MODE(0) }, /* MDIO_CLK */ { MAX_PIN_N, } }; -- cgit v1.2.3 From c689c4867286888099c21e02d2494f047060d06f Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Mon, 4 Mar 2019 16:01:30 +0100 Subject: net: phy: Reloc next and prev pointers inside phy_drivers This patch relocates the pointers inside phy_drivers incase of manual reloc. Without this reloc, these points to invalid pre relocation address and hence causes exception or hang. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek Acked-by: Joe Hershberger --- drivers/net/phy/phy.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 9c3e037682..04af916678 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -462,6 +462,18 @@ static LIST_HEAD(phy_drivers); int phy_init(void) { +#ifdef CONFIG_NEEDS_MANUAL_RELOC + /* + * The pointers inside phy_drivers also needs to be updated incase of + * manual reloc, without which these points to some invalid + * pre reloc address and leads to invalid accesses, hangs. + */ + struct list_head *head = &phy_drivers; + + head->next = (void *)head->next + gd->reloc_off; + head->prev = (void *)head->prev + gd->reloc_off; +#endif + #ifdef CONFIG_B53_SWITCH phy_b53_init(); #endif -- cgit v1.2.3 From 05eb6a698acbd6465c032d39ea77b79f831f05af Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Mon, 4 Mar 2019 16:02:11 +0100 Subject: net: phy: Fix return value check phy_probe Don't ignore return value of phy_probe() call as the probe may fail and it needs to be reported. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek Acked-by: Joe Hershberger --- drivers/net/phy/phy.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 04af916678..c1c1af9abd 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -671,7 +671,10 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr, dev->drv = get_phy_driver(dev, interface); - phy_probe(dev); + if (phy_probe(dev)) { + printf("%s, PHY probe failed\n", __func__); + return NULL; + } if (addr >= 0 && addr < PHY_MAX_ADDR) bus->phymap[addr] = dev; -- cgit v1.2.3 From c940646ed11ed6580a2b7749d05c873e39ad7f42 Mon Sep 17 00:00:00 2001 From: Valentin-catalin Neacsu Date: Wed, 13 Feb 2019 09:14:53 +0000 Subject: net: phy: aquantia: Set only autoneg on in register 4.c441 For AQR405 in register 4.c441 bit 15 was override with 0. This caused the phy to not negotiate at 2.5GB rate with mac. To avoid this override it needed first to know the previous value of reg 4.c441 and set only bit 3. Signed-off-by: Valentin Catalin Neacsu Acked-by: Joe Hershberger --- drivers/net/phy/aquantia.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c index 12df09877d..5c3298d612 100644 --- a/drivers/net/phy/aquantia.c +++ b/drivers/net/phy/aquantia.c @@ -303,9 +303,14 @@ int aquantia_config(struct phy_device *phydev) AQUANTIA_SYSTEM_INTERFACE_SR); /* If SI is USXGMII then start USXGMII autoneg */ if ((val & AQUANTIA_SI_IN_USE_MASK) == AQUANTIA_SI_USXGMII) { + reg_val1 = phy_read(phydev, MDIO_MMD_PHYXS, + AQUANTIA_VENDOR_PROVISIONING_REG); + + reg_val1 |= AQUANTIA_USX_AUTONEG_CONTROL_ENA; + phy_write(phydev, MDIO_MMD_PHYXS, AQUANTIA_VENDOR_PROVISIONING_REG, - AQUANTIA_USX_AUTONEG_CONTROL_ENA); + reg_val1); printf("%s: system interface USXGMII\n", phydev->dev->name); } else { -- cgit v1.2.3 From 83f71ef55866d77c8e84c99d4c06c55836b7820a Mon Sep 17 00:00:00 2001 From: James Byrne Date: Mon, 4 Mar 2019 17:40:33 +0000 Subject: net: phy: micrel: Use correct skew values on KSZ9021 Commit ff7bd212cb8a ("net: phy: micrel: fix divisor value for KSZ9031 phy skew") fixed the skew value divisor for the KSZ9031, but left the code using the same divisor for the KSZ9021, which is incorrect. The preceding commit c16e69f702b1 ("net: phy: micrel: add documentation for Micrel KSZ90x1 binding") added the DTS documentation for the KSZ90x1, changing it from the equivalent file in the Linux kernel to correctly state that for this part the skew value is set in 120ps steps, whereas the Linux documentation and driver continue to this day to use the incorrect value of 200 that came from the original KSZ9021 datasheet before it was corrected in revision 1.2 (Feb 2014). This commit sorts out the resulting confusion in a consistent way by making the following changes: - Update the documentation to be clear about what the skew values mean, in the same was as for the KSZ9031. - Update the Micrel PHY driver to select the appropriate divisor for both parts. - Adjust all the device trees that state skew values for KSZ9021 PHYs to use values based on 120ps steps instead of 200ps steps. This will result in the same values being programmed into the skew registers as the equivalent device trees in the Linux kernel do, where it incorrectly uses 200ps steps (since that's where all these device trees were copied from). Signed-off-by: James Byrne Acked-by: Joe Hershberger --- arch/arm/dts/sama5d3xcm.dtsi | 32 ++++++++++++------------- arch/arm/dts/sama5d3xcm_cmp.dtsi | 32 ++++++++++++------------- arch/arm/dts/socfpga_arria5_socdk.dts | 4 ++-- arch/arm/dts/socfpga_cyclone5_is1.dts | 4 ++-- arch/arm/dts/socfpga_cyclone5_socdk.dts | 4 ++-- arch/arm/dts/socfpga_cyclone5_sockit.dts | 4 ++-- arch/arm/dts/socfpga_cyclone5_vining_fpga.dts | 4 ++-- doc/device-tree-bindings/net/micrel-ksz90x1.txt | 27 +++++++++++++++++++++ drivers/net/phy/micrel_ksz90x1.c | 14 +++++++---- 9 files changed, 79 insertions(+), 46 deletions(-) diff --git a/arch/arm/dts/sama5d3xcm.dtsi b/arch/arm/dts/sama5d3xcm.dtsi index 2cf9c3611d..d123057f30 100644 --- a/arch/arm/dts/sama5d3xcm.dtsi +++ b/arch/arm/dts/sama5d3xcm.dtsi @@ -44,28 +44,28 @@ reg = <0x1>; interrupt-parent = <&pioB>; interrupts = <25 IRQ_TYPE_EDGE_FALLING>; - txen-skew-ps = <800>; - txc-skew-ps = <3000>; - rxdv-skew-ps = <400>; - rxc-skew-ps = <3000>; - rxd0-skew-ps = <400>; - rxd1-skew-ps = <400>; - rxd2-skew-ps = <400>; - rxd3-skew-ps = <400>; + txen-skew-ps = <480>; + txc-skew-ps = <1800>; + rxdv-skew-ps = <240>; + rxc-skew-ps = <1800>; + rxd0-skew-ps = <240>; + rxd1-skew-ps = <240>; + rxd2-skew-ps = <240>; + rxd3-skew-ps = <240>; }; ethernet-phy@7 { reg = <0x7>; interrupt-parent = <&pioB>; interrupts = <25 IRQ_TYPE_EDGE_FALLING>; - txen-skew-ps = <800>; - txc-skew-ps = <3000>; - rxdv-skew-ps = <400>; - rxc-skew-ps = <3000>; - rxd0-skew-ps = <400>; - rxd1-skew-ps = <400>; - rxd2-skew-ps = <400>; - rxd3-skew-ps = <400>; + txen-skew-ps = <480>; + txc-skew-ps = <1800>; + rxdv-skew-ps = <240>; + rxc-skew-ps = <1800>; + rxd0-skew-ps = <240>; + rxd1-skew-ps = <240>; + rxd2-skew-ps = <240>; + rxd3-skew-ps = <240>; }; }; }; diff --git a/arch/arm/dts/sama5d3xcm_cmp.dtsi b/arch/arm/dts/sama5d3xcm_cmp.dtsi index 77638c3cbe..332b057e0a 100644 --- a/arch/arm/dts/sama5d3xcm_cmp.dtsi +++ b/arch/arm/dts/sama5d3xcm_cmp.dtsi @@ -43,28 +43,28 @@ reg = <0x1>; interrupt-parent = <&pioB>; interrupts = <25 IRQ_TYPE_EDGE_FALLING>; - txen-skew-ps = <800>; - txc-skew-ps = <3000>; - rxdv-skew-ps = <400>; - rxc-skew-ps = <3000>; - rxd0-skew-ps = <400>; - rxd1-skew-ps = <400>; - rxd2-skew-ps = <400>; - rxd3-skew-ps = <400>; + txen-skew-ps = <480>; + txc-skew-ps = <1800>; + rxdv-skew-ps = <240>; + rxc-skew-ps = <1800>; + rxd0-skew-ps = <240>; + rxd1-skew-ps = <240>; + rxd2-skew-ps = <240>; + rxd3-skew-ps = <240>; }; ethernet-phy@7 { reg = <0x7>; interrupt-parent = <&pioB>; interrupts = <25 IRQ_TYPE_EDGE_FALLING>; - txen-skew-ps = <800>; - txc-skew-ps = <3000>; - rxdv-skew-ps = <400>; - rxc-skew-ps = <3000>; - rxd0-skew-ps = <400>; - rxd1-skew-ps = <400>; - rxd2-skew-ps = <400>; - rxd3-skew-ps = <400>; + txen-skew-ps = <480>; + txc-skew-ps = <1800>; + rxdv-skew-ps = <240>; + rxc-skew-ps = <1800>; + rxd0-skew-ps = <240>; + rxd1-skew-ps = <240>; + rxd2-skew-ps = <240>; + rxd3-skew-ps = <240>; }; }; diff --git a/arch/arm/dts/socfpga_arria5_socdk.dts b/arch/arm/dts/socfpga_arria5_socdk.dts index 90e676e701..fa972e287f 100644 --- a/arch/arm/dts/socfpga_arria5_socdk.dts +++ b/arch/arm/dts/socfpga_arria5_socdk.dts @@ -67,9 +67,9 @@ rxd2-skew-ps = <0>; rxd3-skew-ps = <0>; txen-skew-ps = <0>; - txc-skew-ps = <2600>; + txc-skew-ps = <1560>; rxdv-skew-ps = <0>; - rxc-skew-ps = <2000>; + rxc-skew-ps = <1200>; }; &gpio0 { diff --git a/arch/arm/dts/socfpga_cyclone5_is1.dts b/arch/arm/dts/socfpga_cyclone5_is1.dts index 2d31412923..a769498791 100644 --- a/arch/arm/dts/socfpga_cyclone5_is1.dts +++ b/arch/arm/dts/socfpga_cyclone5_is1.dts @@ -43,9 +43,9 @@ rxd2-skew-ps = <0>; rxd3-skew-ps = <0>; txen-skew-ps = <0>; - txc-skew-ps = <2600>; + txc-skew-ps = <1560>; rxdv-skew-ps = <0>; - rxc-skew-ps = <2000>; + rxc-skew-ps = <1200>; }; &gpio1 { diff --git a/arch/arm/dts/socfpga_cyclone5_socdk.dts b/arch/arm/dts/socfpga_cyclone5_socdk.dts index 6f138b2b26..95c7619b8d 100644 --- a/arch/arm/dts/socfpga_cyclone5_socdk.dts +++ b/arch/arm/dts/socfpga_cyclone5_socdk.dts @@ -71,9 +71,9 @@ rxd2-skew-ps = <0>; rxd3-skew-ps = <0>; txen-skew-ps = <0>; - txc-skew-ps = <2600>; + txc-skew-ps = <1560>; rxdv-skew-ps = <0>; - rxc-skew-ps = <2000>; + rxc-skew-ps = <1200>; }; &gpio0 { diff --git a/arch/arm/dts/socfpga_cyclone5_sockit.dts b/arch/arm/dts/socfpga_cyclone5_sockit.dts index c155ff02eb..90669cde45 100644 --- a/arch/arm/dts/socfpga_cyclone5_sockit.dts +++ b/arch/arm/dts/socfpga_cyclone5_sockit.dts @@ -128,9 +128,9 @@ rxd2-skew-ps = <0>; rxd3-skew-ps = <0>; txen-skew-ps = <0>; - txc-skew-ps = <2600>; + txc-skew-ps = <1560>; rxdv-skew-ps = <0>; - rxc-skew-ps = <2000>; + rxc-skew-ps = <1200>; }; &gpio0 { /* GPIO 0..29 */ diff --git a/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts b/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts index 355b3dbf43..ac57f41cb5 100644 --- a/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts +++ b/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts @@ -85,9 +85,9 @@ rxd2-skew-ps = <0>; rxd3-skew-ps = <0>; txen-skew-ps = <0>; - txc-skew-ps = <2600>; + txc-skew-ps = <1560>; rxdv-skew-ps = <0>; - rxc-skew-ps = <2000>; + rxc-skew-ps = <1200>; }; }; }; diff --git a/doc/device-tree-bindings/net/micrel-ksz90x1.txt b/doc/device-tree-bindings/net/micrel-ksz90x1.txt index 307f53f726..a214d35fc9 100644 --- a/doc/device-tree-bindings/net/micrel-ksz90x1.txt +++ b/doc/device-tree-bindings/net/micrel-ksz90x1.txt @@ -14,6 +14,33 @@ KSZ9021: value is 0, the maximum value is 1800, and it is incremented by 120ps steps. + The KSZ9021 hardware supports a range of skew values from negative to + positive, where the specific range is property dependent. All values + specified in the devicetree are offset by the minimum value so they + can be represented as positive integers in the devicetree since it's + difficult to represent a negative number in the devictree. + + The following 4-bit values table applies to all the skew properties: + + Pad Skew Value Delay (ps) Devicetree Value + ------------------------------------------------------ + 0000 -840ps 0 + 0001 -720ps 120 + 0010 -600ps 240 + 0011 -480ps 360 + 0100 -360ps 480 + 0101 -240ps 600 + 0110 -120ps 720 + 0111 0ps 840 + 1000 120ps 960 + 1001 240ps 1080 + 1010 360ps 1200 + 1011 480ps 1320 + 1100 600ps 1440 + 1101 720ps 1560 + 1110 840ps 1680 + 1111 960ps 1800 + Optional properties: - rxc-skew-ps : Skew control of RXC pad diff --git a/drivers/net/phy/micrel_ksz90x1.c b/drivers/net/phy/micrel_ksz90x1.c index 63e7b0242b..1f8d86ab2e 100644 --- a/drivers/net/phy/micrel_ksz90x1.c +++ b/drivers/net/phy/micrel_ksz90x1.c @@ -33,10 +33,14 @@ #define CTRL1000_CONFIG_MASTER (1 << 11) #define CTRL1000_MANUAL_CONFIG (1 << 12) +#define KSZ9021_PS_TO_REG 120 + /* KSZ9031 PHY Registers */ #define MII_KSZ9031_MMD_ACCES_CTRL 0x0d #define MII_KSZ9031_MMD_REG_DATA 0x0e +#define KSZ9031_PS_TO_REG 60 + static int ksz90xx_startup(struct phy_device *phydev) { unsigned phy_ctl; @@ -102,11 +106,11 @@ static const struct ksz90x1_reg_field ksz9031_clk_grp[] = { }; static int ksz90x1_of_config_group(struct phy_device *phydev, - struct ksz90x1_ofcfg *ofcfg) + struct ksz90x1_ofcfg *ofcfg, + int ps_to_regval) { struct udevice *dev = phydev->dev; struct phy_driver *drv = phydev->drv; - const int ps_to_regval = 60; int val[4]; int i, changed = 0, offset, max; u16 regval = 0; @@ -148,7 +152,8 @@ static int ksz9021_of_config(struct phy_device *phydev) int i, ret = 0; for (i = 0; i < ARRAY_SIZE(ofcfg); i++) { - ret = ksz90x1_of_config_group(phydev, &(ofcfg[i])); + ret = ksz90x1_of_config_group(phydev, &ofcfg[i], + KSZ9021_PS_TO_REG); if (ret) return ret; } @@ -167,7 +172,8 @@ static int ksz9031_of_config(struct phy_device *phydev) int i, ret = 0; for (i = 0; i < ARRAY_SIZE(ofcfg); i++) { - ret = ksz90x1_of_config_group(phydev, &(ofcfg[i])); + ret = ksz90x1_of_config_group(phydev, &ofcfg[i], + KSZ9031_PS_TO_REG); if (ret) return ret; } -- cgit v1.2.3 From 6314d1c8c035d1c4d14ea1ffd133f25385edd067 Mon Sep 17 00:00:00 2001 From: James Byrne Date: Mon, 4 Mar 2019 17:40:34 +0000 Subject: net: phy: micrel: Find Micrel PHY node correctly In some of the device trees that specify skew values for KSZ90x1 PHYs the values are stored (incorrectly) in the MAC node, whereas in others it is in an 'ethernet-phy' subnode. Previously the code would fail to find and program these skew values, so this commit changes it to look for an "ethernet-phy" subnode first, and revert to looking in the MAC node if there isn't one. The device trees affected (where the skew values are in a subnode) are imx6qdl-icore-rqs.dtsi, r8a77970-eagle.dts, r8a77990-ebisu.dts, r8a77995-draak.dts, salvator-common.dtsi, sama5d3xcm.dtsi, sama5d3xcm_cmp.dtsi, socfpga_cyclone5_vining_fpga.dts, socfpga_stratix10_socdk.dts and ulcb.dtsi. Before this change the skew values in these device trees would be ignored. The device trees where the skew values are in the MAC node are socfpga_arria10_socdk.dtsi, socfpga_arria5_socdk.dts, socfpga_cyclone5_de0_nano_soc.dts, socfpga_cyclone5_de10_nano.dts, socfpga_cyclone5_de1_soc.dts, socfpga_cyclone5_is1.dts, socfpga_cyclone5_socdk.dts, socfpga_cyclone5_sockit.dts. These should be unaffected by this change. The changes were tested on a sama5d3xcm. Signed-off-by: James Byrne Acked-by: Joe Hershberger --- drivers/net/phy/micrel_ksz90x1.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/micrel_ksz90x1.c b/drivers/net/phy/micrel_ksz90x1.c index 1f8d86ab2e..8dec9f2367 100644 --- a/drivers/net/phy/micrel_ksz90x1.c +++ b/drivers/net/phy/micrel_ksz90x1.c @@ -114,12 +114,20 @@ static int ksz90x1_of_config_group(struct phy_device *phydev, int val[4]; int i, changed = 0, offset, max; u16 regval = 0; + ofnode node; if (!drv || !drv->writeext) return -EOPNOTSUPP; + /* Look for a PHY node under the Ethernet node */ + node = dev_read_subnode(dev, "ethernet-phy"); + if (!ofnode_valid(node)) { + /* No node found, look in the Ethernet node */ + node = dev_ofnode(dev); + } + for (i = 0; i < ofcfg->grpsz; i++) { - val[i] = dev_read_u32_default(dev, ofcfg->grp[i].name, ~0); + val[i] = ofnode_read_u32_default(node, ofcfg->grp[i].name, ~0); offset = ofcfg->grp[i].off; if (val[i] == -1) { /* Default register value for KSZ9021 */ -- cgit v1.2.3