aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKamenee Arumugam <kamenee.arumugam@intel.com>2018-02-01 13:52:28 -0500
committerJason Gunthorpe <jgg@mellanox.com>2018-02-01 17:43:30 -0500
commit0719007663ce2d5da653ec1dc3bcfe2ab681b964 (patch)
treed5433c8d8618a90741963986cf9c105b7e75e75c
parent6391214f4d80e32caf622bacab64ed99ed43e1eb (diff)
IB/hfi1: Convert PortXmitWait/PortVLXmitWait counters to flit times
HFI's counters SendWaitCnt and SendWaitVlCnt are in units of TXE cycle time (at 805MHz). OPA counters PortXmitWait and PortVLXmtWait are in units of flit times. Convert the counter values to flit units using following conversion formula: PortXmitWait = SendWaitCnt * 2 * (4 /link_width) * (25 Gbps /link_speed) PortVLXmitWait = SendWaitVLCnt * 2 * (4 /link_width) * (25 Gbps /link_speed) At link up or downgrade events, the link width can change. To ensure accurate counter calculations, sample the counters after the events, during counter requests, and then aggregate the OPA counters. Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com> Signed-off-by: Kamenee Arumugam <kamenee.arumugam@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
-rw-r--r--drivers/infiniband/hw/hfi1/chip.c64
-rw-r--r--drivers/infiniband/hw/hfi1/chip.h4
-rw-r--r--drivers/infiniband/hw/hfi1/hfi.h7
-rw-r--r--drivers/infiniband/hw/hfi1/init.c9
-rw-r--r--drivers/infiniband/hw/hfi1/mad.c127
-rw-r--r--drivers/infiniband/hw/hfi1/mad.h47
6 files changed, 239 insertions, 19 deletions
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c
index 57f0df2f84f2..e6a60fa59f2b 100644
--- a/drivers/infiniband/hw/hfi1/chip.c
+++ b/drivers/infiniband/hw/hfi1/chip.c
@@ -1083,6 +1083,7 @@ static int qos_rmt_entries(struct hfi1_devdata *dd, unsigned int *mp,
1083static void clear_full_mgmt_pkey(struct hfi1_pportdata *ppd); 1083static void clear_full_mgmt_pkey(struct hfi1_pportdata *ppd);
1084static int wait_link_transfer_active(struct hfi1_devdata *dd, int wait_ms); 1084static int wait_link_transfer_active(struct hfi1_devdata *dd, int wait_ms);
1085static void clear_rsm_rule(struct hfi1_devdata *dd, u8 rule_index); 1085static void clear_rsm_rule(struct hfi1_devdata *dd, u8 rule_index);
1086static void update_xmit_counters(struct hfi1_pportdata *ppd, u16 link_width);
1086 1087
1087/* 1088/*
1088 * Error interrupt table entry. This is used as input to the interrupt 1089 * Error interrupt table entry. This is used as input to the interrupt
@@ -6905,6 +6906,32 @@ void handle_freeze(struct work_struct *work)
6905 /* no longer frozen */ 6906 /* no longer frozen */
6906} 6907}
6907 6908
6909/**
6910 * update_xmit_counters - update PortXmitWait/PortVlXmitWait
6911 * counters.
6912 * @ppd: info of physical Hfi port
6913 * @link_width: new link width after link up or downgrade
6914 *
6915 * Update the PortXmitWait and PortVlXmitWait counters after
6916 * a link up or downgrade event to reflect a link width change.
6917 */
6918static void update_xmit_counters(struct hfi1_pportdata *ppd, u16 link_width)
6919{
6920 int i;
6921 u16 tx_width;
6922 u16 link_speed;
6923
6924 tx_width = tx_link_width(link_width);
6925 link_speed = get_link_speed(ppd->link_speed_active);
6926
6927 /*
6928 * There are C_VL_COUNT number of PortVLXmitWait counters.
6929 * Adding 1 to C_VL_COUNT to include the PortXmitWait counter.
6930 */
6931 for (i = 0; i < C_VL_COUNT + 1; i++)
6932 get_xmit_wait_counters(ppd, tx_width, link_speed, i);
6933}
6934
6908/* 6935/*
6909 * Handle a link up interrupt from the 8051. 6936 * Handle a link up interrupt from the 8051.
6910 * 6937 *
@@ -7526,18 +7553,29 @@ void handle_verify_cap(struct work_struct *work)
7526 set_link_state(ppd, HLS_GOING_UP); 7553 set_link_state(ppd, HLS_GOING_UP);
7527} 7554}
7528 7555
7529/* 7556/**
7530 * Apply the link width downgrade enabled policy against the current active 7557 * apply_link_downgrade_policy - Apply the link width downgrade enabled
7531 * link widths. 7558 * policy against the current active link widths.
7559 * @ppd: info of physical Hfi port
7560 * @refresh_widths: True indicates link downgrade event
7561 * @return: True indicates a successful link downgrade. False indicates
7562 * link downgrade event failed and the link will bounce back to
7563 * default link width.
7532 * 7564 *
7533 * Called when the enabled policy changes or the active link widths change. 7565 * Called when the enabled policy changes or the active link widths
7566 * change.
7567 * Refresh_widths indicates that a link downgrade occurred. The
7568 * link_downgraded variable is set by refresh_widths and
7569 * determines the success/failure of the policy application.
7534 */ 7570 */
7535void apply_link_downgrade_policy(struct hfi1_pportdata *ppd, int refresh_widths) 7571bool apply_link_downgrade_policy(struct hfi1_pportdata *ppd,
7572 bool refresh_widths)
7536{ 7573{
7537 int do_bounce = 0; 7574 int do_bounce = 0;
7538 int tries; 7575 int tries;
7539 u16 lwde; 7576 u16 lwde;
7540 u16 tx, rx; 7577 u16 tx, rx;
7578 bool link_downgraded = refresh_widths;
7541 7579
7542 /* use the hls lock to avoid a race with actual link up */ 7580 /* use the hls lock to avoid a race with actual link up */
7543 tries = 0; 7581 tries = 0;
@@ -7571,6 +7609,7 @@ retry:
7571 ppd->link_width_downgrade_rx_active == 0) { 7609 ppd->link_width_downgrade_rx_active == 0) {
7572 /* the 8051 reported a dead link as a downgrade */ 7610 /* the 8051 reported a dead link as a downgrade */
7573 dd_dev_err(ppd->dd, "Link downgrade is really a link down, ignoring\n"); 7611 dd_dev_err(ppd->dd, "Link downgrade is really a link down, ignoring\n");
7612 link_downgraded = false;
7574 } else if (lwde == 0) { 7613 } else if (lwde == 0) {
7575 /* downgrade is disabled */ 7614 /* downgrade is disabled */
7576 7615
@@ -7587,6 +7626,7 @@ retry:
7587 ppd->link_width_downgrade_tx_active, 7626 ppd->link_width_downgrade_tx_active,
7588 ppd->link_width_downgrade_rx_active); 7627 ppd->link_width_downgrade_rx_active);
7589 do_bounce = 1; 7628 do_bounce = 1;
7629 link_downgraded = false;
7590 } 7630 }
7591 } else if ((lwde & ppd->link_width_downgrade_tx_active) == 0 || 7631 } else if ((lwde & ppd->link_width_downgrade_tx_active) == 0 ||
7592 (lwde & ppd->link_width_downgrade_rx_active) == 0) { 7632 (lwde & ppd->link_width_downgrade_rx_active) == 0) {
@@ -7598,6 +7638,7 @@ retry:
7598 lwde, ppd->link_width_downgrade_tx_active, 7638 lwde, ppd->link_width_downgrade_tx_active,
7599 ppd->link_width_downgrade_rx_active); 7639 ppd->link_width_downgrade_rx_active);
7600 do_bounce = 1; 7640 do_bounce = 1;
7641 link_downgraded = false;
7601 } 7642 }
7602 7643
7603done: 7644done:
@@ -7609,6 +7650,8 @@ done:
7609 set_link_state(ppd, HLS_DN_OFFLINE); 7650 set_link_state(ppd, HLS_DN_OFFLINE);
7610 start_link(ppd); 7651 start_link(ppd);
7611 } 7652 }
7653
7654 return link_downgraded;
7612} 7655}
7613 7656
7614/* 7657/*
@@ -7622,7 +7665,8 @@ void handle_link_downgrade(struct work_struct *work)
7622 link_downgrade_work); 7665 link_downgrade_work);
7623 7666
7624 dd_dev_info(ppd->dd, "8051: Link width downgrade\n"); 7667 dd_dev_info(ppd->dd, "8051: Link width downgrade\n");
7625 apply_link_downgrade_policy(ppd, 1); 7668 if (apply_link_downgrade_policy(ppd, true))
7669 update_xmit_counters(ppd, ppd->link_width_downgrade_tx_active);
7626} 7670}
7627 7671
7628static char *dcc_err_string(char *buf, int buf_len, u64 flags) 7672static char *dcc_err_string(char *buf, int buf_len, u64 flags)
@@ -10597,6 +10641,14 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)
10597 add_rcvctrl(dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK); 10641 add_rcvctrl(dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK);
10598 10642
10599 handle_linkup_change(dd, 1); 10643 handle_linkup_change(dd, 1);
10644
10645 /*
10646 * After link up, a new link width will have been set.
10647 * Update the xmit counters with regards to the new
10648 * link width.
10649 */
10650 update_xmit_counters(ppd, ppd->link_width_active);
10651
10600 ppd->host_link_state = HLS_UP_INIT; 10652 ppd->host_link_state = HLS_UP_INIT;
10601 update_statusp(ppd, IB_PORT_INIT); 10653 update_statusp(ppd, IB_PORT_INIT);
10602 break; 10654 break;
diff --git a/drivers/infiniband/hw/hfi1/chip.h b/drivers/infiniband/hw/hfi1/chip.h
index 21fca8ec5076..c0d70f255050 100644
--- a/drivers/infiniband/hw/hfi1/chip.h
+++ b/drivers/infiniband/hw/hfi1/chip.h
@@ -736,8 +736,8 @@ int read_8051_config(struct hfi1_devdata *, u8, u8, u32 *);
736int start_link(struct hfi1_pportdata *ppd); 736int start_link(struct hfi1_pportdata *ppd);
737int bringup_serdes(struct hfi1_pportdata *ppd); 737int bringup_serdes(struct hfi1_pportdata *ppd);
738void set_intr_state(struct hfi1_devdata *dd, u32 enable); 738void set_intr_state(struct hfi1_devdata *dd, u32 enable);
739void apply_link_downgrade_policy(struct hfi1_pportdata *ppd, 739bool apply_link_downgrade_policy(struct hfi1_pportdata *ppd,
740 int refresh_widths); 740 bool refresh_widths);
741void update_usrhead(struct hfi1_ctxtdata *rcd, u32 hd, u32 updegr, u32 egrhd, 741void update_usrhead(struct hfi1_ctxtdata *rcd, u32 hd, u32 updegr, u32 egrhd,
742 u32 intr_adjust, u32 npkts); 742 u32 intr_adjust, u32 npkts);
743int stop_drain_data_vls(struct hfi1_devdata *dd); 743int stop_drain_data_vls(struct hfi1_devdata *dd);
diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h
index 105d11dcc554..90bc8c76d2ca 100644
--- a/drivers/infiniband/hw/hfi1/hfi.h
+++ b/drivers/infiniband/hw/hfi1/hfi.h
@@ -858,6 +858,13 @@ struct hfi1_pportdata {
858 struct work_struct linkstate_active_work; 858 struct work_struct linkstate_active_work;
859 /* Does this port need to prescan for FECNs */ 859 /* Does this port need to prescan for FECNs */
860 bool cc_prescan; 860 bool cc_prescan;
861 /*
862 * Sample sendWaitCnt & sendWaitVlCnt during link transition
863 * and counter request.
864 */
865 u64 port_vl_xmit_wait_last[C_VL_COUNT + 1];
866 u16 prev_link_width;
867 u64 vl_xmit_flit_cnt[C_VL_COUNT + 1];
861}; 868};
862 869
863typedef int (*rhf_rcv_function_ptr)(struct hfi1_packet *packet); 870typedef int (*rhf_rcv_function_ptr)(struct hfi1_packet *packet);
diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c
index 4c51a75b238a..8c4f04032b28 100644
--- a/drivers/infiniband/hw/hfi1/init.c
+++ b/drivers/infiniband/hw/hfi1/init.c
@@ -637,6 +637,15 @@ void hfi1_init_pportdata(struct pci_dev *pdev, struct hfi1_pportdata *ppd,
637 ppd->dd = dd; 637 ppd->dd = dd;
638 ppd->hw_pidx = hw_pidx; 638 ppd->hw_pidx = hw_pidx;
639 ppd->port = port; /* IB port number, not index */ 639 ppd->port = port; /* IB port number, not index */
640 ppd->prev_link_width = LINK_WIDTH_DEFAULT;
641 /*
642 * There are C_VL_COUNT number of PortVLXmitWait counters.
643 * Adding 1 to C_VL_COUNT to include the PortXmitWait counter.
644 */
645 for (i = 0; i < C_VL_COUNT + 1; i++) {
646 ppd->port_vl_xmit_wait_last[i] = 0;
647 ppd->vl_xmit_flit_cnt[i] = 0;
648 }
640 649
641 default_pkey_idx = 1; 650 default_pkey_idx = 1;
642 651
diff --git a/drivers/infiniband/hw/hfi1/mad.c b/drivers/infiniband/hw/hfi1/mad.c
index 34547a48a445..e9962c65c68f 100644
--- a/drivers/infiniband/hw/hfi1/mad.c
+++ b/drivers/infiniband/hw/hfi1/mad.c
@@ -2649,6 +2649,79 @@ static void a0_portstatus(struct hfi1_pportdata *ppd,
2649 } 2649 }
2650} 2650}
2651 2651
2652/**
2653 * tx_link_width - convert link width bitmask to integer
2654 * value representing actual link width.
2655 * @link_width: width of active link
2656 * @return: return index of the bit set in link_width var
2657 *
2658 * The function convert and return the index of bit set
2659 * that indicate the current link width.
2660 */
2661u16 tx_link_width(u16 link_width)
2662{
2663 int n = LINK_WIDTH_DEFAULT;
2664 u16 tx_width = n;
2665
2666 while (link_width && n) {
2667 if (link_width & (1 << (n - 1))) {
2668 tx_width = n;
2669 break;
2670 }
2671 n--;
2672 }
2673
2674 return tx_width;
2675}
2676
2677/**
2678 * get_xmit_wait_counters - Convert HFI 's SendWaitCnt/SendWaitVlCnt
2679 * counter in unit of TXE cycle times to flit times.
2680 * @ppd: info of physical Hfi port
2681 * @link_width: width of active link
2682 * @link_speed: speed of active link
2683 * @vl: represent VL0-VL7, VL15 for PortVLXmitWait counters request
2684 * and if vl value is C_VL_COUNT, it represent SendWaitCnt
2685 * counter request
2686 * @return: return SendWaitCnt/SendWaitVlCnt counter value per vl.
2687 *
2688 * Convert SendWaitCnt/SendWaitVlCnt counter from TXE cycle times to
2689 * flit times. Call this function to samples these counters. This
2690 * function will calculate for previous state transition and update
2691 * current state at end of function using ppd->prev_link_width and
2692 * ppd->port_vl_xmit_wait_last to port_vl_xmit_wait_curr and link_width.
2693 */
2694u64 get_xmit_wait_counters(struct hfi1_pportdata *ppd,
2695 u16 link_width, u16 link_speed, int vl)
2696{
2697 u64 port_vl_xmit_wait_curr;
2698 u64 delta_vl_xmit_wait;
2699 u64 xmit_wait_val;
2700
2701 if (vl > C_VL_COUNT)
2702 return 0;
2703 if (vl < C_VL_COUNT)
2704 port_vl_xmit_wait_curr =
2705 read_port_cntr(ppd, C_TX_WAIT_VL, vl);
2706 else
2707 port_vl_xmit_wait_curr =
2708 read_port_cntr(ppd, C_TX_WAIT, CNTR_INVALID_VL);
2709
2710 xmit_wait_val =
2711 port_vl_xmit_wait_curr -
2712 ppd->port_vl_xmit_wait_last[vl];
2713 delta_vl_xmit_wait =
2714 convert_xmit_counter(xmit_wait_val,
2715 ppd->prev_link_width,
2716 link_speed);
2717
2718 ppd->vl_xmit_flit_cnt[vl] += delta_vl_xmit_wait;
2719 ppd->port_vl_xmit_wait_last[vl] = port_vl_xmit_wait_curr;
2720 ppd->prev_link_width = link_width;
2721
2722 return ppd->vl_xmit_flit_cnt[vl];
2723}
2724
2652static int pma_get_opa_portstatus(struct opa_pma_mad *pmp, 2725static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
2653 struct ib_device *ibdev, 2726 struct ib_device *ibdev,
2654 u8 port, u32 *resp_len) 2727 u8 port, u32 *resp_len)
@@ -2668,6 +2741,8 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
2668 struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); 2741 struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
2669 int vfi; 2742 int vfi;
2670 u64 tmp, tmp2; 2743 u64 tmp, tmp2;
2744 u16 link_width;
2745 u16 link_speed;
2671 2746
2672 response_data_size = sizeof(struct opa_port_status_rsp) + 2747 response_data_size = sizeof(struct opa_port_status_rsp) +
2673 num_vls * sizeof(struct _vls_pctrs); 2748 num_vls * sizeof(struct _vls_pctrs);
@@ -2711,8 +2786,16 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
2711 rsp->port_multicast_rcv_pkts = 2786 rsp->port_multicast_rcv_pkts =
2712 cpu_to_be64(read_dev_cntr(dd, C_DC_MC_RCV_PKTS, 2787 cpu_to_be64(read_dev_cntr(dd, C_DC_MC_RCV_PKTS,
2713 CNTR_INVALID_VL)); 2788 CNTR_INVALID_VL));
2789 /*
2790 * Convert PortXmitWait counter from TXE cycle times
2791 * to flit times.
2792 */
2793 link_width =
2794 tx_link_width(ppd->link_width_downgrade_tx_active);
2795 link_speed = get_link_speed(ppd->link_speed_active);
2714 rsp->port_xmit_wait = 2796 rsp->port_xmit_wait =
2715 cpu_to_be64(read_port_cntr(ppd, C_TX_WAIT, CNTR_INVALID_VL)); 2797 cpu_to_be64(get_xmit_wait_counters(ppd, link_width,
2798 link_speed, C_VL_COUNT));
2716 rsp->port_rcv_fecn = 2799 rsp->port_rcv_fecn =
2717 cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN, CNTR_INVALID_VL)); 2800 cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN, CNTR_INVALID_VL));
2718 rsp->port_rcv_becn = 2801 rsp->port_rcv_becn =
@@ -2777,10 +2860,14 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
2777 rsp->vls[vfi].port_vl_xmit_pkts = 2860 rsp->vls[vfi].port_vl_xmit_pkts =
2778 cpu_to_be64(read_port_cntr(ppd, C_TX_PKT_VL, 2861 cpu_to_be64(read_port_cntr(ppd, C_TX_PKT_VL,
2779 idx_from_vl(vl))); 2862 idx_from_vl(vl)));
2780 2863 /*
2864 * Convert PortVlXmitWait counter from TXE cycle
2865 * times to flit times.
2866 */
2781 rsp->vls[vfi].port_vl_xmit_wait = 2867 rsp->vls[vfi].port_vl_xmit_wait =
2782 cpu_to_be64(read_port_cntr(ppd, C_TX_WAIT_VL, 2868 cpu_to_be64(get_xmit_wait_counters(ppd, link_width,
2783 idx_from_vl(vl))); 2869 link_speed,
2870 idx_from_vl(vl)));
2784 2871
2785 rsp->vls[vfi].port_vl_rcv_fecn = 2872 rsp->vls[vfi].port_vl_rcv_fecn =
2786 cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN_VL, 2873 cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN_VL,
@@ -2910,6 +2997,8 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
2910 unsigned long vl; 2997 unsigned long vl;
2911 u32 vl_select_mask; 2998 u32 vl_select_mask;
2912 int vfi; 2999 int vfi;
3000 u16 link_width;
3001 u16 link_speed;
2913 3002
2914 num_ports = be32_to_cpu(pmp->mad_hdr.attr_mod) >> 24; 3003 num_ports = be32_to_cpu(pmp->mad_hdr.attr_mod) >> 24;
2915 num_vls = hweight32(be32_to_cpu(req->vl_select_mask)); 3004 num_vls = hweight32(be32_to_cpu(req->vl_select_mask));
@@ -2959,8 +3048,16 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
2959 rsp->link_quality_indicator = cpu_to_be32((u32)lq); 3048 rsp->link_quality_indicator = cpu_to_be32((u32)lq);
2960 pma_get_opa_port_dctrs(ibdev, rsp); 3049 pma_get_opa_port_dctrs(ibdev, rsp);
2961 3050
3051 /*
3052 * Convert PortXmitWait counter from TXE
3053 * cycle times to flit times.
3054 */
3055 link_width =
3056 tx_link_width(ppd->link_width_downgrade_tx_active);
3057 link_speed = get_link_speed(ppd->link_speed_active);
2962 rsp->port_xmit_wait = 3058 rsp->port_xmit_wait =
2963 cpu_to_be64(read_port_cntr(ppd, C_TX_WAIT, CNTR_INVALID_VL)); 3059 cpu_to_be64(get_xmit_wait_counters(ppd, link_width,
3060 link_speed, C_VL_COUNT));
2964 rsp->port_rcv_fecn = 3061 rsp->port_rcv_fecn =
2965 cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN, CNTR_INVALID_VL)); 3062 cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN, CNTR_INVALID_VL));
2966 rsp->port_rcv_becn = 3063 rsp->port_rcv_becn =
@@ -2996,9 +3093,14 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
2996 cpu_to_be64(read_dev_cntr(dd, C_DC_RX_PKT_VL, 3093 cpu_to_be64(read_dev_cntr(dd, C_DC_RX_PKT_VL,
2997 idx_from_vl(vl))); 3094 idx_from_vl(vl)));
2998 3095
3096 /*
3097 * Convert PortVlXmitWait counter from TXE
3098 * cycle times to flit times.
3099 */
2999 rsp->vls[vfi].port_vl_xmit_wait = 3100 rsp->vls[vfi].port_vl_xmit_wait =
3000 cpu_to_be64(read_port_cntr(ppd, C_TX_WAIT_VL, 3101 cpu_to_be64(get_xmit_wait_counters(ppd, link_width,
3001 idx_from_vl(vl))); 3102 link_speed,
3103 idx_from_vl(vl)));
3002 3104
3003 rsp->vls[vfi].port_vl_rcv_fecn = 3105 rsp->vls[vfi].port_vl_rcv_fecn =
3004 cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN_VL, 3106 cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN_VL,
@@ -3416,9 +3518,11 @@ static int pma_set_opa_portstatus(struct opa_pma_mad *pmp,
3416 if (counter_select & CS_PORT_MCAST_RCV_PKTS) 3518 if (counter_select & CS_PORT_MCAST_RCV_PKTS)
3417 write_dev_cntr(dd, C_DC_MC_RCV_PKTS, CNTR_INVALID_VL, 0); 3519 write_dev_cntr(dd, C_DC_MC_RCV_PKTS, CNTR_INVALID_VL, 0);
3418 3520
3419 if (counter_select & CS_PORT_XMIT_WAIT) 3521 if (counter_select & CS_PORT_XMIT_WAIT) {
3420 write_port_cntr(ppd, C_TX_WAIT, CNTR_INVALID_VL, 0); 3522 write_port_cntr(ppd, C_TX_WAIT, CNTR_INVALID_VL, 0);
3421 3523 ppd->port_vl_xmit_wait_last[C_VL_COUNT] = 0;
3524 ppd->vl_xmit_flit_cnt[C_VL_COUNT] = 0;
3525 }
3422 /* ignore cs_sw_portCongestion for HFIs */ 3526 /* ignore cs_sw_portCongestion for HFIs */
3423 3527
3424 if (counter_select & CS_PORT_RCV_FECN) 3528 if (counter_select & CS_PORT_RCV_FECN)
@@ -3491,8 +3595,11 @@ static int pma_set_opa_portstatus(struct opa_pma_mad *pmp,
3491 if (counter_select & CS_PORT_RCV_PKTS) 3595 if (counter_select & CS_PORT_RCV_PKTS)
3492 write_dev_cntr(dd, C_DC_RX_PKT_VL, idx_from_vl(vl), 0); 3596 write_dev_cntr(dd, C_DC_RX_PKT_VL, idx_from_vl(vl), 0);
3493 3597
3494 if (counter_select & CS_PORT_XMIT_WAIT) 3598 if (counter_select & CS_PORT_XMIT_WAIT) {
3495 write_port_cntr(ppd, C_TX_WAIT_VL, idx_from_vl(vl), 0); 3599 write_port_cntr(ppd, C_TX_WAIT_VL, idx_from_vl(vl), 0);
3600 ppd->port_vl_xmit_wait_last[idx_from_vl(vl)] = 0;
3601 ppd->vl_xmit_flit_cnt[idx_from_vl(vl)] = 0;
3602 }
3496 3603
3497 /* sw_port_vl_congestion is 0 for HFIs */ 3604 /* sw_port_vl_congestion is 0 for HFIs */
3498 if (counter_select & CS_PORT_RCV_FECN) 3605 if (counter_select & CS_PORT_RCV_FECN)
diff --git a/drivers/infiniband/hw/hfi1/mad.h b/drivers/infiniband/hw/hfi1/mad.h
index c4938f3d97c8..2f48e6953629 100644
--- a/drivers/infiniband/hw/hfi1/mad.h
+++ b/drivers/infiniband/hw/hfi1/mad.h
@@ -180,6 +180,15 @@ struct opa_mad_notice_attr {
180#define OPA_VLARB_PREEMPT_MATRIX 3 180#define OPA_VLARB_PREEMPT_MATRIX 3
181 181
182#define IB_PMA_PORT_COUNTERS_CONG cpu_to_be16(0xFF00) 182#define IB_PMA_PORT_COUNTERS_CONG cpu_to_be16(0xFF00)
183#define LINK_SPEED_25G 1
184#define LINK_SPEED_12_5G 2
185#define LINK_WIDTH_DEFAULT 4
186#define DECIMAL_FACTORING 1000
187/*
188 * The default link width is multiplied by 1000
189 * to get accurate value after division.
190 */
191#define FACTOR_LINK_WIDTH (LINK_WIDTH_DEFAULT * DECIMAL_FACTORING)
183 192
184struct ib_pma_portcounters_cong { 193struct ib_pma_portcounters_cong {
185 u8 reserved; 194 u8 reserved;
@@ -429,5 +438,41 @@ struct sc2vlnt {
429 438
430void hfi1_event_pkey_change(struct hfi1_devdata *dd, u8 port); 439void hfi1_event_pkey_change(struct hfi1_devdata *dd, u8 port);
431void hfi1_handle_trap_timer(struct timer_list *t); 440void hfi1_handle_trap_timer(struct timer_list *t);
432 441u16 tx_link_width(u16 link_width);
442u64 get_xmit_wait_counters(struct hfi1_pportdata *ppd, u16 link_width,
443 u16 link_speed, int vl);
444/**
445 * get_link_speed - determine whether 12.5G or 25G speed
446 * @link_speed: the speed of active link
447 * @return: Return 2 if link speed identified as 12.5G
448 * or return 1 if link speed is 25G.
449 *
450 * The function indirectly calculate required link speed
451 * value for convert_xmit_counter function. If the link
452 * speed is 25G, the function return as 1 as it is required
453 * by xmit counter conversion formula :-( 25G / link_speed).
454 * This conversion will provide value 1 if current
455 * link speed is 25G or 2 if 12.5G.This is done to avoid
456 * 12.5 float number conversion.
457 */
458static inline u16 get_link_speed(u16 link_speed)
459{
460 return (link_speed == 1) ?
461 LINK_SPEED_12_5G : LINK_SPEED_25G;
462}
463
464/**
465 * convert_xmit_counter - calculate flit times for given xmit counter
466 * value
467 * @xmit_wait_val: current xmit counter value
468 * @link_width: width of active link
469 * @link_speed: speed of active link
470 * @return: return xmit counter value in flit times.
471 */
472static inline u64 convert_xmit_counter(u64 xmit_wait_val, u16 link_width,
473 u16 link_speed)
474{
475 return (xmit_wait_val * 2 * (FACTOR_LINK_WIDTH / link_width)
476 * link_speed) / DECIMAL_FACTORING;
477}
433#endif /* _HFI1_MAD_H */ 478#endif /* _HFI1_MAD_H */