]> git.itanic.dy.fi Git - linux-stable/commitdiff
can: at91_can: at91_irq_err_frame(): call directly from IRQ handler
authorMarc Kleine-Budde <mkl@pengutronix.de>
Mon, 1 May 2023 16:14:41 +0000 (18:14 +0200)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Thu, 5 Oct 2023 19:47:01 +0000 (21:47 +0200)
This is a preparation patch to convert the driver to the rx-offload
helper. In rx-offload RX, TX-done and CAN error handling are done in
the IRQ handler, SKB are pushed to the network stack in the NAPI poll
function.

Move the CAN frame error handling from the NAPI function at91_poll()
to the IRQ handler at91_poll(). To reflect this change, rename
at91_poll_err() to at91_irq_err_frame().

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-19-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/at91_can.c

index 5b611657b41fa20f21496512b5d3d1cb99bf0d76..a84da199581601fda67a966fd6e78dc2deef0342 100644 (file)
@@ -155,7 +155,6 @@ struct at91_priv {
 
        void __iomem *reg_base;
 
-       u32 reg_sr;
        unsigned int tx_head;
        unsigned int tx_tail;
        unsigned int rx_next;
@@ -751,7 +750,7 @@ static int at91_poll_rx(struct net_device *dev, int quota)
        return received;
 }
 
-static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
+static void at91_irq_err_frame(struct net_device *dev, const u32 reg_sr)
 {
        struct net_device_stats *stats = &dev->stats;
        struct at91_priv *priv = netdev_priv(dev);
@@ -760,11 +759,9 @@ static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
 
        priv->can.can_stats.bus_error++;
 
-       if (quota) {
-               skb = alloc_can_err_skb(dev, &cf);
-               if (cf)
-                       cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
-       }
+       skb = alloc_can_err_skb(dev, &cf);
+       if (cf)
+               cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
        if (reg_sr & AT91_IRQ_CERR) {
                netdev_dbg(dev, "CRC error\n");
@@ -809,11 +806,9 @@ static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
        }
 
        if (!cf)
-               return 0;
+               return;
 
        netif_receive_skb(skb);
-
-       return 1;
 }
 
 static int at91_poll(struct napi_struct *napi, int quota)
@@ -826,13 +821,6 @@ static int at91_poll(struct napi_struct *napi, int quota)
        if (reg_sr & get_irq_mb_rx(priv))
                work_done += at91_poll_rx(dev, quota - work_done);
 
-       /* The error bits are clear on read,
-        * so use saved value from irq handler.
-        */
-       reg_sr |= priv->reg_sr;
-       if (reg_sr & AT91_IRQ_ERR_FRAME)
-               work_done += at91_poll_err(dev, quota - work_done, reg_sr);
-
        if (work_done < quota) {
                /* enable IRQs for frame errors and all mailboxes >= rx_next */
                u32 reg_ier = AT91_IRQ_ERR_FRAME;
@@ -1092,14 +1080,10 @@ static irqreturn_t at91_irq(int irq, void *dev_id)
 
        handled = IRQ_HANDLED;
 
-       /* Receive or error interrupt? -> napi */
-       if (reg_sr & (get_irq_mb_rx(priv) | AT91_IRQ_ERR_FRAME)) {
-               /* The error bits are clear on read,
-                * save for later use.
-                */
-               priv->reg_sr = reg_sr;
+       /* Receive interrupt? -> napi */
+       if (reg_sr & get_irq_mb_rx(priv)) {
                at91_write(priv, AT91_IDR,
-                          get_irq_mb_rx(priv) | AT91_IRQ_ERR_FRAME);
+                          get_irq_mb_rx(priv));
                napi_schedule(&priv->napi);
        }
 
@@ -1109,6 +1093,10 @@ static irqreturn_t at91_irq(int irq, void *dev_id)
 
        at91_irq_err(dev);
 
+       /* Frame Error Interrupt */
+       if (reg_sr & AT91_IRQ_ERR_FRAME)
+               at91_irq_err_frame(dev, reg_sr);
+
  exit:
        return handled;
 }