RDMA/hns: Refactor process about opcode in post_send()
authorWeihang Li <liweihang@huawei.com>
Sat, 19 Sep 2020 10:03:15 +0000 (18:03 +0800)
committerJason Gunthorpe <jgg@nvidia.com>
Thu, 24 Sep 2020 18:56:26 +0000 (15:56 -0300)
According to the IB specifications, the verbs should return an immediate
error when the users set an unsupported opcode. Furthermore, refactor codes
about opcode in process of post_send to make the difference between opcodes
clearer.

Link: https://lore.kernel.org/r/1600509802-44382-2-git-send-email-liweihang@huawei.com
Signed-off-by: Weihang Li <liweihang@huawei.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/hw/hns/hns_roce_hw_v2.c

index fe0e6b1..00d7cc9 100644 (file)
@@ -292,6 +292,33 @@ static unsigned int calc_wr_sge_num(const struct ib_send_wr *wr,
        return valid_num;
 }
 
+static __le32 get_immtdata(const struct ib_send_wr *wr)
+{
+       switch (wr->opcode) {
+       case IB_WR_SEND_WITH_IMM:
+       case IB_WR_RDMA_WRITE_WITH_IMM:
+               return cpu_to_le32(be32_to_cpu(wr->ex.imm_data));
+       default:
+               return 0;
+       }
+}
+
+static int set_ud_opcode(struct hns_roce_v2_ud_send_wqe *ud_sq_wqe,
+                        const struct ib_send_wr *wr)
+{
+       u32 ib_op = wr->opcode;
+
+       if (ib_op != IB_WR_SEND && ib_op != IB_WR_SEND_WITH_IMM)
+               return -EINVAL;
+
+       ud_sq_wqe->immtdata = get_immtdata(wr);
+
+       roce_set_field(ud_sq_wqe->byte_4, V2_UD_SEND_WQE_BYTE_4_OPCODE_M,
+                      V2_UD_SEND_WQE_BYTE_4_OPCODE_S, to_hr_opcode(ib_op));
+
+       return 0;
+}
+
 static inline int set_ud_wqe(struct hns_roce_qp *qp,
                             const struct ib_send_wr *wr,
                             void *wqe, unsigned int *sge_idx,
@@ -305,10 +332,15 @@ static inline int set_ud_wqe(struct hns_roce_qp *qp,
        u32 msg_len = 0;
        bool loopback;
        u8 *smac;
+       int ret;
 
        valid_num_sge = calc_wr_sge_num(wr, &msg_len);
        memset(ud_sq_wqe, 0, sizeof(*ud_sq_wqe));
 
+       ret = set_ud_opcode(ud_sq_wqe, wr);
+       if (WARN_ON(ret))
+               return ret;
+
        roce_set_field(ud_sq_wqe->dmac, V2_UD_SEND_WQE_DMAC_0_M,
                       V2_UD_SEND_WQE_DMAC_0_S, ah->av.mac[0]);
        roce_set_field(ud_sq_wqe->dmac, V2_UD_SEND_WQE_DMAC_1_M,
@@ -329,23 +361,8 @@ static inline int set_ud_wqe(struct hns_roce_qp *qp,
        roce_set_bit(ud_sq_wqe->byte_40,
                     V2_UD_SEND_WQE_BYTE_40_LBI_S, loopback);
 
-       roce_set_field(ud_sq_wqe->byte_4,
-                      V2_UD_SEND_WQE_BYTE_4_OPCODE_M,
-                      V2_UD_SEND_WQE_BYTE_4_OPCODE_S,
-                      HNS_ROCE_V2_WQE_OP_SEND);
-
        ud_sq_wqe->msg_len = cpu_to_le32(msg_len);
 
-       switch (wr->opcode) {
-       case IB_WR_SEND_WITH_IMM:
-       case IB_WR_RDMA_WRITE_WITH_IMM:
-               ud_sq_wqe->immtdata = cpu_to_le32(be32_to_cpu(wr->ex.imm_data));
-               break;
-       default:
-               ud_sq_wqe->immtdata = 0;
-               break;
-       }
-
        /* Set sig attr */
        roce_set_bit(ud_sq_wqe->byte_4, V2_UD_SEND_WQE_BYTE_4_CQE_S,
                     (wr->send_flags & IB_SEND_SIGNALED) ? 1 : 0);
@@ -402,6 +419,46 @@ static inline int set_ud_wqe(struct hns_roce_qp *qp,
        return 0;
 }
 
+static int set_rc_opcode(struct hns_roce_v2_rc_send_wqe *rc_sq_wqe,
+                        const struct ib_send_wr *wr)
+{
+       u32 ib_op = wr->opcode;
+
+       rc_sq_wqe->immtdata = get_immtdata(wr);
+
+       switch (ib_op) {
+       case IB_WR_RDMA_READ:
+       case IB_WR_RDMA_WRITE:
+       case IB_WR_RDMA_WRITE_WITH_IMM:
+               rc_sq_wqe->rkey = cpu_to_le32(rdma_wr(wr)->rkey);
+               rc_sq_wqe->va = cpu_to_le64(rdma_wr(wr)->remote_addr);
+               break;
+       case IB_WR_SEND:
+       case IB_WR_SEND_WITH_IMM:
+               break;
+       case IB_WR_ATOMIC_CMP_AND_SWP:
+       case IB_WR_ATOMIC_FETCH_AND_ADD:
+               rc_sq_wqe->rkey = cpu_to_le32(atomic_wr(wr)->rkey);
+               rc_sq_wqe->va = cpu_to_le64(atomic_wr(wr)->remote_addr);
+               break;
+       case IB_WR_REG_MR:
+               set_frmr_seg(rc_sq_wqe, reg_wr(wr));
+               break;
+       case IB_WR_LOCAL_INV:
+               roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_SO_S, 1);
+               fallthrough;
+       case IB_WR_SEND_WITH_INV:
+               rc_sq_wqe->inv_key = cpu_to_le32(wr->ex.invalidate_rkey);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       roce_set_field(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_OPCODE_M,
+                      V2_RC_SEND_WQE_BYTE_4_OPCODE_S, to_hr_opcode(ib_op));
+
+       return 0;
+}
 static inline int set_rc_wqe(struct hns_roce_qp *qp,
                             const struct ib_send_wr *wr,
                             void *wqe, unsigned int *sge_idx,
@@ -411,25 +468,16 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp,
        unsigned int curr_idx = *sge_idx;
        unsigned int valid_num_sge;
        u32 msg_len = 0;
-       int ret = 0;
+       int ret;
 
        valid_num_sge = calc_wr_sge_num(wr, &msg_len);
        memset(rc_sq_wqe, 0, sizeof(*rc_sq_wqe));
 
        rc_sq_wqe->msg_len = cpu_to_le32(msg_len);
 
-       switch (wr->opcode) {
-       case IB_WR_SEND_WITH_IMM:
-       case IB_WR_RDMA_WRITE_WITH_IMM:
-               rc_sq_wqe->immtdata = cpu_to_le32(be32_to_cpu(wr->ex.imm_data));
-               break;
-       case IB_WR_SEND_WITH_INV:
-               rc_sq_wqe->inv_key = cpu_to_le32(wr->ex.invalidate_rkey);
-               break;
-       default:
-               rc_sq_wqe->immtdata = 0;
-               break;
-       }
+       ret = set_rc_opcode(rc_sq_wqe, wr);
+       if (WARN_ON(ret))
+               return ret;
 
        roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_FENCE_S,
                     (wr->send_flags & IB_SEND_FENCE) ? 1 : 0);
@@ -443,33 +491,6 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp,
        roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_OWNER_S,
                     owner_bit);
 
-       switch (wr->opcode) {
-       case IB_WR_RDMA_READ:
-       case IB_WR_RDMA_WRITE:
-       case IB_WR_RDMA_WRITE_WITH_IMM:
-               rc_sq_wqe->rkey = cpu_to_le32(rdma_wr(wr)->rkey);
-               rc_sq_wqe->va = cpu_to_le64(rdma_wr(wr)->remote_addr);
-               break;
-       case IB_WR_LOCAL_INV:
-               roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_SO_S, 1);
-               rc_sq_wqe->inv_key = cpu_to_le32(wr->ex.invalidate_rkey);
-               break;
-       case IB_WR_REG_MR:
-               set_frmr_seg(rc_sq_wqe, reg_wr(wr));
-               break;
-       case IB_WR_ATOMIC_CMP_AND_SWP:
-       case IB_WR_ATOMIC_FETCH_AND_ADD:
-               rc_sq_wqe->rkey = cpu_to_le32(atomic_wr(wr)->rkey);
-               rc_sq_wqe->va = cpu_to_le64(atomic_wr(wr)->remote_addr);
-               break;
-       default:
-               break;
-       }
-
-       roce_set_field(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_OPCODE_M,
-                      V2_RC_SEND_WQE_BYTE_4_OPCODE_S,
-                      to_hr_opcode(wr->opcode));
-
        if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
            wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD)
                set_atomic_seg(wr, rc_sq_wqe, valid_num_sge);