@@ -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+
450470static 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
458478int mcp25xxfd_can_rx_handle_int_rxif (struct mcp25xxfd_can_priv * cpriv )
0 commit comments