Skip to content

Commit 6b63597

Browse files
oulijunjgunthorpe
authored andcommitted
RDMA/hns: Add TSQ link table support
In hip08, TSQ(Transport Service Queue) should be extended to host memory to store the doorbells. This patch adds the support of creating TSQ, and then configured to the hardware. Signed-off-by: Yixian Liu <liuyixian@huawei.com> Signed-off-by: Lijun Ou <oulijun@huawei.com> Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
1 parent 0576cbd commit 6b63597

File tree

3 files changed

+297
-7
lines changed

3 files changed

+297
-7
lines changed

drivers/infiniband/hw/hns/hns_roce_device.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,8 @@ struct hns_roce_caps {
720720
u32 eqe_ba_pg_sz;
721721
u32 eqe_buf_pg_sz;
722722
u32 eqe_hop_num;
723+
u32 sl_num;
724+
u32 tsq_buf_pg_sz;
723725
u32 chunk_sz; /* chunk size in non multihop mode*/
724726
u64 flags;
725727
};

drivers/infiniband/hw/hns/hns_roce_hw_v2.c

Lines changed: 211 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,8 @@ static int hns_roce_config_global_param(struct hns_roce_dev *hr_dev)
925925
static int hns_roce_query_pf_resource(struct hns_roce_dev *hr_dev)
926926
{
927927
struct hns_roce_cmq_desc desc[2];
928-
struct hns_roce_pf_res *res;
928+
struct hns_roce_pf_res_a *req_a;
929+
struct hns_roce_pf_res_b *req_b;
929930
int ret;
930931
int i;
931932

@@ -943,21 +944,26 @@ static int hns_roce_query_pf_resource(struct hns_roce_dev *hr_dev)
943944
if (ret)
944945
return ret;
945946

946-
res = (struct hns_roce_pf_res *)desc[0].data;
947+
req_a = (struct hns_roce_pf_res_a *)desc[0].data;
948+
req_b = (struct hns_roce_pf_res_b *)desc[1].data;
947949

948-
hr_dev->caps.qpc_bt_num = roce_get_field(res->qpc_bt_idx_num,
950+
hr_dev->caps.qpc_bt_num = roce_get_field(req_a->qpc_bt_idx_num,
949951
PF_RES_DATA_1_PF_QPC_BT_NUM_M,
950952
PF_RES_DATA_1_PF_QPC_BT_NUM_S);
951-
hr_dev->caps.srqc_bt_num = roce_get_field(res->srqc_bt_idx_num,
953+
hr_dev->caps.srqc_bt_num = roce_get_field(req_a->srqc_bt_idx_num,
952954
PF_RES_DATA_2_PF_SRQC_BT_NUM_M,
953955
PF_RES_DATA_2_PF_SRQC_BT_NUM_S);
954-
hr_dev->caps.cqc_bt_num = roce_get_field(res->cqc_bt_idx_num,
956+
hr_dev->caps.cqc_bt_num = roce_get_field(req_a->cqc_bt_idx_num,
955957
PF_RES_DATA_3_PF_CQC_BT_NUM_M,
956958
PF_RES_DATA_3_PF_CQC_BT_NUM_S);
957-
hr_dev->caps.mpt_bt_num = roce_get_field(res->mpt_bt_idx_num,
959+
hr_dev->caps.mpt_bt_num = roce_get_field(req_a->mpt_bt_idx_num,
958960
PF_RES_DATA_4_PF_MPT_BT_NUM_M,
959961
PF_RES_DATA_4_PF_MPT_BT_NUM_S);
960962

963+
hr_dev->caps.sl_num = roce_get_field(req_b->qid_idx_sl_num,
964+
PF_RES_DATA_3_PF_SL_NUM_M,
965+
PF_RES_DATA_3_PF_SL_NUM_S);
966+
961967
return 0;
962968
}
963969

@@ -1203,6 +1209,7 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev)
12031209
caps->eqe_ba_pg_sz = 0;
12041210
caps->eqe_buf_pg_sz = 0;
12051211
caps->eqe_hop_num = HNS_ROCE_EQE_HOP_NUM;
1212+
caps->tsq_buf_pg_sz = 0;
12061213
caps->chunk_sz = HNS_ROCE_V2_TABLE_CHUNK_SIZE;
12071214

12081215
caps->flags = HNS_ROCE_CAP_FLAG_REREG_MR |
@@ -1224,6 +1231,202 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev)
12241231
return ret;
12251232
}
12261233

1234+
static int hns_roce_config_link_table(struct hns_roce_dev *hr_dev,
1235+
enum hns_roce_link_table_type type)
1236+
{
1237+
struct hns_roce_cmq_desc desc[2];
1238+
struct hns_roce_cfg_llm_a *req_a =
1239+
(struct hns_roce_cfg_llm_a *)desc[0].data;
1240+
struct hns_roce_cfg_llm_b *req_b =
1241+
(struct hns_roce_cfg_llm_b *)desc[1].data;
1242+
struct hns_roce_v2_priv *priv = hr_dev->priv;
1243+
struct hns_roce_link_table *link_tbl;
1244+
struct hns_roce_link_table_entry *entry;
1245+
enum hns_roce_opcode_type opcode;
1246+
u32 page_num;
1247+
int i;
1248+
1249+
switch (type) {
1250+
case TSQ_LINK_TABLE:
1251+
link_tbl = &priv->tsq;
1252+
opcode = HNS_ROCE_OPC_CFG_EXT_LLM;
1253+
break;
1254+
default:
1255+
return -EINVAL;
1256+
}
1257+
1258+
page_num = link_tbl->npages;
1259+
entry = link_tbl->table.buf;
1260+
memset(req_a, 0, sizeof(*req_a));
1261+
memset(req_b, 0, sizeof(*req_b));
1262+
1263+
for (i = 0; i < 2; i++) {
1264+
hns_roce_cmq_setup_basic_desc(&desc[i], opcode, false);
1265+
1266+
if (i == 0)
1267+
desc[i].flag |= cpu_to_le16(HNS_ROCE_CMD_FLAG_NEXT);
1268+
else
1269+
desc[i].flag &= ~cpu_to_le16(HNS_ROCE_CMD_FLAG_NEXT);
1270+
1271+
if (i == 0) {
1272+
req_a->base_addr_l = link_tbl->table.map & 0xffffffff;
1273+
req_a->base_addr_h = (link_tbl->table.map >> 32) &
1274+
0xffffffff;
1275+
roce_set_field(req_a->depth_pgsz_init_en,
1276+
CFG_LLM_QUE_DEPTH_M,
1277+
CFG_LLM_QUE_DEPTH_S,
1278+
link_tbl->npages);
1279+
roce_set_field(req_a->depth_pgsz_init_en,
1280+
CFG_LLM_QUE_PGSZ_M,
1281+
CFG_LLM_QUE_PGSZ_S,
1282+
link_tbl->pg_sz);
1283+
req_a->head_ba_l = entry[0].blk_ba0;
1284+
req_a->head_ba_h_nxtptr = entry[0].blk_ba1_nxt_ptr;
1285+
roce_set_field(req_a->head_ptr,
1286+
CFG_LLM_HEAD_PTR_M,
1287+
CFG_LLM_HEAD_PTR_S, 0);
1288+
} else {
1289+
req_b->tail_ba_l = entry[page_num - 1].blk_ba0;
1290+
roce_set_field(req_b->tail_ba_h,
1291+
CFG_LLM_TAIL_BA_H_M,
1292+
CFG_LLM_TAIL_BA_H_S,
1293+
entry[page_num - 1].blk_ba1_nxt_ptr &
1294+
HNS_ROCE_LINK_TABLE_BA1_M);
1295+
roce_set_field(req_b->tail_ptr,
1296+
CFG_LLM_TAIL_PTR_M,
1297+
CFG_LLM_TAIL_PTR_S,
1298+
(entry[page_num - 2].blk_ba1_nxt_ptr &
1299+
HNS_ROCE_LINK_TABLE_NXT_PTR_M) >>
1300+
HNS_ROCE_LINK_TABLE_NXT_PTR_S);
1301+
}
1302+
}
1303+
roce_set_field(req_a->depth_pgsz_init_en,
1304+
CFG_LLM_INIT_EN_M, CFG_LLM_INIT_EN_S, 1);
1305+
1306+
return hns_roce_cmq_send(hr_dev, desc, 2);
1307+
}
1308+
1309+
static int hns_roce_init_link_table(struct hns_roce_dev *hr_dev,
1310+
enum hns_roce_link_table_type type)
1311+
{
1312+
struct hns_roce_v2_priv *priv = hr_dev->priv;
1313+
struct hns_roce_link_table *link_tbl;
1314+
struct hns_roce_link_table_entry *entry;
1315+
struct device *dev = hr_dev->dev;
1316+
u32 buf_chk_sz;
1317+
dma_addr_t t;
1318+
int pg_num_a;
1319+
int pg_num_b;
1320+
int pg_num;
1321+
int size;
1322+
int i;
1323+
1324+
switch (type) {
1325+
case TSQ_LINK_TABLE:
1326+
link_tbl = &priv->tsq;
1327+
buf_chk_sz = 1 << (hr_dev->caps.tsq_buf_pg_sz + PAGE_SHIFT);
1328+
pg_num_a = hr_dev->caps.num_qps * 8 / buf_chk_sz;
1329+
pg_num_b = hr_dev->caps.sl_num * 4 + 2;
1330+
break;
1331+
default:
1332+
return -EINVAL;
1333+
}
1334+
1335+
pg_num = max(pg_num_a, pg_num_b);
1336+
size = pg_num * sizeof(struct hns_roce_link_table_entry);
1337+
1338+
link_tbl->table.buf = dma_alloc_coherent(dev, size,
1339+
&link_tbl->table.map,
1340+
GFP_KERNEL);
1341+
if (!link_tbl->table.buf)
1342+
goto out;
1343+
1344+
link_tbl->pg_list = kcalloc(pg_num, sizeof(*link_tbl->pg_list),
1345+
GFP_KERNEL);
1346+
if (!link_tbl->pg_list)
1347+
goto err_kcalloc_failed;
1348+
1349+
entry = link_tbl->table.buf;
1350+
for (i = 0; i < pg_num; ++i) {
1351+
link_tbl->pg_list[i].buf = dma_alloc_coherent(dev, buf_chk_sz,
1352+
&t, GFP_KERNEL);
1353+
if (!link_tbl->pg_list[i].buf)
1354+
goto err_alloc_buf_failed;
1355+
1356+
link_tbl->pg_list[i].map = t;
1357+
memset(link_tbl->pg_list[i].buf, 0, buf_chk_sz);
1358+
1359+
entry[i].blk_ba0 = (t >> 12) & 0xffffffff;
1360+
roce_set_field(entry[i].blk_ba1_nxt_ptr,
1361+
HNS_ROCE_LINK_TABLE_BA1_M,
1362+
HNS_ROCE_LINK_TABLE_BA1_S,
1363+
t >> 44);
1364+
1365+
if (i < (pg_num - 1))
1366+
roce_set_field(entry[i].blk_ba1_nxt_ptr,
1367+
HNS_ROCE_LINK_TABLE_NXT_PTR_M,
1368+
HNS_ROCE_LINK_TABLE_NXT_PTR_S,
1369+
i + 1);
1370+
}
1371+
link_tbl->npages = pg_num;
1372+
link_tbl->pg_sz = buf_chk_sz;
1373+
1374+
return hns_roce_config_link_table(hr_dev, type);
1375+
1376+
err_alloc_buf_failed:
1377+
for (i -= 1; i >= 0; i--)
1378+
dma_free_coherent(dev, buf_chk_sz,
1379+
link_tbl->pg_list[i].buf,
1380+
link_tbl->pg_list[i].map);
1381+
kfree(link_tbl->pg_list);
1382+
1383+
err_kcalloc_failed:
1384+
dma_free_coherent(dev, size, link_tbl->table.buf,
1385+
link_tbl->table.map);
1386+
1387+
out:
1388+
return -ENOMEM;
1389+
}
1390+
1391+
static void hns_roce_free_link_table(struct hns_roce_dev *hr_dev,
1392+
struct hns_roce_link_table *link_tbl)
1393+
{
1394+
struct device *dev = hr_dev->dev;
1395+
int size;
1396+
int i;
1397+
1398+
size = link_tbl->npages * sizeof(struct hns_roce_link_table_entry);
1399+
1400+
for (i = 0; i < link_tbl->npages; ++i)
1401+
if (link_tbl->pg_list[i].buf)
1402+
dma_free_coherent(dev, link_tbl->pg_sz,
1403+
link_tbl->pg_list[i].buf,
1404+
link_tbl->pg_list[i].map);
1405+
kfree(link_tbl->pg_list);
1406+
1407+
dma_free_coherent(dev, size, link_tbl->table.buf,
1408+
link_tbl->table.map);
1409+
}
1410+
1411+
static int hns_roce_v2_init(struct hns_roce_dev *hr_dev)
1412+
{
1413+
int ret;
1414+
1415+
/* TSQ includes SQ doorbell and ack doorbell */
1416+
ret = hns_roce_init_link_table(hr_dev, TSQ_LINK_TABLE);
1417+
if (ret)
1418+
dev_err(hr_dev->dev, "TSQ init failed, ret = %d.\n", ret);
1419+
1420+
return ret;
1421+
}
1422+
1423+
static void hns_roce_v2_exit(struct hns_roce_dev *hr_dev)
1424+
{
1425+
struct hns_roce_v2_priv *priv = hr_dev->priv;
1426+
1427+
hns_roce_free_link_table(hr_dev, &priv->tsq);
1428+
}
1429+
12271430
static int hns_roce_v2_cmd_pending(struct hns_roce_dev *hr_dev)
12281431
{
12291432
u32 status = readl(hr_dev->reg_base + ROCEE_VF_MB_STATUS_REG);
@@ -4722,6 +4925,8 @@ static const struct hns_roce_hw hns_roce_hw_v2 = {
47224925
.cmq_init = hns_roce_v2_cmq_init,
47234926
.cmq_exit = hns_roce_v2_cmq_exit,
47244927
.hw_profile = hns_roce_v2_profile,
4928+
.hw_init = hns_roce_v2_init,
4929+
.hw_exit = hns_roce_v2_exit,
47254930
.post_mbox = hns_roce_v2_post_mbox,
47264931
.chk_mbox = hns_roce_v2_chk_mbox,
47274932
.set_gid = hns_roce_v2_set_gid,

drivers/infiniband/hw/hns/hns_roce_hw_v2.h

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ enum hns_roce_opcode_type {
203203
HNS_ROCE_OPC_ALLOC_PF_RES = 0x8004,
204204
HNS_ROCE_OPC_QUERY_PF_RES = 0x8400,
205205
HNS_ROCE_OPC_ALLOC_VF_RES = 0x8401,
206+
HNS_ROCE_OPC_CFG_EXT_LLM = 0x8403,
206207
HNS_ROCE_OPC_CFG_BT_ATTR = 0x8506,
207208
};
208209

@@ -1061,6 +1062,40 @@ struct hns_roce_query_version {
10611062
__le32 rsv[5];
10621063
};
10631064

1065+
struct hns_roce_cfg_llm_a {
1066+
__le32 base_addr_l;
1067+
__le32 base_addr_h;
1068+
__le32 depth_pgsz_init_en;
1069+
__le32 head_ba_l;
1070+
__le32 head_ba_h_nxtptr;
1071+
__le32 head_ptr;
1072+
};
1073+
1074+
#define CFG_LLM_QUE_DEPTH_S 0
1075+
#define CFG_LLM_QUE_DEPTH_M GENMASK(12, 0)
1076+
1077+
#define CFG_LLM_QUE_PGSZ_S 16
1078+
#define CFG_LLM_QUE_PGSZ_M GENMASK(19, 16)
1079+
1080+
#define CFG_LLM_INIT_EN_S 20
1081+
#define CFG_LLM_INIT_EN_M GENMASK(20, 20)
1082+
1083+
#define CFG_LLM_HEAD_PTR_S 0
1084+
#define CFG_LLM_HEAD_PTR_M GENMASK(11, 0)
1085+
1086+
struct hns_roce_cfg_llm_b {
1087+
__le32 tail_ba_l;
1088+
__le32 tail_ba_h;
1089+
__le32 tail_ptr;
1090+
__le32 rsv[3];
1091+
};
1092+
1093+
#define CFG_LLM_TAIL_BA_H_S 0
1094+
#define CFG_LLM_TAIL_BA_H_M GENMASK(19, 0)
1095+
1096+
#define CFG_LLM_TAIL_PTR_S 0
1097+
#define CFG_LLM_TAIL_PTR_M GENMASK(11, 0)
1098+
10641099
struct hns_roce_cfg_global_param {
10651100
__le32 time_cfg_udp_port;
10661101
__le32 rsv[5];
@@ -1072,7 +1107,7 @@ struct hns_roce_cfg_global_param {
10721107
#define CFG_GLOBAL_PARAM_DATA_0_ROCEE_UDP_PORT_S 16
10731108
#define CFG_GLOBAL_PARAM_DATA_0_ROCEE_UDP_PORT_M GENMASK(31, 16)
10741109

1075-
struct hns_roce_pf_res {
1110+
struct hns_roce_pf_res_a {
10761111
__le32 rsv;
10771112
__le32 qpc_bt_idx_num;
10781113
__le32 srqc_bt_idx_num;
@@ -1111,6 +1146,32 @@ struct hns_roce_pf_res {
11111146
#define PF_RES_DATA_5_PF_EQC_BT_NUM_S 16
11121147
#define PF_RES_DATA_5_PF_EQC_BT_NUM_M GENMASK(25, 16)
11131148

1149+
struct hns_roce_pf_res_b {
1150+
__le32 rsv0;
1151+
__le32 smac_idx_num;
1152+
__le32 sgid_idx_num;
1153+
__le32 qid_idx_sl_num;
1154+
__le32 rsv[2];
1155+
};
1156+
1157+
#define PF_RES_DATA_1_PF_SMAC_IDX_S 0
1158+
#define PF_RES_DATA_1_PF_SMAC_IDX_M GENMASK(7, 0)
1159+
1160+
#define PF_RES_DATA_1_PF_SMAC_NUM_S 8
1161+
#define PF_RES_DATA_1_PF_SMAC_NUM_M GENMASK(16, 8)
1162+
1163+
#define PF_RES_DATA_2_PF_SGID_IDX_S 0
1164+
#define PF_RES_DATA_2_PF_SGID_IDX_M GENMASK(7, 0)
1165+
1166+
#define PF_RES_DATA_2_PF_SGID_NUM_S 8
1167+
#define PF_RES_DATA_2_PF_SGID_NUM_M GENMASK(16, 8)
1168+
1169+
#define PF_RES_DATA_3_PF_QID_IDX_S 0
1170+
#define PF_RES_DATA_3_PF_QID_IDX_M GENMASK(9, 0)
1171+
1172+
#define PF_RES_DATA_3_PF_SL_NUM_S 16
1173+
#define PF_RES_DATA_3_PF_SL_NUM_M GENMASK(26, 16)
1174+
11141175
struct hns_roce_vf_res_a {
11151176
__le32 vf_id;
11161177
__le32 vf_qpc_bt_idx_num;
@@ -1276,8 +1337,30 @@ struct hns_roce_v2_cmq {
12761337
u16 last_status;
12771338
};
12781339

1340+
enum hns_roce_link_table_type {
1341+
TSQ_LINK_TABLE,
1342+
};
1343+
1344+
struct hns_roce_link_table {
1345+
struct hns_roce_buf_list table;
1346+
struct hns_roce_buf_list *pg_list;
1347+
u32 npages;
1348+
u32 pg_sz;
1349+
};
1350+
1351+
struct hns_roce_link_table_entry {
1352+
u32 blk_ba0;
1353+
u32 blk_ba1_nxt_ptr;
1354+
};
1355+
#define HNS_ROCE_LINK_TABLE_BA1_S 0
1356+
#define HNS_ROCE_LINK_TABLE_BA1_M GENMASK(19, 0)
1357+
1358+
#define HNS_ROCE_LINK_TABLE_NXT_PTR_S 20
1359+
#define HNS_ROCE_LINK_TABLE_NXT_PTR_M GENMASK(31, 20)
1360+
12791361
struct hns_roce_v2_priv {
12801362
struct hns_roce_v2_cmq cmq;
1363+
struct hns_roce_link_table tsq;
12811364
};
12821365

12831366
struct hns_roce_eq_context {

0 commit comments

Comments
 (0)