@@ -515,6 +515,83 @@ static void hns_roce_get_fw_ver(struct ib_device *device, char *str)
515515 sub_minor );
516516}
517517
518+ #define HNS_ROCE_HW_CNT (ename , cname ) \
519+ [HNS_ROCE_HW_##ename##_CNT].name = cname
520+
521+ static const struct rdma_stat_desc hns_roce_port_stats_descs [] = {
522+ HNS_ROCE_HW_CNT (RX_RC_PKT , "rx_rc_pkt" ),
523+ HNS_ROCE_HW_CNT (RX_UC_PKT , "rx_uc_pkt" ),
524+ HNS_ROCE_HW_CNT (RX_UD_PKT , "rx_ud_pkt" ),
525+ HNS_ROCE_HW_CNT (RX_XRC_PKT , "rx_xrc_pkt" ),
526+ HNS_ROCE_HW_CNT (RX_PKT , "rx_pkt" ),
527+ HNS_ROCE_HW_CNT (RX_ERR_PKT , "rx_err_pkt" ),
528+ HNS_ROCE_HW_CNT (RX_CNP_PKT , "rx_cnp_pkt" ),
529+ HNS_ROCE_HW_CNT (TX_RC_PKT , "tx_rc_pkt" ),
530+ HNS_ROCE_HW_CNT (TX_UC_PKT , "tx_uc_pkt" ),
531+ HNS_ROCE_HW_CNT (TX_UD_PKT , "tx_ud_pkt" ),
532+ HNS_ROCE_HW_CNT (TX_XRC_PKT , "tx_xrc_pkt" ),
533+ HNS_ROCE_HW_CNT (TX_PKT , "tx_pkt" ),
534+ HNS_ROCE_HW_CNT (TX_ERR_PKT , "tx_err_pkt" ),
535+ HNS_ROCE_HW_CNT (TX_CNP_PKT , "tx_cnp_pkt" ),
536+ HNS_ROCE_HW_CNT (TRP_GET_MPT_ERR_PKT , "trp_get_mpt_err_pkt" ),
537+ HNS_ROCE_HW_CNT (TRP_GET_IRRL_ERR_PKT , "trp_get_irrl_err_pkt" ),
538+ HNS_ROCE_HW_CNT (ECN_DB , "ecn_doorbell" ),
539+ HNS_ROCE_HW_CNT (RX_BUF , "rx_buffer" ),
540+ HNS_ROCE_HW_CNT (TRP_RX_SOF , "trp_rx_sof" ),
541+ HNS_ROCE_HW_CNT (CQ_CQE , "cq_cqe" ),
542+ HNS_ROCE_HW_CNT (CQ_POE , "cq_poe" ),
543+ HNS_ROCE_HW_CNT (CQ_NOTIFY , "cq_notify" ),
544+ };
545+
546+ static struct rdma_hw_stats * hns_roce_alloc_hw_port_stats (
547+ struct ib_device * device , u32 port_num )
548+ {
549+ struct hns_roce_dev * hr_dev = to_hr_dev (device );
550+ u32 port = port_num - 1 ;
551+
552+ if (port > hr_dev -> caps .num_ports ) {
553+ ibdev_err (device , "invalid port num.\n" );
554+ return NULL ;
555+ }
556+
557+ if (hr_dev -> pci_dev -> revision <= PCI_REVISION_ID_HIP08 ||
558+ hr_dev -> is_vf )
559+ return NULL ;
560+
561+ return rdma_alloc_hw_stats_struct (hns_roce_port_stats_descs ,
562+ ARRAY_SIZE (hns_roce_port_stats_descs ),
563+ RDMA_HW_STATS_DEFAULT_LIFESPAN );
564+ }
565+
566+ static int hns_roce_get_hw_stats (struct ib_device * device ,
567+ struct rdma_hw_stats * stats ,
568+ u32 port , int index )
569+ {
570+ struct hns_roce_dev * hr_dev = to_hr_dev (device );
571+ int num_counters = HNS_ROCE_HW_CNT_TOTAL ;
572+ int ret ;
573+
574+ if (port == 0 )
575+ return 0 ;
576+
577+ if (port > hr_dev -> caps .num_ports )
578+ return - EINVAL ;
579+
580+ if (hr_dev -> pci_dev -> revision <= PCI_REVISION_ID_HIP08 ||
581+ hr_dev -> is_vf )
582+ return - EOPNOTSUPP ;
583+
584+ ret = hr_dev -> hw -> query_hw_counter (hr_dev , stats -> value , port ,
585+ & num_counters );
586+ if (ret ) {
587+ ibdev_err (device , "failed to query hw counter, ret = %d\n" ,
588+ ret );
589+ return ret ;
590+ }
591+
592+ return num_counters ;
593+ }
594+
518595static void hns_roce_unregister_device (struct hns_roce_dev * hr_dev )
519596{
520597 struct hns_roce_ib_iboe * iboe = & hr_dev -> iboe ;
@@ -557,6 +634,8 @@ static const struct ib_device_ops hns_roce_dev_ops = {
557634 .query_pkey = hns_roce_query_pkey ,
558635 .query_port = hns_roce_query_port ,
559636 .reg_user_mr = hns_roce_reg_user_mr ,
637+ .alloc_hw_port_stats = hns_roce_alloc_hw_port_stats ,
638+ .get_hw_stats = hns_roce_get_hw_stats ,
560639
561640 INIT_RDMA_OBJ_SIZE (ib_ah , hns_roce_ah , ibah ),
562641 INIT_RDMA_OBJ_SIZE (ib_cq , hns_roce_cq , ib_cq ),
0 commit comments