RDMA/hns: Add SCC context allocation support for hip08
authorYangyang Li <liyangyang20@huawei.com>
Tue, 18 Dec 2018 13:21:53 +0000 (21:21 +0800)
committerJason Gunthorpe <jgg@mellanox.com>
Thu, 24 Jan 2019 16:22:30 +0000 (09:22 -0700)
This patch adds SCC context allocation and initialization support for
DCQCN in kernel space driver.

Signed-off-by: Yangyang Li <liyangyang20@huawei.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/hw/hns/hns_roce_cmd.h
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 927701d..f682cb4 100644 (file)
@@ -98,6 +98,10 @@ enum {
        HNS_ROCE_CMD_MODIFY_CEQC        = 0x91,
        HNS_ROCE_CMD_QUERY_CEQC         = 0x92,
        HNS_ROCE_CMD_DESTROY_CEQC       = 0x93,
+
+       /* SCC CTX BT commands */
+       HNS_ROCE_CMD_READ_SCCC_BT0      = 0xa4,
+       HNS_ROCE_CMD_WRITE_SCCC_BT0     = 0xa5,
 };
 
 enum {
index 9a4be70..7c93be4 100644 (file)
@@ -482,6 +482,7 @@ struct hns_roce_qp_table {
        struct hns_roce_hem_table       qp_table;
        struct hns_roce_hem_table       irrl_table;
        struct hns_roce_hem_table       trrl_table;
+       struct hns_roce_hem_table       sccc_table;
 };
 
 struct hns_roce_cq_table {
@@ -768,6 +769,7 @@ struct hns_roce_caps {
        int             irrl_entry_sz;
        int             trrl_entry_sz;
        int             cqc_entry_sz;
+       int             sccc_entry_sz;
        int             srqc_entry_sz;
        int             idx_entry_sz;
        u32             pbl_ba_pg_sz;
@@ -780,6 +782,7 @@ struct hns_roce_caps {
        u32             srqc_bt_num;
        u32             cqc_bt_num;
        u32             mpt_bt_num;
+       u32             sccc_bt_num;
        u32             qpc_ba_pg_sz;
        u32             qpc_buf_pg_sz;
        u32             qpc_hop_num;
@@ -795,6 +798,9 @@ struct hns_roce_caps {
        u32             mtt_ba_pg_sz;
        u32             mtt_buf_pg_sz;
        u32             mtt_hop_num;
+       u32             sccc_ba_pg_sz;
+       u32             sccc_buf_pg_sz;
+       u32             sccc_hop_num;
        u32             cqe_ba_pg_sz;
        u32             cqe_buf_pg_sz;
        u32             cqe_hop_num;
index 4cdbcaf..fc7b69e 100644 (file)
@@ -45,6 +45,7 @@ bool hns_roce_check_whether_mhop(struct hns_roce_dev *hr_dev, u32 type)
            (hr_dev->caps.mpt_hop_num && type == HEM_TYPE_MTPT) ||
            (hr_dev->caps.cqc_hop_num && type == HEM_TYPE_CQC) ||
            (hr_dev->caps.srqc_hop_num && type == HEM_TYPE_SRQC) ||
+           (hr_dev->caps.sccc_hop_num && type == HEM_TYPE_SCCC) ||
            (hr_dev->caps.cqe_hop_num && type == HEM_TYPE_CQE) ||
            (hr_dev->caps.mtt_hop_num && type == HEM_TYPE_MTT) ||
            (hr_dev->caps.srqwqe_hop_num && type == HEM_TYPE_SRQWQE) ||
@@ -125,6 +126,14 @@ int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
                mhop->ba_l0_num = hr_dev->caps.cqc_bt_num;
                mhop->hop_num = hr_dev->caps.cqc_hop_num;
                break;
+       case HEM_TYPE_SCCC:
+               mhop->buf_chunk_size = 1 << (hr_dev->caps.sccc_buf_pg_sz
+                                            + PAGE_SHIFT);
+               mhop->bt_chunk_size = 1 << (hr_dev->caps.sccc_ba_pg_sz
+                                           + PAGE_SHIFT);
+               mhop->ba_l0_num = hr_dev->caps.sccc_bt_num;
+               mhop->hop_num = hr_dev->caps.sccc_hop_num;
+               break;
        case HEM_TYPE_SRQC:
                mhop->buf_chunk_size = 1 << (hr_dev->caps.srqc_buf_pg_sz
                                             + PAGE_SHIFT);
@@ -175,7 +184,7 @@ int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
                return 0;
 
        /*
-        * QPC/MTPT/CQC/SRQC alloc hem for buffer pages.
+        * QPC/MTPT/CQC/SRQC/SCCC alloc hem for buffer pages.
         * MTT/CQE alloc hem for bt pages.
         */
        bt_num = hns_roce_get_bt_num(table->type, mhop->hop_num);
@@ -486,7 +495,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,
        }
 
        /*
-        * alloc buffer space chunk for QPC/MTPT/CQC/SRQC.
+        * alloc buffer space chunk for QPC/MTPT/CQC/SRQC/SCCC.
         * alloc bt space chunk for MTT/CQE.
         */
        size = table->type < HEM_TYPE_MTT ? buf_chunk_size : bt_chunk_size;
@@ -658,7 +667,7 @@ static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev,
        }
 
        /*
-        * free buffer space chunk for QPC/MTPT/CQC/SRQC.
+        * free buffer space chunk for QPC/MTPT/CQC/SRQC/SCCC.
         * free bt space chunk for MTT/CQE.
         */
        hns_roce_free_hem(hr_dev, table->hem[hem_idx]);
@@ -904,6 +913,14 @@ int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev,
                        num_bt_l0 = hr_dev->caps.cqc_bt_num;
                        hop_num = hr_dev->caps.cqc_hop_num;
                        break;
+               case HEM_TYPE_SCCC:
+                       buf_chunk_size = 1 << (hr_dev->caps.sccc_buf_pg_sz
+                                       + PAGE_SHIFT);
+                       bt_chunk_size = 1 << (hr_dev->caps.sccc_ba_pg_sz
+                                       + PAGE_SHIFT);
+                       num_bt_l0 = hr_dev->caps.sccc_bt_num;
+                       hop_num = hr_dev->caps.sccc_hop_num;
+                       break;
                case HEM_TYPE_SRQC:
                        buf_chunk_size = 1 << (hr_dev->caps.srqc_buf_pg_sz
                                        + PAGE_SHIFT);
@@ -1081,6 +1098,9 @@ void hns_roce_cleanup_hem(struct hns_roce_dev *hr_dev)
                hns_roce_cleanup_hem_table(hr_dev,
                                           &hr_dev->srq_table.table);
        hns_roce_cleanup_hem_table(hr_dev, &hr_dev->cq_table.table);
+       if (hr_dev->caps.sccc_entry_sz)
+               hns_roce_cleanup_hem_table(hr_dev,
+                                          &hr_dev->qp_table.sccc_table);
        if (hr_dev->caps.trrl_entry_sz)
                hns_roce_cleanup_hem_table(hr_dev,
                                           &hr_dev->qp_table.trrl_table);
index a650278..b2aeb74 100644 (file)
@@ -44,6 +44,7 @@ enum {
        HEM_TYPE_MTPT,
        HEM_TYPE_CQC,
        HEM_TYPE_SRQC,
+       HEM_TYPE_SCCC,
 
         /* UNMAP HEM */
        HEM_TYPE_MTT,
index fb990ff..549a601 100644 (file)
@@ -1078,6 +1078,9 @@ static int hns_roce_query_pf_resource(struct hns_roce_dev *hr_dev)
        hr_dev->caps.sl_num = roce_get_field(req_b->qid_idx_sl_num,
                                             PF_RES_DATA_3_PF_SL_NUM_M,
                                             PF_RES_DATA_3_PF_SL_NUM_S);
+       hr_dev->caps.sccc_bt_num = roce_get_field(req_b->sccc_bt_idx_num,
+                                            PF_RES_DATA_4_PF_SCCC_BT_NUM_M,
+                                            PF_RES_DATA_4_PF_SCCC_BT_NUM_S);
 
        return 0;
 }
@@ -1193,6 +1196,14 @@ static int hns_roce_alloc_vf_resource(struct hns_roce_dev *hr_dev)
                                       VF_RES_B_DATA_3_VF_SL_NUM_M,
                                       VF_RES_B_DATA_3_VF_SL_NUM_S,
                                       HNS_ROCE_VF_SL_NUM);
+
+                       roce_set_field(req_b->vf_sccc_idx_num,
+                                      VF_RES_B_DATA_4_VF_SCCC_BT_IDX_M,
+                                      VF_RES_B_DATA_4_VF_SCCC_BT_IDX_S, 0);
+                       roce_set_field(req_b->vf_sccc_idx_num,
+                                      VF_RES_B_DATA_4_VF_SCCC_BT_NUM_M,
+                                      VF_RES_B_DATA_4_VF_SCCC_BT_NUM_S,
+                                      HNS_ROCE_VF_SCCC_BT_NUM);
                }
        }
 
