Hello. On 12/20/2015 12:15 PM, Yoshihiro Kaneko wrote:
From: Kazuya Mizuguchi <kazuya.mizuguchi...@renesas.com> This patch supports the following interrupts. - One interrupt for multiple (descriptor, error, management) - One interrupt for emac - Four interrupts for dma queue (best effort rx/tx, network control rx/tx)
You still don't say why it's better than the current scheme...
Signed-off-by: Kazuya Mizuguchi <kazuya.mizuguchi...@renesas.com> Signed-off-by: Yoshihiro Kaneko <ykaneko0...@gmail.com> --- This patch is based on the master branch of David Miller's next networking tree. v2 [Yoshihiro Kaneko] * compile tested only * As suggested by Sergei Shtylyov - add comment to CIE - remove comments from CIE bits - fix value of TIx_ALL - define each bits for CIE, GIE, GID, RIE0, RID0, RIE2, RID2, TIE, TID - reversed Christmas tree declaration ordered - rename _ravb_emac_interrupt() to ravb_emac_interrupt_unlocked() - remove unnecessary clearing of CIE - use a bit name corresponding to the target register, RIE0, RIE2, TIE, TID, RID2, GID, GIE drivers/net/ethernet/renesas/ravb.h | 213 ++++++++++++++++++++++++++ drivers/net/ethernet/renesas/ravb_main.c | 247 +++++++++++++++++++++++++++---- drivers/net/ethernet/renesas/ravb_ptp.c | 45 ++++-- 3 files changed, 464 insertions(+), 41 deletions(-) diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h index 9fbe92a..71badd6d 100644 --- a/drivers/net/ethernet/renesas/ravb.h +++ b/drivers/net/ethernet/renesas/ravb.h @@ -157,6 +157,7 @@ enum ravb_reg { TIC = 0x0378, TIS = 0x037C, ISS = 0x0380, + CIE = 0x0384, /* R-Car Gen3 only */ GCCR = 0x0390, GMTT = 0x0394, GPTC = 0x0398, @@ -170,6 +171,15 @@ enum ravb_reg { GCT0 = 0x03B8, GCT1 = 0x03BC, GCT2 = 0x03C0, + GIE = 0x03CC, + GID = 0x03D0, + DIL = 0x0440, + RIE0 = 0x0460, + RID0 = 0x0464, + RIE2 = 0x0470, + RID2 = 0x0474, + TIE = 0x0478, + TID = 0x047c,
So you only commented on CIE and considered it done? :-) [...]
@@ -411,14 +422,27 @@ static int ravb_dmac_init(struct net_device *ndev) ravb_write(ndev, TCCR_TFEN, TCCR); /* Interrupt init: */ - /* Frame receive */ - ravb_write(ndev, RIC0_FRE0 | RIC0_FRE1, RIC0); - /* Disable FIFO full warning */ - ravb_write(ndev, 0, RIC1); - /* Receive FIFO full error, descriptor empty */ - ravb_write(ndev, RIC2_QFE0 | RIC2_QFE1 | RIC2_RFFE, RIC2); - /* Frame transmitted, timestamp FIFO updated */ - ravb_write(ndev, TIC_FTE0 | TIC_FTE1 | TIC_TFUE, TIC); + if (priv->chip_id == RCAR_GEN2) { + /* Frame receive */ + ravb_write(ndev, RIC0_FRE0 | RIC0_FRE1, RIC0); + /* Disable FIFO full warning */ + ravb_write(ndev, 0, RIC1); + /* Receive FIFO full error, descriptor empty */ + ravb_write(ndev, RIC2_QFE0 | RIC2_QFE1 | RIC2_RFFE, RIC2); + /* Frame transmitted, timestamp FIFO updated */ + ravb_write(ndev, TIC_FTE0 | TIC_FTE1 | TIC_TFUE, TIC); + } else { + /* Clear DIL.DPLx */ + ravb_write(ndev, 0, DIL); + /* Set queue specific interrupt */ + ravb_write(ndev, CIE_CRIE | CIE_CTIE | CIE_CL0M, CIE); + /* Frame receive */ + ravb_write(ndev, RIE0_FRS0 | RIE0_FRS1, RIE0); + /* Receive FIFO full error, descriptor empty */ + ravb_write(ndev, RIE2_QFS0 | RIE2_QFS1 | RIE2_RFFS, RIE2); + /* Frame transmitted, timestamp FIFO updated */ + ravb_write(ndev, TIE_FTS0 | TIE_FTS1 | TIE_TFUS, TIE); + }
So in this case for gen3 we enable interrupts we need in addition to already enabled (by a boot loader perhaps)? I don't think you actually want it... [...]
@@ -690,7 +726,10 @@ static void ravb_error_interrupt(struct net_device *ndev) ravb_write(ndev, ~EIS_QFS, EIS); if (eis & EIS_QFS) { ris2 = ravb_read(ndev, RIS2); - ravb_write(ndev, ~(RIS2_QFF0 | RIS2_RFFF), RIS2); + if (priv->chip_id == RCAR_GEN2) + ravb_write(ndev, ~(RIS2_QFF0 | RIS2_RFFF), RIS2); + else + ravb_write(ndev, RID2_QFD0 | RID2_RFFD, RID2);
Err, aren't you doing 2 different things for gen2 and gen3 here. For gen2 you're clearing the QFF0/RFFF interrupts, for gen3 you're disabling them, no?
[...]
@@ -758,16 +797,43 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id)
[...]
+/* Descriptor IRQ/Error/Management interrupt handler */ +static irqreturn_t ravb_multi_interrupt(int irq, void *dev_id) +{ + struct net_device *ndev = dev_id; + struct ravb_private *priv = netdev_priv(ndev); + irqreturn_t result = IRQ_NONE; + u32 iss; + + spin_lock(&priv->lock); + /* Get interrupt status */ + iss = ravb_read(ndev, ISS); + /* Error status summary */ if (iss & ISS_ES) { ravb_error_interrupt(ndev); result = IRQ_HANDLED; } + /* Management */
I still doubt this comment is valid...
if (iss & ISS_CGIS) result = ravb_ptp_interrupt(ndev);
[...]
@@ -1223,23 +1343,68 @@ static const struct ethtool_ops ravb_ethtool_ops = { static int ravb_open(struct net_device *ndev) { struct ravb_private *priv = netdev_priv(ndev); - int error; + struct platform_device *pdev = priv->pdev; + struct device *dev = &pdev->dev; + int error, i; + char *name; napi_enable(&priv->napi[RAVB_BE]); napi_enable(&priv->napi[RAVB_NC]); - error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED, ndev->name, - ndev); - if (error) { - netdev_err(ndev, "cannot request IRQ\n"); - goto out_napi_off; - } - - if (priv->chip_id == RCAR_GEN3) { - error = request_irq(priv->emac_irq, ravb_interrupt, - IRQF_SHARED, ndev->name, ndev); + if (priv->chip_id == RCAR_GEN2) { + error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED, + ndev->name, ndev); if (error) { netdev_err(ndev, "cannot request IRQ\n"); + goto out_napi_off; + } + } else { + name = devm_kasprintf(dev, GFP_KERNEL, "%s:ch22:multi", + ndev->name); + error = request_irq(ndev->irq, ravb_multi_interrupt, + IRQF_SHARED, name, ndev); + if (error) { + netdev_err(ndev, "cannot request IRQ %s\n", name); + goto out_napi_off; + } + name = devm_kasprintf(dev, GFP_KERNEL, "%s:ch24:emac", + ndev->name); + error = request_irq(priv->emac_irq, ravb_emac_interrupt, + IRQF_SHARED, name, ndev); + if (error) { + netdev_err(ndev, "cannot request IRQ %s\n", name); + goto out_free_irq; + } + name = devm_kasprintf(dev, GFP_KERNEL, "%s:ch0:rx_be", + ndev->name); + error = request_irq(priv->rx_irqs[RAVB_BE], ravb_be_interrupt, + IRQF_SHARED, name, ndev); + if (error) { + netdev_err(ndev, "cannot request IRQ %s\n", name); + goto out_free_irq; + } + name = devm_kasprintf(dev, GFP_KERNEL, "%s:ch18:tx_be", + ndev->name); + error = request_irq(priv->tx_irqs[RAVB_BE], ravb_be_interrupt, + IRQF_SHARED, name, ndev); + if (error) { + netdev_err(ndev, "cannot request IRQ %s\n", name); + goto out_free_irq; + } + name = devm_kasprintf(dev, GFP_KERNEL, "%s:ch1:rx_nc", + ndev->name); + error = request_irq(priv->rx_irqs[RAVB_NC], ravb_nc_interrupt, + IRQF_SHARED, name, ndev); + if (error) { + netdev_err(ndev, "cannot request IRQ %s\n", name); + goto out_free_irq; + } + name = devm_kasprintf(dev, GFP_KERNEL, "%s:ch19:tx_nc", + ndev->name); + error = request_irq(priv->tx_irqs[RAVB_NC], ravb_nc_interrupt, + IRQF_SHARED, name, ndev); + if (error) { + netdev_err(ndev, "cannot request IRQ %s\n", name); goto out_free_irq; }
This error case is repetitive, couldn't you consolidate it somehow? [...]
@@ -1494,10 +1663,15 @@ static int ravb_close(struct net_device *ndev) netif_tx_stop_all_queues(ndev); /* Disable interrupts by clearing the interrupt masks. */ - ravb_write(ndev, 0, RIC0); - ravb_write(ndev, 0, RIC2); - ravb_write(ndev, 0, TIC); - + if (priv->chip_id == RCAR_GEN2) { + ravb_write(ndev, 0, RIC0); + ravb_write(ndev, 0, RIC2); + ravb_write(ndev, 0, TIC); + } else { + ravb_write(ndev, RID0_ALL, RID0); + ravb_write(ndev, RID2_ALL, RID2); + ravb_write(ndev, TID_ALL, TID); + }
Don't see why this is better than the old code. We don't care about atomicity here AFAIU.
[...]
@@ -1798,6 +1973,22 @@ static int ravb_probe(struct platform_device *pdev) goto out_release; } priv->emac_irq = irq; + for (i = 0; i < NUM_RX_QUEUE; i++) { + irq = platform_get_irq_byname(pdev, ravb_rx_irqs[i]); + if (irq < 0) { + error = irq; + goto out_release; + } + priv->rx_irqs[i] = irq; + } + for (i = 0; i < NUM_TX_QUEUE; i++) { + irq = platform_get_irq_byname(pdev, ravb_tx_irqs[i]); + if (irq < 0) { + error = irq; + goto out_release; + } + priv->tx_irqs[i] = irq; + }
Perhaps it would better to use sprintf() here, in both loops... [...]
diff --git a/drivers/net/ethernet/renesas/ravb_ptp.c b/drivers/net/ethernet/renesas/ravb_ptp.c index 7a8ce92..870d7b7 100644 --- a/drivers/net/ethernet/renesas/ravb_ptp.c +++ b/drivers/net/ethernet/renesas/ravb_ptp.c
[...]
@@ -352,7 +367,11 @@ void ravb_ptp_stop(struct net_device *ndev) { struct ravb_private *priv = netdev_priv(ndev); - ravb_write(ndev, 0, GIC); + if (priv->chip_id == RCAR_GEN2) + ravb_write(ndev, 0, GIC); + else + ravb_write(ndev, GID_ALL, GID);
Again, don't see why it's better than the old code. [...] MBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html