Skip to content

Commit 5382033

Browse files
rarun-mchpPaolo Abeni
authored andcommitted
net: phy: lan87xx: change interrupt src of link_up to comm_ready
Currently phy link up/down interrupt is enabled using the LAN87xx_INTERRUPT_MASK register. In the lan87xx_read_status function, phy link is determined using the T1_MODE_STAT_REG register comm_ready bit. comm_ready bit is set using the loc_rcvr_status & rem_rcvr_status. Whenever the phy link is up, LAN87xx_INTERRUPT_SOURCE link_up bit is set first but comm_ready bit takes some time to set based on local and remote receiver status. As per the current implementation, interrupt is triggered using link_up but the comm_ready bit is still cleared in the read_status function. So, link is always down. Initially tested with the shared interrupt mechanism with switch and internal phy which is working, but after implementing interrupt controller it is not working. It can fixed either by updating the read_status function to read from LAN87XX_INTERRUPT_SOURCE register or enable the interrupt mask for comm_ready bit. But the validation team recommends the use of comm_ready for link detection. This patch fixes by enabling the comm_ready bit for link_up in the LAN87XX_INTERRUPT_MASK_2 register (MISC Bank) and link_down in LAN87xx_INTERRUPT_MASK register. Fixes: 8a1b415 ("net: phy: added ethtool master-slave configuration support") Signed-off-by: Arun Ramadoss <[email protected]> Reviewed-by: Andrew Lunn <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent e9b1a4f commit 5382033

File tree

1 file changed

+54
-4
lines changed

1 file changed

+54
-4
lines changed

drivers/net/phy/microchip_t1.c

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,16 @@
2828

2929
/* Interrupt Source Register */
3030
#define LAN87XX_INTERRUPT_SOURCE (0x18)
31+
#define LAN87XX_INTERRUPT_SOURCE_2 (0x08)
3132

3233
/* Interrupt Mask Register */
3334
#define LAN87XX_INTERRUPT_MASK (0x19)
3435
#define LAN87XX_MASK_LINK_UP (0x0004)
3536
#define LAN87XX_MASK_LINK_DOWN (0x0002)
3637

38+
#define LAN87XX_INTERRUPT_MASK_2 (0x09)
39+
#define LAN87XX_MASK_COMM_RDY BIT(10)
40+
3741
/* MISC Control 1 Register */
3842
#define LAN87XX_CTRL_1 (0x11)
3943
#define LAN87XX_MASK_RGMII_TXC_DLY_EN (0x4000)
@@ -424,17 +428,55 @@ static int lan87xx_phy_config_intr(struct phy_device *phydev)
424428
int rc, val = 0;
425429

426430
if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
427-
/* unmask all source and clear them before enable */
428-
rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, 0x7FFF);
431+
/* clear all interrupt */
432+
rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, val);
433+
if (rc < 0)
434+
return rc;
435+
429436
rc = phy_read(phydev, LAN87XX_INTERRUPT_SOURCE);
430-
val = LAN87XX_MASK_LINK_UP | LAN87XX_MASK_LINK_DOWN;
437+
if (rc < 0)
438+
return rc;
439+
440+
rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE,
441+
PHYACC_ATTR_BANK_MISC,
442+
LAN87XX_INTERRUPT_MASK_2, val);
443+
if (rc < 0)
444+
return rc;
445+
446+
rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
447+
PHYACC_ATTR_BANK_MISC,
448+
LAN87XX_INTERRUPT_SOURCE_2, 0);
449+
if (rc < 0)
450+
return rc;
451+
452+
/* enable link down and comm ready interrupt */
453+
val = LAN87XX_MASK_LINK_DOWN;
431454
rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, val);
455+
if (rc < 0)
456+
return rc;
457+
458+
val = LAN87XX_MASK_COMM_RDY;
459+
rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE,
460+
PHYACC_ATTR_BANK_MISC,
461+
LAN87XX_INTERRUPT_MASK_2, val);
432462
} else {
433463
rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, val);
434-
if (rc)
464+
if (rc < 0)
435465
return rc;
436466

437467
rc = phy_read(phydev, LAN87XX_INTERRUPT_SOURCE);
468+
if (rc < 0)
469+
return rc;
470+
471+
rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE,
472+
PHYACC_ATTR_BANK_MISC,
473+
LAN87XX_INTERRUPT_MASK_2, val);
474+
if (rc < 0)
475+
return rc;
476+
477+
rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
478+
PHYACC_ATTR_BANK_MISC,
479+
LAN87XX_INTERRUPT_SOURCE_2, 0);
438480
}
439481

440482
return rc < 0 ? rc : 0;
@@ -444,6 +486,14 @@ static irqreturn_t lan87xx_handle_interrupt(struct phy_device *phydev)
444486
{
445487
int irq_status;
446488

489+
irq_status = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
490+
PHYACC_ATTR_BANK_MISC,
491+
LAN87XX_INTERRUPT_SOURCE_2, 0);
492+
if (irq_status < 0) {
493+
phy_error(phydev);
494+
return IRQ_NONE;
495+
}
496+
447497
irq_status = phy_read(phydev, LAN87XX_INTERRUPT_SOURCE);
448498
if (irq_status < 0) {
449499
phy_error(phydev);

0 commit comments

Comments
 (0)