Skip to content

Commit 2ddb6c1

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 a41712b commit 2ddb6c1

File tree

2 files changed

+35
-14
lines changed

2 files changed

+35
-14
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ struct mcp25xxfd_can_priv {
178178
struct {
179179
#define MCP25XXFD_CAN_RX_DLC_HISTORY_SIZE 32
180180
u8 dlc[MCP25XXFD_CAN_RX_DLC_HISTORY_SIZE];
181+
u8 brs[MCP25XXFD_CAN_RX_DLC_HISTORY_SIZE];
181182
u8 index;
182183
u32 predicted_len;
183184
} rx_history;

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

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ int mcp25xxfd_can_rx_submit_frame(struct mcp25xxfd_can_priv *cpriv, int fifo)
104104

105105
/* add to rx_history */
106106
cpriv->rx_history.dlc[cpriv->rx_history.index] = dlc;
107+
cpriv->rx_history.brs[cpriv->rx_history.index] =
108+
(rx->flags & MCP25XXFD_CAN_OBJ_FLAGS_BRS) ? CANFD_BRS : 0;
107109
cpriv->rx_history.index++;
108110
if (cpriv->rx_history.index >= MCP25XXFD_CAN_RX_DLC_HISTORY_SIZE)
109111
cpriv->rx_history.index = 0;
@@ -395,19 +397,10 @@ static int mcp25xxfd_can_rx_predict_prefetch(struct mcp25xxfd_can_priv *cpriv)
395397
* reading multiple rx fifos is a realistic option of optimization
396398
*/
397399

398-
/* right now we only optimize for sd (can2.0) frame case,
399-
* but in principle it could be also be valuable for CANFD
400-
* frames when we receive lots of 64 byte packets with BRS set
401-
* and a big difference between nominal and data bitrates
402-
*/
403-
404-
int mcp25xxfd_can_rx_read_fd_frames(struct mcp25xxfd_can_priv *cpriv)
400+
static int mcp25xxfd_can_rx_read_single_frames(struct mcp25xxfd_can_priv *cpriv,
401+
int prefetch)
405402
{
406-
int i, f, prefetch;
407-
int ret;
408-
409-
/* calculate optimal prefetch to use */
410-
prefetch = mcp25xxfd_can_rx_predict_prefetch(cpriv);
403+
int i, f, ret;
411404

412405
/* loop all frames */
413406
for (i = 0, f = cpriv->fifos.rx.start; i < cpriv->fifos.rx.count;
@@ -424,7 +417,7 @@ int mcp25xxfd_can_rx_read_fd_frames(struct mcp25xxfd_can_priv *cpriv)
424417
return 0;
425418
}
426419

427-
static int mcp25xxfd_can_rx_read_sd_frames(struct mcp25xxfd_can_priv *cpriv)
420+
static int mcp25xxfd_can_rx_read_bulk_frames(struct mcp25xxfd_can_priv *cpriv)
428421
{
429422
int i, start, end;
430423
int ret;
@@ -447,12 +440,39 @@ static int mcp25xxfd_can_rx_read_sd_frames(struct mcp25xxfd_can_priv *cpriv)
447440
return 0;
448441
}
449442

443+
static int mcp25xxfd_can_rx_read_fd_frames(struct mcp25xxfd_can_priv *cpriv)
444+
{
445+
int i, count_dlc15, count_brs, prefetch;
446+
447+
/* get a prediction on prefetch */
448+
prefetch = mcp25xxfd_can_rx_predict_prefetch(cpriv);
449+
450+
/* if the prefetch is < 64 then just read single */
451+
if (prefetch < 64)
452+
return mcp25xxfd_can_rx_read_single_frames(cpriv, prefetch);
453+
454+
/* check if we have mostly brs frames of those DLC=15 frames */
455+
for (i = 0, count_brs = 0, count_dlc15 = 0;
456+
i < MCP25XXFD_CAN_RX_DLC_HISTORY_SIZE; i++)
457+
if (cpriv->rx_history.dlc[i] == 15) {
458+
count_dlc15++;
459+
if (cpriv->rx_history.brs[i])
460+
count_brs++;
461+
}
462+
463+
/* if we have at least 33% brs frames then run bulk */
464+
if (count_brs * 3 >= count_dlc15 )
465+
return mcp25xxfd_can_rx_read_bulk_frames(cpriv);
466+
else
467+
return mcp25xxfd_can_rx_read_single_frames(cpriv, prefetch);
468+
}
469+
450470
static int mcp25xxfd_can_rx_read_frames(struct mcp25xxfd_can_priv *cpriv)
451471
{
452472
if (cpriv->can.dev->mtu == CANFD_MTU)
453473
return mcp25xxfd_can_rx_read_fd_frames(cpriv);
454474
else
455-
return mcp25xxfd_can_rx_read_sd_frames(cpriv);
475+
return mcp25xxfd_can_rx_read_bulk_frames(cpriv);
456476
}
457477

458478
int mcp25xxfd_can_rx_handle_int_rxif(struct mcp25xxfd_can_priv *cpriv)

0 commit comments

Comments
 (0)