diff options
Diffstat (limited to 'drivers/net/phy/realtek.c')
-rw-r--r-- | drivers/net/phy/realtek.c | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 4ae050128c..c23947b7cb 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * drivers/net/phy/realtek.c * @@ -6,12 +7,6 @@ * Author: Johnson Leung <r58129@freescale.com> * * Copyright (c) 2004 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #include <common.h> #include <init.h> @@ -34,6 +29,7 @@ #define RTL8211F_INSR 0x1d #define RTL8211F_TX_DELAY BIT(8) +#define RTL8211F_RX_DELAY BIT(3) #define RTL8201F_ISR 0x1e #define RTL8201F_IER 0x13 @@ -84,19 +80,50 @@ static int rtl8211c_config_init(struct phy_device *phydev) static int rtl8211f_config_init(struct phy_device *phydev) { + struct device *dev = &phydev->dev; + u16 val_txdly, val_rxdly; int ret; - u16 val = 0; - ret = genphy_config_init(phydev); - if (ret < 0) + switch (phydev->interface) { + case PHY_INTERFACE_MODE_RGMII: + val_txdly = 0; + val_rxdly = 0; + break; + + case PHY_INTERFACE_MODE_RGMII_RXID: + val_txdly = 0; + val_rxdly = RTL8211F_RX_DELAY; + break; + + case PHY_INTERFACE_MODE_RGMII_TXID: + val_txdly = RTL8211F_TX_DELAY; + val_rxdly = 0; + break; + + case PHY_INTERFACE_MODE_RGMII_ID: + val_txdly = RTL8211F_TX_DELAY; + val_rxdly = RTL8211F_RX_DELAY; + break; + + default: /* the rest of the modes imply leaving delay as is. */ + return 0; + } + + ret = phy_modify_paged(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY, + val_txdly); + if (ret < 0) { + dev_err(dev, "Failed to update the TX delay register\n"); return ret; + } - /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */ - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || - phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) - val = RTL8211F_TX_DELAY; + ret = phy_modify_paged(phydev, 0xd08, 0x15, RTL8211F_RX_DELAY, + val_rxdly); + if (ret < 0) { + dev_err(dev, "Failed to update the RX delay register\n"); + return ret; + } - return phy_modify_paged(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY, val); + return 0; } static int rtl8366rb_config_init(struct phy_device *phydev) @@ -128,6 +155,12 @@ static struct phy_driver realtek_drvs[] = { .read_page = rtl821x_read_page, .write_page = rtl821x_write_page, }, { + PHY_ID_MATCH_EXACT(0x001cc840), + .drv.name = "RTL8226B_RTL8221B 2.5Gbps PHY", + .features = PHY_GBIT_FEATURES, + .read_page = rtl821x_read_page, + .write_page = rtl821x_write_page, + }, { PHY_ID_MATCH_EXACT(0x001cc910), .drv.name = "RTL8211 Gigabit Ethernet", .features = PHY_GBIT_FEATURES, @@ -164,9 +197,4 @@ static struct phy_driver realtek_drvs[] = { }, }; -static int __init realtek_phy_init(void) -{ - return phy_drivers_register(realtek_drvs, - ARRAY_SIZE(realtek_drvs)); -} -fs_initcall(realtek_phy_init); +device_phy_drivers(realtek_drvs); |