Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma
[cascardo/linux.git] / drivers / infiniband / hw / mlx5 / qp.c
index affc3f6..41f4c2a 100644 (file)
@@ -35,7 +35,6 @@
 #include <rdma/ib_cache.h>
 #include <rdma/ib_user_verbs.h>
 #include "mlx5_ib.h"
-#include "user.h"
 
 /* not supported currently */
 static int wq_signature;
@@ -77,6 +76,17 @@ struct mlx5_wqe_eth_pad {
        u8 rsvd0[16];
 };
 
+enum raw_qp_set_mask_map {
+       MLX5_RAW_QP_MOD_SET_RQ_Q_CTR_ID         = 1UL << 0,
+};
+
+struct mlx5_modify_raw_qp_param {
+       u16 operation;
+
+       u32 set_mask; /* raw_qp_set_mask_map */
+       u8 rq_q_ctr_id;
+};
+
 static void get_cqs(enum ib_qp_type qp_type,
                    struct ib_cq *ib_send_cq, struct ib_cq *ib_recv_cq,
                    struct mlx5_ib_cq **send_cq, struct mlx5_ib_cq **recv_cq);
@@ -726,7 +736,7 @@ err_umem:
 static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                          struct mlx5_ib_qp *qp, struct ib_udata *udata,
                          struct ib_qp_init_attr *attr,
-                         struct mlx5_create_qp_mbox_in **in,
+                         u32 **in,
                          struct mlx5_ib_create_qp_resp *resp, int *inlen,
                          struct mlx5_ib_qp_base *base)
 {
@@ -739,6 +749,8 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
        u32 offset = 0;
        int uuarn;
        int ncont = 0;
+       __be64 *pas;
+       void *qpc;
        int err;
 
        err = ib_copy_from_udata(&ucmd, udata, sizeof(ucmd));
@@ -795,20 +807,24 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                ubuffer->umem = NULL;
        }
 
-       *inlen = sizeof(**in) + sizeof(*(*in)->pas) * ncont;
+       *inlen = MLX5_ST_SZ_BYTES(create_qp_in) +
+                MLX5_FLD_SZ_BYTES(create_qp_in, pas[0]) * ncont;
        *in = mlx5_vzalloc(*inlen);
        if (!*in) {
                err = -ENOMEM;
                goto err_umem;
        }
+
+       pas = (__be64 *)MLX5_ADDR_OF(create_qp_in, *in, pas);
        if (ubuffer->umem)
-               mlx5_ib_populate_pas(dev, ubuffer->umem, page_shift,
-                                    (*in)->pas, 0);
-       (*in)->ctx.log_pg_sz_remote_qpn =
-               cpu_to_be32((page_shift - MLX5_ADAPTER_PAGE_SHIFT) << 24);
-       (*in)->ctx.params2 = cpu_to_be32(offset << 6);
+               mlx5_ib_populate_pas(dev, ubuffer->umem, page_shift, pas, 0);
+
+       qpc = MLX5_ADDR_OF(create_qp_in, *in, qpc);
 
-       (*in)->ctx.qp_counter_set_usr_page = cpu_to_be32(uar_index);
+       MLX5_SET(qpc, qpc, log_page_size, page_shift - MLX5_ADAPTER_PAGE_SHIFT);
+       MLX5_SET(qpc, qpc, page_offset, offset);
+
+       MLX5_SET(qpc, qpc, uar_page, uar_index);
        resp->uuar_index = uuarn;
        qp->uuarn = uuarn;
 
