Skip to content

Commit 169d00a

Browse files
can: mcp251xfd: add TX IRQ coalescing support
This patch adds TX IRQ coalescing support to the driver. The implemented algorithm is similar to the RX IRQ coalescing support added in the previous patch. Link: https://lore.kernel.org/[email protected] Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent 846990e commit 169d00a

File tree

3 files changed

+77
-5
lines changed

3 files changed

+77
-5
lines changed

drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,17 @@ mcp251xfd_ring_init_tef(struct mcp251xfd_priv *priv, u16 *base)
7171
/* TEF- and TX-FIFO have same number of objects */
7272
*base = mcp251xfd_get_tef_obj_addr(priv->tx->obj_num);
7373

74+
/* FIFO IRQ enable */
75+
addr = MCP251XFD_REG_TEFCON;
76+
val = MCP251XFD_REG_TEFCON_TEFOVIE | MCP251XFD_REG_TEFCON_TEFNEIE;
77+
78+
len = mcp251xfd_cmd_prepare_write_reg(priv, &tef_ring->irq_enable_buf,
79+
addr, val, val);
80+
tef_ring->irq_enable_xfer.tx_buf = &tef_ring->irq_enable_buf;
81+
tef_ring->irq_enable_xfer.len = len;
82+
spi_message_init_with_transfers(&tef_ring->irq_enable_msg,
83+
&tef_ring->irq_enable_xfer, 1);
84+
7485
/* FIFO increment TEF tail pointer */
7586
addr = MCP251XFD_REG_TEFCON;
7687
val = MCP251XFD_REG_TEFCON_UINC;
@@ -94,6 +105,18 @@ mcp251xfd_ring_init_tef(struct mcp251xfd_priv *priv, u16 *base)
94105
* message.
95106
*/
96107
xfer->cs_change = 0;
108+
109+
if (priv->tx_coalesce_usecs_irq || priv->tx_obj_num_coalesce_irq) {
110+
val = MCP251XFD_REG_TEFCON_UINC |
111+
MCP251XFD_REG_TEFCON_TEFOVIE |
112+
MCP251XFD_REG_TEFCON_TEFHIE;
113+
114+
len = mcp251xfd_cmd_prepare_write_reg(priv,
115+
&tef_ring->uinc_irq_disable_buf,
116+
addr, val, val);
117+
xfer->tx_buf = &tef_ring->uinc_irq_disable_buf;
118+
xfer->len = len;
119+
}
97120
}
98121

99122
static void
@@ -282,11 +305,29 @@ int mcp251xfd_ring_init(struct mcp251xfd_priv *priv)
282305
*/
283306
priv->regs_status.rxif = BIT(priv->rx[0]->fifo_nr);
284307

285-
netdev_dbg(priv->ndev,
286-
"FIFO setup: TEF: 0x%03x: %2d*%zu bytes = %4zu bytes\n",
287-
mcp251xfd_get_tef_obj_addr(0),
288-
priv->tx->obj_num, sizeof(struct mcp251xfd_hw_tef_obj),
289-
priv->tx->obj_num * sizeof(struct mcp251xfd_hw_tef_obj));
308+
if (priv->tx_obj_num_coalesce_irq) {
309+
netdev_dbg(priv->ndev,
310+
"FIFO setup: TEF: 0x%03x: %2d*%zu bytes = %4zu bytes (coalesce)\n",
311+
mcp251xfd_get_tef_obj_addr(0),
312+
priv->tx_obj_num_coalesce_irq,
313+
sizeof(struct mcp251xfd_hw_tef_obj),
314+
priv->tx_obj_num_coalesce_irq *
315+
sizeof(struct mcp251xfd_hw_tef_obj));
316+
317+
netdev_dbg(priv->ndev,
318+
" 0x%03x: %2d*%zu bytes = %4zu bytes\n",
319+
mcp251xfd_get_tef_obj_addr(priv->tx_obj_num_coalesce_irq),
320+
priv->tx->obj_num - priv->tx_obj_num_coalesce_irq,
321+
sizeof(struct mcp251xfd_hw_tef_obj),
322+
(priv->tx->obj_num - priv->tx_obj_num_coalesce_irq) *
323+
sizeof(struct mcp251xfd_hw_tef_obj));
324+
} else {
325+
netdev_dbg(priv->ndev,
326+
"FIFO setup: TEF: 0x%03x: %2d*%zu bytes = %4zu bytes\n",
327+
mcp251xfd_get_tef_obj_addr(0),
328+
priv->tx->obj_num, sizeof(struct mcp251xfd_hw_tef_obj),
329+
priv->tx->obj_num * sizeof(struct mcp251xfd_hw_tef_obj));
330+
}
290331

