@@ -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- */
481475static
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+
519542int 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