@@ -389,7 +389,253 @@ static int otx2_set_coalesce(struct net_device *netdev,
389
389
return 0 ;
390
390
}
391
391
392
+ static int otx2_get_rss_hash_opts (struct otx2_nic * pfvf ,
393
+ struct ethtool_rxnfc * nfc )
394
+ {
395
+ struct otx2_rss_info * rss = & pfvf -> hw .rss_info ;
396
+
397
+ if (!(rss -> flowkey_cfg &
398
+ (NIX_FLOW_KEY_TYPE_IPV4 | NIX_FLOW_KEY_TYPE_IPV6 )))
399
+ return 0 ;
400
+
401
+ /* Mimimum is IPv4 and IPv6, SIP/DIP */
402
+ nfc -> data = RXH_IP_SRC | RXH_IP_DST ;
403
+
404
+ switch (nfc -> flow_type ) {
405
+ case TCP_V4_FLOW :
406
+ case TCP_V6_FLOW :
407
+ if (rss -> flowkey_cfg & NIX_FLOW_KEY_TYPE_TCP )
408
+ nfc -> data |= RXH_L4_B_0_1 | RXH_L4_B_2_3 ;
409
+ break ;
410
+ case UDP_V4_FLOW :
411
+ case UDP_V6_FLOW :
412
+ if (rss -> flowkey_cfg & NIX_FLOW_KEY_TYPE_UDP )
413
+ nfc -> data |= RXH_L4_B_0_1 | RXH_L4_B_2_3 ;
414
+ break ;
415
+ case SCTP_V4_FLOW :
416
+ case SCTP_V6_FLOW :
417
+ if (rss -> flowkey_cfg & NIX_FLOW_KEY_TYPE_SCTP )
418
+ nfc -> data |= RXH_L4_B_0_1 | RXH_L4_B_2_3 ;
419
+ break ;
420
+ case AH_ESP_V4_FLOW :
421
+ case AH_V4_FLOW :
422
+ case ESP_V4_FLOW :
423
+ case IPV4_FLOW :
424
+ case AH_ESP_V6_FLOW :
425
+ case AH_V6_FLOW :
426
+ case ESP_V6_FLOW :
427
+ case IPV6_FLOW :
428
+ break ;
429
+ default :
430
+ return - EINVAL ;
431
+ }
432
+ return 0 ;
433
+ }
434
+
435
+ static int otx2_set_rss_hash_opts (struct otx2_nic * pfvf ,
436
+ struct ethtool_rxnfc * nfc )
437
+ {
438
+ struct otx2_rss_info * rss = & pfvf -> hw .rss_info ;
439
+ u32 rxh_l4 = RXH_L4_B_0_1 | RXH_L4_B_2_3 ;
440
+ u32 rss_cfg = rss -> flowkey_cfg ;
441
+
442
+ if (!rss -> enable ) {
443
+ netdev_err (pfvf -> netdev ,
444
+ "RSS is disabled, cannot change settings\n" );
445
+ return - EIO ;
446
+ }
447
+
448
+ /* Mimimum is IPv4 and IPv6, SIP/DIP */
449
+ if (!(nfc -> data & RXH_IP_SRC ) || !(nfc -> data & RXH_IP_DST ))
450
+ return - EINVAL ;
451
+
452
+ switch (nfc -> flow_type ) {
453
+ case TCP_V4_FLOW :
454
+ case TCP_V6_FLOW :
455
+ /* Different config for v4 and v6 is not supported.
456
+ * Both of them have to be either 4-tuple or 2-tuple.
457
+ */
458
+ switch (nfc -> data & rxh_l4 ) {
459
+ case 0 :
460
+ rss_cfg &= ~NIX_FLOW_KEY_TYPE_TCP ;
461
+ break ;
462
+ case (RXH_L4_B_0_1 | RXH_L4_B_2_3 ):
463
+ rss_cfg |= NIX_FLOW_KEY_TYPE_TCP ;
464
+ break ;
465
+ default :
466
+ return - EINVAL ;
467
+ }
468
+ break ;
469
+ case UDP_V4_FLOW :
470
+ case UDP_V6_FLOW :
471
+ switch (nfc -> data & rxh_l4 ) {
472
+ case 0 :
473
+ rss_cfg &= ~NIX_FLOW_KEY_TYPE_UDP ;
474
+ break ;
475
+ case (RXH_L4_B_0_1 | RXH_L4_B_2_3 ):
476
+ rss_cfg |= NIX_FLOW_KEY_TYPE_UDP ;
477
+ break ;
478
+ default :
479
+ return - EINVAL ;
480
+ }
481
+ break ;
482
+ case SCTP_V4_FLOW :
483
+ case SCTP_V6_FLOW :
484
+ switch (nfc -> data & rxh_l4 ) {
485
+ case 0 :
486
+ rss_cfg &= ~NIX_FLOW_KEY_TYPE_SCTP ;
487
+ break ;
488
+ case (RXH_L4_B_0_1 | RXH_L4_B_2_3 ):
489
+ rss_cfg |= NIX_FLOW_KEY_TYPE_SCTP ;
490
+ break ;
491
+ default :
492
+ return - EINVAL ;
493
+ }
494
+ break ;
495
+ case IPV4_FLOW :
496
+ case IPV6_FLOW :
497
+ rss_cfg = NIX_FLOW_KEY_TYPE_IPV4 | NIX_FLOW_KEY_TYPE_IPV6 ;
498
+ break ;
499
+ default :
500
+ return - EINVAL ;
501
+ }
502
+
503
+ rss -> flowkey_cfg = rss_cfg ;
504
+ otx2_set_flowkey_cfg (pfvf );
505
+ return 0 ;
506
+ }
507
+
508
+ static int otx2_get_rxnfc (struct net_device * dev ,
509
+ struct ethtool_rxnfc * nfc , u32 * rules )
510
+ {
511
+ struct otx2_nic * pfvf = netdev_priv (dev );
512
+ int ret = - EOPNOTSUPP ;
513
+
514
+ switch (nfc -> cmd ) {
515
+ case ETHTOOL_GRXRINGS :
516
+ nfc -> data = pfvf -> hw .rx_queues ;
517
+ ret = 0 ;
518
+ break ;
519
+ case ETHTOOL_GRXFH :
520
+ return otx2_get_rss_hash_opts (pfvf , nfc );
521
+ default :
522
+ break ;
523
+ }
524
+ return ret ;
525
+ }
526
+
527
+ static int otx2_set_rxnfc (struct net_device * dev , struct ethtool_rxnfc * nfc )
528
+ {
529
+ struct otx2_nic * pfvf = netdev_priv (dev );
530
+ int ret = - EOPNOTSUPP ;
531
+
532
+ switch (nfc -> cmd ) {
533
+ case ETHTOOL_SRXFH :
534
+ ret = otx2_set_rss_hash_opts (pfvf , nfc );
535
+ break ;
536
+ default :
537
+ break ;
538
+ }
539
+
540
+ return ret ;
541
+ }
542
+
543
+ static u32 otx2_get_rxfh_key_size (struct net_device * netdev )
544
+ {
545
+ struct otx2_nic * pfvf = netdev_priv (netdev );
546
+ struct otx2_rss_info * rss ;
547
+
548
+ rss = & pfvf -> hw .rss_info ;
549
+
550
+ return sizeof (rss -> key );
551
+ }
552
+
553
+ static u32 otx2_get_rxfh_indir_size (struct net_device * dev )
554
+ {
555
+ struct otx2_nic * pfvf = netdev_priv (dev );
556
+
557
+ return pfvf -> hw .rss_info .rss_size ;
558
+ }
559
+
560
+ /* Get RSS configuration */
561
+ static int otx2_get_rxfh (struct net_device * dev , u32 * indir ,
562
+ u8 * hkey , u8 * hfunc )
563
+ {
564
+ struct otx2_nic * pfvf = netdev_priv (dev );
565
+ struct otx2_rss_info * rss ;
566
+ int idx ;
567
+
568
+ rss = & pfvf -> hw .rss_info ;
569
+
570
+ if (indir ) {
571
+ for (idx = 0 ; idx < rss -> rss_size ; idx ++ )
572
+ indir [idx ] = rss -> ind_tbl [idx ];
573
+ }
574
+
575
+ if (hkey )
576
+ memcpy (hkey , rss -> key , sizeof (rss -> key ));
577
+
578
+ if (hfunc )
579
+ * hfunc = ETH_RSS_HASH_TOP ;
580
+
581
+ return 0 ;
582
+ }
583
+
584
+ /* Configure RSS table and hash key */
585
+ static int otx2_set_rxfh (struct net_device * dev , const u32 * indir ,
586
+ const u8 * hkey , const u8 hfunc )
587
+ {
588
+ struct otx2_nic * pfvf = netdev_priv (dev );
589
+ struct otx2_rss_info * rss ;
590
+ int idx ;
591
+
592
+ if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP )
593
+ return - EOPNOTSUPP ;
594
+
595
+ rss = & pfvf -> hw .rss_info ;
596
+
597
+ if (!rss -> enable ) {
598
+ netdev_err (dev , "RSS is disabled, cannot change settings\n" );
599
+ return - EIO ;
600
+ }
601
+
602
+ if (indir ) {
603
+ for (idx = 0 ; idx < rss -> rss_size ; idx ++ )
604
+ rss -> ind_tbl [idx ] = indir [idx ];
605
+ }
606
+
607
+ if (hkey ) {
608
+ memcpy (rss -> key , hkey , sizeof (rss -> key ));
609
+ otx2_set_rss_key (pfvf );
610
+ }
611
+
612
+ otx2_set_rss_table (pfvf );
613
+ return 0 ;
614
+ }
615
+
616
+ static u32 otx2_get_msglevel (struct net_device * netdev )
617
+ {
618
+ struct otx2_nic * pfvf = netdev_priv (netdev );
619
+
620
+ return pfvf -> msg_enable ;
621
+ }
622
+
623
+ static void otx2_set_msglevel (struct net_device * netdev , u32 val )
624
+ {
625
+ struct otx2_nic * pfvf = netdev_priv (netdev );
626
+
627
+ pfvf -> msg_enable = val ;
628
+ }
629
+
630
+ static u32 otx2_get_link (struct net_device * netdev )
631
+ {
632
+ struct otx2_nic * pfvf = netdev_priv (netdev );
633
+
634
+ return pfvf -> linfo .link_up ;
635
+ }
636
+
392
637
static const struct ethtool_ops otx2_ethtool_ops = {
638
+ .get_link = otx2_get_link ,
393
639
.get_drvinfo = otx2_get_drvinfo ,
394
640
.get_strings = otx2_get_strings ,
395
641
.get_ethtool_stats = otx2_get_ethtool_stats ,
@@ -400,6 +646,14 @@ static const struct ethtool_ops otx2_ethtool_ops = {
400
646
.set_ringparam = otx2_set_ringparam ,
401
647
.get_coalesce = otx2_get_coalesce ,
402
648
.set_coalesce = otx2_set_coalesce ,
649
+ .get_rxnfc = otx2_get_rxnfc ,
650
+ .set_rxnfc = otx2_set_rxnfc ,
651
+ .get_rxfh_key_size = otx2_get_rxfh_key_size ,
652
+ .get_rxfh_indir_size = otx2_get_rxfh_indir_size ,
653
+ .get_rxfh = otx2_get_rxfh ,
654
+ .set_rxfh = otx2_set_rxfh ,
655
+ .get_msglevel = otx2_get_msglevel ,
656
+ .set_msglevel = otx2_set_msglevel ,
403
657
};
404
658
405
659
void otx2_set_ethtool_ops (struct net_device * netdev )
0 commit comments