summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorMarkus Schneider-Pargmann <msp@baylibre.com>2022-12-06 12:57:23 +0100
committerMarc Kleine-Budde <mkl@pengutronix.de>2022-12-12 11:58:32 +0100
commite3bff5256a0f12a1edc8d79bdef53eb83c2f1fbf (patch)
treee0d6dadebe8cd17f1e997a1f5f4f4cf78f6c9189 /drivers/net
parent6355a3c983e6d6fc998f4223bd2c7ef047e4572b (diff)
can: m_can: Batch acknowledge transmit events
Transmit events from the txe fifo can be batch acknowledged by acknowledging the last read txe fifo item. This will save txe_count writes which is important for peripheral chips. Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com> Link: https://lore.kernel.org/all/20221206115728.1056014-7-msp@baylibre.com Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/can/m_can/m_can.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 9476d96013fa..656d2daafad1 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -1023,7 +1023,9 @@ static int m_can_echo_tx_event(struct net_device *dev)
u32 txe_count = 0;
u32 m_can_txefs;
u32 fgi = 0;
+ int ack_fgi = -1;
int i = 0;
+ int err = 0;
unsigned int msg_mark;
struct m_can_classdev *cdev = netdev_priv(dev);
@@ -1038,28 +1040,29 @@ static int m_can_echo_tx_event(struct net_device *dev)
/* Get and process all sent elements */
for (i = 0; i < txe_count; i++) {
u32 txe, timestamp = 0;
- int err;
/* get message marker, timestamp */
err = m_can_txe_fifo_read(cdev, fgi, 4, &txe);
if (err) {
netdev_err(dev, "TXE FIFO read returned %d\n", err);
- return err;
+ break;
}
msg_mark = FIELD_GET(TX_EVENT_MM_MASK, txe);
timestamp = FIELD_GET(TX_EVENT_TXTS_MASK, txe) << 16;
- /* ack txe element */
- m_can_write(cdev, M_CAN_TXEFA, FIELD_PREP(TXEFA_EFAI_MASK,
- fgi));
+ ack_fgi = fgi;
fgi = (++fgi >= cdev->mcfg[MRAM_TXE].num ? 0 : fgi);
/* update stats */
m_can_tx_update_stats(cdev, msg_mark, timestamp);
}
- return 0;
+ if (ack_fgi != -1)
+ m_can_write(cdev, M_CAN_TXEFA, FIELD_PREP(TXEFA_EFAI_MASK,
+ ack_fgi));
+
+ return err;
}
static irqreturn_t m_can_isr(int irq, void *dev_id)