RDMA/hns: Configure TRRL field in hip08 RoCE device
authoroulijun <oulijun@huawei.com>
Fri, 10 Nov 2017 08:55:44 +0000 (16:55 +0800)
committerDoug Ledford <dledford@redhat.com>
Fri, 10 Nov 2017 17:29:47 +0000 (12:29 -0500)
The TRRL(Target RDMA Read/aTOMIC List) record the information
of receiving RDMA READ or ATOMIC operation in hip08. It will
be used the hardware. The driver need to assign a continuous
physical address for trrl_ba field of qp context.

Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Shaobo Xu <xushaobo2@huawei.com>
Signed-off-by: Yixian Liu <liuyixian@huawei.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/hns/hns_roce_device.h
drivers/infiniband/hw/hns/hns_roce_hem.c
drivers/infiniband/hw/hns/hns_roce_hem.h
drivers/infiniband/hw/hns/hns_roce_hw_v2.c
drivers/infiniband/hw/hns/hns_roce_hw_v2.h
drivers/infiniband/hw/hns/hns_roce_main.c
drivers/infiniband/hw/hns/hns_roce_qp.c

index c4a28a00fe88100fc7ea86b846ea4eae9c41f207..724a5a0c1991ec303072429fe7de8f9bbad18f73 100644 (file)
@@ -367,6 +367,7 @@ struct hns_roce_qp_table {
        spinlock_t                      lock;
        struct hns_roce_hem_table       qp_table;
        struct hns_roce_hem_table       irrl_table;
+       struct hns_roce_hem_table       trrl_table;
 };
 
 struct hns_roce_cq_table {
@@ -542,6 +543,7 @@ struct hns_roce_caps {
        int             mtpt_entry_sz;
        int             qpc_entry_sz;
        int             irrl_entry_sz;
+       int             trrl_entry_sz;
        int             cqc_entry_sz;
        u32             pbl_ba_pg_sz;
        u32             pbl_buf_pg_sz;
index 576eb3bb1f2d1cbc2b62e0b1e8cb1287be771f1f..f1f8fa43d59d1bb9e8f0e216351d22385aac11e1 100644 (file)
@@ -1037,6 +1037,9 @@ void hns_roce_cleanup_hem(struct hns_roce_dev *hr_dev)
 {
        hns_roce_cleanup_hem_table(hr_dev, &hr_dev->cq_table.table);
        hns_roce_cleanup_hem_table(hr_dev, &hr_dev->qp_table.irrl_table);
+       if (hr_dev->caps.trrl_entry_sz)
+               hns_roce_cleanup_hem_table(hr_dev,
+                                          &hr_dev->qp_table.trrl_table);
        hns_roce_cleanup_hem_table(hr_dev, &hr_dev->qp_table.qp_table);
        hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtpt_table);
        hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtt_table);
index af28bbf31c7fe98d50f7f93d757e476e152af291..db66db12075e2b42151fbc24d148615e0841b8f9 100644 (file)
@@ -49,6 +49,7 @@ enum {
        HEM_TYPE_MTT,
        HEM_TYPE_CQE,
        HEM_TYPE_IRRL,
+       HEM_TYPE_TRRL,
 };
 
 #define HNS_ROCE_HEM_CHUNK_LEN \
index a950f78385556a1237f18fad537a880674262051..8ed81644e0225b87a7475fc31ce9beae61feae1b 100644 (file)
@@ -911,6 +911,7 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev)
        caps->max_srq_desc_sz   = HNS_ROCE_V2_MAX_SRQ_DESC_SZ;
        caps->qpc_entry_sz      = HNS_ROCE_V2_QPC_ENTRY_SZ;
        caps->irrl_entry_sz     = HNS_ROCE_V2_IRRL_ENTRY_SZ;