@@ -857,12 +873,13 @@ static void destroy_qp_user(struct ib_pd *pd, struct mlx5_ib_qp *qp,
 static int create_kernel_qp(struct mlx5_ib_dev *dev,
                            struct ib_qp_init_attr *init_attr,
                            struct mlx5_ib_qp *qp,
-                           struct mlx5_create_qp_mbox_in **in, int *inlen,
+                           u32 **in, int *inlen,
                            struct mlx5_ib_qp_base *base)
 {
        enum mlx5_ib_latency_class lc = MLX5_IB_LATENCY_CLASS_LOW;
        struct mlx5_uuar_info *uuari;
        int uar_index;
+       void *qpc;
        int uuarn;
        int err;
 
@@ -902,25 +919,29 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
        }
 
        qp->sq.qend = mlx5_get_send_wqe(qp, qp->sq.wqe_cnt);
-       *inlen = sizeof(**in) + sizeof(*(*in)->pas) * qp->buf.npages;
+       *inlen = MLX5_ST_SZ_BYTES(create_qp_in) +
+                MLX5_FLD_SZ_BYTES(create_qp_in, pas[0]) * qp->buf.npages;
        *in = mlx5_vzalloc(*inlen);
        if (!*in) {
                err = -ENOMEM;
                goto err_buf;
        }
-       (*in)->ctx.qp_counter_set_usr_page = cpu_to_be32(uar_index);
-       (*in)->ctx.log_pg_sz_remote_qpn =
-               cpu_to_be32((qp->buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT) << 24);
+
+       qpc = MLX5_ADDR_OF(create_qp_in, *in, qpc);
+       MLX5_SET(qpc, qpc, uar_page, uar_index);
+       MLX5_SET(qpc, qpc, log_page_size, qp->buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
+
        /* Set "fast registration enabled" for all kernel QPs */
-       (*in)->ctx.params1 |= cpu_to_be32(1 << 11);
-       (*in)->ctx.sq_crq_size |= cpu_to_be16(1 << 4);
+       MLX5_SET(qpc, qpc, fre, 1);
+       MLX5_SET(qpc, qpc, rlky, 1);
 
        if (init_attr->create_flags & mlx5_ib_create_qp_sqpn_qp1()) {
-               (*in)->ctx.deth_sqpn = cpu_to_be32(1);
+               MLX5_SET(qpc, qpc, deth_sqpn, 1);
                qp->flags |= MLX5_IB_QP_SQPN_QP1;
        }
 
-       mlx5_fill_page_array(&qp->buf, (*in)->pas);
+       mlx5_fill_page_array(&qp->buf,
+                            (__be64 *)MLX5_ADDR_OF(create_qp_in, *in, pas));
 
        err = mlx5_db_alloc(dev->mdev, &qp->db);
        if (err) {
@@ -974,15 +995,15 @@ static void destroy_qp_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
        free_uuar(&dev->mdev->priv.uuari, qp->bf->uuarn);
 }
 
-static __be32 get_rx_type(struct mlx5_ib_qp *qp, struct ib_qp_init_attr *attr)
+static u32 get_rx_type(struct mlx5_ib_qp *qp, struct ib_qp_init_attr *attr)
 {
        if (attr->srq || (attr->qp_type == IB_QPT_XRC_TGT) ||
            (attr->qp_type == IB_QPT_XRC_INI))
-               return cpu_to_be32(MLX5_SRQ_RQ);
+               return MLX5_SRQ_RQ;
        else if (!qp->has_rq)
-               return cpu_to_be32(MLX5_ZERO_LEN_RQ);
+               return MLX5_ZERO_LEN_RQ;
        else
-               return cpu_to_be32(MLX5_NON_ZERO_RQ);
+               return MLX5_NON_ZERO_RQ;
 }
 
 static int is_connected(enum ib_qp_type qp_type)
@@ -996,13 +1017,10 @@ static int is_connected(enum ib_qp_type qp_type)
 static int create_raw_packet_qp_tis(struct mlx5_ib_dev *dev,
                                    struct mlx5_ib_sq *sq, u32 tdn)
 {
-       u32 in[MLX5_ST_SZ_DW(create_tis_in)];
+       u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {0};
        void *tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
 
-       memset(in, 0, sizeof(in));
-
        MLX5_SET(tisc, tisc, transport_domain, tdn);
-
        return mlx5_core_create_tis(dev->mdev, in, sizeof(in), &sq->tisn);
 }
 
@@ -1191,7 +1209,7 @@ static void destroy_raw_packet_qp_tir(struct mlx5_ib_dev *dev,
 }
 
 static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
-                               struct mlx5_create_qp_mbox_in *in,
+                               u32 *in,
                                struct ib_pd *pd)
 {
        struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;
@@ -1462,18 +1480,18 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                            struct ib_udata *udata, struct mlx5_ib_qp *qp)
 {
        struct mlx5_ib_resources *devr = &dev->devr;
+       int inlen = MLX5_ST_SZ_BYTES(create_qp_in);
        struct mlx5_core_dev *mdev = dev->mdev;
-       struct mlx5_ib_qp_base *base;
        struct mlx5_ib_create_qp_resp resp;
-       struct mlx5_create_qp_mbox_in *in;
-       struct mlx5_ib_create_qp ucmd;
        struct mlx5_ib_cq *send_cq;
        struct mlx5_ib_cq *recv_cq;
        unsigned long flags;
-       int inlen = sizeof(*in);
-       int err;
        u32 uidx = MLX5_IB_DEFAULT_UIDX;
+       struct mlx5_ib_create_qp ucmd;
+       struct mlx5_ib_qp_base *base;
        void *qpc;
+       u32 *in;
+       int err;
 
        base = init_attr->qp_type == IB_QPT_RAW_PACKET ?
               &qp->raw_packet_qp.rq.base :
@@ -1601,7 +1619,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                if (err)
                        return err;
        } else {
-               in = mlx5_vzalloc(sizeof(*in));
+               in = mlx5_vzalloc(inlen);
                if (!in)
                        return -ENOMEM;
 
@@ -1611,26 +1629,29 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
        if (is_sqp(init_attr->qp_type))
                qp->port = init_attr->port_num;
 
-       in->ctx.flags = cpu_to_be32(to_mlx5_st(init_attr->qp_type) << 16 |
-                                   MLX5_QP_PM_MIGRATED << 11);
+       qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
+
+       MLX5_SET(qpc, qpc, st, to_mlx5_st(init_attr->qp_type));
+       MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
 
        if (init_attr->qp_type != MLX5_IB_QPT_REG_UMR)
-               in->ctx.flags_pd = cpu_to_be32(to_mpd(pd ? pd : devr->p0)->pdn);
+               MLX5_SET(qpc, qpc, pd, to_mpd(pd ? pd : devr->p0)->pdn);
        else
-               in->ctx.flags_pd = cpu_to_be32(MLX5_QP_LAT_SENSITIVE);
+               MLX5_SET(qpc, qpc, latency_sensitive, 1);
+
 
        if (qp->wq_sig)
-               in->ctx.flags_pd |= cpu_to_be32(MLX5_QP_ENABLE_SIG);
+               MLX5_SET(qpc, qpc, wq_signature, 1);
 
        if (qp->flags & MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK)
-               in->ctx.flags_pd |= cpu_to_be32(MLX5_QP_BLOCK_MCAST);
+               MLX5_SET(qpc, qpc, block_lb_mc, 1);
 
        if (qp->flags & MLX5_IB_QP_CROSS_CHANNEL)
-               in->ctx.params2 |= cpu_to_be32(MLX5_QP_BIT_CC_MASTER);
+               MLX5_SET(qpc, qpc, cd_master, 1);
        if (qp->flags & MLX5_IB_QP_MANAGED_SEND)
-               in->ctx.params2 |= cpu_to_be32(MLX5_QP_BIT_CC_SLAVE_SEND);
+               MLX5_SET(qpc, qpc, cd_slave_send, 1);
        if (qp->flags & MLX5_IB_QP_MANAGED_RECV)
-               in->ctx.params2 |= cpu_to_be32(MLX5_QP_BIT_CC_SLAVE_RECV);
+               MLX5_SET(qpc, qpc, cd_slave_receive, 1);
 
        if (qp->scat_cqe && is_connected(init_attr->qp_type)) {
                int rcqe_sz;
@@ -1640,71 +1661,68 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                scqe_sz = mlx5_ib_get_cqe_size(dev, init_attr->send_cq);
 
                if (rcqe_sz == 128)
-                       in->ctx.cs_res = MLX5_RES_SCAT_DATA64_CQE;
+                       MLX5_SET(qpc, qpc, cs_res, MLX5_RES_SCAT_DATA64_CQE);
                else
-                       in->ctx.cs_res = MLX5_RES_SCAT_DATA32_CQE;
+                       MLX5_SET(qpc, qpc, cs_res, MLX5_RES_SCAT_DATA32_CQE);
 
                if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) {
                        if (scqe_sz == 128)
-                               in->ctx.cs_req = MLX5_REQ_SCAT_DATA64_CQE;
+                               MLX5_SET(qpc, qpc, cs_req, MLX5_REQ_SCAT_DATA64_CQE);
                        else
-                               in->ctx.cs_req = MLX5_REQ_SCAT_DATA32_CQE;
+                               MLX5_SET(qpc, qpc, cs_req, MLX5_REQ_SCAT_DATA32_CQE);
                }
        }
 
        if (qp->rq.wqe_cnt) {
-               in->ctx.rq_size_stride = (qp->rq.wqe_shift - 4);
-               in->ctx.rq_size_stride |= ilog2(qp->rq.wqe_cnt) << 3;
+               MLX5_SET(qpc, qpc, log_rq_stride, qp->rq.wqe_shift - 4);
+               MLX5_SET(qpc, qpc, log_rq_size, ilog2(qp->rq.wqe_cnt));
        }
 
-       in->ctx.rq_type_srqn = get_rx_type(qp, init_attr);
+       MLX5_SET(qpc, qpc, rq_type, get_rx_type(qp, init_attr));
 
        if (qp->sq.wqe_cnt)
-               in->ctx.sq_crq_size |= cpu_to_be16(ilog2(qp->sq.wqe_cnt) << 11);
+               MLX5_SET(qpc, qpc, log_sq_size, ilog2(qp->sq.wqe_cnt));
        else
-               in->ctx.sq_crq_size |= cpu_to_be16(0x8000);
+               MLX5_SET(qpc, qpc, no_sq, 1);
 
        /* Set default resources */
        switch (init_attr->qp_type) {
        case IB_QPT_XRC_TGT:
-               in->ctx.cqn_recv = cpu_to_be32(to_mcq(devr->c0)->mcq.cqn);
-               in->ctx.cqn_send = cpu_to_be32(to_mcq(devr->c0)->mcq.cqn);
-               in->ctx.rq_type_srqn |= cpu_to_be32(to_msrq(devr->s0)->msrq.srqn);
-               in->ctx.xrcd = cpu_to_be32(to_mxrcd(init_attr->xrcd)->xrcdn);
+               MLX5_SET(qpc, qpc, cqn_rcv, to_mcq(devr->c0)->mcq.cqn);
+               MLX5_SET(qpc, qpc, cqn_snd, to_mcq(devr->c0)->mcq.cqn);
+               MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, to_msrq(devr->s0)->msrq.srqn);
+               MLX5_SET(qpc, qpc, xrcd, to_mxrcd(init_attr->xrcd)->xrcdn);
                break;
        case IB_QPT_XRC_INI:
-               in->ctx.cqn_recv = cpu_to_be32(to_mcq(devr->c0)->mcq.cqn);
-               in->ctx.xrcd = cpu_to_be32(to_mxrcd(devr->x1)->xrcdn);
-               in->ctx.rq_type_srqn |= cpu_to_be32(to_msrq(devr->s0)->msrq.srqn);
+               MLX5_SET(qpc, qpc, cqn_rcv, to_mcq(devr->c0)->mcq.cqn);
+               MLX5_SET(qpc, qpc, xrcd, to_mxrcd(devr->x1)->xrcdn);
+               MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, to_msrq(devr->s0)->msrq.srqn);
                break;
        default:
                if (init_attr->srq) {
-                       in->ctx.xrcd = cpu_to_be32(to_mxrcd(devr->x0)->xrcdn);
-                       in->ctx.rq_type_srqn |= cpu_to_be32(to_msrq(init_attr->srq)->msrq.srqn);
+                       MLX5_SET(qpc, qpc, xrcd, to_mxrcd(devr->x0)->xrcdn);
+                       MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, to_msrq(init_attr->srq)->msrq.srqn);
                } else {
-                       in->ctx.xrcd = cpu_to_be32(to_mxrcd(devr->x1)->xrcdn);
-                       in->ctx.rq_type_srqn |=
-                               cpu_to_be32(to_msrq(devr->s1)->msrq.srqn);
+                       MLX5_SET(qpc, qpc, xrcd, to_mxrcd(devr->x1)->xrcdn);
+                       MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, to_msrq(devr->s1)->msrq.srqn);
                }
        }
 
        if (init_attr->send_cq)
