destroy_qp(dev, qp, base, udata);
 }
 
-static int create_dct(struct ib_pd *pd, struct mlx5_ib_qp *qp,
+static int create_dct(struct mlx5_ib_dev *dev, struct ib_pd *pd,
+                     struct mlx5_ib_qp *qp,
                      struct mlx5_create_qp_params *params)
 {
        struct ib_qp_init_attr *attr = params->attr;
        MLX5_SET(dctc, dctc, cqn, to_mcq(attr->recv_cq)->mcq.cqn);
        MLX5_SET64(dctc, dctc, dc_access_key, ucmd->access_key);
        MLX5_SET(dctc, dctc, user_index, uidx);
+       if (MLX5_CAP_GEN(dev->mdev, ece_support))
+               MLX5_SET(dctc, dctc, ece, ucmd->ece_options);
 
        if (qp->flags_en & MLX5_QP_FLAG_SCATTER_CQE) {
                int rcqe_sz = mlx5_ib_get_cqe_size(attr->recv_cq);
        }
 
        if (qp->type == MLX5_IB_QPT_DCT) {
-               err = create_dct(pd, qp, params);
+               err = create_dct(dev, pd, qp, params);
                goto out;
        }
 
                 */
                last = sizeof(struct mlx5_ib_create_qp_rss);
        else
-               /* IB_QPT_RAW_PACKET and IB_QPT_DRIVER don't have ECE data */
+               /* IB_QPT_RAW_PACKET doesn't have ECE data */
                switch (attr->qp_type) {
-               case IB_QPT_DRIVER:
                case IB_QPT_RAW_PACKET:
                        last = offsetof(struct mlx5_ib_create_qp, ece_options);
                        break;
  * Other transitions and attributes are illegal
  */
 static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr,
-                             int attr_mask, struct ib_udata *udata)
+                             int attr_mask, struct mlx5_ib_modify_qp *ucmd,
+                             struct ib_udata *udata)
 {
        struct mlx5_ib_qp *qp = to_mqp(ibqp);
        struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
        new_state = attr->qp_state;
 
        dctc = MLX5_ADDR_OF(create_dct_in, qp->dct.in, dct_context_entry);
+       if (MLX5_CAP_GEN(dev->mdev, ece_support) && ucmd->ece_options)
+               /*
+                * DCT doesn't initialize QP till modify command is executed,
+                * so we need to overwrite previously set ECE field if user
+                * provided any value except zero, which means not set/not
+                * valid.
+                */
+               MLX5_SET(dctc, dctc, ece, ucmd->ece_options);
+
        if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
                u16 set_id;
 
                MLX5_SET(dctc, dctc, counter_set_id, set_id);
        } else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
                struct mlx5_ib_modify_qp_resp resp = {};
-               u32 out[MLX5_ST_SZ_DW(create_dct_out)] = {0};
-               u32 min_resp_len = offsetof(typeof(resp), dctn) +
-                                  sizeof(resp.dctn);
+               u32 out[MLX5_ST_SZ_DW(create_dct_out)] = {};
+               u32 min_resp_len = offsetofend(typeof(resp), dctn);
 
                if (udata->outlen < min_resp_len)
                        return -EINVAL;
                resp.response_length = min_resp_len;
 
+               /*
+                * If we don't have enough space for the ECE options,
+                * simply indicate it with resp.response_length.
+                */
+               resp.response_length = (udata->outlen < sizeof(resp)) ?
+                                              min_resp_len :
+                                              sizeof(resp);
+
                required |= IB_QP_MIN_RNR_TIMER | IB_QP_AV | IB_QP_PATH_MTU;
                if (!is_valid_mask(attr_mask, required, 0))
                        return -EINVAL;
                if (err)
                        return err;
                resp.dctn = qp->dct.mdct.mqp.qpn;
+               if (MLX5_CAP_GEN(dev->mdev, ece_support))
+                       resp.ece_options = MLX5_GET(create_dct_out, out, ece);
                err = ib_copy_to_udata(udata, &resp, resp.response_length);
                if (err) {
                        mlx5_core_destroy_dct(dev, &qp->dct.mdct);
        qp_type = (unlikely(ibqp->qp_type == MLX5_IB_QPT_HW_GSI)) ? IB_QPT_GSI :
                                                                    qp->type;
 
-       if (qp_type == MLX5_IB_QPT_DCT) {
-               if (memchr_inv(&ucmd.ece_options, 0, sizeof(ucmd.ece_options)))
-                       return -EOPNOTSUPP;
-
-               return mlx5_ib_modify_dct(ibqp, attr, attr_mask, udata);
-       }
+       if (qp_type == MLX5_IB_QPT_DCT)
+               return mlx5_ib_modify_dct(ibqp, attr, attr_mask, &ucmd, udata);
 
        mutex_lock(&qp->mutex);