summaryrefslogtreecommitdiff
path: root/drivers/net/phy/microchip.c
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2023-04-19 20:38:10 +0200
committerMiquel Raynal <miquel.raynal@bootlin.com>2023-04-19 20:38:20 +0200
commit38f1aa5566730cdc5e09ec982c80489d87f0f0a7 (patch)
tree853cc489bbb113b86c0cf22dd4277d0b7fd9e59a /drivers/net/phy/microchip.c
parente6026eb080fa1c1ef6eec24567b733809a5e3018 (diff)
parentdf6def86b9dcbc3e8ed4964c7b79b70c9b0c3040 (diff)
Merge tag 'spi-nor/for-6.4' into mtd/next
SPI NOR core changes: * introduce Read While Write support for flashes featuring several banks * set the 4-Byte Address Mode method based on SFDP data * allow post_sfdp hook to return errors * parse SCCR MC table and introduce support for multi-chip devices SPI NOR manufacturer drivers changes: * macronix: add support for mx25uw51245g with RWW * spansion: - determine current address mode at runtime as it can be changed in a non-volatile way and differ from factory defaults or from what SFDP advertises. - enable JFFS2 write buffer mode for few ECC'd NOR flashes: S25FS256T, s25hx and s28hx - add support for s25hl02gt and s25hs02gt Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Diffstat (limited to 'drivers/net/phy/microchip.c')
-rw-r--r--drivers/net/phy/microchip.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c
index ccecee2524ce..0b88635f4fbc 100644
--- a/drivers/net/phy/microchip.c
+++ b/drivers/net/phy/microchip.c
@@ -342,6 +342,37 @@ static int lan88xx_config_aneg(struct phy_device *phydev)
return genphy_config_aneg(phydev);
}
+static void lan88xx_link_change_notify(struct phy_device *phydev)
+{
+ int temp;
+
+ /* At forced 100 F/H mode, chip may fail to set mode correctly
+ * when cable is switched between long(~50+m) and short one.
+ * As workaround, set to 10 before setting to 100
+ * at forced 100 F/H mode.
+ */
+ if (!phydev->autoneg && phydev->speed == 100) {
+ /* disable phy interrupt */
+ temp = phy_read(phydev, LAN88XX_INT_MASK);
+ temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_;
+ phy_write(phydev, LAN88XX_INT_MASK, temp);
+
+ temp = phy_read(phydev, MII_BMCR);
+ temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000);
+ phy_write(phydev, MII_BMCR, temp); /* set to 10 first */
+ temp |= BMCR_SPEED100;
+ phy_write(phydev, MII_BMCR, temp); /* set to 100 later */
+
+ /* clear pending interrupt generated while workaround */
+ temp = phy_read(phydev, LAN88XX_INT_STS);
+
+ /* enable phy interrupt back */
+ temp = phy_read(phydev, LAN88XX_INT_MASK);
+ temp |= LAN88XX_INT_MASK_MDINTPIN_EN_;
+ phy_write(phydev, LAN88XX_INT_MASK, temp);
+ }
+}
+
static struct phy_driver microchip_phy_driver[] = {
{
.phy_id = 0x0007c132,
@@ -359,6 +390,7 @@ static struct phy_driver microchip_phy_driver[] = {
.config_init = lan88xx_config_init,
.config_aneg = lan88xx_config_aneg,
+ .link_change_notify = lan88xx_link_change_notify,
.config_intr = lan88xx_phy_config_intr,
.handle_interrupt = lan88xx_handle_interrupt,