summaryrefslogtreecommitdiff
path: root/drivers/infiniband/hw/bnxt_re/ib_verbs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/bnxt_re/ib_verbs.c')
-rw-r--r--drivers/infiniband/hw/bnxt_re/ib_verbs.c34
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)