RDMA/hns: Fix mis-modifying default congestion control algorithm
[linux-2.6-microblaze.git] / drivers / infiniband / hw / hns / hns_roce_hw_v2.c
index de56dc6..42e2858 100644 (file)
@@ -4738,12 +4738,15 @@ static int check_cong_type(struct ib_qp *ibqp,
                           struct hns_roce_congestion_algorithm *cong_alg)
 {
        struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+       struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
 
-       if (ibqp->qp_type == IB_QPT_UD)
-               hr_dev->caps.cong_type = CONG_TYPE_DCQCN;
+       if (ibqp->qp_type == IB_QPT_UD || ibqp->qp_type == IB_QPT_GSI)
+               hr_qp->cong_type = CONG_TYPE_DCQCN;
+       else
+               hr_qp->cong_type = hr_dev->caps.cong_type;
 
        /* different congestion types match different configurations */
-       switch (hr_dev->caps.cong_type) {
+       switch (hr_qp->cong_type) {
        case CONG_TYPE_DCQCN:
                cong_alg->alg_sel = CONG_DCQCN;
                cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL;
@@ -4771,8 +4774,8 @@ static int check_cong_type(struct ib_qp *ibqp,
        default:
                ibdev_warn(&hr_dev->ib_dev,
                           "invalid type(%u) for congestion selection.\n",
-                          hr_dev->caps.cong_type);
-               hr_dev->caps.cong_type = CONG_TYPE_DCQCN;
+                          hr_qp->cong_type);
+               hr_qp->cong_type = CONG_TYPE_DCQCN;
                cong_alg->alg_sel = CONG_DCQCN;
                cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL;
                cong_alg->dip_vld = DIP_INVALID;
@@ -4791,6 +4794,7 @@ static int fill_cong_field(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
        struct hns_roce_congestion_algorithm cong_field;
        struct ib_device *ibdev = ibqp->device;
        struct hns_roce_dev *hr_dev = to_hr_dev(ibdev);
+       struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
        u32 dip_idx = 0;
        int ret;
 
@@ -4803,7 +4807,7 @@ static int fill_cong_field(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
                return ret;
 
        hr_reg_write(context, QPC_CONG_ALGO_TMPL_ID, hr_dev->cong_algo_tmpl_id +
-                    hr_dev->caps.cong_type * HNS_ROCE_CONG_SIZE);
+                    hr_qp->cong_type * HNS_ROCE_CONG_SIZE);
        hr_reg_clear(qpc_mask, QPC_CONG_ALGO_TMPL_ID);
        hr_reg_write(&context->ext, QPCEX_CONG_ALG_SEL, cong_field.alg_sel);
        hr_reg_clear(&qpc_mask->ext, QPCEX_CONG_ALG_SEL);