-               in->ctx.cqn_send = cpu_to_be32(to_mcq(init_attr->send_cq)->mcq.cqn);
+               MLX5_SET(qpc, qpc, cqn_snd, to_mcq(init_attr->send_cq)->mcq.cqn);
 
        if (init_attr->recv_cq)
-               in->ctx.cqn_recv = cpu_to_be32(to_mcq(init_attr->recv_cq)->mcq.cqn);
+               MLX5_SET(qpc, qpc, cqn_rcv, to_mcq(init_attr->recv_cq)->mcq.cqn);
 
-       in->ctx.db_rec_addr = cpu_to_be64(qp->db.dma);
+       MLX5_SET64(qpc, qpc, dbr_addr, qp->db.dma);
 
-       if (MLX5_CAP_GEN(mdev, cqe_version) == MLX5_CQE_VERSION_V1) {
-               qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
-               /* 0xffffff means we ask to work with cqe version 0 */
+       /* 0xffffff means we ask to work with cqe version 0 */
+       if (MLX5_CAP_GEN(mdev, cqe_version) == MLX5_CQE_VERSION_V1)
                MLX5_SET(qpc, qpc, user_index, uidx);
-       }
+
        /* we use IB_QP_CREATE_IPOIB_UD_LSO to indicates ipoib qp */
        if (init_attr->qp_type == IB_QPT_UD &&
            (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO)) {
-               qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
                MLX5_SET(qpc, qpc, ulp_stateless_offload_mode, 1);
                qp->flags |= MLX5_IB_QP_LSO;
        }