@@ -1205,6 +1216,7 @@ static int hns_roce_v2_set_bt(struct hns_roce_dev *hr_dev)
        u8 qpc_hop_num = hr_dev->caps.qpc_hop_num;
        u8 cqc_hop_num = hr_dev->caps.cqc_hop_num;
        u8 mpt_hop_num = hr_dev->caps.mpt_hop_num;
+       u8 sccc_hop_num = hr_dev->caps.sccc_hop_num;
        struct hns_roce_cfg_bt_attr *req;
        struct hns_roce_cmq_desc desc;
 
@@ -1252,6 +1264,20 @@ static int hns_roce_v2_set_bt(struct hns_roce_dev *hr_dev)
                       CFG_BT_ATTR_DATA_3_VF_MPT_HOPNUM_S,
                       mpt_hop_num == HNS_ROCE_HOP_NUM_0 ? 0 : mpt_hop_num);
 
+       roce_set_field(req->vf_sccc_cfg,
+                      CFG_BT_ATTR_DATA_4_VF_SCCC_BA_PGSZ_M,
+                      CFG_BT_ATTR_DATA_4_VF_SCCC_BA_PGSZ_S,
+                      hr_dev->caps.sccc_ba_pg_sz + PG_SHIFT_OFFSET);
+       roce_set_field(req->vf_sccc_cfg,
+                      CFG_BT_ATTR_DATA_4_VF_SCCC_BUF_PGSZ_M,
+                      CFG_BT_ATTR_DATA_4_VF_SCCC_BUF_PGSZ_S,
+                      hr_dev->caps.sccc_buf_pg_sz + PG_SHIFT_OFFSET);
+       roce_set_field(req->vf_sccc_cfg,
+                      CFG_BT_ATTR_DATA_4_VF_SCCC_HOPNUM_M,
+                      CFG_BT_ATTR_DATA_4_VF_SCCC_HOPNUM_S,
+                      sccc_hop_num ==
+                             HNS_ROCE_HOP_NUM_0 ? 0 : sccc_hop_num);
+
        return hns_roce_cmq_send(hr_dev, &desc, 1);
 }
 
