return rc;
}
+static bool bnxt_re_is_modify_ok(enum ib_qp_attr_mask ext_mask,
+ enum ib_qp_type type, enum ib_qp_state cur,
+ enum ib_qp_state next)
+{
+ if (!ext_mask)
+ return true;
+
+ if (ext_mask & ~IB_QP_RATE_LIMIT)
+ return false;
+
+ /* Rate limit is only supported for RC QPs during specific transitions */
+ return type == IB_QPT_RC &&
+ ((cur == IB_QPS_INIT && next == IB_QPS_RTR) ||
+ (cur == IB_QPS_RTR && next == IB_QPS_RTS) ||
+ (cur == IB_QPS_RTS && next == IB_QPS_RTS));
+}
+
int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
int qp_attr_mask, struct ib_udata *udata)
{
curr_qp_state = __to_ib_qp_state(qp->qplib_qp.cur_qp_state);
new_qp_state = qp_attr->qp_state;
if (!ib_modify_qp_is_ok(curr_qp_state, new_qp_state,
- ib_qp->qp_type, qp_attr_mask)) {
+ ib_qp->qp_type, qp_attr_mask) ||
+ !bnxt_re_is_modify_ok(qp_attr_mask & ~IB_QP_ATTR_STANDARD_BITS,
+ ib_qp->qp_type, curr_qp_state,
+ new_qp_state)) {
ibdev_err(&rdev->ibdev,
"Invalid attribute mask: %#x specified ",
qp_attr_mask);