+       caps->trrl_entry_sz     = HNS_ROCE_V2_TRRL_ENTRY_SZ;
        caps->cqc_entry_sz      = HNS_ROCE_V2_CQC_ENTRY_SZ;
        caps->mtpt_entry_sz     = HNS_ROCE_V2_MTPT_ENTRY_SZ;
        caps->mtt_entry_sz      = HNS_ROCE_V2_MTT_ENTRY_SZ;
@@ -2265,10 +2266,12 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
        struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
        struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
        struct device *dev = hr_dev->dev;
+       dma_addr_t dma_handle_3;
        dma_addr_t dma_handle_2;
        dma_addr_t dma_handle;
        u32 page_size;
        u8 port_num;
+       u64 *mtts_3;
        u64 *mtts_2;
        u64 *mtts;
        u8 *dmac;
@@ -2291,6 +2294,14 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
                return -EINVAL;
        }
 
+       /* Search TRRL's mtts */
+       mtts_3 = hns_roce_table_find(hr_dev, &hr_dev->qp_table.trrl_table,
+                                    hr_qp->qpn, &dma_handle_3);
+       if (!mtts_3) {
+               dev_err(dev, "qp trrl_table find failed\n");
+               return -EINVAL;
+       }
+
        if ((attr_mask & IB_QP_ALT_PATH) || (attr_mask & IB_QP_ACCESS_FLAGS) ||
            (attr_mask & IB_QP_PKEY_INDEX) || (attr_mask & IB_QP_QKEY)) {
                dev_err(dev, "INIT2RTR attr_mask (0x%x) error\n", attr_mask);
@@ -2393,6 +2404,18 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
                       V2_QPC_BYTE_108_RX_REQ_EPSN_M,
                       V2_QPC_BYTE_108_RX_REQ_EPSN_S, 0);
 
+       roce_set_field(context->byte_132_trrl, V2_QPC_BYTE_132_TRRL_BA_M,
+                      V2_QPC_BYTE_132_TRRL_BA_S, dma_handle_3 >> 4);
+       roce_set_field(qpc_mask->byte_132_trrl, V2_QPC_BYTE_132_TRRL_BA_M,
+                      V2_QPC_BYTE_132_TRRL_BA_S, 0);
+       context->trrl_ba = (u32)(dma_handle_3 >> (16 + 4));
+       qpc_mask->trrl_ba = 0;
+       roce_set_field(context->byte_140_raq, V2_QPC_BYTE_140_TRRL_BA_M,
+                      V2_QPC_BYTE_140_TRRL_BA_S,
+                      (u32)(dma_handle_3 >> (32 + 16 + 4)));
+       roce_set_field(qpc_mask->byte_140_raq, V2_QPC_BYTE_140_TRRL_BA_M,
+                      V2_QPC_BYTE_140_TRRL_BA_S, 0);
+
        context->irrl_ba = (u32)(dma_handle_2 >> 6);
        qpc_mask->irrl_ba = 0;
        roce_set_field(context->byte_208_irrl, V2_QPC_BYTE_208_IRRL_BA_M,
index 864fcd1448b73b96c760a3706f788d1cfb442901..ea142253d8f8daf0c1b84c8599c8032c0248cea9 100644 (file)
@@ -64,6 +64,7 @@
 #define HNS_ROCE_V2_MAX_SRQ_DESC_SZ            64
 #define HNS_ROCE_V2_QPC_ENTRY_SZ               256
 #define HNS_ROCE_V2_IRRL_ENTRY_SZ              64
+#define HNS_ROCE_V2_TRRL_ENTRY_SZ              48
 #define HNS_ROCE_V2_CQC_ENTRY_SZ               64
 #define HNS_ROCE_V2_MTPT_ENTRY_SZ              64
 #define HNS_ROCE_V2_MTT_ENTRY_SZ               64
index 5bc8cc2d9ef48ee098415c75381253c1e470d4d8..cf02ac2d3596221d8b9d86c2ce301c37e0cf25c0 100644 (file)
@@ -597,16 +597,35 @@ static int hns_roce_init_hem(struct hns_roce_dev *hr_dev)
                goto err_unmap_qp;
        }
 