@@ -1408,9 +1434,14 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev)
        caps->max_srq_wrs       = HNS_ROCE_V2_MAX_SRQ_WR;
        caps->max_srq_sges      = HNS_ROCE_V2_MAX_SRQ_SGE;
 
-       if (hr_dev->pci_dev->revision == 0x21)
+       if (hr_dev->pci_dev->revision == 0x21) {
                caps->flags |= HNS_ROCE_CAP_FLAG_ATOMIC |
                               HNS_ROCE_CAP_FLAG_SRQ;
+               caps->sccc_entry_sz     = HNS_ROCE_V2_SCCC_ENTRY_SZ;
+               caps->sccc_ba_pg_sz     = 0;
+               caps->sccc_buf_pg_sz    = 0;
+               caps->sccc_hop_num      = HNS_ROCE_SCCC_HOP_NUM;
+       }
 
        ret = hns_roce_v2_set_bt(hr_dev);
        if (ret)
@@ -2663,11 +2694,18 @@ static int hns_roce_v2_set_hem(struct hns_roce_dev *hr_dev,
        case HEM_TYPE_SRQC:
                op = HNS_ROCE_CMD_WRITE_SRQC_BT0;
                break;
+       case HEM_TYPE_SCCC:
+               op = HNS_ROCE_CMD_WRITE_SCCC_BT0;
+               break;
        default:
                dev_warn(dev, "Table %d not to be written by mailbox!\n",
                         table->type);
                return 0;
        }
+
+       if (table->type == HEM_TYPE_SCCC && step_idx)
+               return 0;
+
        op += step_idx;
 
        mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