@@ -1855,13 +1873,13 @@ static void get_cqs(enum ib_qp_type qp_type,
 }
 
 static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
-                               u16 operation);
+                               const struct mlx5_modify_raw_qp_param *raw_qp_param,
+                               u8 lag_tx_affinity);
 
 static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
 {
        struct mlx5_ib_cq *send_cq, *recv_cq;
        struct mlx5_ib_qp_base *base = &qp->trans_qp.base;
-       struct mlx5_modify_qp_mbox_in *in;
        unsigned long flags;
        int err;
 
@@ -1874,19 +1892,18 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
               &qp->raw_packet_qp.rq.base :
               &qp->trans_qp.base;
 
-       in = kzalloc(sizeof(*in), GFP_KERNEL);
-       if (!in)
-               return;
-
        if (qp->state != IB_QPS_RESET) {
                if (qp->ibqp.qp_type != IB_QPT_RAW_PACKET) {
                        mlx5_ib_qp_disable_pagefaults(qp);
                        err = mlx5_core_qp_modify(dev->mdev,
-                                                 MLX5_CMD_OP_2RST_QP, in, 0,
-                                                 &base->mqp);
+                                                 MLX5_CMD_OP_2RST_QP, 0,
+                                                 NULL, &base->mqp);
                } else {
-                       err = modify_raw_packet_qp(dev, qp,
-                                                  MLX5_CMD_OP_2RST_QP);
+                       struct mlx5_modify_raw_qp_param raw_qp_param = {
+                               .operation = MLX5_CMD_OP_2RST_QP
+                       };
+
+                       err = modify_raw_packet_qp(dev, qp, &raw_qp_param, 0);
                }
                if (err)
                        mlx5_ib_warn(dev, "mlx5_ib: modify QP 0x%06x to RESET failed\n",
@@ -1925,8 +1942,6 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
                                     base->mqp.qpn);
        }
 
