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) 37 static 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(ib, NULL, 0, 0, 1, 0); 49 50 if (ib_query_port(dev, opa->port_num, &port_attr)) { 51 /* Set to default subnet to indicate error */ 52 rdma_ah_set_subnet_prefix(ib, OPA_DEFAULT_GID_PREFIX); 53 ret = -EINVAL; 54 } else { 55 rdma_ah_set_subnet_prefix(ib, 56 cpu_to_be64(port_attr.subnet_prefix)); 57 } 58 rdma_ah_set_interface_id(ib, OPA_MAKE_ID(rdma_ah_get_dlid(opa))); 59 return ret; 60 } 61 62 void 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.reserved, 0, sizeof(dst->grh.reserved)); 70 71 if ((ah_attr->type == RDMA_AH_ATTR_TYPE_OPA) && 72 (rdma_ah_get_dlid(ah_attr) > be16_to_cpu(IB_LID_PERMISSIVE)) && 73 (!rdma_ah_conv_opa_to_ib(device, &conv_ah, ah_attr))) 74 src = &conv_ah; 75 76 dst->dlid = rdma_ah_get_dlid(src); 77 dst->sl = rdma_ah_get_sl(src); 78 dst->src_path_bits = rdma_ah_get_path_bits(src); 79 dst->static_rate = rdma_ah_get_static_rate(src); 80 dst->is_global = rdma_ah_get_ah_flags(src) & 81 IB_AH_GRH ? 1 : 0; 82 if (dst->is_global) { 83 const struct ib_global_route *grh = rdma_ah_read_grh(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(src); 92 dst->reserved = 0; 93 } 94 EXPORT_SYMBOL(ib_copy_ah_attr_to_user); 95 96 void 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 } 134 EXPORT_SYMBOL(ib_copy_qp_attr_to_user); 135 136 static 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(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 161 void 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(&rec, src); 168 __ib_copy_path_rec_to_user(dst, &rec); 169 return; 170 } 171 __ib_copy_path_rec_to_user(dst, src); 172 } 173 EXPORT_SYMBOL(ib_copy_path_rec_to_user); 174 175 void 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((union ib_gid *)src->sgid)) || 182 (ib_is_opa_gid((union ib_gid *)src->dgid))) { 183 dst->rec_type = SA_PATH_REC_TYPE_OPA; 184 slid = opa_get_lid_from_gid((union ib_gid *)src->sgid); 185 dlid = opa_get_lid_from_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(dst, dlid); 195 sa_path_set_slid(dst, slid); 196 sa_path_set_raw_traffic(dst, 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(dst); 214 sa_path_set_ndev(dst, NULL); 215 sa_path_set_ifindex(dst, 0); 216 } 217 EXPORT_SYMBOL(ib_copy_path_rec_from_user); 218