net: phy: tja11xx: add support for master-slave configuration
The TJA11xx PHYs have a vendor specific Master/Slave configuration bit, which is not compatible with IEEE 803.2-2018 spec for 100Base-T1 devices. So, provide a custom config_ange call back to solve this problem. Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
bdbdac7649
commit
b883e47bde
@ -30,6 +30,7 @@
|
||||
#define MII_ECTRL_WAKE_REQUEST BIT(0)
|
||||
|
||||
#define MII_CFG1 18
|
||||
#define MII_CFG1_MASTER_SLAVE BIT(15)
|
||||
#define MII_CFG1_AUTO_OP BIT(14)
|
||||
#define MII_CFG1_SLEEP_CONFIRM BIT(6)
|
||||
#define MII_CFG1_LED_MODE_MASK GENMASK(5, 4)
|
||||
@ -167,6 +168,32 @@ static int tja11xx_soft_reset(struct phy_device *phydev)
|
||||
return genphy_soft_reset(phydev);
|
||||
}
|
||||
|
||||
static int tja11xx_config_aneg(struct phy_device *phydev)
|
||||
{
|
||||
u16 ctl = 0;
|
||||
int ret;
|
||||
|
||||
switch (phydev->master_slave_set) {
|
||||
case MASTER_SLAVE_CFG_MASTER_FORCE:
|
||||
ctl |= MII_CFG1_MASTER_SLAVE;
|
||||
break;
|
||||
case MASTER_SLAVE_CFG_SLAVE_FORCE:
|
||||
break;
|
||||
case MASTER_SLAVE_CFG_UNKNOWN:
|
||||
case MASTER_SLAVE_CFG_UNSUPPORTED:
|
||||
return 0;
|
||||
default:
|
||||
phydev_warn(phydev, "Unsupported Master/Slave mode\n");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
ret = phy_modify_changed(phydev, MII_CFG1, MII_CFG1_MASTER_SLAVE, ctl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return __genphy_config_aneg(phydev, ret);
|
||||
}
|
||||
|
||||
static int tja11xx_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
@ -224,10 +251,22 @@ static int tja11xx_read_status(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
|
||||
phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED;
|
||||
|
||||
ret = genphy_update_link(phydev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = phy_read(phydev, MII_CFG1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ret & MII_CFG1_MASTER_SLAVE)
|
||||
phydev->master_slave_get = MASTER_SLAVE_CFG_MASTER_FORCE;
|
||||
else
|
||||
phydev->master_slave_get = MASTER_SLAVE_CFG_SLAVE_FORCE;
|
||||
|
||||
if (phydev->link) {
|
||||
ret = phy_read(phydev, MII_COMMSTAT);
|
||||
if (ret < 0)
|
||||
@ -504,6 +543,7 @@ static struct phy_driver tja11xx_driver[] = {
|
||||
.features = PHY_BASIC_T1_FEATURES,
|
||||
.probe = tja11xx_probe,
|
||||
.soft_reset = tja11xx_soft_reset,
|
||||
.config_aneg = tja11xx_config_aneg,
|
||||
.config_init = tja11xx_config_init,
|
||||
.read_status = tja11xx_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
@ -519,6 +559,7 @@ static struct phy_driver tja11xx_driver[] = {
|
||||
.features = PHY_BASIC_T1_FEATURES,
|
||||
.probe = tja11xx_probe,
|
||||
.soft_reset = tja11xx_soft_reset,
|
||||
.config_aneg = tja11xx_config_aneg,
|
||||
.config_init = tja11xx_config_init,
|
||||
.read_status = tja11xx_read_status,
|
||||
.suspend = genphy_suspend,
|
||||
@ -533,6 +574,7 @@ static struct phy_driver tja11xx_driver[] = {
|
||||
.features = PHY_BASIC_T1_FEATURES,
|
||||
.probe = tja1102_p0_probe,
|
||||
.soft_reset = tja11xx_soft_reset,
|
||||
.config_aneg = tja11xx_config_aneg,
|
||||
.config_init = tja11xx_config_init,
|
||||
.read_status = tja11xx_read_status,
|
||||
.match_phy_device = tja1102_p0_match_phy_device,
|
||||
@ -551,6 +593,7 @@ static struct phy_driver tja11xx_driver[] = {
|
||||
.features = PHY_BASIC_T1_FEATURES,
|
||||
/* currently no probe for Port 1 is need */
|
||||
.soft_reset = tja11xx_soft_reset,
|
||||
.config_aneg = tja11xx_config_aneg,
|
||||
.config_init = tja11xx_config_init,
|
||||
.read_status = tja11xx_read_status,
|
||||
.match_phy_device = tja1102_p1_match_phy_device,
|
||||
|
Loading…
Reference in New Issue
Block a user