-       kfree(in);
-
        if (qp->create_type == MLX5_QP_KERNEL)
                destroy_qp_kernel(dev, qp);
        else if (qp->create_type == MLX5_QP_USER)
@@ -2152,6 +2167,31 @@ static int modify_raw_packet_eth_prio(struct mlx5_core_dev *dev,
        return err;
 }
 
+static int modify_raw_packet_tx_affinity(struct mlx5_core_dev *dev,
+                                        struct mlx5_ib_sq *sq, u8 tx_affinity)
+{
+       void *in;
+       void *tisc;
+       int inlen;
+       int err;
+
+       inlen = MLX5_ST_SZ_BYTES(modify_tis_in);
+       in = mlx5_vzalloc(inlen);
+       if (!in)
+               return -ENOMEM;
+
+       MLX5_SET(modify_tis_in, in, bitmask.lag_tx_port_affinity, 1);
+
+       tisc = MLX5_ADDR_OF(modify_tis_in, in, ctx);
+       MLX5_SET(tisc, tisc, lag_tx_port_affinity, tx_affinity);
+
+       err = mlx5_core_modify_tis(dev, sq->tisn, in, inlen);
+
+       kvfree(in);
+
+       return err;
+}
+
 static int mlx5_set_path(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
                         const struct ib_ah_attr *ah,
                         struct mlx5_qp_path *path, u8 port, int attr_mask,
@@ -2362,8 +2402,9 @@ static int ib_mask_to_mlx5_opt(int ib_mask)
        return result;
 }
 
-static int modify_raw_packet_qp_rq(struct mlx5_core_dev *dev,
-                                  struct mlx5_ib_rq *rq, int new_state)
+static int modify_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
+                                  struct mlx5_ib_rq *rq, int new_state,
+                                  const struct mlx5_modify_raw_qp_param *raw_qp_param)
 {
        void *in;
        void *rqc;
@@ -2380,7 +2421,17 @@ static int modify_raw_packet_qp_rq(struct mlx5_core_dev *dev,
        rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);
        MLX5_SET(rqc, rqc, state, new_state);
 
-       err = mlx5_core_modify_rq(dev, rq->base.mqp.qpn, in, inlen);
+       if (raw_qp_param->set_mask & MLX5_RAW_QP_MOD_SET_RQ_Q_CTR_ID) {
+               if (MLX5_CAP_GEN(dev->mdev, modify_rq_counter_set_id)) {
+                       MLX5_SET64(modify_rq_in, in, modify_bitmask,
+                                  MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_MODIFY_RQ_COUNTER_SET_ID);
+                       MLX5_SET(rqc, rqc, counter_set_id, raw_qp_param->rq_q_ctr_id);
+               } else
+                       pr_info_once("%s: RAW PACKET QP counters are not supported on current FW\n",
+                                    dev->ib_dev.name);
+       }
+
+       err = mlx5_core_modify_rq(dev->mdev, rq->base.mqp.qpn, in, inlen);
        if (err)
                goto out;
 
@@ -2421,7 +2472,8 @@ out:
 }
 
 static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
