Skip to content

Commit 79c7bc0

Browse files
Luo Jiedavem330
authored andcommitted
net: phy: add qca8081 read_status
1. Separate the function at803x_read_specific_status from the at803x_read_status, since it can be reused by the read_status of qca8081 phy driver excepting adding the 2500M speed. 2. Add the qca8081 read_status function qca808x_read_status. Signed-off-by: Luo Jie <luoj@codeaurora.org> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent daf6173 commit 79c7bc0

File tree

1 file changed

+73
-22
lines changed

1 file changed

+73
-22
lines changed

drivers/net/phy/at803x.c

Lines changed: 73 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
#define AT803X_SS_SPEED_DUPLEX_RESOLVED BIT(11)
4242
#define AT803X_SS_MDIX BIT(6)
4343

44+
#define QCA808X_SS_SPEED_MASK GENMASK(9, 7)
45+
#define QCA808X_SS_SPEED_2500 4
46+
4447
#define AT803X_INTR_ENABLE 0x12
4548
#define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15)
4649
#define AT803X_INTR_ENABLE_SPEED_CHANGED BIT(14)
@@ -959,27 +962,9 @@ static void at803x_link_change_notify(struct phy_device *phydev)
959962
}
960963
}
961964

962-
static int at803x_read_status(struct phy_device *phydev)
965+
static int at803x_read_specific_status(struct phy_device *phydev)
963966
{
964-
int ss, err, old_link = phydev->link;
965-
966-
/* Update the link, but return if there was an error */
967-
err = genphy_update_link(phydev);
968-
if (err)
969-
return err;
970-
971-
/* why bother the PHY if nothing can have changed */
972-
if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
973-
return 0;
974-
975-
phydev->speed = SPEED_UNKNOWN;
976-
phydev->duplex = DUPLEX_UNKNOWN;
977-
phydev->pause = 0;
978-
phydev->asym_pause = 0;
979-
980-
err = genphy_read_lpa(phydev);
981-
if (err < 0)
982-
return err;
967+
int ss;
983968

984969
/* Read the AT8035 PHY-Specific Status register, which indicates the
985970
* speed and duplex that the PHY is actually using, irrespective of
@@ -990,13 +975,19 @@ static int at803x_read_status(struct phy_device *phydev)
990975
return ss;
991976

992977
if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) {
993-
int sfc;
978+
int sfc, speed;
994979

995980
sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL);
996981
if (sfc < 0)
997982
return sfc;
998983

999-
switch (FIELD_GET(AT803X_SS_SPEED_MASK, ss)) {
984+
/* qca8081 takes the different bits for speed value from at803x */
985+
if (phydev->drv->phy_id == QCA8081_PHY_ID)
986+
speed = FIELD_GET(QCA808X_SS_SPEED_MASK, ss);
987+
else
988+
speed = FIELD_GET(AT803X_SS_SPEED_MASK, ss);
989+
990+
switch (speed) {
1000991
case AT803X_SS_SPEED_10:
1001992
phydev->speed = SPEED_10;
1002993
break;
@@ -1006,6 +997,9 @@ static int at803x_read_status(struct phy_device *phydev)
1006997
case AT803X_SS_SPEED_1000:
1007998
phydev->speed = SPEED_1000;
1008999
break;
1000+
case QCA808X_SS_SPEED_2500:
1001+
phydev->speed = SPEED_2500;
1002+
break;
10091003
}
10101004
if (ss & AT803X_SS_DUPLEX)
10111005
phydev->duplex = DUPLEX_FULL;
@@ -1030,6 +1024,35 @@ static int at803x_read_status(struct phy_device *phydev)
10301024
}
10311025
}
10321026

1027+
return 0;
1028+
}
1029+
1030+
static int at803x_read_status(struct phy_device *phydev)
1031+
{
1032+
int err, old_link = phydev->link;
1033+
1034+
/* Update the link, but return if there was an error */
1035+
err = genphy_update_link(phydev);
1036+
if (err)
1037+
return err;
1038+
1039+
/* why bother the PHY if nothing can have changed */
1040+
if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
1041+
return 0;
1042+
1043+
phydev->speed = SPEED_UNKNOWN;
1044+
phydev->duplex = DUPLEX_UNKNOWN;
1045+
phydev->pause = 0;
1046+
phydev->asym_pause = 0;
1047+
1048+
err = genphy_read_lpa(phydev);
1049+
if (err < 0)
1050+
return err;
1051+
1052+
err = at803x_read_specific_status(phydev);
1053+
if (err < 0)
1054+
return err;
1055+
10331056
if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
10341057
phy_resolve_aneg_pause(phydev);
10351058

@@ -1434,6 +1457,33 @@ static int qca83xx_suspend(struct phy_device *phydev)
14341457
return 0;
14351458
}
14361459

1460+
static int qca808x_read_status(struct phy_device *phydev)
1461+
{
1462+
int ret;
1463+
1464+
ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
1465+
if (ret < 0)
1466+
return ret;
1467+
1468+
linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising,
1469+
ret & MDIO_AN_10GBT_STAT_LP2_5G);
1470+
1471+
ret = genphy_read_status(phydev);
1472+
if (ret)
1473+
return ret;
1474+
1475+
ret = at803x_read_specific_status(phydev);
1476+
if (ret < 0)
1477+
return ret;
1478+
1479+
if (phydev->link && phydev->speed == SPEED_2500)
1480+
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
1481+
else
1482+
phydev->interface = PHY_INTERFACE_MODE_SMII;
1483+
1484+
return 0;
1485+
}
1486+
14371487
static struct phy_driver at803x_driver[] = {
14381488
{
14391489
/* Qualcomm Atheros AR8035 */
@@ -1605,6 +1655,7 @@ static struct phy_driver at803x_driver[] = {
16051655
.get_wol = at803x_get_wol,
16061656
.suspend = genphy_suspend,
16071657
.resume = genphy_resume,
1658+
.read_status = qca808x_read_status,
16081659
}, };
16091660

16101661
module_phy_driver(at803x_driver);

0 commit comments

Comments
 (0)