Skip to content

Commit

Permalink
can: mcp25xxfd: optimize TEF read avoiding unnecessary SPI transfers
Browse files Browse the repository at this point in the history
We have already enough information to know how many tx-messages have
been terminated so that we do not have to query TEF every time if
there is anything pending but we can read the tefs blindly.

This avoids 1 SPI transfer per TEF read.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
  • Loading branch information
msperl committed May 11, 2019
1 parent cf733ff commit d86b484
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,13 @@ int mcp25xxfd_can_tx_handle_int_tefif_fifo(struct mcp25xxfd_can_priv *cpriv)
MCP25XXFD_CAN_TEFCON_UINC);
}

/* reading TEF entries can be made even more efficient by reading
* multiple TEF entries in one go.
* Under the assumption that we have count(TEF) >= count(TX_FIFO)
* we can even release TEFs early (before we read them)
* (and potentially restarting the transmit-queue early aswell)
*/

static int
mcp25xxfd_can_tx_handle_int_tefif_conservative(struct mcp25xxfd_can_priv *cpriv)
{
Expand Down Expand Up @@ -304,6 +311,25 @@ mcp25xxfd_can_tx_handle_int_tefif_conservative(struct mcp25xxfd_can_priv *cpriv)
return 0;
}

static int
mcp25xxfd_can_tx_handle_int_tefif_optimized(struct mcp25xxfd_can_priv *cpriv,
u32 finished)
{
int i, fifo, ret;

/* now iterate those */
for (i = 0, fifo = cpriv->fifos.tx.start; i < cpriv->fifos.tx.count;
i++, fifo++) {
if (finished & BIT(fifo)) {
ret = mcp25xxfd_can_tx_handle_int_tefif_fifo(cpriv);
if (ret)
return ret;
}
}

return 0;
}

int mcp25xxfd_can_tx_handle_int_tefif(struct mcp25xxfd_can_priv *cpriv)
{
unsigned long flags;
Expand All @@ -323,6 +349,13 @@ int mcp25xxfd_can_tx_handle_int_tefif(struct mcp25xxfd_can_priv *cpriv)

spin_unlock_irqrestore(&cpriv->fifos.tx_queue->lock, flags);

/* run in optimized mode if possible */
if (finished)
return mcp25xxfd_can_tx_handle_int_tefif_optimized(cpriv,
finished);
/* otherwise play it safe */
netdev_warn(cpriv->can.dev,
"Something is wrong - we got a TEF interrupt but we were not able to detect a finished fifo\n");
return mcp25xxfd_can_tx_handle_int_tefif_conservative(cpriv);
}

Expand Down

0 comments on commit d86b484

Please sign in to comment.