0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include <linux/pci.h>
0034 #include <rdma/ib_addr.h>
0035 #include <rdma/ib_cache.h>
0036 #include "hns_roce_device.h"
0037
0038 static inline u16 get_ah_udp_sport(const struct rdma_ah_attr *ah_attr)
0039 {
0040 u32 fl = ah_attr->grh.flow_label;
0041 u16 sport;
0042
0043 if (!fl)
0044 sport = get_random_u32() %
0045 (IB_ROCE_UDP_ENCAP_VALID_PORT_MAX + 1 -
0046 IB_ROCE_UDP_ENCAP_VALID_PORT_MIN) +
0047 IB_ROCE_UDP_ENCAP_VALID_PORT_MIN;
0048 else
0049 sport = rdma_flow_label_to_udp_sport(fl);
0050
0051 return sport;
0052 }
0053
0054 int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
0055 struct ib_udata *udata)
0056 {
0057 struct rdma_ah_attr *ah_attr = init_attr->ah_attr;
0058 const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr);
0059 struct hns_roce_dev *hr_dev = to_hr_dev(ibah->device);
0060 struct hns_roce_ah *ah = to_hr_ah(ibah);
0061 int ret = 0;
0062
0063 if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08 && udata)
0064 return -EOPNOTSUPP;
0065
0066 ah->av.port = rdma_ah_get_port_num(ah_attr);
0067 ah->av.gid_index = grh->sgid_index;
0068
0069 if (rdma_ah_get_static_rate(ah_attr))
0070 ah->av.stat_rate = IB_RATE_10_GBPS;
0071
0072 ah->av.hop_limit = grh->hop_limit;
0073 ah->av.flowlabel = grh->flow_label;
0074 ah->av.udp_sport = get_ah_udp_sport(ah_attr);
0075 ah->av.sl = rdma_ah_get_sl(ah_attr);
0076 ah->av.tclass = get_tclass(grh);
0077
0078 memcpy(ah->av.dgid, grh->dgid.raw, HNS_ROCE_GID_SIZE);
0079 memcpy(ah->av.mac, ah_attr->roce.dmac, ETH_ALEN);
0080
0081
0082 if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) {
0083 ret = rdma_read_gid_l2_fields(ah_attr->grh.sgid_attr,
0084 &ah->av.vlan_id, NULL);
0085 if (ret)
0086 return ret;
0087
0088 ah->av.vlan_en = ah->av.vlan_id < VLAN_N_VID;
0089 }
0090
0091 return ret;
0092 }
0093
0094 int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
0095 {
0096 struct hns_roce_ah *ah = to_hr_ah(ibah);
0097
0098 memset(ah_attr, 0, sizeof(*ah_attr));
0099
0100 rdma_ah_set_sl(ah_attr, ah->av.sl);
0101 rdma_ah_set_port_num(ah_attr, ah->av.port);
0102 rdma_ah_set_static_rate(ah_attr, ah->av.stat_rate);
0103 rdma_ah_set_grh(ah_attr, NULL, ah->av.flowlabel,
0104 ah->av.gid_index, ah->av.hop_limit, ah->av.tclass);
0105 rdma_ah_set_dgid_raw(ah_attr, ah->av.dgid);
0106
0107 return 0;
0108 }