216 lines · c
1/*2 * Copyright (c) 2005 Intel Corporation. All rights reserved.3 *4 * This software is available to you under a choice of one of two5 * licenses. You may choose to be licensed under the terms of the GNU6 * General Public License (GPL) Version 2, available from the file7 * COPYING in the main directory of this source tree, or the8 * OpenIB.org BSD license below:9 *10 * Redistribution and use in source and binary forms, with or11 * without modification, are permitted provided that the following12 * conditions are met:13 *14 * - Redistributions of source code must retain the above15 * copyright notice, this list of conditions and the following16 * disclaimer.17 *18 * - Redistributions in binary form must reproduce the above19 * copyright notice, this list of conditions and the following20 * disclaimer in the documentation and/or other materials21 * 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 OF25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE30 * 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(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 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(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}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(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(&rec, src);168 __ib_copy_path_rec_to_user(dst, &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((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}215EXPORT_SYMBOL(ib_copy_path_rec_from_user);216