提交 60da510b 编写于 作者: O oulijun 提交者: Xie XiuQi

RDMA/hns: Copy some information of AV to user

driver inclusion
category: bugfix
bugzilla: NA
CVE: NA

When the driver support UD transport in user mode, it needs to
create the Address Handle(AH) and transfer Address Vector to
The hardware. The Address Vector includes the destination mac
and vlan inforation and it will be generated from the kernel
driver. As a result, we can copy this information to user
through ib_copy_to_udata function.

Feature or Bugfix:Bugfix
Signed-off-by: Noulijun <oulijun@huawei.com>
Reviewed-by: Nliuyixian <liuyixian@huawei.com>
Reviewed-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 8c4ac95b
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "roce_k_compat.h" #include "roce_k_compat.h"
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <rdma/hns-abi.h>
#include <rdma/ib_addr.h> #include <rdma/ib_addr.h>
#include <rdma/ib_cache.h> #include <rdma/ib_cache.h>
#include "hns_roce_device.h" #include "hns_roce_device.h"
...@@ -45,9 +46,11 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, ...@@ -45,9 +46,11 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd,
struct ib_udata *udata) struct ib_udata *udata)
{ {
struct hns_roce_dev *hr_dev = to_hr_dev(ibpd->device); struct hns_roce_dev *hr_dev = to_hr_dev(ibpd->device);
struct hns_roce_ib_create_ah_resp resp = {};
struct device *dev = hr_dev->dev; struct device *dev = hr_dev->dev;
#ifdef CONFIG_KERNEL_419 #ifdef CONFIG_KERNEL_419
const struct ib_gid_attr *gid_attr; const struct ib_gid_attr *gid_attr;
int ret = 0;
#else #else
struct ib_gid_attr gid_attr; struct ib_gid_attr gid_attr;
union ib_gid sgid; union ib_gid sgid;
...@@ -57,7 +60,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, ...@@ -57,7 +60,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd,
u16 vlan_tag = 0xffff; u16 vlan_tag = 0xffff;
struct in6_addr in6; struct in6_addr in6;
const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr); const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr);
bool vlan_en = false; u8 vlan_en = 0;
rdfx_func_cnt(hr_dev, RDFX_FUNC_CREATE_AH); rdfx_func_cnt(hr_dev, RDFX_FUNC_CREATE_AH);
...@@ -84,7 +87,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, ...@@ -84,7 +87,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd,
gid_attr = ah_attr->grh.sgid_attr; gid_attr = ah_attr->grh.sgid_attr;
if (is_vlan_dev(gid_attr->ndev)) { if (is_vlan_dev(gid_attr->ndev)) {
vlan_tag = vlan_dev_vlan_id(gid_attr->ndev); vlan_tag = vlan_dev_vlan_id(gid_attr->ndev);
vlan_en = true; vlan_en = 1;
} }
#else #else
/* Get source gid */ /* Get source gid */
...@@ -100,7 +103,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, ...@@ -100,7 +103,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd,
if (gid_attr.ndev) { if (gid_attr.ndev) {
if (is_vlan_dev(gid_attr.ndev)) { if (is_vlan_dev(gid_attr.ndev)) {
vlan_tag = vlan_dev_vlan_id(gid_attr.ndev); vlan_tag = vlan_dev_vlan_id(gid_attr.ndev);
vlan_en = true; vlan_en = 1;
} }
dev_put(gid_attr.ndev); dev_put(gid_attr.ndev);
} }
...@@ -134,6 +137,18 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, ...@@ -134,6 +137,18 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd,
ah->av.hop_limit = grh->hop_limit; ah->av.hop_limit = grh->hop_limit;
} }
if (udata) {
memcpy(resp.dmac, ah_attr->roce.dmac, ETH_ALEN);
resp.vlan = vlan_tag;
resp.vlan_en = vlan_en;
ret = ib_copy_to_udata(udata, &resp,
min(udata->outlen, sizeof(resp)));
if (ret) {
kfree(ah);
return ERR_PTR(ret);
}
}
return &ah->ibah; return &ah->ibah;
} }
......
...@@ -232,6 +232,7 @@ enum { ...@@ -232,6 +232,7 @@ enum {
HNS_ROCE_CAP_FLAG_FRMR = BIT(8), HNS_ROCE_CAP_FLAG_FRMR = BIT(8),
HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL = BIT(9), HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL = BIT(9),
HNS_ROCE_CAP_FLAG_ATOMIC = BIT(10), HNS_ROCE_CAP_FLAG_ATOMIC = BIT(10),
HNS_ROCE_CAP_FLAG_UD = BIT(11),
}; };
enum hns_roce_mtt_type { enum hns_roce_mtt_type {
...@@ -668,7 +669,7 @@ struct hns_roce_av { ...@@ -668,7 +669,7 @@ struct hns_roce_av {
u8 dgid[HNS_ROCE_GID_SIZE]; u8 dgid[HNS_ROCE_GID_SIZE];
u8 mac[ETH_ALEN]; u8 mac[ETH_ALEN];
__le16 vlan; __le16 vlan;
bool vlan_en; u8 vlan_en;
}; };
struct hns_roce_ah { struct hns_roce_ah {
......
...@@ -1961,7 +1961,8 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev) ...@@ -1961,7 +1961,8 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev)
caps->flags |= (HNS_ROCE_CAP_FLAG_XRC | HNS_ROCE_CAP_FLAG_SRQ | caps->flags |= (HNS_ROCE_CAP_FLAG_XRC | HNS_ROCE_CAP_FLAG_SRQ |
HNS_ROCE_CAP_FLAG_MW | HNS_ROCE_CAP_FLAG_MW |
HNS_ROCE_CAP_FLAG_FRMR | HNS_ROCE_CAP_FLAG_FRMR |
HNS_ROCE_CAP_FLAG_ATOMIC); HNS_ROCE_CAP_FLAG_ATOMIC) |
HNS_ROCE_CAP_FLAG_UD;
caps->num_qpc_timer = HNS_ROCE_V2_MAX_QPC_TIMER_NUM; caps->num_qpc_timer = HNS_ROCE_V2_MAX_QPC_TIMER_NUM;
caps->num_cqc_timer = HNS_ROCE_V2_MAX_CQC_TIMER_NUM; caps->num_cqc_timer = HNS_ROCE_V2_MAX_CQC_TIMER_NUM;
caps->qpc_timer_entry_sz = HNS_ROCE_V2_QPC_TIMER_ENTRY_SZ; caps->qpc_timer_entry_sz = HNS_ROCE_V2_QPC_TIMER_ENTRY_SZ;
......
...@@ -978,6 +978,12 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev) ...@@ -978,6 +978,12 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
(1ULL << IB_USER_VERBS_CMD_CLOSE_XRCD); (1ULL << IB_USER_VERBS_CMD_CLOSE_XRCD);
} }
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_UD) {
ib_dev->uverbs_cmd_mask |=
(1ULL << IB_USER_VERBS_CMD_CREATE_AH) |
(1ULL << IB_USER_VERBS_CMD_DESTROY_AH);
}
#ifdef CONFIG_NEW_KERNEL #ifdef CONFIG_NEW_KERNEL
ib_dev->driver_id = RDMA_DRIVER_HNS; ib_dev->driver_id = RDMA_DRIVER_HNS;
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册