diff options
Diffstat (limited to 'drivers/infiniband/hw/bnxt_re/ib_verbs.c')
| -rw-r--r-- | drivers/infiniband/hw/bnxt_re/ib_verbs.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c index ff91511bd338..be3c3f1f87f7 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c @@ -186,6 +186,9 @@ int bnxt_re_query_device(struct ib_device *ibdev, { struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev); struct bnxt_qplib_dev_attr *dev_attr = rdev->dev_attr; + struct bnxt_re_query_device_ex_resp resp = {}; + size_t outlen = (udata) ? udata->outlen : 0; + int rc = 0; memset(ib_attr, 0, sizeof(*ib_attr)); memcpy(&ib_attr->fw_ver, dev_attr->fw_ver, @@ -250,7 +253,21 @@ int bnxt_re_query_device(struct ib_device *ibdev, ib_attr->max_pkeys = 1; ib_attr->local_ca_ack_delay = BNXT_RE_DEFAULT_ACK_DELAY; - return 0; + + if ((offsetofend(typeof(resp), packet_pacing_caps) <= outlen) && + _is_modify_qp_rate_limit_supported(dev_attr->dev_cap_flags2)) { + resp.packet_pacing_caps.qp_rate_limit_min = + dev_attr->rate_limit_min; + resp.packet_pacing_caps.qp_rate_limit_max = + dev_attr->rate_limit_max; + resp.packet_pacing_caps.supported_qpts = + 1 << IB_QPT_RC; + } + if (outlen) + rc = ib_copy_to_udata(udata, &resp, + min(sizeof(resp), outlen)); + + return rc; } int bnxt_re_modify_device(struct ib_device *ibdev, @@ -2089,10 +2106,11 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, unsigned int flags; u8 nw_type; - if (qp_attr_mask & ~IB_QP_ATTR_STANDARD_BITS) + if (qp_attr_mask & ~(IB_QP_ATTR_STANDARD_BITS | IB_QP_RATE_LIMIT)) return -EOPNOTSUPP; qp->qplib_qp.modify_flags = 0; + qp->qplib_qp.ext_modify_flags = 0; if (qp_attr_mask & IB_QP_STATE) { curr_qp_state = __to_ib_qp_state(qp->qplib_qp.cur_qp_state); new_qp_state = qp_attr->qp_state; @@ -2129,6 +2147,15 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, bnxt_re_unlock_cqs(qp, flags); } } + + if (qp_attr_mask & IB_QP_RATE_LIMIT) { + if (qp->qplib_qp.type != IB_QPT_RC || + !_is_modify_qp_rate_limit_supported(dev_attr->dev_cap_flags2)) + return -EOPNOTSUPP; + qp->qplib_qp.ext_modify_flags |= + CMDQ_MODIFY_QP_EXT_MODIFY_MASK_RATE_LIMIT_VALID; + qp->qplib_qp.rate_limit = qp_attr->rate_limit; + } if (qp_attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY) { qp->qplib_qp.modify_flags |= CMDQ_MODIFY_QP_MODIFY_MASK_EN_SQD_ASYNC_NOTIFY; @@ -4386,6 +4413,9 @@ int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata) if (_is_host_msn_table(rdev->qplib_res.dattr->dev_cap_flags2)) resp.comp_mask |= BNXT_RE_UCNTX_CMASK_MSN_TABLE_ENABLED; + if (_is_modify_qp_rate_limit_supported(dev_attr->dev_cap_flags2)) + resp.comp_mask |= BNXT_RE_UCNTX_CMASK_QP_RATE_LIMIT_ENABLED; + if (udata->inlen >= sizeof(ureq)) { rc = ib_copy_from_udata(&ureq, udata, min(udata->inlen, sizeof(ureq))); if (rc) |
