Skip to content

Commit

Permalink
net: mvpp2: restructure "link status" interrupt handling
Browse files Browse the repository at this point in the history
The "link status" interrupt is used for more than just link status.
Restructure mvpp2_link_status_isr() so we can add additional handling.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Russell King authored and David S. Miller committed Sep 9, 2020
1 parent b599a5b commit 36cfd3a
Showing 1 changed file with 51 additions and 32 deletions.
83 changes: 51 additions & 32 deletions drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2974,44 +2974,17 @@ static irqreturn_t mvpp2_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}

/* Per-port interrupt for link status changes */
static irqreturn_t mvpp2_link_status_isr(int irq, void *dev_id)
static void mvpp2_isr_handle_link(struct mvpp2_port *port, bool link)
{
struct mvpp2_port *port = (struct mvpp2_port *)dev_id;
struct net_device *dev = port->dev;
bool event = false, link = false;
u32 val;

mvpp22_gop_mask_irq(port);

if (mvpp2_port_supports_xlg(port) &&
mvpp2_is_xlg(port->phy_interface)) {
val = readl(port->base + MVPP22_XLG_INT_STAT);
if (val & MVPP22_XLG_INT_STAT_LINK) {
event = true;
val = readl(port->base + MVPP22_XLG_STATUS);
if (val & MVPP22_XLG_STATUS_LINK_UP)
link = true;
}
} else if (phy_interface_mode_is_rgmii(port->phy_interface) ||
phy_interface_mode_is_8023z(port->phy_interface) ||
port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
val = readl(port->base + MVPP22_GMAC_INT_STAT);
if (val & MVPP22_GMAC_INT_STAT_LINK) {
event = true;
val = readl(port->base + MVPP2_GMAC_STATUS0);
if (val & MVPP2_GMAC_STATUS0_LINK_UP)
link = true;
}
}

if (port->phylink) {
phylink_mac_change(port->phylink, link);
goto handled;
return;
}

if (!netif_running(dev) || !event)
goto handled;
if (!netif_running(dev))
return;

if (link) {
mvpp2_interrupts_enable(port);
Expand All @@ -3028,8 +3001,54 @@ static irqreturn_t mvpp2_link_status_isr(int irq, void *dev_id)

mvpp2_interrupts_disable(port);
}
}

static void mvpp2_isr_handle_xlg(struct mvpp2_port *port)
{
bool link;
u32 val;

val = readl(port->base + MVPP22_XLG_INT_STAT);
if (val & MVPP22_XLG_INT_STAT_LINK) {
val = readl(port->base + MVPP22_XLG_STATUS);
if (val & MVPP22_XLG_STATUS_LINK_UP)
link = true;
mvpp2_isr_handle_link(port, link);
}
}

static void mvpp2_isr_handle_gmac_internal(struct mvpp2_port *port)
{
bool link;
u32 val;

if (phy_interface_mode_is_rgmii(port->phy_interface) ||
phy_interface_mode_is_8023z(port->phy_interface) ||
port->phy_interface == PHY_INTERFACE_MODE_SGMII) {
val = readl(port->base + MVPP22_GMAC_INT_STAT);
if (val & MVPP22_GMAC_INT_STAT_LINK) {
val = readl(port->base + MVPP2_GMAC_STATUS0);
if (val & MVPP2_GMAC_STATUS0_LINK_UP)
link = true;
mvpp2_isr_handle_link(port, link);
}
}
}

/* Per-port interrupt for link status changes */
static irqreturn_t mvpp2_link_status_isr(int irq, void *dev_id)
{
struct mvpp2_port *port = (struct mvpp2_port *)dev_id;

mvpp22_gop_mask_irq(port);

if (mvpp2_port_supports_xlg(port) &&
mvpp2_is_xlg(port->phy_interface)) {
mvpp2_isr_handle_xlg(port);
} else {
mvpp2_isr_handle_gmac_internal(port);
}

handled:
mvpp22_gop_unmask_irq(port);
return IRQ_HANDLED;
}
Expand Down

0 comments on commit 36cfd3a

Please sign in to comment.