@@ -2722,6 +2760,8 @@ static int hns_roce_v2_clear_hem(struct hns_roce_dev *hr_dev,
        case HEM_TYPE_CQC:
                op = HNS_ROCE_CMD_DESTROY_CQC_BT0;
                break;
+       case HEM_TYPE_SCCC:
+               break;
        case HEM_TYPE_SRQC:
                op = HNS_ROCE_CMD_DESTROY_SRQC_BT0;
                break;
@@ -2730,6 +2770,10 @@ static int hns_roce_v2_clear_hem(struct hns_roce_dev *hr_dev,
                         table->type);
                return 0;
        }
+
+       if (table->type == HEM_TYPE_SCCC)
+               return 0;
+
        op += step_idx;
 
        mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
index b72d044..007caa2 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/bitops.h>
 
 #define HNS_ROCE_VF_QPC_BT_NUM                 256
+#define HNS_ROCE_VF_SCCC_BT_NUM                        64
 #define HNS_ROCE_VF_SRQC_BT_NUM                        64
 #define HNS_ROCE_VF_CQC_BT_NUM                 64
 #define HNS_ROCE_VF_MPT_BT_NUM                 64
@@ -83,6 +84,7 @@
 #define HNS_ROCE_V2_MTPT_ENTRY_SZ              64
 #define HNS_ROCE_V2_MTT_ENTRY_SZ               64
 #define HNS_ROCE_V2_CQE_ENTRY_SIZE             32
+#define HNS_ROCE_V2_SCCC_ENTRY_SZ              32
 #define HNS_ROCE_V2_PAGE_SIZE_SUPPORTED                0xFFFFF000
 #define HNS_ROCE_V2_MAX_INNER_MTPT_NUM         2
 #define HNS_ROCE_INVALID_LKEY                  0x100
@@ -91,6 +93,7 @@
 #define HNS_ROCE_V2_RSV_QPS                    8
 
 #define HNS_ROCE_CONTEXT_HOP_NUM               1
+#define HNS_ROCE_SCCC_HOP_NUM                  1
 #define HNS_ROCE_MTT_HOP_NUM                   1
 #define HNS_ROCE_CQE_HOP_NUM                   1
 #define HNS_ROCE_SRQWQE_HOP_NUM                        1
@@ -1300,7 +1303,8 @@ struct hns_roce_pf_res_b {
        __le32  smac_idx_num;
        __le32  sgid_idx_num;
        __le32  qid_idx_sl_num;
-       __le32  rsv[2];
+       __le32  sccc_bt_idx_num;
+       __le32  rsv;
 };
 
 #define PF_RES_DATA_1_PF_SMAC_IDX_S 0
