From 60da510b2e1ab0f1bd6da4ba168e7dd0ce7f5d7f Mon Sep 17 00:00:00 2001 From: oulijun Date: Wed, 31 Jul 2019 09:42:21 +0800 Subject: [PATCH] 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: oulijun Reviewed-by: liuyixian Reviewed-by: Yang Yingliang Signed-off-by: Yang Yingliang --- drivers/infiniband/hw/hns/hns_roce_ah.c | 21 ++++++++++++++++++--- drivers/infiniband/hw/hns/hns_roce_device.h | 3 ++- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 ++- drivers/infiniband/hw/hns/hns_roce_main.c | 6 ++++++ 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_ah.c b/drivers/infiniband/hw/hns/hns_roce_ah.c index 62ba652d7d59..7255062387f5 100644 --- a/drivers/infiniband/hw/hns/hns_roce_ah.c +++ b/drivers/infiniband/hw/hns/hns_roce_ah.c @@ -32,6 +32,7 @@ #include "roce_k_compat.h" #include +#include #include #include #include "hns_roce_device.h" @@ -45,9 +46,11 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, struct ib_udata *udata) { 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; #ifdef CONFIG_KERNEL_419 const struct ib_gid_attr *gid_attr; + int ret = 0; #else struct ib_gid_attr gid_attr; union ib_gid sgid; @@ -57,7 +60,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, u16 vlan_tag = 0xffff; struct in6_addr in6; 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); @@ -84,7 +87,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, gid_attr = ah_attr->grh.sgid_attr; if (is_vlan_dev(gid_attr->ndev)) { vlan_tag = vlan_dev_vlan_id(gid_attr->ndev); - vlan_en = true; + vlan_en = 1; } #else /* Get source gid */ @@ -100,7 +103,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, if (gid_attr.ndev) { if (is_vlan_dev(gid_attr.ndev)) { vlan_tag = vlan_dev_vlan_id(gid_attr.ndev); - vlan_en = true; + vlan_en = 1; } dev_put(gid_attr.ndev); } @@ -134,6 +137,18 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, 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; } diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index bfe74364129d..097ddcbb3e28 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -232,6 +232,7 @@ enum { HNS_ROCE_CAP_FLAG_FRMR = BIT(8), HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL = BIT(9), HNS_ROCE_CAP_FLAG_ATOMIC = BIT(10), + HNS_ROCE_CAP_FLAG_UD = BIT(11), }; enum hns_roce_mtt_type { @@ -668,7 +669,7 @@ struct hns_roce_av { u8 dgid[HNS_ROCE_GID_SIZE]; u8 mac[ETH_ALEN]; __le16 vlan; - bool vlan_en; + u8 vlan_en; }; struct hns_roce_ah { diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index bea07b9074bb..2b5307ac96c2 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -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 | HNS_ROCE_CAP_FLAG_MW | 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_cqc_timer = HNS_ROCE_V2_MAX_CQC_TIMER_NUM; caps->qpc_timer_entry_sz = HNS_ROCE_V2_QPC_TIMER_ENTRY_SZ; diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 97fffdfb95be..e40d76debff1 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -978,6 +978,12 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev) (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 ib_dev->driver_id = RDMA_DRIVER_HNS; #endif -- GitLab