diff --git a/drivers/infiniband/hw/hns/hns_roce_ah.c b/drivers/infiniband/hw/hns/hns_roce_ah.c index 62ba652d7d59d3b2c2712e322999b20979a0b20c..7255062387f5fb8889246379321f32e95dddcad1 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 bfe74364129dabcfd212a4517edefecf22f926dd..097ddcbb3e28f58a01d2dbe63198b81759284d1c 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 bea07b9074bb1b37f83758fef54cc55cbd49762b..2b5307ac96c226c7f0191d5f68ce0e6755edf98a 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 97fffdfb95be5df078cb5ecc21edaa793fee44d5..e40d76debff11962bf68584ddc26de861276cb3b 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