aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Kleine-Budde <mkl@pengutronix.de>2023-05-01 18:14:41 +0200
committerMarc Kleine-Budde <mkl@pengutronix.de>2023-10-05 21:47:01 +0200
commitd3f4cf05402b06631f282e23dcba85daed732e38 (patch)
tree8a1e58de3a9828a963967a897397ea81488232f5
parentaa3f5d935cbb302dce89e8f278f6e8a3e2ecea18 (diff)
downloadnf-next-d3f4cf05402b06631f282e23dcba85daed732e38.tar.gz
can: at91_can: at91_irq_err_frame(): call directly from IRQ handler
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>
-rw-r--r--drivers/net/can/at91_can.c36
1 files changed, 12 insertions, 24 deletions
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 5b611657b41fa2..a84da199581601 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -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;
}