@@ -398,21 +398,21 @@ struct port_table_attribute port_pma_attr_##_name = { \
398
398
.index = (_offset) | ((_width) << 16) | ((_counter) << 24) \
399
399
}
400
400
401
- static ssize_t show_pma_counter (struct ib_port * p , struct port_attribute * attr ,
402
- char * buf )
401
+ /*
402
+ * Get a Perfmgmt MAD block of data.
403
+ * Returns error code or the number of bytes retrieved.
404
+ */
405
+ static int get_perf_mad (struct ib_device * dev , int port_num , int attr ,
406
+ void * data , int offset , size_t size )
403
407
{
404
- struct port_table_attribute * tab_attr =
405
- container_of (attr , struct port_table_attribute , attr );
406
- int offset = tab_attr -> index & 0xffff ;
407
- int width = (tab_attr -> index >> 16 ) & 0xff ;
408
- struct ib_mad * in_mad = NULL ;
409
- struct ib_mad * out_mad = NULL ;
408
+ struct ib_mad * in_mad ;
409
+ struct ib_mad * out_mad ;
410
410
size_t mad_size = sizeof (* out_mad );
411
411
u16 out_mad_pkey_index = 0 ;
412
412
ssize_t ret ;
413
413
414
- if (!p -> ibdev -> process_mad )
415
- return sprintf ( buf , "N/A (no PMA)\n" ) ;
414
+ if (!dev -> process_mad )
415
+ return - ENOSYS ;
416
416
417
417
in_mad = kzalloc (sizeof * in_mad , GFP_KERNEL );
418
418
out_mad = kmalloc (sizeof * out_mad , GFP_KERNEL );
@@ -425,12 +425,12 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
425
425
in_mad -> mad_hdr .mgmt_class = IB_MGMT_CLASS_PERF_MGMT ;
426
426
in_mad -> mad_hdr .class_version = 1 ;
427
427
in_mad -> mad_hdr .method = IB_MGMT_METHOD_GET ;
428
- in_mad -> mad_hdr .attr_id = cpu_to_be16 ( 0x12 ); /* PortCounters */
428
+ in_mad -> mad_hdr .attr_id = attr ;
429
429
430
- in_mad -> data [41 ] = p -> port_num ; /* PortSelect field */
430
+ in_mad -> data [41 ] = port_num ; /* PortSelect field */
431
431
432
- if ((p -> ibdev -> process_mad (p -> ibdev , IB_MAD_IGNORE_MKEY ,
433
- p -> port_num , NULL , NULL ,
432
+ if ((dev -> process_mad (dev , IB_MAD_IGNORE_MKEY ,
433
+ port_num , NULL , NULL ,
434
434
(const struct ib_mad_hdr * )in_mad , mad_size ,
435
435
(struct ib_mad_hdr * )out_mad , & mad_size ,
436
436
& out_mad_pkey_index ) &
@@ -439,31 +439,49 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
439
439
ret = - EINVAL ;
440
440
goto out ;
441
441
}
442
+ memcpy (data , out_mad -> data + offset , size );
443
+ ret = size ;
444
+ out :
445
+ kfree (in_mad );
446
+ kfree (out_mad );
447
+ return ret ;
448
+ }
449
+
450
+ static ssize_t show_pma_counter (struct ib_port * p , struct port_attribute * attr ,
451
+ char * buf )
452
+ {
453
+ struct port_table_attribute * tab_attr =
454
+ container_of (attr , struct port_table_attribute , attr );
455
+ int offset = tab_attr -> index & 0xffff ;
456
+ int width = (tab_attr -> index >> 16 ) & 0xff ;
457
+ ssize_t ret ;
458
+ u8 data [8 ];
459
+
460
+ ret = get_perf_mad (p -> ibdev , p -> port_num , cpu_to_be16 (0x12 ), & data ,
461
+ 40 + offset / 8 , sizeof (data ));
462
+ if (ret < 0 )
463
+ return sprintf (buf , "N/A (no PMA)\n" );
442
464
443
465
switch (width ) {
444
466
case 4 :
445
- ret = sprintf (buf , "%u\n" , (out_mad -> data [ 40 + offset / 8 ] >>
467
+ ret = sprintf (buf , "%u\n" , (* data >>
446
468
(4 - (offset % 8 ))) & 0xf );
447
469
break ;
448
470
case 8 :
449
- ret = sprintf (buf , "%u\n" , out_mad -> data [ 40 + offset / 8 ] );
471
+ ret = sprintf (buf , "%u\n" , * data );
450
472
break ;
451
473
case 16 :
452
474
ret = sprintf (buf , "%u\n" ,
453
- be16_to_cpup ((__be16 * )( out_mad -> data + 40 + offset / 8 ) ));
475
+ be16_to_cpup ((__be16 * )data ));
454
476
break ;
455
477
case 32 :
456
478
ret = sprintf (buf , "%u\n" ,
457
- be32_to_cpup ((__be32 * )( out_mad -> data + 40 + offset / 8 ) ));
479
+ be32_to_cpup ((__be32 * )data ));
458
480
break ;
459
481
default :
460
482
ret = 0 ;
461
483
}
462
484
463
- out :
464
- kfree (in_mad );
465
- kfree (out_mad );
466
-
467
485
return ret ;
468
486
}
469
487
0 commit comments