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/export.h>
0034 #include <rdma/ib_marshall.h>
0035
0036 #define OPA_DEFAULT_GID_PREFIX cpu_to_be64(0xfe80000000000000ULL)
0037 static int rdma_ah_conv_opa_to_ib(struct ib_device *dev,
0038 struct rdma_ah_attr *ib,
0039 struct rdma_ah_attr *opa)
0040 {
0041 struct ib_port_attr port_attr;
0042 int ret = 0;
0043
0044
0045 *ib = *opa;
0046
0047 ib->type = RDMA_AH_ATTR_TYPE_IB;
0048 rdma_ah_set_grh(ib, NULL, 0, 0, 1, 0);
0049
0050 if (ib_query_port(dev, opa->port_num, &port_attr)) {
0051
0052 rdma_ah_set_subnet_prefix(ib, OPA_DEFAULT_GID_PREFIX);
0053 ret = -EINVAL;
0054 } else {
0055 rdma_ah_set_subnet_prefix(ib,
0056 cpu_to_be64(port_attr.subnet_prefix));
0057 }
0058 rdma_ah_set_interface_id(ib, OPA_MAKE_ID(rdma_ah_get_dlid(opa)));
0059 return ret;
0060 }
0061
0062 void ib_copy_ah_attr_to_user(struct ib_device *device,
0063 struct ib_uverbs_ah_attr *dst,
0064 struct rdma_ah_attr *ah_attr)
0065 {
0066 struct rdma_ah_attr *src = ah_attr;
0067 struct rdma_ah_attr conv_ah;
0068
0069 memset(&dst->grh, 0, sizeof(dst->grh));
0070
0071 if ((ah_attr->type == RDMA_AH_ATTR_TYPE_OPA) &&
0072 (rdma_ah_get_dlid(ah_attr) > be16_to_cpu(IB_LID_PERMISSIVE)) &&
0073 (!rdma_ah_conv_opa_to_ib(device, &conv_ah, ah_attr)))
0074 src = &conv_ah;
0075
0076 dst->dlid = rdma_ah_get_dlid(src);
0077 dst->sl = rdma_ah_get_sl(src);
0078 dst->src_path_bits = rdma_ah_get_path_bits(src);
0079 dst->static_rate = rdma_ah_get_static_rate(src);
0080 dst->is_global = rdma_ah_get_ah_flags(src) &
0081 IB_AH_GRH ? 1 : 0;
0082 if (dst->is_global) {
0083 const struct ib_global_route *grh = rdma_ah_read_grh(src);
0084
0085 memcpy(dst->grh.dgid, grh->dgid.raw, sizeof(grh->dgid));
0086 dst->grh.flow_label = grh->flow_label;
0087 dst->grh.sgid_index = grh->sgid_index;
0088 dst->grh.hop_limit = grh->hop_limit;
0089 dst->grh.traffic_class = grh->traffic_class;
0090 }
0091 dst->port_num = rdma_ah_get_port_num(src);
0092 dst->reserved = 0;
0093 }
0094 EXPORT_SYMBOL(ib_copy_ah_attr_to_user);
0095
0096 void ib_copy_qp_attr_to_user(struct ib_device *device,
0097 struct ib_uverbs_qp_attr *dst,
0098 struct ib_qp_attr *src)
0099 {
0100 dst->qp_state = src->qp_state;
0101 dst->cur_qp_state = src->cur_qp_state;
0102 dst->path_mtu = src->path_mtu;
0103 dst->path_mig_state = src->path_mig_state;
0104 dst->qkey = src->qkey;
0105 dst->rq_psn = src->rq_psn;
0106 dst->sq_psn = src->sq_psn;
0107 dst->dest_qp_num = src->dest_qp_num;
0108 dst->qp_access_flags = src->qp_access_flags;
0109
0110 dst->max_send_wr = src->cap.max_send_wr;
0111 dst->max_recv_wr = src->cap.max_recv_wr;
0112 dst->max_send_sge = src->cap.max_send_sge;
0113 dst->max_recv_sge = src->cap.max_recv_sge;
0114 dst->max_inline_data = src->cap.max_inline_data;
0115
0116 ib_copy_ah_attr_to_user(device, &dst->ah_attr, &src->ah_attr);
0117 ib_copy_ah_attr_to_user(device, &dst->alt_ah_attr, &src->alt_ah_attr);
0118
0119 dst->pkey_index = src->pkey_index;
0120 dst->alt_pkey_index = src->alt_pkey_index;
0121 dst->en_sqd_async_notify = src->en_sqd_async_notify;
0122 dst->sq_draining = src->sq_draining;
0123 dst->max_rd_atomic = src->max_rd_atomic;
0124 dst->max_dest_rd_atomic = src->max_dest_rd_atomic;
0125 dst->min_rnr_timer = src->min_rnr_timer;
0126 dst->port_num = src->port_num;
0127 dst->timeout = src->timeout;
0128 dst->retry_cnt = src->retry_cnt;
0129 dst->rnr_retry = src->rnr_retry;
0130 dst->alt_port_num = src->alt_port_num;
0131 dst->alt_timeout = src->alt_timeout;
0132 memset(dst->reserved, 0, sizeof(dst->reserved));
0133 }
0134 EXPORT_SYMBOL(ib_copy_qp_attr_to_user);
0135
0136 static void __ib_copy_path_rec_to_user(struct ib_user_path_rec *dst,
0137 struct sa_path_rec *src)
0138 {
0139 memcpy(dst->dgid, src->dgid.raw, sizeof(src->dgid));
0140 memcpy(dst->sgid, src->sgid.raw, sizeof(src->sgid));
0141
0142 dst->dlid = htons(ntohl(sa_path_get_dlid(src)));
0143 dst->slid = htons(ntohl(sa_path_get_slid(src)));
0144 dst->raw_traffic = sa_path_get_raw_traffic(src);
0145 dst->flow_label = src->flow_label;
0146 dst->hop_limit = src->hop_limit;
0147 dst->traffic_class = src->traffic_class;
0148 dst->reversible = src->reversible;
0149 dst->numb_path = src->numb_path;
0150 dst->pkey = src->pkey;
0151 dst->sl = src->sl;
0152 dst->mtu_selector = src->mtu_selector;
0153 dst->mtu = src->mtu;
0154 dst->rate_selector = src->rate_selector;
0155 dst->rate = src->rate;
0156 dst->packet_life_time = src->packet_life_time;
0157 dst->preference = src->preference;
0158 dst->packet_life_time_selector = src->packet_life_time_selector;
0159 }
0160
0161 void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst,
0162 struct sa_path_rec *src)
0163 {
0164 struct sa_path_rec rec;
0165
0166 if (src->rec_type == SA_PATH_REC_TYPE_OPA) {
0167 sa_convert_path_opa_to_ib(&rec, src);
0168 __ib_copy_path_rec_to_user(dst, &rec);
0169 return;
0170 }
0171 __ib_copy_path_rec_to_user(dst, src);
0172 }
0173 EXPORT_SYMBOL(ib_copy_path_rec_to_user);
0174
0175 void ib_copy_path_rec_from_user(struct sa_path_rec *dst,
0176 struct ib_user_path_rec *src)
0177 {
0178 u32 slid, dlid;
0179
0180 memset(dst, 0, sizeof(*dst));
0181 if ((ib_is_opa_gid((union ib_gid *)src->sgid)) ||
0182 (ib_is_opa_gid((union ib_gid *)src->dgid))) {
0183 dst->rec_type = SA_PATH_REC_TYPE_OPA;
0184 slid = opa_get_lid_from_gid((union ib_gid *)src->sgid);
0185 dlid = opa_get_lid_from_gid((union ib_gid *)src->dgid);
0186 } else {
0187 dst->rec_type = SA_PATH_REC_TYPE_IB;
0188 slid = ntohs(src->slid);
0189 dlid = ntohs(src->dlid);
0190 }
0191 memcpy(dst->dgid.raw, src->dgid, sizeof dst->dgid);
0192 memcpy(dst->sgid.raw, src->sgid, sizeof dst->sgid);
0193
0194 sa_path_set_dlid(dst, dlid);
0195 sa_path_set_slid(dst, slid);
0196 sa_path_set_raw_traffic(dst, src->raw_traffic);
0197 dst->flow_label = src->flow_label;
0198 dst->hop_limit = src->hop_limit;
0199 dst->traffic_class = src->traffic_class;
0200 dst->reversible = src->reversible;
0201 dst->numb_path = src->numb_path;
0202 dst->pkey = src->pkey;
0203 dst->sl = src->sl;
0204 dst->mtu_selector = src->mtu_selector;
0205 dst->mtu = src->mtu;
0206 dst->rate_selector = src->rate_selector;
0207 dst->rate = src->rate;
0208 dst->packet_life_time = src->packet_life_time;
0209 dst->preference = src->preference;
0210 dst->packet_life_time_selector = src->packet_life_time_selector;
0211
0212
0213 sa_path_set_dmac_zero(dst);
0214 }
0215 EXPORT_SYMBOL(ib_copy_path_rec_from_user);