@@ -57,6 +57,7 @@ struct ib_port {
57
57
struct attribute_group gid_group ;
58
58
struct attribute_group pkey_group ;
59
59
u8 port_num ;
60
+ struct attribute_group * pma_table ;
60
61
};
61
62
62
63
struct port_attribute {
@@ -401,6 +402,13 @@ struct port_table_attribute port_pma_attr_##_name = { \
401
402
.attr_id = IB_PMA_PORT_COUNTERS , \
402
403
}
403
404
405
+ #define PORT_PMA_ATTR_EXT (_name , _width , _offset ) \
406
+ struct port_table_attribute port_pma_attr_ext_##_name = { \
407
+ .attr = __ATTR(_name, S_IRUGO, show_pma_counter, NULL), \
408
+ .index = (_offset) | ((_width) << 16), \
409
+ .attr_id = IB_PMA_PORT_COUNTERS_EXT , \
410
+ }
411
+
404
412
/*
405
413
* Get a Perfmgmt MAD block of data.
406
414
* Returns error code or the number of bytes retrieved.
@@ -481,6 +489,11 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
481
489
ret = sprintf (buf , "%u\n" ,
482
490
be32_to_cpup ((__be32 * )data ));
483
491
break ;
492
+ case 64 :
493
+ ret = sprintf (buf , "%llu\n" ,
494
+ be64_to_cpup ((__be64 * )data ));
495
+ break ;
496
+
484
497
default :
485
498
ret = 0 ;
486
499
}
@@ -505,6 +518,18 @@ static PORT_PMA_ATTR(port_rcv_data , 13, 32, 224);
505
518
static PORT_PMA_ATTR (port_xmit_packets , 14 , 32 , 256 ) ;
506
519
static PORT_PMA_ATTR (port_rcv_packets , 15 , 32 , 288 ) ;
507
520
521
+ /*
522
+ * Counters added by extended set
523
+ */
524
+ static PORT_PMA_ATTR_EXT (port_xmit_data , 64 , 64 ) ;
525
+ static PORT_PMA_ATTR_EXT (port_rcv_data , 64 , 128 ) ;
526
+ static PORT_PMA_ATTR_EXT (port_xmit_packets , 64 , 192 ) ;
527
+ static PORT_PMA_ATTR_EXT (port_rcv_packets , 64 , 256 ) ;
528
+ static PORT_PMA_ATTR_EXT (unicast_xmit_packets , 64 , 320 ) ;
529
+ static PORT_PMA_ATTR_EXT (unicast_rcv_packets , 64 , 384 ) ;
530
+ static PORT_PMA_ATTR_EXT (multicast_xmit_packets , 64 , 448 ) ;
531
+ static PORT_PMA_ATTR_EXT (multicast_rcv_packets , 64 , 512 ) ;
532
+
508
533
static struct attribute * pma_attrs [] = {
509
534
& port_pma_attr_symbol_error .attr .attr ,
510
535
& port_pma_attr_link_error_recovery .attr .attr ,
@@ -525,11 +550,65 @@ static struct attribute *pma_attrs[] = {
525
550
NULL
526
551
};
527
552
553
+ static struct attribute * pma_attrs_ext [] = {
554
+ & port_pma_attr_symbol_error .attr .attr ,
555
+ & port_pma_attr_link_error_recovery .attr .attr ,
556
+ & port_pma_attr_link_downed .attr .attr ,
557
+ & port_pma_attr_port_rcv_errors .attr .attr ,
558
+ & port_pma_attr_port_rcv_remote_physical_errors .attr .attr ,
559
+ & port_pma_attr_port_rcv_switch_relay_errors .attr .attr ,
560
+ & port_pma_attr_port_xmit_discards .attr .attr ,
561
+ & port_pma_attr_port_xmit_constraint_errors .attr .attr ,
562
+ & port_pma_attr_port_rcv_constraint_errors .attr .attr ,
563
+ & port_pma_attr_local_link_integrity_errors .attr .attr ,
564
+ & port_pma_attr_excessive_buffer_overrun_errors .attr .attr ,
565
+ & port_pma_attr_VL15_dropped .attr .attr ,
566
+ & port_pma_attr_ext_port_xmit_data .attr .attr ,
567
+ & port_pma_attr_ext_port_rcv_data .attr .attr ,
568
+ & port_pma_attr_ext_port_xmit_packets .attr .attr ,
569
+ & port_pma_attr_ext_port_rcv_packets .attr .attr ,
570
+ & port_pma_attr_ext_unicast_rcv_packets .attr .attr ,
571
+ & port_pma_attr_ext_unicast_xmit_packets .attr .attr ,
572
+ & port_pma_attr_ext_multicast_rcv_packets .attr .attr ,
573
+ & port_pma_attr_ext_multicast_xmit_packets .attr .attr ,
574
+ NULL
575
+ };
576
+
577
+ static struct attribute * pma_attrs_noietf [] = {
578
+ & port_pma_attr_symbol_error .attr .attr ,
579
+ & port_pma_attr_link_error_recovery .attr .attr ,
580
+ & port_pma_attr_link_downed .attr .attr ,
581
+ & port_pma_attr_port_rcv_errors .attr .attr ,
582
+ & port_pma_attr_port_rcv_remote_physical_errors .attr .attr ,
583
+ & port_pma_attr_port_rcv_switch_relay_errors .attr .attr ,
584
+ & port_pma_attr_port_xmit_discards .attr .attr ,
585
+ & port_pma_attr_port_xmit_constraint_errors .attr .attr ,
586
+ & port_pma_attr_port_rcv_constraint_errors .attr .attr ,
587
+ & port_pma_attr_local_link_integrity_errors .attr .attr ,
588
+ & port_pma_attr_excessive_buffer_overrun_errors .attr .attr ,
589
+ & port_pma_attr_VL15_dropped .attr .attr ,
590
+ & port_pma_attr_ext_port_xmit_data .attr .attr ,
591
+ & port_pma_attr_ext_port_rcv_data .attr .attr ,
592
+ & port_pma_attr_ext_port_xmit_packets .attr .attr ,
593
+ & port_pma_attr_ext_port_rcv_packets .attr .attr ,
594
+ NULL
595
+ };
596
+
528
597
static struct attribute_group pma_group = {
529
598
.name = "counters" ,
530
599
.attrs = pma_attrs
531
600
};
532
601
602
+ static struct attribute_group pma_group_ext = {
603
+ .name = "counters" ,
604
+ .attrs = pma_attrs_ext
605
+ };
606
+
607
+ static struct attribute_group pma_group_noietf = {
608
+ .name = "counters" ,
609
+ .attrs = pma_attrs_noietf
610
+ };
611
+
533
612
static void ib_port_release (struct kobject * kobj )
534
613
{
535
614
struct ib_port * p = container_of (kobj , struct ib_port , kobj );
@@ -631,6 +710,30 @@ alloc_group_attrs(ssize_t (*show)(struct ib_port *,
631
710
return NULL ;
632
711
}
633
712
713
+ /*
714
+ * Figure out which counter table to use depending on
715
+ * the device capabilities.
716
+ */
717
+ static struct attribute_group * get_counter_table (struct ib_device * dev )
718
+ {
719
+ struct ib_class_port_info cpi ;
720
+
721
+ if (get_perf_mad (dev , 0 , IB_PMA_CLASS_PORT_INFO ,
722
+ & cpi , 40 , sizeof (cpi )) >= 0 ) {
723
+
724
+ if (cpi .capability_mask && IB_PMA_CLASS_CAP_EXT_WIDTH )
725
+ /* We have extended counters */
726
+ return & pma_group_ext ;
727
+
728
+ if (cpi .capability_mask && IB_PMA_CLASS_CAP_EXT_WIDTH_NOIETF )
729
+ /* But not the IETF ones */
730
+ return & pma_group_noietf ;
731
+ }
732
+
733
+ /* Fall back to normal counters */
734
+ return & pma_group ;
735
+ }
736
+
634
737
static int add_port (struct ib_device * device , int port_num ,
635
738
int (* port_callback )(struct ib_device * ,
636
739
u8 , struct kobject * ))
@@ -673,7 +776,8 @@ static int add_port(struct ib_device *device, int port_num,
673
776
goto err_put ;
674
777
}
675
778
676
- ret = sysfs_create_group (& p -> kobj , & pma_group );
779
+ p -> pma_table = get_counter_table (device );
780
+ ret = sysfs_create_group (& p -> kobj , p -> pma_table );
677
781
if (ret )
678
782
goto err_put_gid_attrs ;
679
783
@@ -780,7 +884,7 @@ static int add_port(struct ib_device *device, int port_num,
780
884
p -> gid_group .attrs = NULL ;
781
885
782
886
err_remove_pma :
783
- sysfs_remove_group (& p -> kobj , & pma_group );
887
+ sysfs_remove_group (& p -> kobj , p -> pma_table );
784
888
785
889
err_put_gid_attrs :
786
890
kobject_put (& p -> gid_attr_group -> kobj );
@@ -990,7 +1094,7 @@ static void free_port_list_attributes(struct ib_device *device)
990
1094
list_for_each_entry_safe (p , t , & device -> port_list , entry ) {
991
1095
struct ib_port * port = container_of (p , struct ib_port , kobj );
992
1096
list_del (& p -> entry );
993
- sysfs_remove_group (p , & pma_group );
1097
+ sysfs_remove_group (p , port -> pma_table );
994
1098
sysfs_remove_group (p , & port -> pkey_group );
995
1099
sysfs_remove_group (p , & port -> gid_group );
996
1100
sysfs_remove_group (& port -> gid_attr_group -> kobj ,
0 commit comments