-                               u16 operation)
+                               const struct mlx5_modify_raw_qp_param *raw_qp_param,
+                               u8 tx_affinity)
 {
        struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;
        struct mlx5_ib_rq *rq = &raw_packet_qp->rq;
@@ -2430,7 +2482,7 @@ static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
        int sq_state;
        int err;
 
-       switch (operation) {
+       switch (raw_qp_param->operation) {
        case MLX5_CMD_OP_RST2INIT_QP:
                rq_state = MLX5_RQC_STATE_RDY;
                sq_state = MLX5_SQC_STATE_RDY;
@@ -2447,21 +2499,31 @@ static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
        case MLX5_CMD_OP_INIT2RTR_QP:
        case MLX5_CMD_OP_RTR2RTS_QP:
        case MLX5_CMD_OP_RTS2RTS_QP:
-               /* Nothing to do here... */
-               return 0;
+               if (raw_qp_param->set_mask)
+                       return -EINVAL;
+               else
+                       return 0;
        default:
                WARN_ON(1);
                return -EINVAL;
        }
 
        if (qp->rq.wqe_cnt) {
-               err =  modify_raw_packet_qp_rq(dev->mdev, rq, rq_state);
+               err = modify_raw_packet_qp_rq(dev, rq, rq_state, raw_qp_param);
                if (err)
                        return err;
        }
 
-       if (qp->sq.wqe_cnt)
+       if (qp->sq.wqe_cnt) {
+               if (tx_affinity) {
+                       err = modify_raw_packet_tx_affinity(dev->mdev, sq,
+                                                           tx_affinity);
+                       if (err)
+                               return err;
+               }
+
                return modify_raw_packet_qp_sq(dev->mdev, sq, sq_state);
+       }
 
        return 0;
 }
@@ -2512,20 +2574,20 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
        struct mlx5_ib_qp_base *base = &qp->trans_qp.base;
        struct mlx5_ib_cq *send_cq, *recv_cq;
        struct mlx5_qp_context *context;
-       struct mlx5_modify_qp_mbox_in *in;
        struct mlx5_ib_pd *pd;
+       struct mlx5_ib_port *mibport = NULL;
        enum mlx5_qp_state mlx5_cur, mlx5_new;
        enum mlx5_qp_optpar optpar;
        int sqd_event;
        int mlx5_st;
        int err;
        u16 op;
+       u8 tx_affinity = 0;
 
-       in = kzalloc(sizeof(*in), GFP_KERNEL);
-       if (!in)
+       context = kzalloc(sizeof(*context), GFP_KERNEL);
+       if (!context)
                return -ENOMEM;
 
-       context = &in->ctx;
        err = to_mlx5_st(ibqp->qp_type);
        if (err < 0) {
                mlx5_ib_dbg(dev, "unsupported qp type %d\n", ibqp->qp_type);
@@ -2550,6 +2612,23 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
                }
        }
 
+       if ((cur_state == IB_QPS_RESET) && (new_state == IB_QPS_INIT)) {
+               if ((ibqp->qp_type == IB_QPT_RC) ||
+                   (ibqp->qp_type == IB_QPT_UD &&
+                    !(qp->flags & MLX5_IB_QP_SQPN_QP1)) ||
+                   (ibqp->qp_type == IB_QPT_UC) ||
+                   (ibqp->qp_type == IB_QPT_RAW_PACKET) ||
+                   (ibqp->qp_type == IB_QPT_XRC_INI) ||
+                   (ibqp->qp_type == IB_QPT_XRC_TGT)) {
+                       if (mlx5_lag_is_active(dev->mdev)) {
+                               tx_affinity = (unsigned int)atomic_add_return(1,
+                                               &dev->roce.next_port) %
+                                               MLX5_MAX_PORTS + 1;
+                               context->flags |= cpu_to_be32(tx_affinity << 24);
+                       }
+               }
+       }
+
        if (is_sqp(ibqp->qp_type)) {
                context->mtu_msgmax = (IB_MTU_256 << 5) | 8;
        } else if (ibqp->qp_type == IB_QPT_UD ||
@@ -2655,8 +2734,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
        if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
                u8 port_num = (attr_mask & IB_QP_PORT ? attr->port_num :
                               qp->port) - 1;
-               struct mlx5_ib_port *mibport = &dev->port[port_num];
-
+               mibport = &dev->port[port_num];
                context->qp_counter_set_usr_page |=
                        cpu_to_be32((u32)(mibport->q_cnt_id) << 24);
        }
