diff options
Diffstat (limited to 'drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c')
-rw-r--r-- | drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index 0ca5e30fc5e1..dc19f7f81acd 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -1297,6 +1297,10 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port) { u32 val; + mvpp2_modify(port->base + MVPP22_GMAC_INT_SUM_MASK, + MVPP22_GMAC_INT_SUM_MASK_PTP, + MVPP22_GMAC_INT_SUM_MASK_PTP); + if (port->phylink || phy_interface_mode_is_rgmii(port->phy_interface) || phy_interface_mode_is_8023z(port->phy_interface) || @@ -1310,6 +1314,10 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port) val = readl(port->base + MVPP22_XLG_INT_MASK); val |= MVPP22_XLG_INT_MASK_LINK; writel(val, port->base + MVPP22_XLG_INT_MASK); + + mvpp2_modify(port->base + MVPP22_XLG_EXT_INT_MASK, + MVPP22_XLG_EXT_INT_MASK_PTP, + MVPP22_XLG_EXT_INT_MASK_PTP); } mvpp22_gop_unmask_irq(port); @@ -2746,6 +2754,38 @@ static irqreturn_t mvpp2_isr(int irq, void *dev_id) return IRQ_HANDLED; } +static void mvpp2_isr_handle_ptp_queue(struct mvpp2_port *port, int nq) +{ + void __iomem *ptp_q; + u32 r0, r1, r2; + + ptp_q = port->priv->iface_base + MVPP22_PTP_BASE(port->gop_id); + if (nq) + ptp_q += MVPP22_PTP_TX_Q1_R0 - MVPP22_PTP_TX_Q0_R0; + + while (1) { + r0 = readl_relaxed(ptp_q + MVPP22_PTP_TX_Q0_R0) & 0xffff; + if (!r0) + break; + + r1 = readl_relaxed(ptp_q + MVPP22_PTP_TX_Q0_R1) & 0xffff; + r2 = readl_relaxed(ptp_q + MVPP22_PTP_TX_Q0_R2) & 0xffff; + } +} + +static void mvpp2_isr_handle_ptp(struct mvpp2_port *port) +{ + void __iomem *ptp; + u32 val; + + ptp = port->priv->iface_base + MVPP22_PTP_BASE(port->gop_id); + val = readl(ptp + MVPP22_PTP_INT_CAUSE); + if (val & MVPP22_PTP_INT_CAUSE_QUEUE0) + mvpp2_isr_handle_ptp_queue(port, 0); + if (val & MVPP22_PTP_INT_CAUSE_QUEUE1) + mvpp2_isr_handle_ptp_queue(port, 1); +} + static void mvpp2_isr_handle_link(struct mvpp2_port *port, bool link) { struct net_device *dev = port->dev; @@ -2821,6 +2861,8 @@ static irqreturn_t mvpp2_port_isr(int irq, void *dev_id) val = readl(port->base + MVPP22_XLG_EXT_INT_STAT); if (val & MVPP22_XLG_EXT_INT_STAT_XLG) mvpp2_isr_handle_xlg(port); + if (val & MVPP22_XLG_EXT_INT_STAT_PTP) + mvpp2_isr_handle_ptp(port); } else { /* If it's not the XLG, we must be using the GMAC. * Check the summary status. @@ -2828,6 +2870,8 @@ static irqreturn_t mvpp2_port_isr(int irq, void *dev_id) val = readl(port->base + MVPP22_GMAC_INT_SUM_STAT); if (val & MVPP22_GMAC_INT_SUM_STAT_INTERNAL) mvpp2_isr_handle_gmac_internal(port); + if (val & MVPP22_GMAC_INT_SUM_STAT_PTP) + mvpp2_isr_handle_ptp(port); } mvpp22_gop_unmask_irq(port); |