aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDevesh Sharma <devesh.sharma@broadcom.com>2017-11-08 02:48:45 -0500
committerDoug Ledford <dledford@redhat.com>2017-11-13 16:28:44 -0500
commit84511455ac5bd2fec100c5b07b21f725eaa536f6 (patch)
tree6525ad7526999bdca78c2090daf90e882a367e70
parent877add28178a7fa3c68f29c450d050a8e6513f08 (diff)
RDMA/bnxt_re: report vlan_id and sl in qp1 recv completion
In a real RoCE v2 network it is possible to have two Sections of network have same IP hence same gid. However those may have different vlans. During connection resolution it is important to report the actual vlan on which the MAD packet was received instead of relying on other means to resolve vlan-id. ib_find_gid_index should not be used to resolve the vlan-id using sgid of the local system where the packet was received. Our device has the capability to report the actual VLAN-ID in the GSI qp completions. Since we have the capability our driver should move away from resolving the vlan-id with the help of SGID at the destination port. Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com> Reported-by: Parav Pandit <parav@mellanox.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/hw/bnxt_re/ib_verbs.c35
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_fp.c1
2 files changed, 35 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 526ab3f10a90..2032db7db766 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -2769,6 +2769,32 @@ static void bnxt_re_process_res_rawqp1_wc(struct ib_wc *wc,
2769 wc->wc_flags |= IB_WC_GRH; 2769 wc->wc_flags |= IB_WC_GRH;
2770} 2770}
2771 2771
2772static bool bnxt_re_is_vlan_pkt(struct bnxt_qplib_cqe *orig_cqe,
2773 u16 *vid, u8 *sl)
2774{
2775 bool ret = false;
2776 u32 metadata;
2777 u16 tpid;
2778
2779 metadata = orig_cqe->raweth_qp1_metadata;
2780 if (orig_cqe->raweth_qp1_flags2 &
2781 CQ_RES_RAWETH_QP1_RAWETH_QP1_FLAGS2_META_FORMAT_VLAN) {
2782 tpid = ((metadata &
2783 CQ_RES_RAWETH_QP1_RAWETH_QP1_METADATA_TPID_MASK) >>
2784 CQ_RES_RAWETH_QP1_RAWETH_QP1_METADATA_TPID_SFT);
2785 if (tpid == ETH_P_8021Q) {
2786 *vid = metadata &
2787 CQ_RES_RAWETH_QP1_RAWETH_QP1_METADATA_VID_MASK;
2788 *sl = (metadata &
2789 CQ_RES_RAWETH_QP1_RAWETH_QP1_METADATA_PRI_MASK) >>
2790 CQ_RES_RAWETH_QP1_RAWETH_QP1_METADATA_PRI_SFT;
2791 ret = true;
2792 }
2793 }
2794
2795 return ret;
2796}
2797
2772static void bnxt_re_process_res_rc_wc(struct ib_wc *wc, 2798static void bnxt_re_process_res_rc_wc(struct ib_wc *wc,
2773 struct bnxt_qplib_cqe *cqe) 2799 struct bnxt_qplib_cqe *cqe)
2774{ 2800{
@@ -2788,12 +2814,14 @@ static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *qp,
2788 struct ib_wc *wc, 2814 struct ib_wc *wc,
2789 struct bnxt_qplib_cqe *cqe) 2815 struct bnxt_qplib_cqe *cqe)
2790{ 2816{
2791 u32 tbl_idx;
2792 struct bnxt_re_dev *rdev = qp->rdev; 2817 struct bnxt_re_dev *rdev = qp->rdev;
2793 struct bnxt_re_qp *qp1_qp = NULL; 2818 struct bnxt_re_qp *qp1_qp = NULL;
2794 struct bnxt_qplib_cqe *orig_cqe = NULL; 2819 struct bnxt_qplib_cqe *orig_cqe = NULL;
2795 struct bnxt_re_sqp_entries *sqp_entry = NULL; 2820 struct bnxt_re_sqp_entries *sqp_entry = NULL;
2796 int nw_type; 2821 int nw_type;
2822 u32 tbl_idx;
2823 u16 vlan_id;
2824 u8 sl;
2797 2825
2798 tbl_idx = cqe->wr_id; 2826 tbl_idx = cqe->wr_id;
2799 2827
@@ -2808,6 +2836,11 @@ static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *qp,
2808 wc->ex.imm_data = orig_cqe->immdata; 2836 wc->ex.imm_data = orig_cqe->immdata;
2809 wc->src_qp = orig_cqe->src_qp; 2837 wc->src_qp = orig_cqe->src_qp;
2810 memcpy(wc->smac, orig_cqe->smac, ETH_ALEN); 2838 memcpy(wc->smac, orig_cqe->smac, ETH_ALEN);
2839 if (bnxt_re_is_vlan_pkt(orig_cqe, &vlan_id, &sl)) {
2840 wc->vlan_id = vlan_id;
2841 wc->sl = sl;
2842 wc->wc_flags |= IB_WC_WITH_VLAN;
2843 }
2811 wc->port_num = 1; 2844 wc->port_num = 1;
2812 wc->vendor_err = orig_cqe->status; 2845 wc->vendor_err = orig_cqe->status;
2813 2846
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index c0f813366ad6..61764f7aa79b 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -2254,6 +2254,7 @@ static int bnxt_qplib_cq_process_res_raweth_qp1(struct bnxt_qplib_cq *cq,
2254 2254
2255 cqe->raweth_qp1_flags = le16_to_cpu(hwcqe->raweth_qp1_flags); 2255 cqe->raweth_qp1_flags = le16_to_cpu(hwcqe->raweth_qp1_flags);
2256 cqe->raweth_qp1_flags2 = le32_to_cpu(hwcqe->raweth_qp1_flags2); 2256 cqe->raweth_qp1_flags2 = le32_to_cpu(hwcqe->raweth_qp1_flags2);
2257 cqe->raweth_qp1_metadata = le32_to_cpu(hwcqe->raweth_qp1_metadata);
2257 2258
2258 rq = &qp->rq; 2259 rq = &qp->rq;
2259 if (wr_id_idx > rq->hwq.max_elements) { 2260 if (wr_id_idx > rq->hwq.max_elements) {