.. | .. |
---|
31 | 31 | */ |
---|
32 | 32 | |
---|
33 | 33 | #include <linux/platform_device.h> |
---|
| 34 | +#include <linux/pci.h> |
---|
34 | 35 | #include <rdma/ib_addr.h> |
---|
35 | 36 | #include <rdma/ib_cache.h> |
---|
36 | 37 | #include "hns_roce_device.h" |
---|
37 | 38 | |
---|
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) |
---|
45 | 40 | { |
---|
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; |
---|
51 | 59 | 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; |
---|
52 | 63 | |
---|
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); |
---|
72 | 65 | 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); |
---|
76 | 66 | |
---|
77 | 67 | if (rdma_ah_get_static_rate(ah_attr)) |
---|
78 | 68 | ah->av.stat_rate = IB_RATE_10_GBPS; |
---|
79 | 69 | |
---|
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); |
---|
83 | 75 | |
---|
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; |
---|
85 | 90 | } |
---|
86 | 91 | |
---|
87 | 92 | int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr) |
---|
.. | .. |
---|
90 | 95 | |
---|
91 | 96 | memset(ah_attr, 0, sizeof(*ah_attr)); |
---|
92 | 97 | |
---|
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); |
---|
97 | 100 | 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); |
---|
104 | 103 | 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)); |
---|
112 | 104 | |
---|
113 | 105 | return 0; |
---|
114 | 106 | } |
---|