Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fba69f60 authored by Pali Rohár's avatar Pali Rohár Committed by Greg Kroah-Hartman
Browse files

net: phy: marvell: fix detection of PHY on Topaz switches



commit 1fe976d308acb6374c899a4ee8025a0a016e453e upstream.

Since commit fee2d546 ("net: phy: marvell: mv88e6390 temperature
sensor reading"), Linux reports the temperature of Topaz hwmon as
constant -75°C.

This is because switches from the Topaz family (88E6141 / 88E6341) have
the address of the temperature sensor register different from Peridot.

This address is instead compatible with 88E1510 PHYs, as was used for
Topaz before the above mentioned commit.

Create a new mapping table between switch family and PHY ID for families
which don't have a model number. And define PHY IDs for Topaz and Peridot
families.

Create a new PHY ID and a new PHY driver for Topaz's internal PHY.
The only difference from Peridot's PHY driver is the HWMON probing
method.

Prior this change Topaz's internal PHY is detected by kernel as:

  PHY [...] driver [Marvell 88E6390] (irq=63)

And afterwards as:

  PHY [...] driver [Marvell 88E6341 Family] (irq=63)

Signed-off-by: default avatarPali Rohár <pali@kernel.org>
BugLink: https://github.com/globalscaletechnologies/linux/issues/1


Fixes: fee2d546 ("net: phy: marvell: mv88e6390 temperature sensor reading")
Reviewed-by: default avatarMarek Behún <kabel@kernel.org>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c9167374
Loading
Loading
Loading
Loading
+13 −17
Original line number Diff line number Diff line
@@ -2634,10 +2634,17 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
	return err;
}

/* prod_id for switch families which do not have a PHY model number */
static const u16 family_prod_id_table[] = {
	[MV88E6XXX_FAMILY_6341] = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
	[MV88E6XXX_FAMILY_6390] = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
};

static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
{
	struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
	struct mv88e6xxx_chip *chip = mdio_bus->chip;
	u16 prod_id;
	u16 val;
	int err;

@@ -2648,23 +2655,12 @@ static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
	err = chip->info->ops->phy_read(chip, bus, phy, reg, &val);
	mutex_unlock(&chip->reg_lock);

	if (reg == MII_PHYSID2) {
	/* Some internal PHYs don't have a model number. */
		if (chip->info->family != MV88E6XXX_FAMILY_6165)
			/* Then there is the 6165 family. It gets is
			 * PHYs correct. But it can also have two
			 * SERDES interfaces in the PHY address
			 * space. And these don't have a model
			 * number. But they are not PHYs, so we don't
			 * want to give them something a PHY driver
			 * will recognise.
			 *
			 * Use the mv88e6390 family model number
			 * instead, for anything which really could be
			 * a PHY,
			 */
			if (!(val & 0x3f0))
				val |= MV88E6XXX_PORT_SWITCH_ID_PROD_6390 >> 4;
	if (reg == MII_PHYSID2 && !(val & 0x3f0) &&
	    chip->info->family < ARRAY_SIZE(family_prod_id_table)) {
		prod_id = family_prod_id_table[chip->info->family];
		if (prod_id)
			val |= prod_id >> 4;
	}

	return err ? err : val;
+25 −3
Original line number Diff line number Diff line
@@ -2329,9 +2329,30 @@ static struct phy_driver marvell_drivers[] = {
		.get_stats = marvell_get_stats,
	},
	{
		.phy_id = MARVELL_PHY_ID_88E6390,
		.phy_id = MARVELL_PHY_ID_88E6341_FAMILY,
		.phy_id_mask = MARVELL_PHY_ID_MASK,
		.name = "Marvell 88E6390",
		.name = "Marvell 88E6341 Family",
		.features = PHY_GBIT_FEATURES,
		.flags = PHY_HAS_INTERRUPT,
		.probe = m88e1510_probe,
		.config_init = &marvell_config_init,
		.config_aneg = &m88e6390_config_aneg,
		.read_status = &marvell_read_status,
		.ack_interrupt = &marvell_ack_interrupt,
		.config_intr = &marvell_config_intr,
		.did_interrupt = &m88e1121_did_interrupt,
		.resume = &genphy_resume,
		.suspend = &genphy_suspend,
		.read_page = marvell_read_page,
		.write_page = marvell_write_page,
		.get_sset_count = marvell_get_sset_count,
		.get_strings = marvell_get_strings,
		.get_stats = marvell_get_stats,
	},
	{
		.phy_id = MARVELL_PHY_ID_88E6390_FAMILY,
		.phy_id_mask = MARVELL_PHY_ID_MASK,
		.name = "Marvell 88E6390 Family",
		.features = PHY_GBIT_FEATURES,
		.flags = PHY_HAS_INTERRUPT,
		.probe = m88e6390_probe,
@@ -2368,7 +2389,8 @@ static struct mdio_device_id __maybe_unused marvell_tbl[] = {
	{ MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK },
	{ MARVELL_PHY_ID_88E1545, MARVELL_PHY_ID_MASK },
	{ MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK },
	{ MARVELL_PHY_ID_88E6390, MARVELL_PHY_ID_MASK },
	{ MARVELL_PHY_ID_88E6341_FAMILY, MARVELL_PHY_ID_MASK },
	{ MARVELL_PHY_ID_88E6390_FAMILY, MARVELL_PHY_ID_MASK },
	{ }
};

+3 −2
Original line number Diff line number Diff line
@@ -21,11 +21,12 @@
#define MARVELL_PHY_ID_88E1545		0x01410ea0
#define MARVELL_PHY_ID_88E3016		0x01410e60

/* The MV88e6390 Ethernet switch contains embedded PHYs. These PHYs do
/* These Ethernet switch families contain embedded PHYs, but they do
 * not have a model ID. So the switch driver traps reads to the ID2
 * register and returns the switch family ID
 */
#define MARVELL_PHY_ID_88E6390		0x01410f90
#define MARVELL_PHY_ID_88E6341_FAMILY	0x01410f41
#define MARVELL_PHY_ID_88E6390_FAMILY	0x01410f90

#define MARVELL_PHY_FAMILY_ID(id)	((id) >> 4)