1/*
2 * Copyright (c) 2005 Intel Corporation. All rights reserved.
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
33#include <linux/export.h>
34#include <rdma/ib_marshall.h>
35
36#define OPA_DEFAULT_GID_PREFIX cpu_to_be64(0xfe80000000000000ULL)
37static int rdma_ah_conv_opa_to_ib(struct ib_device *dev,
38 struct rdma_ah_attr *ib,
39 struct rdma_ah_attr *opa)
40{
41 struct ib_port_attr port_attr;
42 int ret = 0;
43
44 /* Do structure copy and the over-write fields */
45 *ib = *opa;
46
47 ib->type = RDMA_AH_ATTR_TYPE_IB;
48 rdma_ah_set_grh(attr: ib, NULL, flow_label: 0, sgid_index: 0, hop_limit: 1, traffic_class: 0);
49
50 if (ib_query_port(device: dev, port_num: opa->port_num, port_attr: &port_attr)) {
51 /* Set to default subnet to indicate error */
52 rdma_ah_set_subnet_prefix(attr: ib, OPA_DEFAULT_GID_PREFIX);
53 ret = -EINVAL;
54 } else {
55 rdma_ah_set_subnet_prefix(attr: ib,
56 cpu_to_be64(port_attr.subnet_prefix));
57 }
58 rdma_ah_set_interface_id(attr: ib, OPA_MAKE_ID(rdma_ah_get_dlid(opa)));
59 return ret;
60}
61
62void ib_copy_ah_attr_to_user(struct ib_device *device,
63 struct ib_uverbs_ah_attr *dst,
64 struct rdma_ah_attr *ah_attr)
65{
66 struct rdma_ah_attr *src = ah_attr;
67 struct rdma_ah_attr conv_ah;
68
69 memset(&dst->grh, 0, sizeof(dst->grh));
70
71 if ((ah_attr->type == RDMA_AH_ATTR_TYPE_OPA) &&
72 (rdma_ah_get_dlid(attr: ah_attr) > be16_to_cpu(IB_LID_PERMISSIVE)) &&
73 (!rdma_ah_conv_opa_to_ib(dev: device, ib: &conv_ah, opa: ah_attr)))
74 src = &conv_ah;
75
76 dst->dlid = rdma_ah_get_dlid(attr: src);
77 dst->sl = rdma_ah_get_sl(attr: src);
78 dst->src_path_bits = rdma_ah_get_path_bits(attr: src);
79 dst->static_rate = rdma_ah_get_static_rate(attr: src);
80 dst->is_global = rdma_ah_get_ah_flags(attr: src) &
81 IB_AH_GRH ? 1 : 0;
82 if (dst->is_global) {
83 const struct ib_global_route *grh = rdma_ah_read_grh(attr: src);
84
85 memcpy(dst->grh.dgid, grh->dgid.raw, sizeof(grh->dgid));
86 dst->grh.flow_label = grh->flow_label;
87 dst->grh.sgid_index = grh->sgid_index;
88 dst->grh.hop_limit = grh->hop_limit;
89 dst->grh.traffic_class = grh->traffic_class;
90 }
91 dst->port_num = rdma_ah_get_port_num(attr: src);
92 dst->reserved = 0;
93}
94EXPORT_SYMBOL(ib_copy_ah_attr_to_user);
95
96void ib_copy_qp_attr_to_user(struct ib_device *device,
97 struct ib_uverbs_qp_attr *dst,
98 struct ib_qp_attr *src)
99{
100 dst->qp_state = src->qp_state;
101 dst->cur_qp_state = src->cur_qp_state;
102 dst->path_mtu = src->path_mtu;
103 dst->path_mig_state = src->path_mig_state;
104 dst->qkey = src->qkey;
105 dst->rq_psn = src->rq_psn;
106 dst->sq_psn = src->sq_psn;
107 dst->dest_qp_num = src->dest_qp_num;
108 dst->qp_access_flags = src->qp_access_flags;
109
110 dst->max_send_wr = src->cap.max_send_wr;
111 dst->max_recv_wr = src->cap.max_recv_wr;
112 dst->max_send_sge = src->cap.max_send_sge;
113 dst->max_recv_sge = src->cap.max_recv_sge;
114 dst->max_inline_data = src->cap.max_inline_data;
115
116 ib_copy_ah_attr_to_user(device, &dst->ah_attr, &src->ah_attr);
117 ib_copy_ah_attr_to_user(device, &dst->alt_ah_attr, &src->alt_ah_attr);
118
119 dst->pkey_index = src->pkey_index;
120 dst->alt_pkey_index = src->alt_pkey_index;
121 dst->en_sqd_async_notify = src->en_sqd_async_notify;
122 dst->sq_draining = src->sq_draining;
123 dst->max_rd_atomic = src->max_rd_atomic;
124 dst->max_dest_rd_atomic = src->max_dest_rd_atomic;
125 dst->min_rnr_timer = src->min_rnr_timer;
126 dst->port_num = src->port_num;
127 dst->timeout = src->timeout;
128 dst->retry_cnt = src->retry_cnt;
129 dst->rnr_retry = src->rnr_retry;
130 dst->alt_port_num = src->alt_port_num;
131 dst->alt_timeout = src->alt_timeout;
132 memset(dst->reserved, 0, sizeof(dst->reserved));
133}
134EXPORT_SYMBOL(ib_copy_qp_attr_to_user);
135
136static void __ib_copy_path_rec_to_user(struct ib_user_path_rec *dst,
137 struct sa_path_rec *src)
138{
139 memcpy(dst->dgid, src->dgid.raw, sizeof(src->dgid));
140 memcpy(dst->sgid, src->sgid.raw, sizeof(src->sgid));
141
142 dst->dlid = htons(ntohl(sa_path_get_dlid(src)));
143 dst->slid = htons(ntohl(sa_path_get_slid(src)));
144 dst->raw_traffic = sa_path_get_raw_traffic(rec: src);
145 dst->flow_label = src->flow_label;
146 dst->hop_limit = src->hop_limit;
147 dst->traffic_class = src->traffic_class;
148 dst->reversible = src->reversible;
149 dst->numb_path = src->numb_path;
150 dst->pkey = src->pkey;
151 dst->sl = src->sl;
152 dst->mtu_selector = src->mtu_selector;
153 dst->mtu = src->mtu;
154 dst->rate_selector = src->rate_selector;
155 dst->rate = src->rate;
156 dst->packet_life_time = src->packet_life_time;
157 dst->preference = src->preference;
158 dst->packet_life_time_selector = src->packet_life_time_selector;
159}
160
161void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst,
162 struct sa_path_rec *src)
163{
164 struct sa_path_rec rec;
165
166 if (src->rec_type == SA_PATH_REC_TYPE_OPA) {
167 sa_convert_path_opa_to_ib(dest: &rec, src);
168 __ib_copy_path_rec_to_user(dst, src: &rec);
169 return;
170 }
171 __ib_copy_path_rec_to_user(dst, src);
172}
173EXPORT_SYMBOL(ib_copy_path_rec_to_user);
174
175void ib_copy_path_rec_from_user(struct sa_path_rec *dst,
176 struct ib_user_path_rec *src)
177{
178 u32 slid, dlid;
179
180 memset(dst, 0, sizeof(*dst));
181 if ((ib_is_opa_gid(gid: (union ib_gid *)src->sgid)) ||
182 (ib_is_opa_gid(gid: (union ib_gid *)src->dgid))) {
183 dst->rec_type = SA_PATH_REC_TYPE_OPA;
184 slid = opa_get_lid_from_gid(gid: (union ib_gid *)src->sgid);
185 dlid = opa_get_lid_from_gid(gid: (union ib_gid *)src->dgid);
186 } else {
187 dst->rec_type = SA_PATH_REC_TYPE_IB;
188 slid = ntohs(src->slid);
189 dlid = ntohs(src->dlid);
190 }
191 memcpy(dst->dgid.raw, src->dgid, sizeof dst->dgid);
192 memcpy(dst->sgid.raw, src->sgid, sizeof dst->sgid);
193
194 sa_path_set_dlid(rec: dst, dlid);
195 sa_path_set_slid(rec: dst, slid);
196 sa_path_set_raw_traffic(rec: dst, raw_traffic: src->raw_traffic);
197 dst->flow_label = src->flow_label;
198 dst->hop_limit = src->hop_limit;
199 dst->traffic_class = src->traffic_class;
200 dst->reversible = src->reversible;
201 dst->numb_path = src->numb_path;
202 dst->pkey = src->pkey;
203 dst->sl = src->sl;
204 dst->mtu_selector = src->mtu_selector;
205 dst->mtu = src->mtu;
206 dst->rate_selector = src->rate_selector;
207 dst->rate = src->rate;
208 dst->packet_life_time = src->packet_life_time;
209 dst->preference = src->preference;
210 dst->packet_life_time_selector = src->packet_life_time_selector;
211
212 /* TODO: No need to set this */
213 sa_path_set_dmac_zero(rec: dst);
214}
215EXPORT_SYMBOL(ib_copy_path_rec_from_user);
216

source code of linux/drivers/infiniband/core/uverbs_marshall.c