Commit | Line | Data |
---|---|---|
9a443537 | 1 | /* |
2 | * Copyright (c) 2016 Hisilicon Limited. | |
3 | * | |
4 | * This software is available to you under a choice of one of two | |
5 | * licenses. You may choose to be licensed under the terms of the GNU | |
6 | * General Public License (GPL) Version 2, available from the file | |
7 | * COPYING in the main directory of this source tree, or the | |
8 | * OpenIB.org BSD license below: | |
9 | * | |
10 | * Redistribution and use in source and binary forms, with or | |
11 | * without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistributions of source code must retain the above | |
15 | * copyright notice, this list of conditions and the following | |
16 | * disclaimer. | |
17 | * | |
18 | * - Redistributions in binary form must reproduce the above | |
19 | * copyright notice, this list of conditions and the following | |
20 | * disclaimer in the documentation and/or other materials | |
21 | * provided with the distribution. | |
22 | * | |
23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
30 | * SOFTWARE. | |
31 | */ | |
32 | ||
7406c003 | 33 | #include <linux/pci.h> |
9a443537 | 34 | #include <rdma/ib_addr.h> |
35 | #include <rdma/ib_cache.h> | |
36 | #include "hns_roce_device.h" | |
37 | ||
074bf2c2 WL |
38 | static inline u16 get_ah_udp_sport(const struct rdma_ah_attr *ah_attr) |
39 | { | |
40 | u32 fl = ah_attr->grh.flow_label; | |
41 | u16 sport; | |
42 | ||
43 | if (!fl) | |
8032bf12 JD |
44 | sport = get_random_u32_below(IB_ROCE_UDP_ENCAP_VALID_PORT_MAX + |
45 | 1 - IB_ROCE_UDP_ENCAP_VALID_PORT_MIN) + | |
074bf2c2 WL |
46 | IB_ROCE_UDP_ENCAP_VALID_PORT_MIN; |
47 | else | |
48 | sport = rdma_flow_label_to_udp_sport(fl); | |
49 | ||
50 | return sport; | |
51 | } | |
52 | ||
fa5d010c MG |
53 | int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr, |
54 | struct ib_udata *udata) | |
9a443537 | 55 | { |
fa5d010c | 56 | struct rdma_ah_attr *ah_attr = init_attr->ah_attr; |
d8966fcd | 57 | const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr); |
7406c003 WL |
58 | struct hns_roce_dev *hr_dev = to_hr_dev(ibah->device); |
59 | struct hns_roce_ah *ah = to_hr_ah(ibah); | |
60 | int ret = 0; | |
9a443537 | 61 | |
38d22088 | 62 | if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08 && udata) |
66d86e52 WL |
63 | return -EOPNOTSUPP; |
64 | ||
82e620d9 | 65 | ah->av.port = rdma_ah_get_port_num(ah_attr); |
d8966fcd | 66 | ah->av.gid_index = grh->sgid_index; |
9a443537 | 67 | |
d8966fcd | 68 | if (rdma_ah_get_static_rate(ah_attr)) |
9a443537 | 69 | ah->av.stat_rate = IB_RATE_10_GBPS; |
70 | ||
fba429fc | 71 | ah->av.hop_limit = grh->hop_limit; |
074bf2c2 WL |
72 | ah->av.flowlabel = grh->flow_label; |
73 | ah->av.udp_sport = get_ah_udp_sport(ah_attr); | |
fba429fc | 74 | ah->av.sl = rdma_ah_get_sl(ah_attr); |
603bee93 | 75 | ah->av.tclass = get_tclass(grh); |
fba429fc WL |
76 | |
77 | memcpy(ah->av.dgid, grh->dgid.raw, HNS_ROCE_GID_SIZE); | |
78 | memcpy(ah->av.mac, ah_attr->roce.dmac, ETH_ALEN); | |
9a443537 | 79 | |
7406c003 | 80 | /* HIP08 needs to record vlan info in Address Vector */ |
38d22088 | 81 | if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) { |
7406c003 WL |
82 | ret = rdma_read_gid_l2_fields(ah_attr->grh.sgid_attr, |
83 | &ah->av.vlan_id, NULL); | |
84 | if (ret) | |
85 | return ret; | |
86 | ||
94a8c4df | 87 | ah->av.vlan_en = ah->av.vlan_id < VLAN_N_VID; |
7406c003 WL |
88 | } |
89 | ||
90 | return ret; | |
9a443537 | 91 | } |
92 | ||
90898850 | 93 | int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr) |
9a443537 | 94 | { |
95 | struct hns_roce_ah *ah = to_hr_ah(ibah); | |
96 | ||
97 | memset(ah_attr, 0, sizeof(*ah_attr)); | |
98 | ||
82e620d9 LC |
99 | rdma_ah_set_sl(ah_attr, ah->av.sl); |
100 | rdma_ah_set_port_num(ah_attr, ah->av.port); | |
d8966fcd | 101 | rdma_ah_set_static_rate(ah_attr, ah->av.stat_rate); |
82e620d9 LC |
102 | rdma_ah_set_grh(ah_attr, NULL, ah->av.flowlabel, |
103 | ah->av.gid_index, ah->av.hop_limit, ah->av.tclass); | |
d8966fcd | 104 | rdma_ah_set_dgid_raw(ah_attr, ah->av.dgid); |
9a443537 | 105 | |
106 | return 0; | |
107 | } |