41
41
#define AT803X_SS_SPEED_DUPLEX_RESOLVED BIT(11)
42
42
#define AT803X_SS_MDIX BIT(6)
43
43
44
+ #define QCA808X_SS_SPEED_MASK GENMASK(9, 7)
45
+ #define QCA808X_SS_SPEED_2500 4
46
+
44
47
#define AT803X_INTR_ENABLE 0x12
45
48
#define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15)
46
49
#define AT803X_INTR_ENABLE_SPEED_CHANGED BIT(14)
@@ -959,27 +962,9 @@ static void at803x_link_change_notify(struct phy_device *phydev)
959
962
}
960
963
}
961
964
962
- static int at803x_read_status (struct phy_device * phydev )
965
+ static int at803x_read_specific_status (struct phy_device * phydev )
963
966
{
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 ;
983
968
984
969
/* Read the AT8035 PHY-Specific Status register, which indicates the
985
970
* speed and duplex that the PHY is actually using, irrespective of
@@ -990,13 +975,19 @@ static int at803x_read_status(struct phy_device *phydev)
990
975
return ss ;
991
976
992
977
if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED ) {
993
- int sfc ;
978
+ int sfc , speed ;
994
979
995
980
sfc = phy_read (phydev , AT803X_SPECIFIC_FUNCTION_CONTROL );
996
981
if (sfc < 0 )
997
982
return sfc ;
998
983
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 ) {
1000
991
case AT803X_SS_SPEED_10 :
1001
992
phydev -> speed = SPEED_10 ;
1002
993
break ;
@@ -1006,6 +997,9 @@ static int at803x_read_status(struct phy_device *phydev)
1006
997
case AT803X_SS_SPEED_1000 :
1007
998
phydev -> speed = SPEED_1000 ;
1008
999
break ;
1000
+ case QCA808X_SS_SPEED_2500 :
1001
+ phydev -> speed = SPEED_2500 ;
1002
+ break ;
1009
1003
}
1010
1004
if (ss & AT803X_SS_DUPLEX )
1011
1005
phydev -> duplex = DUPLEX_FULL ;
@@ -1030,6 +1024,35 @@ static int at803x_read_status(struct phy_device *phydev)
1030
1024
}
1031
1025
}
1032
1026
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
+
1033
1056
if (phydev -> autoneg == AUTONEG_ENABLE && phydev -> autoneg_complete )
1034
1057
phy_resolve_aneg_pause (phydev );
1035
1058
@@ -1434,6 +1457,33 @@ static int qca83xx_suspend(struct phy_device *phydev)
1434
1457
return 0 ;
1435
1458
}
1436
1459
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
+
1437
1487
static struct phy_driver at803x_driver [] = {
1438
1488
{
1439
1489
/* Qualcomm Atheros AR8035 */
@@ -1605,6 +1655,7 @@ static struct phy_driver at803x_driver[] = {
1605
1655
.get_wol = at803x_get_wol ,
1606
1656
.suspend = genphy_suspend ,
1607
1657
.resume = genphy_resume ,
1658
+ .read_status = qca808x_read_status ,
1608
1659
}, };
1609
1660
1610
1661
module_phy_driver (at803x_driver );
0 commit comments