From f457a4648d8705a563be72ac736f65639de11d52 Mon Sep 17 00:00:00 2001
From: Yixing Liu <liuyixing1@huawei.com>
Date: Thu, 22 Feb 2024 15:55:24 +0800
Subject: [PATCH 2/2] libhns: Support DSCP

driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I92J5Q

------------------------------------------------------------------

This patch adds user mode DSCP function through
the mapping of dscp-tc configured in kernel mode.

Signed-off-by: Yixing Liu <liuyixing1@huawei.com>
Signed-off-by: Ran Zhou <zhouran10@h-partners.com>
---
 providers/hns/hns_roce_u.h       |  7 +++++++
 providers/hns/hns_roce_u_abi.h   |  3 +++
 providers/hns/hns_roce_u_hw_v2.c | 24 ++++++++++++++++++------
 providers/hns/hns_roce_u_verbs.c |  3 +++
 4 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/providers/hns/hns_roce_u.h b/providers/hns/hns_roce_u.h
index afb68fe..5ec2734 100644
--- a/providers/hns/hns_roce_u.h
+++ b/providers/hns/hns_roce_u.h
@@ -182,6 +182,11 @@ enum hns_roce_pktype {
 	HNS_ROCE_PKTYPE_ROCE_V2_IPV4,
 };
 
+enum hns_roce_tc_map_mode {
+	HNS_ROCE_TC_MAP_MODE_PRIO,
+	HNS_ROCE_TC_MAP_MODE_DSCP,
+};
+
 struct hns_roce_db_page {
 	struct hns_roce_db_page	*prev, *next;
 	struct hns_roce_buf	buf;
@@ -323,6 +328,8 @@ struct hns_roce_qp {
 	unsigned int			next_sge;
 	int				port_num;
 	uint8_t				sl;
+	uint8_t				tc_mode;
+	uint8_t				priority;
 	unsigned int			qkey;
 	enum ibv_mtu			path_mtu;
 
diff --git a/providers/hns/hns_roce_u_abi.h b/providers/hns/hns_roce_u_abi.h
index 3f98eb3..ec47c4b 100644
--- a/providers/hns/hns_roce_u_abi.h
+++ b/providers/hns/hns_roce_u_abi.h
@@ -64,4 +64,7 @@ DECLARE_DRV_CMD(hns_roce_create_srq_ex, IB_USER_VERBS_CMD_CREATE_XSRQ,
 DECLARE_DRV_CMD(hns_roce_create_ah, IB_USER_VERBS_CMD_CREATE_AH, empty,
 		hns_roce_ib_create_ah_resp);
 
+DECLARE_DRV_CMD(hns_roce_modify_qp_ex, IB_USER_VERBS_EX_CMD_MODIFY_QP,
+		empty, hns_roce_ib_modify_qp_resp);
+
 #endif /* _HNS_ROCE_U_ABI_H */
diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c
index daef17a..dd13049 100644
--- a/providers/hns/hns_roce_u_hw_v2.c
+++ b/providers/hns/hns_roce_u_hw_v2.c
@@ -1523,8 +1523,12 @@ static void record_qp_attr(struct ibv_qp *qp, struct ibv_qp_attr *attr,
 	if (attr_mask & IBV_QP_PORT)
 		hr_qp->port_num = attr->port_num;
 
-	if (attr_mask & IBV_QP_AV)
-		hr_qp->sl = attr->ah_attr.sl;
+	if (hr_qp->tc_mode == HNS_ROCE_TC_MAP_MODE_DSCP)
+		hr_qp->sl = hr_qp->priority;
+	else {
+		if (attr_mask & IBV_QP_AV)
+			hr_qp->sl = attr->ah_attr.sl;
+	}
 
 	if (attr_mask & IBV_QP_QKEY)
 		hr_qp->qkey = attr->qkey;
@@ -1538,10 +1542,11 @@ static void record_qp_attr(struct ibv_qp *qp, struct ibv_qp_attr *attr,
 static int hns_roce_u_v2_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
 				   int attr_mask)
 {
-	int ret;
-	struct ibv_modify_qp cmd;
+	struct hns_roce_modify_qp_ex_resp resp_ex = {};
+	struct hns_roce_modify_qp_ex cmd_ex = {};
 	struct hns_roce_qp *hr_qp = to_hr_qp(qp);
 	bool flag = false; /* modify qp to error */
+	int ret;
 
 	if ((attr_mask & IBV_QP_STATE) && (attr->qp_state == IBV_QPS_ERR)) {
 		pthread_spin_lock(&hr_qp->sq.lock);
@@ -1549,7 +1554,9 @@ static int hns_roce_u_v2_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
 		flag = true;
 	}
 
-	ret = ibv_cmd_modify_qp(qp, attr, attr_mask, &cmd, sizeof(cmd));
+	ret = ibv_cmd_modify_qp_ex(qp, attr, attr_mask, &cmd_ex.ibv_cmd,
+				   sizeof(cmd_ex), &resp_ex.ibv_resp,
+				   sizeof(resp_ex));
 
 	if (flag) {
 		if (!ret)
@@ -1561,8 +1568,13 @@ static int hns_roce_u_v2_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
 	if (ret)
 		return ret;
 
-	if (attr_mask & IBV_QP_STATE)
+	if (attr_mask & IBV_QP_STATE) {
 		qp->state = attr->qp_state;
+		if (attr->qp_state == IBV_QPS_RTR) {
+			hr_qp->tc_mode = resp_ex.drv_payload.tc_mode;
+			hr_qp->priority = resp_ex.drv_payload.priority;
+		}
+	}
 
 	if ((attr_mask & IBV_QP_STATE) && attr->qp_state == IBV_QPS_RESET) {
 		if (qp->recv_cq)
diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
index 34f7ee4..d081bb3 100644
--- a/providers/hns/hns_roce_u_verbs.c
+++ b/providers/hns/hns_roce_u_verbs.c
@@ -1486,6 +1486,9 @@ struct ibv_ah *hns_roce_u_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr)
 					     ah->av.mac, NULL))
 		goto err;
 
+	if (resp.tc_mode == HNS_ROCE_TC_MAP_MODE_DSCP)
+		ah->av.sl = resp.priority;
+
 	ah->av.udp_sport = get_ah_udp_sport(attr);
 
 	return &ah->ibv_ah;
-- 
2.25.1