291332
mcp251xfd_for_each_rx_ring(priv, rx_ring, i) {
292333
if (rx_ring->nr == 0 && priv->rx_obj_num_coalesce_irq) {
@@ -364,6 +405,20 @@ static enum hrtimer_restart mcp251xfd_rx_irq_timer(struct hrtimer *t)
364405
return HRTIMER_NORESTART;
365406
}
366407

408+
static enum hrtimer_restart mcp251xfd_tx_irq_timer(struct hrtimer *t)
409+
{
410+
struct mcp251xfd_priv *priv = container_of(t, struct mcp251xfd_priv,
411+
tx_irq_timer);
412+
struct mcp251xfd_tef_ring *ring = priv->tef;
413+
414+
if (test_bit(MCP251XFD_FLAGS_DOWN, priv->flags))
415+
return HRTIMER_NORESTART;
416+
417+
spi_async(priv->spi, &ring->irq_enable_msg);
418+
419+
return HRTIMER_NORESTART;
420+
}
421+
367422
const struct can_ram_config mcp251xfd_ram_config = {
368423
.rx = {
369424
.size[CAN_RAM_MODE_CAN] = sizeof(struct mcp251xfd_hw_rx_obj_can),
@@ -449,5 +504,8 @@ int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv)
449504
hrtimer_init(&priv->rx_irq_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
450505
priv->rx_irq_timer.function = mcp251xfd_rx_irq_timer;
451506

507+
hrtimer_init(&priv->tx_irq_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
508+
priv->tx_irq_timer.function = mcp251xfd_tx_irq_timer;
509+
452510
return 0;
453511
}

drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,5 +256,11 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
256256
netif_wake_queue(priv->ndev);
257257
}
258258

259+
if (priv->tx_coalesce_usecs_irq)
260+
hrtimer_start(&priv->tx_irq_timer,
261+
ns_to_ktime(priv->tx_coalesce_usecs_irq *
262+
NSEC_PER_USEC),
263+
HRTIMER_MODE_REL);
264+
259265
return 0;
260266
}

drivers/net/can/spi/mcp251xfd/mcp251xfd.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,12 @@ struct mcp251xfd_tef_ring {
518518
/* u8 obj_num equals tx_ring->obj_num */
519519
/* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */
520520

521+
union mcp251xfd_write_reg_buf irq_enable_buf;
522+
struct spi_transfer irq_enable_xfer;
523+
struct spi_message irq_enable_msg;
524+
521525
union mcp251xfd_write_reg_buf uinc_buf;
526+
union mcp251xfd_write_reg_buf uinc_irq_disable_buf;
522527
struct spi_transfer uinc_xfer[MCP251XFD_TX_OBJ_NUM_MAX];
523528
};
524529

@@ -625,9 +630,12 @@ struct mcp251xfd_priv {
625630
u8 rx_ring_num;
626631
u8 rx_obj_num;
627632
u8 rx_obj_num_coalesce_irq;
633+
u8 tx_obj_num_coalesce_irq;
628634

629635
u32 rx_coalesce_usecs_irq;
636+
u32 tx_coalesce_usecs_irq;
630637
struct hrtimer rx_irq_timer;
638+
struct hrtimer tx_irq_timer;
631639

632640
struct mcp251xfd_ecc ecc;
633641
struct mcp251xfd_regs_status regs_status;

0 commit comments

Comments
 (0)