Skip to content

Commit 26dd297

Browse files
robhancocksedkuba-moo
authored andcommitted
net: phy: micrel: Move KSZ9477 errata fixes to PHY driver
The ksz9477 DSA switch driver is currently updating some MMD registers on the internal port PHYs to address some chip errata. However, these errata are really a property of the PHY itself, not the switch they are part of, so this is kind of a layering violation. It makes more sense for these writes to be done inside the driver which binds to the PHY and not the driver for the containing device. This also addresses some issues where the ordering of when these writes are done may have been incorrect, causing the link to erratically fail to come up at the proper speed or at all. Doing this in the PHY driver during config_init ensures that they happen before anything else tries to change the state of the PHY on the port. The new code also ensures that autonegotiation is disabled during the register writes and re-enabled afterwards, as indicated by the latest version of the errata documentation from Microchip. Signed-off-by: Robert Hancock <[email protected]> Reviewed-by: Andrew Lunn <[email protected]> Reviewed-by: Florian Fainelli <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 2dc4764 commit 26dd297

File tree

1 file changed

+74
-1
lines changed

1 file changed

+74
-1
lines changed

drivers/net/phy/micrel.c

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1774,6 +1774,79 @@ static int ksz886x_read_status(struct phy_device *phydev)
17741774
return genphy_read_status(phydev);
17751775
}
17761776

1777+
struct ksz9477_errata_write {
1778+
u8 dev_addr;
1779+
u8 reg_addr;
1780+
u16 val;
1781+
};
1782+
1783+
static const struct ksz9477_errata_write ksz9477_errata_writes[] = {
1784+
/* Register settings are needed to improve PHY receive performance */
1785+
{0x01, 0x6f, 0xdd0b},
1786+
{0x01, 0x8f, 0x6032},
1787+
{0x01, 0x9d, 0x248c},
1788+
{0x01, 0x75, 0x0060},
1789+
{0x01, 0xd3, 0x7777},
1790+
{0x1c, 0x06, 0x3008},
1791+
{0x1c, 0x08, 0x2000},
1792+
1793+
/* Transmit waveform amplitude can be improved (1000BASE-T, 100BASE-TX, 10BASE-Te) */
1794+
{0x1c, 0x04, 0x00d0},
1795+
1796+
/* Energy Efficient Ethernet (EEE) feature select must be manually disabled */
1797+
{0x07, 0x3c, 0x0000},
1798+
1799+
/* Register settings are required to meet data sheet supply current specifications */
1800+
{0x1c, 0x13, 0x6eff},
1801+
{0x1c, 0x14, 0xe6ff},
1802+
{0x1c, 0x15, 0x6eff},
1803+
{0x1c, 0x16, 0xe6ff},
1804+
{0x1c, 0x17, 0x00ff},
1805+
{0x1c, 0x18, 0x43ff},
1806+
{0x1c, 0x19, 0xc3ff},
1807+
{0x1c, 0x1a, 0x6fff},
1808+
{0x1c, 0x1b, 0x07ff},
1809+
{0x1c, 0x1c, 0x0fff},
1810+
{0x1c, 0x1d, 0xe7ff},
1811+
{0x1c, 0x1e, 0xefff},
1812+
{0x1c, 0x20, 0xeeee},
1813+
};
1814+
1815+
static int ksz9477_config_init(struct phy_device *phydev)
1816+
{
1817+
int err;
1818+
int i;
1819+
1820+
/* Apply PHY settings to address errata listed in
1821+
* KSZ9477, KSZ9897, KSZ9896, KSZ9567, KSZ8565
1822+
* Silicon Errata and Data Sheet Clarification documents.
1823+
*
1824+
* Document notes: Before configuring the PHY MMD registers, it is
1825+
* necessary to set the PHY to 100 Mbps speed with auto-negotiation
1826+
* disabled by writing to register 0xN100-0xN101. After writing the
1827+
* MMD registers, and after all errata workarounds that involve PHY
1828+
* register settings, write register 0xN100-0xN101 again to enable
1829+
* and restart auto-negotiation.
1830+
*/
1831+
err = phy_write(phydev, MII_BMCR, BMCR_SPEED100 | BMCR_FULLDPLX);
1832+
if (err)
1833+
return err;
1834+
1835+
for (i = 0; i < ARRAY_SIZE(ksz9477_errata_writes); ++i) {
1836+
const struct ksz9477_errata_write *errata = &ksz9477_errata_writes[i];
1837+
1838+
err = phy_write_mmd(phydev, errata->dev_addr, errata->reg_addr, errata->val);
1839+
if (err)
1840+
return err;
1841+
}
1842+
1843+
err = genphy_restart_aneg(phydev);
1844+
if (err)
1845+
return err;
1846+
1847+
return kszphy_config_init(phydev);
1848+
}
1849+
17771850
static int kszphy_get_sset_count(struct phy_device *phydev)
17781851
{
17791852
return ARRAY_SIZE(kszphy_hw_stats);
@@ -4735,7 +4808,7 @@ static struct phy_driver ksphy_driver[] = {
47354808
.phy_id_mask = MICREL_PHY_ID_MASK,
47364809
.name = "Microchip KSZ9477",
47374810
/* PHY_GBIT_FEATURES */
4738-
.config_init = kszphy_config_init,
4811+
.config_init = ksz9477_config_init,
47394812
.config_intr = kszphy_config_intr,
47404813
.handle_interrupt = kszphy_handle_interrupt,
47414814
.suspend = genphy_suspend,

0 commit comments

Comments
 (0)