@@ -2690,13 +2768,21 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
        op = optab[mlx5_cur][mlx5_new];
        optpar = ib_mask_to_mlx5_opt(attr_mask);
        optpar &= opt_mask[mlx5_cur][mlx5_new][mlx5_st];
-       in->optparam = cpu_to_be32(optpar);
 
-       if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET)
-               err = modify_raw_packet_qp(dev, qp, op);
-       else
-               err = mlx5_core_qp_modify(dev->mdev, op, in, sqd_event,
+       if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET) {
+               struct mlx5_modify_raw_qp_param raw_qp_param = {};
+
+               raw_qp_param.operation = op;
+               if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
+                       raw_qp_param.rq_q_ctr_id = mibport->q_cnt_id;
+                       raw_qp_param.set_mask |= MLX5_RAW_QP_MOD_SET_RQ_Q_CTR_ID;
+               }
+               err = modify_raw_packet_qp(dev, qp, &raw_qp_param, tx_affinity);
+       } else {
+               err = mlx5_core_qp_modify(dev->mdev, op, optpar, context,
                                          &base->mqp);
+       }
+
        if (err)
                goto out;
 
@@ -2736,7 +2822,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
        }
 
 out:
-       kfree(in);
+       kfree(context);
        return err;
 }
 
@@ -2969,7 +3055,7 @@ static void set_reg_umr_seg(struct mlx5_wqe_umr_ctrl_seg *umr,
 
        memset(umr, 0, sizeof(*umr));
 
-       if (mr->access_mode == MLX5_ACCESS_MODE_KLM)
+       if (mr->access_mode == MLX5_MKC_ACCESS_MODE_KLMS)
                /* KLMs take twice the size of MTTs */
                ndescs *= 2;
 
@@ -3112,9 +3198,9 @@ static void set_reg_mkey_seg(struct mlx5_mkey_seg *seg,
 
        memset(seg, 0, sizeof(*seg));
 
-       if (mr->access_mode == MLX5_ACCESS_MODE_MTT)
+       if (mr->access_mode == MLX5_MKC_ACCESS_MODE_MTT)
                seg->log2_page_size = ilog2(mr->ibmr.page_size);
-       else if (mr->access_mode == MLX5_ACCESS_MODE_KLM)
+       else if (mr->access_mode == MLX5_MKC_ACCESS_MODE_KLMS)
                /* KLMs take twice the size of MTTs */
                ndescs *= 2;
 
@@ -3455,7 +3541,7 @@ static void set_sig_mkey_segment(struct mlx5_mkey_seg *seg,
        memset(seg, 0, sizeof(*seg));
 
        seg->flags = get_umr_flags(wr->access_flags) |
-                                  MLX5_ACCESS_MODE_KLM;
+                                  MLX5_MKC_ACCESS_MODE_KLMS;
        seg->qpn_mkey7_0 = cpu_to_be32((sig_key & 0xff) | 0xffffff00);
        seg->flags_pd = cpu_to_be32(MLX5_MKEY_REMOTE_INVAL | sigerr << 26 |
                                    MLX5_MKEY_BSF_EN | pdn);
@@ -4317,21 +4403,24 @@ static int query_raw_packet_qp_state(struct mlx5_ib_dev *dev,
 static int query_qp_attr(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
                         struct ib_qp_attr *qp_attr)
 {
-       struct mlx5_query_qp_mbox_out *outb;
+       int outlen = MLX5_ST_SZ_BYTES(query_qp_out);
        struct mlx5_qp_context *context;
        int mlx5_state;
+       u32 *outb;
        int err = 0;
 
-       outb = kzalloc(sizeof(*outb), GFP_KERNEL);
+       outb = kzalloc(outlen, GFP_KERNEL);
        if (!outb)
                return -ENOMEM;
 
-       context = &outb->ctx;
        err = mlx5_core_qp_query(dev->mdev, &qp->trans_qp.base.mqp, outb,
-                                sizeof(*outb));
+                                outlen);
        if (err)
                goto out;
 
+       /* FIXME: use MLX5_GET rather than mlx5_qp_context manual struct */
+       context = (struct mlx5_qp_context *)MLX5_ADDR_OF(query_qp_out, outb, qpc);
+
        mlx5_state = be32_to_cpu(context->flags) >> 28;
 
        qp->state                    = to_ib_qp_state(mlx5_state);
@@ -4496,6 +4585,28 @@ int mlx5_ib_dealloc_xrcd(struct ib_xrcd *xrcd)
        return 0;
 }
 
+static void mlx5_ib_wq_event(struct mlx5_core_qp *core_qp, int type)
+{
+       struct mlx5_ib_rwq *rwq = to_mibrwq(core_qp);
+       struct mlx5_ib_dev *dev = to_mdev(rwq->ibwq.device);
+       struct ib_event event;
+
+       if (rwq->ibwq.event_handler) {
+               event.device     = rwq->ibwq.device;
+               event.element.wq = &rwq->ibwq;
+               switch (type) {
+               case MLX5_EVENT_TYPE_WQ_CATAS_ERROR:
+                       event.event = IB_EVENT_WQ_FATAL;
+                       break;
+               default:
+                       mlx5_ib_warn(dev, "Unexpected event type %d on WQ %06x\n", type, core_qp->qpn);
+                       return;
+               }
+
+               rwq->ibwq.event_handler(&event, rwq->ibwq.wq_context);
+       }
+}
+
 static int  create_rq(struct mlx5_ib_rwq *rwq, struct ib_pd *pd,
                      struct ib_wq_init_attr *init_attr)
 {
@@ -4533,7 +4644,7 @@ static int  create_rq(struct mlx5_ib_rwq *rwq, struct ib_pd *pd,
        MLX5_SET64(wq, wq, dbr_addr, rwq->db.dma);
        rq_pas0 = (__be64 *)MLX5_ADDR_OF(wq, wq, pas);
        mlx5_ib_populate_pas(dev, rwq->umem, rwq->page_shift, rq_pas0, 0);
-       err = mlx5_core_create_rq(dev->mdev, in, inlen, &rwq->rqn);
+       err = mlx5_core_create_rq_tracked(dev->mdev, in, inlen, &rwq->core_qp);
        kvfree(in);
        return err;
 }
@@ -4649,7 +4760,7 @@ struct ib_wq *mlx5_ib_create_wq(struct ib_pd *pd,
                return ERR_PTR(-EINVAL);
        }
 
-       rwq->ibwq.wq_num = rwq->rqn;
+       rwq->ibwq.wq_num = rwq->core_qp.qpn;
        rwq->ibwq.state = IB_WQS_RESET;
        if (udata->outlen) {
                resp.response_length = offsetof(typeof(resp), response_length) +
@@ -4659,10 +4770,12 @@ struct ib_wq *mlx5_ib_create_wq(struct ib_pd *pd,
                        goto err_copy;
        }
 
+       rwq->core_qp.event = mlx5_ib_wq_event;
+       rwq->ibwq.event_handler = init_attr->event_handler;
        return &rwq->ibwq;
 
 err_copy:
-       mlx5_core_destroy_rq(dev->mdev, rwq->rqn);
+       mlx5_core_destroy_rq_tracked(dev->mdev, &rwq->core_qp);
 err_user_rq:
        destroy_user_rq(pd, rwq);
 err:
@@ -4675,7 +4788,7 @@ int mlx5_ib_destroy_wq(struct ib_wq *wq)
        struct mlx5_ib_dev *dev = to_mdev(wq->device);
        struct mlx5_ib_rwq *rwq = to_mrwq(wq);
 
-       mlx5_core_destroy_rq(dev->mdev, rwq->rqn);
+       mlx5_core_destroy_rq_tracked(dev->mdev, &rwq->core_qp);
        destroy_user_rq(wq->pd, rwq);
        kfree(rwq);
 
@@ -4807,7 +4920,7 @@ int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
        MLX5_SET(modify_rq_in, in, rq_state, curr_wq_state);
        MLX5_SET(rqc, rqc, state, wq_state);
 
-       err = mlx5_core_modify_rq(dev->mdev, rwq->rqn, in, inlen);
+       err = mlx5_core_modify_rq(dev->mdev, rwq->core_qp.qpn, in, inlen);
        kvfree(in);
        if (!err)
                rwq->ibwq.state = (wq_state == MLX5_RQC_STATE_ERR) ? IB_WQS_ERR : wq_state;