+       if (hr_dev->caps.trrl_entry_sz) {
+               ret = hns_roce_init_hem_table(hr_dev,
+                                             &hr_dev->qp_table.trrl_table,
+                                             HEM_TYPE_TRRL,
+                                             hr_dev->caps.trrl_entry_sz *
+                                             hr_dev->caps.max_qp_dest_rdma,
+                                             hr_dev->caps.num_qps, 1);
+               if (ret) {
+                       dev_err(dev,
+                              "Failed to init trrl_table memory, aborting.\n");
+                       goto err_unmap_irrl;
+               }
+       }
+
        ret = hns_roce_init_hem_table(hr_dev, &hr_dev->cq_table.table,
                                      HEM_TYPE_CQC, hr_dev->caps.cqc_entry_sz,
                                      hr_dev->caps.num_cqs, 1);
        if (ret) {
                dev_err(dev, "Failed to init CQ context memory, aborting.\n");
-               goto err_unmap_irrl;
+               goto err_unmap_trrl;
        }
 
        return 0;
 
+err_unmap_trrl:
+       if (hr_dev->caps.trrl_entry_sz)
+               hns_roce_cleanup_hem_table(hr_dev,
+                                          &hr_dev->qp_table.trrl_table);
+
 err_unmap_irrl:
        hns_roce_cleanup_hem_table(hr_dev, &hr_dev->qp_table.irrl_table);
 
index b1c9a3768b19696ac65048b69392221ccdd41205..49586ec8126ad6d7c8e2b3d5ef929319249153fe 100644 (file)
@@ -194,13 +194,23 @@ static int hns_roce_qp_alloc(struct hns_roce_dev *hr_dev, unsigned long qpn,
                goto err_put_qp;
        }
 
+       if (hr_dev->caps.trrl_entry_sz) {
+               /* Alloc memory for TRRL */
+               ret = hns_roce_table_get(hr_dev, &qp_table->trrl_table,
+                                        hr_qp->qpn);
+               if (ret) {
+                       dev_err(dev, "TRRL table get failed\n");
+                       goto err_put_irrl;
+               }
+       }
+
        spin_lock_irq(&qp_table->lock);
        ret = radix_tree_insert(&hr_dev->qp_table_tree,
                                hr_qp->qpn & (hr_dev->caps.num_qps - 1), hr_qp);
        spin_unlock_irq(&qp_table->lock);
        if (ret) {
                dev_err(dev, "QPC radix_tree_insert failed\n");
-               goto err_put_irrl;
+               goto err_put_trrl;
        }
 
        atomic_set(&hr_qp->refcount, 1);
@@ -208,6 +218,10 @@ static int hns_roce_qp_alloc(struct hns_roce_dev *hr_dev, unsigned long qpn,
 
        return 0;
 
+err_put_trrl:
+       if (hr_dev->caps.trrl_entry_sz)
+               hns_roce_table_put(hr_dev, &qp_table->trrl_table, hr_qp->qpn);
+
 err_put_irrl:
        hns_roce_table_put(hr_dev, &qp_table->irrl_table, hr_qp->qpn);
 
@@ -239,6 +253,9 @@ void hns_roce_qp_free(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp)
        wait_for_completion(&hr_qp->free);
 
        if ((hr_qp->ibqp.qp_type) != IB_QPT_GSI) {
+               if (hr_dev->caps.trrl_entry_sz)
+                       hns_roce_table_put(hr_dev, &qp_table->trrl_table,
+                                          hr_qp->qpn);
                hns_roce_table_put(hr_dev, &qp_table->irrl_table, hr_qp->qpn);
                hns_roce_table_put(hr_dev, &qp_table->qp_table, hr_qp->qpn);
        }