@@ -1321,6 +1325,12 @@ struct hns_roce_pf_res_b {
 #define PF_RES_DATA_3_PF_SL_NUM_S 16
 #define PF_RES_DATA_3_PF_SL_NUM_M GENMASK(26, 16)
 
+#define PF_RES_DATA_4_PF_SCCC_BT_IDX_S 0
+#define PF_RES_DATA_4_PF_SCCC_BT_IDX_M GENMASK(8, 0)
+
+#define PF_RES_DATA_4_PF_SCCC_BT_NUM_S 9
+#define PF_RES_DATA_4_PF_SCCC_BT_NUM_M GENMASK(17, 9)
+
 struct hns_roce_vf_res_a {
        __le32 vf_id;
        __le32 vf_qpc_bt_idx_num;
@@ -1365,7 +1375,8 @@ struct hns_roce_vf_res_b {
        __le32 vf_smac_idx_num;
        __le32 vf_sgid_idx_num;
        __le32 vf_qid_idx_sl_num;
-       __le32 rsv[2];
+       __le32 vf_sccc_idx_num;
+       __le32 rsv1;
 };
 
 #define VF_RES_B_DATA_0_VF_ID_S 0
@@ -1389,6 +1400,12 @@ struct hns_roce_vf_res_b {
 #define VF_RES_B_DATA_3_VF_SL_NUM_S 16
 #define VF_RES_B_DATA_3_VF_SL_NUM_M GENMASK(19, 16)
 
+#define VF_RES_B_DATA_4_VF_SCCC_BT_IDX_S 0
+#define VF_RES_B_DATA_4_VF_SCCC_BT_IDX_M GENMASK(8, 0)
+
+#define VF_RES_B_DATA_4_VF_SCCC_BT_NUM_S 9
+#define VF_RES_B_DATA_4_VF_SCCC_BT_NUM_M GENMASK(17, 9)
+
 struct hns_roce_vf_switch {
        __le32 rocee_sel;
        __le32 fun_id;
@@ -1424,7 +1441,8 @@ struct hns_roce_cfg_bt_attr {
        __le32 vf_srqc_cfg;
        __le32 vf_cqc_cfg;
        __le32 vf_mpt_cfg;
-       __le32 rsv[2];
+       __le32 vf_sccc_cfg;
+       __le32 rsv;
 };
 
 #define CFG_BT_ATTR_DATA_0_VF_QPC_BA_PGSZ_S 0
@@ -1463,6 +1481,15 @@ struct hns_roce_cfg_bt_attr {
 #define CFG_BT_ATTR_DATA_3_VF_MPT_HOPNUM_S 8
 #define CFG_BT_ATTR_DATA_3_VF_MPT_HOPNUM_M GENMASK(9, 8)
 
+#define CFG_BT_ATTR_DATA_4_VF_SCCC_BA_PGSZ_S 0
+#define CFG_BT_ATTR_DATA_4_VF_SCCC_BA_PGSZ_M GENMASK(3, 0)
+
+#define CFG_BT_ATTR_DATA_4_VF_SCCC_BUF_PGSZ_S 4
+#define CFG_BT_ATTR_DATA_4_VF_SCCC_BUF_PGSZ_M GENMASK(7, 4)
+
+#define CFG_BT_ATTR_DATA_4_VF_SCCC_HOPNUM_S 8
+#define CFG_BT_ATTR_DATA_4_VF_SCCC_HOPNUM_M GENMASK(9, 8)
+
 struct hns_roce_cfg_sgid_tb {
        __le32  table_idx_rsv;
        __le32  vf_sgid_l;
index 46ede58..3145866 100644 (file)
@@ -702,8 +702,26 @@ static int hns_roce_init_hem(struct hns_roce_dev *hr_dev)
                }
        }
 
+       if (hr_dev->caps.sccc_entry_sz) {
+               ret = hns_roce_init_hem_table(hr_dev,
+                                             &hr_dev->qp_table.sccc_table,
+                                             HEM_TYPE_SCCC,
+                                             hr_dev->caps.sccc_entry_sz,
+                                             hr_dev->caps.num_qps, 1);
+               if (ret) {
+                       dev_err(dev,
+                             "Failed to init SCC context memory, aborting.\n");
+                       goto err_unmap_idx;
+               }
+       }
+
        return 0;
 
+err_unmap_idx:
+       if (hr_dev->caps.num_idx_segs)
+               hns_roce_cleanup_hem_table(hr_dev,
+                                          &hr_dev->mr_table.mtt_idx_table);
+
 err_unmap_srqwqe:
        if (hr_dev->caps.num_srqwqe_segs)
                hns_roce_cleanup_hem_table(hr_dev,
index 507de9d..dc9a30e 100644 (file)
@@ -209,13 +209,23 @@ static int hns_roce_qp_alloc(struct hns_roce_dev *hr_dev, unsigned long qpn,
                }
        }
 
+       if (hr_dev->caps.sccc_entry_sz) {
+               /* Alloc memory for SCC CTX */
+               ret = hns_roce_table_get(hr_dev, &qp_table->sccc_table,
+                                        hr_qp->qpn);
+               if (ret) {
+                       dev_err(dev, "SCC CTX table get failed\n");
+                       goto err_put_trrl;
+               }
+       }
+
        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_trrl;
+               goto err_put_sccc;
        }
 
        atomic_set(&hr_qp->refcount, 1);
@@ -223,6 +233,11 @@ static int hns_roce_qp_alloc(struct hns_roce_dev *hr_dev, unsigned long qpn,
 
        return 0;
 
+err_put_sccc:
+       if (hr_dev->caps.sccc_entry_sz)
+               hns_roce_table_put(hr_dev, &qp_table->sccc_table,
+                                  hr_qp->qpn);
+
 err_put_trrl:
        if (hr_dev->caps.trrl_entry_sz)
                hns_roce_table_put(hr_dev, &qp_table->trrl_table, hr_qp->qpn);
@@ -258,6 +273,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.sccc_entry_sz)
+                       hns_roce_table_put(hr_dev, &qp_table->sccc_table,
+                                          hr_qp->qpn);
                if (hr_dev->caps.trrl_entry_sz)
                        hns_roce_table_put(hr_dev, &qp_table->trrl_table,
                                           hr_qp->qpn);