net: phy: microchip_t1: Interrupt support for lan887x

Add support for link up and link down interrupts in lan887x.

Signed-off-by: Divya Koppera <divya.koppera@microchip.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Link: https://patch.msgid.link/20241001144421.6661-1-divya.koppera@microchip.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Divya Koppera 2024-10-01 20:14:21 +05:30 committed by Jakub Kicinski
parent 046e64f547
commit 5fad1c1a09

View File

@ -226,6 +226,18 @@
#define MICROCHIP_CABLE_MAX_TIME_DIFF \
(MICROCHIP_CABLE_MIN_TIME_DIFF + MICROCHIP_CABLE_TIME_MARGIN)
#define LAN887X_INT_STS 0xf000
#define LAN887X_INT_MSK 0xf001
#define LAN887X_INT_MSK_T1_PHY_INT_MSK BIT(2)
#define LAN887X_INT_MSK_LINK_UP_MSK BIT(1)
#define LAN887X_INT_MSK_LINK_DOWN_MSK BIT(0)
#define LAN887X_MX_CHIP_TOP_LINK_MSK (LAN887X_INT_MSK_LINK_UP_MSK |\
LAN887X_INT_MSK_LINK_DOWN_MSK)
#define LAN887X_MX_CHIP_TOP_ALL_MSK (LAN887X_INT_MSK_T1_PHY_INT_MSK |\
LAN887X_MX_CHIP_TOP_LINK_MSK)
#define DRIVER_AUTHOR "Nisar Sayed <nisar.sayed@microchip.com>"
#define DRIVER_DESC "Microchip LAN87XX/LAN937x/LAN887x T1 PHY driver"
@ -1474,6 +1486,49 @@ static void lan887x_get_strings(struct phy_device *phydev, u8 *data)
ethtool_puts(&data, lan887x_hw_stats[i].string);
}
static int lan887x_config_intr(struct phy_device *phydev)
{
int rc;
if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
/* Clear the interrupt status before enabling interrupts */
rc = phy_read_mmd(phydev, MDIO_MMD_VEND1, LAN887X_INT_STS);
if (rc < 0)
return rc;
/* Unmask for enabling interrupt */
rc = phy_write_mmd(phydev, MDIO_MMD_VEND1, LAN887X_INT_MSK,
(u16)~LAN887X_MX_CHIP_TOP_ALL_MSK);
} else {
rc = phy_write_mmd(phydev, MDIO_MMD_VEND1, LAN887X_INT_MSK,
GENMASK(15, 0));
if (rc < 0)
return rc;
rc = phy_read_mmd(phydev, MDIO_MMD_VEND1, LAN887X_INT_STS);
}
return rc < 0 ? rc : 0;
}
static irqreturn_t lan887x_handle_interrupt(struct phy_device *phydev)
{
int irq_status;
irq_status = phy_read_mmd(phydev, MDIO_MMD_VEND1, LAN887X_INT_STS);
if (irq_status < 0) {
phy_error(phydev);
return IRQ_NONE;
}
if (irq_status & LAN887X_MX_CHIP_TOP_LINK_MSK) {
phy_trigger_machine(phydev);
return IRQ_HANDLED;
}
return IRQ_NONE;
}
static int lan887x_cd_reset(struct phy_device *phydev,
enum cable_diag_state cd_done)
{
@ -1504,6 +1559,10 @@ static int lan887x_cd_reset(struct phy_device *phydev,
if (rc < 0)
return rc;
rc = lan887x_config_intr(phydev);
if (rc < 0)
return rc;
rc = lan887x_phy_reconfig(phydev);
if (rc < 0)
return rc;
@ -1881,6 +1940,8 @@ static struct phy_driver microchip_t1_phy_driver[] = {
.read_status = genphy_c45_read_status,
.cable_test_start = lan887x_cable_test_start,
.cable_test_get_status = lan887x_cable_test_get_status,
.config_intr = lan887x_config_intr,
.handle_interrupt = lan887x_handle_interrupt,
}
};