@@ -184,8 +184,10 @@ int mcp25xxfd_can_submit_rx_frame(struct spi_device *spi, int fifo)
184
184
if (rx -> flags & CAN_OBJ_FLAGS_FDF )
185
185
cpriv -> fifos .rx .fd_count ++ ;
186
186
187
- /* add to rx_dlc_history */
187
+ /* add to rx_history */
188
188
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 ;
189
191
cpriv -> stats .rx_history_index ++ ;
190
192
if (cpriv -> stats .rx_history_index >= RX_HISTORY_SIZE )
191
193
cpriv -> stats .rx_history_index = 0 ;
@@ -446,16 +448,13 @@ static int mcp25xxfd_can_read_rx_frame_bulk(struct spi_device *spi,
446
448
* reading multiple rx fifos is a realistic option of optimization
447
449
*/
448
450
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 )
450
453
{
451
454
struct mcp25xxfd_priv * priv = spi_get_drvdata (spi );
452
455
struct net_device * net = priv -> net ;
453
456
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 ;
459
458
460
459
/* loop all frames */
461
460
for (i = 0 , fifo = cpriv -> fifos .rx .start ;
@@ -473,13 +472,8 @@ static int mcp25xxfd_can_read_rx_frames_fd(struct spi_device *spi)
473
472
return 0 ;
474
473
}
475
474
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
- */
481
475
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 )
483
477
{
484
478
struct mcp25xxfd_priv * priv = spi_get_drvdata (spi );
485
479
struct net_device * net = priv -> net ;
@@ -516,6 +510,35 @@ int mcp25xxfd_can_read_rx_frames_sd(struct spi_device *spi)
516
510
return 0 ;
517
511
}
518
512
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
+
519
542
int mcp25xxfd_can_read_rx_frames (struct spi_device * spi )
520
543
{
521
544
struct mcp25xxfd_priv * priv = spi_get_drvdata (spi );
@@ -524,5 +547,5 @@ int mcp25xxfd_can_read_rx_frames(struct spi_device *spi)
524
547
if (net -> mtu == CANFD_MTU )
525
548
return mcp25xxfd_can_read_rx_frames_fd (spi );
526
549
else
527
- return mcp25xxfd_can_read_rx_frames_sd (spi );
550
+ return mcp25xxfd_can_read_rx_frames_bulk (spi );
528
551
}
0 commit comments