hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/infiniband/hw/hns/hns_roce_ah.c
....@@ -31,57 +31,62 @@
3131 */
3232
3333 #include <linux/platform_device.h>
34
+#include <linux/pci.h>
3435 #include <rdma/ib_addr.h>
3536 #include <rdma/ib_cache.h>
3637 #include "hns_roce_device.h"
3738
38
-#define HNS_ROCE_PORT_NUM_SHIFT 24
39
-#define HNS_ROCE_VLAN_SL_BIT_MASK 7
40
-#define HNS_ROCE_VLAN_SL_SHIFT 13
41
-
42
-struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd,
43
- struct rdma_ah_attr *ah_attr,
44
- struct ib_udata *udata)
39
+static inline u16 get_ah_udp_sport(const struct rdma_ah_attr *ah_attr)
4540 {
46
- struct hns_roce_dev *hr_dev = to_hr_dev(ibpd->device);
47
- const struct ib_gid_attr *gid_attr;
48
- struct device *dev = hr_dev->dev;
49
- struct hns_roce_ah *ah;
50
- u16 vlan_tag = 0xffff;
41
+ u32 fl = ah_attr->grh.flow_label;
42
+ u16 sport;
43
+
44
+ if (!fl)
45
+ sport = get_random_u32() %
46
+ (IB_ROCE_UDP_ENCAP_VALID_PORT_MAX + 1 -
47
+ IB_ROCE_UDP_ENCAP_VALID_PORT_MIN) +
48
+ IB_ROCE_UDP_ENCAP_VALID_PORT_MIN;
49
+ else
50
+ sport = rdma_flow_label_to_udp_sport(fl);
51
+
52
+ return sport;
53
+}
54
+
55
+int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
56
+ struct ib_udata *udata)
57
+{
58
+ struct rdma_ah_attr *ah_attr = init_attr->ah_attr;
5159 const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr);
60
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibah->device);
61
+ struct hns_roce_ah *ah = to_hr_ah(ibah);
62
+ int ret = 0;
5263
53
- ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
54
- if (!ah)
55
- return ERR_PTR(-ENOMEM);
56
-
57
- /* Get mac address */
58
- memcpy(ah->av.mac, ah_attr->roce.dmac, ETH_ALEN);
59
-
60
- gid_attr = ah_attr->grh.sgid_attr;
61
- if (is_vlan_dev(gid_attr->ndev))
62
- vlan_tag = vlan_dev_vlan_id(gid_attr->ndev);
63
-
64
- if (vlan_tag < 0x1000)
65
- vlan_tag |= (rdma_ah_get_sl(ah_attr) &
66
- HNS_ROCE_VLAN_SL_BIT_MASK) <<
67
- HNS_ROCE_VLAN_SL_SHIFT;
68
-
69
- ah->av.port_pd = cpu_to_le32(to_hr_pd(ibpd)->pdn |
70
- (rdma_ah_get_port_num(ah_attr) <<
71
- HNS_ROCE_PORT_NUM_SHIFT));
64
+ ah->av.port = rdma_ah_get_port_num(ah_attr);
7265 ah->av.gid_index = grh->sgid_index;
73
- ah->av.vlan = cpu_to_le16(vlan_tag);
74
- dev_dbg(dev, "gid_index = 0x%x,vlan = 0x%x\n", ah->av.gid_index,
75
- ah->av.vlan);
7666
7767 if (rdma_ah_get_static_rate(ah_attr))
7868 ah->av.stat_rate = IB_RATE_10_GBPS;
7969
80
- memcpy(ah->av.dgid, grh->dgid.raw, HNS_ROCE_GID_SIZE);
81
- ah->av.sl_tclass_flowlabel = cpu_to_le32(rdma_ah_get_sl(ah_attr) <<
82
- HNS_ROCE_SL_SHIFT);
70
+ ah->av.hop_limit = grh->hop_limit;
71
+ ah->av.flowlabel = grh->flow_label;
72
+ ah->av.udp_sport = get_ah_udp_sport(ah_attr);
73
+ ah->av.sl = rdma_ah_get_sl(ah_attr);
74
+ ah->av.tclass = get_tclass(grh);
8375
84
- return &ah->ibah;
76
+ memcpy(ah->av.dgid, grh->dgid.raw, HNS_ROCE_GID_SIZE);
77
+ memcpy(ah->av.mac, ah_attr->roce.dmac, ETH_ALEN);
78
+
79
+ /* HIP08 needs to record vlan info in Address Vector */
80
+ if (hr_dev->pci_dev->revision <= PCI_REVISION_ID_HIP08) {
81
+ ret = rdma_read_gid_l2_fields(ah_attr->grh.sgid_attr,
82
+ &ah->av.vlan_id, NULL);
83
+ if (ret)
84
+ return ret;
85
+
86
+ ah->av.vlan_en = ah->av.vlan_id < VLAN_N_VID;
87
+ }
88
+
89
+ return ret;
8590 }
8691
8792 int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
....@@ -90,25 +95,12 @@
9095
9196 memset(ah_attr, 0, sizeof(*ah_attr));
9297
93
- rdma_ah_set_sl(ah_attr, (le32_to_cpu(ah->av.sl_tclass_flowlabel) >>
94
- HNS_ROCE_SL_SHIFT));
95
- rdma_ah_set_port_num(ah_attr, (le32_to_cpu(ah->av.port_pd) >>
96
- HNS_ROCE_PORT_NUM_SHIFT));
98
+ rdma_ah_set_sl(ah_attr, ah->av.sl);
99
+ rdma_ah_set_port_num(ah_attr, ah->av.port);
97100 rdma_ah_set_static_rate(ah_attr, ah->av.stat_rate);
98
- rdma_ah_set_grh(ah_attr, NULL,
99
- (le32_to_cpu(ah->av.sl_tclass_flowlabel) &
100
- HNS_ROCE_FLOW_LABEL_MASK), ah->av.gid_index,
101
- ah->av.hop_limit,
102
- (le32_to_cpu(ah->av.sl_tclass_flowlabel) >>
103
- HNS_ROCE_TCLASS_SHIFT));
101
+ rdma_ah_set_grh(ah_attr, NULL, ah->av.flowlabel,
102
+ ah->av.gid_index, ah->av.hop_limit, ah->av.tclass);
104103 rdma_ah_set_dgid_raw(ah_attr, ah->av.dgid);
105
-
106
- return 0;
107
-}
108
-
109
-int hns_roce_destroy_ah(struct ib_ah *ah)
110
-{
111
- kfree(to_hr_ah(ah));
112104
113105 return 0;
114106 }