net: phy: realtek: implement configuring in-band an
Implement the inband_caps() and config_inband() PHY driver methods to allow configuring the use of in-band-status with SGMII and 2500Base-X on RTL8226 and RTL8221B 2.5GE PHYs. Signed-off-by: Daniel Golle <daniel@makrotopia.org> Link: https://patch.msgid.link/82a78a06d67be19e856d646cf880b2021ea9d837.1767630451.git.daniel@makrotopia.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
50326b48f0
commit
10fbd71fc5
|
|
@ -131,6 +131,15 @@
|
|||
#define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII 0x02
|
||||
#define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX 0x16
|
||||
|
||||
#define RTL822X_VND1_SERDES_CMD 0x7587
|
||||
#define RTL822X_VND1_SERDES_CMD_WRITE BIT(1)
|
||||
#define RTL822X_VND1_SERDES_CMD_BUSY BIT(0)
|
||||
#define RTL822X_VND1_SERDES_ADDR 0x7588
|
||||
#define RTL822X_VND1_SERDES_ADDR_AUTONEG 0x2
|
||||
#define RTL822X_VND1_SERDES_INBAND_DISABLE 0x71d0
|
||||
#define RTL822X_VND1_SERDES_INBAND_ENABLE 0x70d0
|
||||
#define RTL822X_VND1_SERDES_DATA 0x7589
|
||||
|
||||
/* RTL822X_VND2_XXXXX registers are only accessible when phydev->is_c45
|
||||
* is set, they cannot be accessed by C45-over-C22.
|
||||
*/
|
||||
|
|
@ -1308,6 +1317,50 @@ static int rtl822xb_config_init(struct phy_device *phydev)
|
|||
return rtl822x_set_serdes_option_mode(phydev, false);
|
||||
}
|
||||
|
||||
static int rtl822x_serdes_write(struct phy_device *phydev, u16 reg, u16 val)
|
||||
{
|
||||
int ret, poll;
|
||||
|
||||
ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_ADDR, reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_DATA, val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_CMD,
|
||||
RTL822X_VND1_SERDES_CMD_WRITE |
|
||||
RTL822X_VND1_SERDES_CMD_BUSY);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
|
||||
RTL822X_VND1_SERDES_CMD, poll,
|
||||
!(poll & RTL822X_VND1_SERDES_CMD_BUSY),
|
||||
500, 100000, false);
|
||||
}
|
||||
|
||||
static int rtl822x_config_inband(struct phy_device *phydev, unsigned int modes)
|
||||
{
|
||||
return rtl822x_serdes_write(phydev, RTL822X_VND1_SERDES_ADDR_AUTONEG,
|
||||
(modes != LINK_INBAND_DISABLE) ?
|
||||
RTL822X_VND1_SERDES_INBAND_ENABLE :
|
||||
RTL822X_VND1_SERDES_INBAND_DISABLE);
|
||||
}
|
||||
|
||||
static unsigned int rtl822x_inband_caps(struct phy_device *phydev,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
switch (interface) {
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int rtl822xb_get_rate_matching(struct phy_device *phydev,
|
||||
phy_interface_t iface)
|
||||
{
|
||||
|
|
@ -2103,6 +2156,8 @@ static struct phy_driver realtek_drvs[] = {
|
|||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.inband_caps = rtl822x_inband_caps,
|
||||
.config_inband = rtl822x_config_inband,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.read_status = rtl822xb_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
|
|
@ -2116,6 +2171,8 @@ static struct phy_driver realtek_drvs[] = {
|
|||
.get_features = rtl822x_c45_get_features,
|
||||
.config_aneg = rtl822x_c45_config_aneg,
|
||||
.config_init = rtl822x_config_init,
|
||||
.inband_caps = rtl822x_inband_caps,
|
||||
.config_inband = rtl822x_config_inband,
|
||||
.read_status = rtl822xb_c45_read_status,
|
||||
.suspend = genphy_c45_pma_suspend,
|
||||
.resume = rtlgen_c45_resume,
|
||||
|
|
@ -2125,6 +2182,8 @@ static struct phy_driver realtek_drvs[] = {
|
|||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.inband_caps = rtl822x_inband_caps,
|
||||
.config_inband = rtl822x_config_inband,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.read_status = rtl822xb_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
|
|
@ -2138,6 +2197,8 @@ static struct phy_driver realtek_drvs[] = {
|
|||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.inband_caps = rtl822x_inband_caps,
|
||||
.config_inband = rtl822x_config_inband,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.read_status = rtl822xb_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
|
|
@ -2151,6 +2212,8 @@ static struct phy_driver realtek_drvs[] = {
|
|||
.handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.probe = rtl822x_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.inband_caps = rtl822x_inband_caps,
|
||||
.config_inband = rtl822x_config_inband,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
.config_aneg = rtl822x_c45_config_aneg,
|
||||
|
|
@ -2164,6 +2227,8 @@ static struct phy_driver realtek_drvs[] = {
|
|||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.inband_caps = rtl822x_inband_caps,
|
||||
.config_inband = rtl822x_config_inband,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.read_status = rtl822xb_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
|
|
@ -2177,6 +2242,8 @@ static struct phy_driver realtek_drvs[] = {
|
|||
.handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.probe = rtl822x_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.inband_caps = rtl822x_inband_caps,
|
||||
.config_inband = rtl822x_config_inband,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
.config_aneg = rtl822x_c45_config_aneg,
|
||||
|
|
|
|||
Loading…
Reference in New Issue