Skip to content

Commit a5de4be

Browse files
elkablodavem330
authored andcommitted
net: phy: marvell10g: fix differentiation of 88X3310 from 88X3340
It seems that we cannot differentiate 88X3310 from 88X3340 by simply looking at bit 3 of revision ID. This only works on revisions A0 and A1. On revision B0, this bit is always 1. Instead use the 3.d00d register for differentiation, since this register contains information about number of ports on the device. Fixes: 9885d01 ("net: phy: marvell10g: add separate structure for 88X3340") Signed-off-by: Marek Behún <[email protected]> Reported-by: Matteo Croce <[email protected]> Tested-by: Matteo Croce <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 84f7e0b commit a5de4be

File tree

2 files changed

+36
-10
lines changed

2 files changed

+36
-10
lines changed

drivers/net/phy/marvell10g.c

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ enum {
7878
/* Temperature read register (88E2110 only) */
7979
MV_PCS_TEMP = 0x8042,
8080

81+
/* Number of ports on the device */
82+
MV_PCS_PORT_INFO = 0xd00d,
83+
MV_PCS_PORT_INFO_NPORTS_MASK = 0x0380,
84+
MV_PCS_PORT_INFO_NPORTS_SHIFT = 7,
85+
8186
/* These registers appear at 0x800X and 0xa00X - the 0xa00X control
8287
* registers appear to set themselves to the 0x800X when AN is
8388
* restarted, but status registers appear readable from either.
@@ -966,6 +971,30 @@ static const struct mv3310_chip mv2111_type = {
966971
#endif
967972
};
968973

974+
static int mv3310_get_number_of_ports(struct phy_device *phydev)
975+
{
976+
int ret;
977+
978+
ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_PORT_INFO);
979+
if (ret < 0)
980+
return ret;
981+
982+
ret &= MV_PCS_PORT_INFO_NPORTS_MASK;
983+
ret >>= MV_PCS_PORT_INFO_NPORTS_SHIFT;
984+
985+
return ret + 1;
986+
}
987+
988+
static int mv3310_match_phy_device(struct phy_device *phydev)
989+
{
990+
return mv3310_get_number_of_ports(phydev) == 1;
991+
}
992+
993+
static int mv3340_match_phy_device(struct phy_device *phydev)
994+
{
995+
return mv3310_get_number_of_ports(phydev) == 4;
996+
}
997+
969998
static int mv211x_match_phy_device(struct phy_device *phydev, bool has_5g)
970999
{
9711000
int val;
@@ -994,7 +1023,8 @@ static int mv2111_match_phy_device(struct phy_device *phydev)
9941023
static struct phy_driver mv3310_drivers[] = {
9951024
{
9961025
.phy_id = MARVELL_PHY_ID_88X3310,
997-
.phy_id_mask = MARVELL_PHY_ID_88X33X0_MASK,
1026+
.phy_id_mask = MARVELL_PHY_ID_MASK,
1027+
.match_phy_device = mv3310_match_phy_device,
9981028
.name = "mv88x3310",
9991029
.driver_data = &mv3310_type,
10001030
.get_features = mv3310_get_features,
@@ -1011,8 +1041,9 @@ static struct phy_driver mv3310_drivers[] = {
10111041
.set_loopback = genphy_c45_loopback,
10121042
},
10131043
{
1014-
.phy_id = MARVELL_PHY_ID_88X3340,
1015-
.phy_id_mask = MARVELL_PHY_ID_88X33X0_MASK,
1044+
.phy_id = MARVELL_PHY_ID_88X3310,
1045+
.phy_id_mask = MARVELL_PHY_ID_MASK,
1046+
.match_phy_device = mv3340_match_phy_device,
10161047
.name = "mv88x3340",
10171048
.driver_data = &mv3340_type,
10181049
.get_features = mv3310_get_features,
@@ -1069,8 +1100,7 @@ static struct phy_driver mv3310_drivers[] = {
10691100
module_phy_driver(mv3310_drivers);
10701101

10711102
static struct mdio_device_id __maybe_unused mv3310_tbl[] = {
1072-
{ MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_88X33X0_MASK },
1073-
{ MARVELL_PHY_ID_88X3340, MARVELL_PHY_ID_88X33X0_MASK },
1103+
{ MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK },
10741104
{ MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK },
10751105
{ },
10761106
};

include/linux/marvell_phy.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,10 @@
2222
#define MARVELL_PHY_ID_88E1545 0x01410ea0
2323
#define MARVELL_PHY_ID_88E1548P 0x01410ec0
2424
#define MARVELL_PHY_ID_88E3016 0x01410e60
25+
#define MARVELL_PHY_ID_88X3310 0x002b09a0
2526
#define MARVELL_PHY_ID_88E2110 0x002b09b0
2627
#define MARVELL_PHY_ID_88X2222 0x01410f10
2728

28-
/* PHY IDs and mask for Alaska 10G PHYs */
29-
#define MARVELL_PHY_ID_88X33X0_MASK 0xfffffff8
30-
#define MARVELL_PHY_ID_88X3310 0x002b09a0
31-
#define MARVELL_PHY_ID_88X3340 0x002b09a8
32-
3329
/* Marvel 88E1111 in Finisar SFP module with modified PHY ID */
3430
#define MARVELL_PHY_ID_88E1111_FINISAR 0x01ff0cc0
3531

0 commit comments

Comments
 (0)