Skip to content

Commit 273d86d

Browse files
committed
can: mcp25xxfd: optimize reception of big CanFD frame reception with BRS
In case of predicted DLC=15 and in case at least 33% of those are sent via BRS be aggressive and use bulk fifo reads to avoid missing any frames due to releasing FIFOs not as fast as possible. This would be of most impact when having a 1MHz Can Bus with a 8MHz data bitrate. Signed-off-by: Martin Sperl <[email protected]>
1 parent 922d228 commit 273d86d

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,7 @@ struct mcp25xxfd_can_priv {
642642
u64 rx_bulk_read_sizes[RX_BULK_READ_STATS_BINS];
643643
#define RX_HISTORY_SIZE 32
644644
u8 rx_history_dlc[RX_HISTORY_SIZE];
645+
u8 rx_history_brs[RX_HISTORY_SIZE];
645646
u8 rx_history_index;
646647
u32 rx_reads_prefetch_predicted;
647648
} stats;

drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can_rx.c

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,10 @@ int mcp25xxfd_can_submit_rx_frame(struct spi_device *spi, int fifo)
184184
if (rx->flags & CAN_OBJ_FLAGS_FDF)
185185
cpriv->fifos.rx.fd_count++;
186186

187-
/* add to rx_dlc_history */
187+
/* add to rx_history */
188188
cpriv->stats.rx_history_dlc[cpriv->stats.rx_history_index] = dlc;
189+
cpriv->stats.rx_history_brs[cpriv->stats.rx_history_index] =
190+
(rx->flags & CAN_OBJ_FLAGS_BRS) ? CANFD_BRS : 0;
189191
cpriv->stats.rx_history_index++;
190192
if (cpriv->stats.rx_history_index >= RX_HISTORY_SIZE)
191193
cpriv->stats.rx_history_index = 0;
@@ -446,16 +448,13 @@ static int mcp25xxfd_can_read_rx_frame_bulk(struct spi_device *spi,
446448
* reading multiple rx fifos is a realistic option of optimization
447449
*/
448450

449-
static int mcp25xxfd_can_read_rx_frames_fd(struct spi_device *spi)
451+
static int mcp25xxfd_can_read_rx_frames_single(struct spi_device *spi,
452+
int prefetch)
450453
{
451454
struct mcp25xxfd_priv *priv = spi_get_drvdata(spi);
452455
struct net_device *net = priv->net;
453456
struct mcp25xxfd_can_priv *cpriv = netdev_priv(net);
454-
int i, fifo, prefetch;
455-
int ret;
456-
457-
/* calculate optimal prefetch to use */
458-
prefetch = mcp25xxfd_can_rx_predict_prefetch(net);
457+
int i, fifo, ret;
459458

460459
/* loop all frames */
461460
for (i = 0, fifo = cpriv->fifos.rx.start;
@@ -473,13 +472,8 @@ static int mcp25xxfd_can_read_rx_frames_fd(struct spi_device *spi)
473472
return 0;
474473
}
475474

476-
/* right now we only optimize for sd (can2.0) frame case,
477-
* but in principle it could be also be valuable for CANFD
478-
* frames when we receive lots of 64 byte packets with BRS set
479-
* and a big difference between nominal and data bitrates
480-
*/
481475
static
482-
int mcp25xxfd_can_read_rx_frames_sd(struct spi_device *spi)
476+
int mcp25xxfd_can_read_rx_frames_bulk(struct spi_device *spi)
483477
{
484478
struct mcp25xxfd_priv *priv = spi_get_drvdata(spi);
485479
struct net_device *net = priv->net;
@@ -516,6 +510,35 @@ int mcp25xxfd_can_read_rx_frames_sd(struct spi_device *spi)
516510
return 0;
517511
}
518512

513+
static int mcp25xxfd_can_read_rx_frames_fd(struct spi_device *spi)
514+
{
515+
struct mcp25xxfd_priv *priv = spi_get_drvdata(spi);
516+
struct net_device *net = priv->net;
517+
struct mcp25xxfd_can_priv *cpriv = netdev_priv(net);
518+
int i, count_dlc15, count_brs, prefetch;
519+
520+
/* get a prediction on prefetch */
521+
prefetch = mcp25xxfd_can_rx_predict_prefetch(net);
522+
523+
/* if the prefetch is < 64 then just read single */
524+
if (prefetch < 64)
525+
return mcp25xxfd_can_read_rx_frames_single(spi, prefetch);
526+
527+
/* check if we have mostly brs frames of those DLC=15 frames */
528+
for (i = 0, count_brs = 0, count_dlc15 = 0; i < RX_HISTORY_SIZE; i++)
529+
if (cpriv->stats.rx_history_dlc[i] == 15) {
530+
count_dlc15++;
531+
if (cpriv->stats.rx_history_brs[i])
532+
count_brs++;
533+
}
534+
535+
/* if we have at least 33% brs frames then run bulk */
536+
if (count_brs > (count_dlc15 / 3))
537+
return mcp25xxfd_can_read_rx_frames_bulk(spi);
538+
else
539+
return mcp25xxfd_can_read_rx_frames_single(spi, prefetch);
540+
}
541+
519542
int mcp25xxfd_can_read_rx_frames(struct spi_device *spi)
520543
{
521544
struct mcp25xxfd_priv *priv = spi_get_drvdata(spi);
@@ -524,5 +547,5 @@ int mcp25xxfd_can_read_rx_frames(struct spi_device *spi)
524547
if (net->mtu == CANFD_MTU)
525548
return mcp25xxfd_can_read_rx_frames_fd(spi);
526549
else
527-
return mcp25xxfd_can_read_rx_frames_sd(spi);
550+
return mcp25xxfd_can_read_rx_frames_bulk(spi);
528551
}

0 commit comments

Comments
 (0)