diff options
-rw-r--r-- | drivers/infiniband/core/cm.c | 34 | ||||
-rw-r--r-- | drivers/infiniband/core/sa_query.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/core/ucma.c | 22 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_marshall.c | 40 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_fs.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 14 | ||||
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.c | 2 | ||||
-rw-r--r-- | include/rdma/ib_sa.h | 121 |
8 files changed, 197 insertions, 42 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index ca742e84e68b..1844770f3ae8 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
@@ -1203,8 +1203,10 @@ static void cm_format_req(struct cm_req_msg *req_msg, | |||
1203 | } | 1203 | } |
1204 | 1204 | ||
1205 | if (pri_path->hop_limit <= 1) { | 1205 | if (pri_path->hop_limit <= 1) { |
1206 | req_msg->primary_local_lid = sa_path_get_slid(pri_path); | 1206 | req_msg->primary_local_lid = |
1207 | req_msg->primary_remote_lid = sa_path_get_dlid(pri_path); | 1207 | htons(ntohl(sa_path_get_slid(pri_path))); |
1208 | req_msg->primary_remote_lid = | ||
1209 | htons(ntohl(sa_path_get_dlid(pri_path))); | ||
1208 | } else { | 1210 | } else { |
1209 | /* Work-around until there's a way to obtain remote LID info */ | 1211 | /* Work-around until there's a way to obtain remote LID info */ |
1210 | req_msg->primary_local_lid = IB_LID_PERMISSIVE; | 1212 | req_msg->primary_local_lid = IB_LID_PERMISSIVE; |
@@ -1224,8 +1226,10 @@ static void cm_format_req(struct cm_req_msg *req_msg, | |||
1224 | 1226 | ||
1225 | if (alt_path) { | 1227 | if (alt_path) { |
1226 | if (alt_path->hop_limit <= 1) { | 1228 | if (alt_path->hop_limit <= 1) { |
1227 | req_msg->alt_local_lid = sa_path_get_slid(alt_path); | 1229 | req_msg->alt_local_lid = |
1228 | req_msg->alt_remote_lid = sa_path_get_dlid(alt_path); | 1230 | htons(ntohl(sa_path_get_slid(alt_path))); |
1231 | req_msg->alt_remote_lid = | ||
1232 | htons(ntohl(sa_path_get_dlid(alt_path))); | ||
1229 | } else { | 1233 | } else { |
1230 | req_msg->alt_local_lid = IB_LID_PERMISSIVE; | 1234 | req_msg->alt_local_lid = IB_LID_PERMISSIVE; |
1231 | req_msg->alt_remote_lid = IB_LID_PERMISSIVE; | 1235 | req_msg->alt_remote_lid = IB_LID_PERMISSIVE; |
@@ -1407,8 +1411,10 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg, | |||
1407 | { | 1411 | { |
1408 | primary_path->dgid = req_msg->primary_local_gid; | 1412 | primary_path->dgid = req_msg->primary_local_gid; |
1409 | primary_path->sgid = req_msg->primary_remote_gid; | 1413 | primary_path->sgid = req_msg->primary_remote_gid; |
1410 | sa_path_set_dlid(primary_path, req_msg->primary_local_lid); | 1414 | sa_path_set_dlid(primary_path, |
1411 | sa_path_set_slid(primary_path, req_msg->primary_remote_lid); | 1415 | htonl(ntohs(req_msg->primary_local_lid))); |
1416 | sa_path_set_slid(primary_path, | ||
1417 | htonl(ntohs(req_msg->primary_remote_lid))); | ||
1412 | primary_path->flow_label = cm_req_get_primary_flow_label(req_msg); | 1418 | primary_path->flow_label = cm_req_get_primary_flow_label(req_msg); |
1413 | primary_path->hop_limit = req_msg->primary_hop_limit; | 1419 | primary_path->hop_limit = req_msg->primary_hop_limit; |
1414 | primary_path->traffic_class = req_msg->primary_traffic_class; | 1420 | primary_path->traffic_class = req_msg->primary_traffic_class; |
@@ -1428,8 +1434,10 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg, | |||
1428 | if (req_msg->alt_local_lid) { | 1434 | if (req_msg->alt_local_lid) { |
1429 | alt_path->dgid = req_msg->alt_local_gid; | 1435 | alt_path->dgid = req_msg->alt_local_gid; |
1430 | alt_path->sgid = req_msg->alt_remote_gid; | 1436 | alt_path->sgid = req_msg->alt_remote_gid; |
1431 | sa_path_set_dlid(alt_path, req_msg->alt_local_lid); | 1437 | sa_path_set_dlid(alt_path, |
1432 | sa_path_set_slid(alt_path, req_msg->alt_remote_lid); | 1438 | htonl(ntohs(req_msg->alt_local_lid))); |
1439 | sa_path_set_slid(alt_path, | ||
1440 | htonl(ntohs(req_msg->alt_remote_lid))); | ||
1433 | alt_path->flow_label = cm_req_get_alt_flow_label(req_msg); | 1441 | alt_path->flow_label = cm_req_get_alt_flow_label(req_msg); |
1434 | alt_path->hop_limit = req_msg->alt_hop_limit; | 1442 | alt_path->hop_limit = req_msg->alt_hop_limit; |
1435 | alt_path->traffic_class = req_msg->alt_traffic_class; | 1443 | alt_path->traffic_class = req_msg->alt_traffic_class; |
@@ -2842,8 +2850,10 @@ static void cm_format_lap(struct cm_lap_msg *lap_msg, | |||
2842 | cm_lap_set_remote_qpn(lap_msg, cm_id_priv->remote_qpn); | 2850 | cm_lap_set_remote_qpn(lap_msg, cm_id_priv->remote_qpn); |
2843 | /* todo: need remote CM response timeout */ | 2851 | /* todo: need remote CM response timeout */ |
2844 | cm_lap_set_remote_resp_timeout(lap_msg, 0x1F); | 2852 | cm_lap_set_remote_resp_timeout(lap_msg, 0x1F); |
2845 | lap_msg->alt_local_lid = sa_path_get_slid(alternate_path); | 2853 | lap_msg->alt_local_lid = |
2846 | lap_msg->alt_remote_lid = sa_path_get_dlid(alternate_path); | 2854 | htons(ntohl(sa_path_get_slid(alternate_path))); |
2855 | lap_msg->alt_remote_lid = | ||
2856 | htons(ntohl(sa_path_get_dlid(alternate_path))); | ||
2847 | lap_msg->alt_local_gid = alternate_path->sgid; | 2857 | lap_msg->alt_local_gid = alternate_path->sgid; |
2848 | lap_msg->alt_remote_gid = alternate_path->dgid; | 2858 | lap_msg->alt_remote_gid = alternate_path->dgid; |
2849 | cm_lap_set_flow_label(lap_msg, alternate_path->flow_label); | 2859 | cm_lap_set_flow_label(lap_msg, alternate_path->flow_label); |
@@ -2922,8 +2932,8 @@ static void cm_format_path_from_lap(struct cm_id_private *cm_id_priv, | |||
2922 | path->rec_type = SA_PATH_REC_TYPE_IB; | 2932 | path->rec_type = SA_PATH_REC_TYPE_IB; |
2923 | path->dgid = lap_msg->alt_local_gid; | 2933 | path->dgid = lap_msg->alt_local_gid; |
2924 | path->sgid = lap_msg->alt_remote_gid; | 2934 | path->sgid = lap_msg->alt_remote_gid; |
2925 | sa_path_set_dlid(path, lap_msg->alt_local_lid); | 2935 | sa_path_set_dlid(path, htonl(ntohs(lap_msg->alt_local_lid))); |
2926 | sa_path_set_slid(path, lap_msg->alt_remote_lid); | 2936 | sa_path_set_slid(path, htonl(ntohs(lap_msg->alt_remote_lid))); |
2927 | path->flow_label = cm_lap_get_flow_label(lap_msg); | 2937 | path->flow_label = cm_lap_get_flow_label(lap_msg); |
2928 | path->hop_limit = lap_msg->alt_hop_limit; | 2938 | path->hop_limit = lap_msg->alt_hop_limit; |
2929 | path->traffic_class = cm_lap_get_traffic_class(lap_msg); | 2939 | path->traffic_class = cm_lap_get_traffic_class(lap_msg); |
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 88361c164d73..249247609b60 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c | |||
@@ -1110,9 +1110,9 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num, | |||
1110 | memset(ah_attr, 0, sizeof *ah_attr); | 1110 | memset(ah_attr, 0, sizeof *ah_attr); |
1111 | ah_attr->type = rdma_ah_find_type(device, port_num); | 1111 | ah_attr->type = rdma_ah_find_type(device, port_num); |
1112 | 1112 | ||
1113 | rdma_ah_set_dlid(ah_attr, be16_to_cpu(sa_path_get_dlid(rec))); | 1113 | rdma_ah_set_dlid(ah_attr, be32_to_cpu(sa_path_get_dlid(rec))); |
1114 | rdma_ah_set_sl(ah_attr, rec->sl); | 1114 | rdma_ah_set_sl(ah_attr, rec->sl); |
1115 | rdma_ah_set_path_bits(ah_attr, be16_to_cpu(sa_path_get_slid(rec)) & | 1115 | rdma_ah_set_path_bits(ah_attr, be32_to_cpu(sa_path_get_slid(rec)) & |
1116 | get_src_path_mask(device, port_num)); | 1116 | get_src_path_mask(device, port_num)); |
1117 | rdma_ah_set_port_num(ah_attr, port_num); | 1117 | rdma_ah_set_port_num(ah_attr, port_num); |
1118 | rdma_ah_set_static_rate(ah_attr, rec->rate); | 1118 | rdma_ah_set_static_rate(ah_attr, rec->rate); |
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 2beff90f4bbb..276f0ef835bd 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
@@ -898,11 +898,18 @@ static ssize_t ucma_query_path(struct ucma_context *ctx, | |||
898 | for (i = 0, out_len -= sizeof(*resp); | 898 | for (i = 0, out_len -= sizeof(*resp); |
899 | i < resp->num_paths && out_len > sizeof(struct ib_path_rec_data); | 899 | i < resp->num_paths && out_len > sizeof(struct ib_path_rec_data); |
900 | i++, out_len -= sizeof(struct ib_path_rec_data)) { | 900 | i++, out_len -= sizeof(struct ib_path_rec_data)) { |
901 | struct sa_path_rec *rec = &ctx->cm_id->route.path_rec[i]; | ||
901 | 902 | ||
902 | resp->path_data[i].flags = IB_PATH_GMP | IB_PATH_PRIMARY | | 903 | resp->path_data[i].flags = IB_PATH_GMP | IB_PATH_PRIMARY | |
903 | IB_PATH_BIDIRECTIONAL; | 904 | IB_PATH_BIDIRECTIONAL; |
904 | ib_sa_pack_path(&ctx->cm_id->route.path_rec[i], | 905 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) { |
905 | &resp->path_data[i].path_rec); | 906 | ib_sa_pack_path(rec, &resp->path_data[i].path_rec); |
907 | } else { | ||
908 | struct sa_path_rec ib; | ||
909 | |||
910 | sa_convert_path_opa_to_ib(&ib, rec); | ||
911 | ib_sa_pack_path(&ib, &resp->path_data[i].path_rec); | ||
912 | } | ||
906 | } | 913 | } |
907 | 914 | ||
908 | if (copy_to_user(response, resp, | 915 | if (copy_to_user(response, resp, |
@@ -1215,8 +1222,17 @@ static int ucma_set_ib_path(struct ucma_context *ctx, | |||
1215 | 1222 | ||
1216 | memset(&sa_path, 0, sizeof(sa_path)); | 1223 | memset(&sa_path, 0, sizeof(sa_path)); |
1217 | 1224 | ||
1225 | sa_path.rec_type = SA_PATH_REC_TYPE_IB; | ||
1218 | ib_sa_unpack_path(path_data->path_rec, &sa_path); | 1226 | ib_sa_unpack_path(path_data->path_rec, &sa_path); |
1219 | ret = rdma_set_ib_paths(ctx->cm_id, &sa_path, 1); | 1227 | |
1228 | if (rdma_cap_opa_ah(ctx->cm_id->device, ctx->cm_id->port_num)) { | ||
1229 | struct sa_path_rec opa; | ||
1230 | |||
1231 | sa_convert_path_ib_to_opa(&opa, &sa_path); | ||
1232 | ret = rdma_set_ib_paths(ctx->cm_id, &opa, 1); | ||
1233 | } else { | ||
1234 | ret = rdma_set_ib_paths(ctx->cm_id, &sa_path, 1); | ||
1235 | } | ||
1220 | if (ret) | 1236 | if (ret) |
1221 | return ret; | 1237 | return ret; |
1222 | 1238 | ||
diff --git a/drivers/infiniband/core/uverbs_marshall.c b/drivers/infiniband/core/uverbs_marshall.c index 50575b63905c..8b9587fe2303 100644 --- a/drivers/infiniband/core/uverbs_marshall.c +++ b/drivers/infiniband/core/uverbs_marshall.c | |||
@@ -96,14 +96,14 @@ void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst, | |||
96 | } | 96 | } |
97 | EXPORT_SYMBOL(ib_copy_qp_attr_to_user); | 97 | EXPORT_SYMBOL(ib_copy_qp_attr_to_user); |
98 | 98 | ||
99 | void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst, | 99 | void __ib_copy_path_rec_to_user(struct ib_user_path_rec *dst, |
100 | struct sa_path_rec *src) | 100 | struct sa_path_rec *src) |
101 | { | 101 | { |
102 | memcpy(dst->dgid, src->dgid.raw, sizeof src->dgid); | 102 | memcpy(dst->dgid, src->dgid.raw, sizeof src->dgid); |
103 | memcpy(dst->sgid, src->sgid.raw, sizeof src->sgid); | 103 | memcpy(dst->sgid, src->sgid.raw, sizeof src->sgid); |
104 | 104 | ||
105 | dst->dlid = sa_path_get_dlid(src); | 105 | dst->dlid = htons(ntohl(sa_path_get_dlid(src))); |
106 | dst->slid = sa_path_get_slid(src); | 106 | dst->slid = htons(ntohl(sa_path_get_slid(src))); |
107 | dst->raw_traffic = sa_path_get_raw_traffic(src); | 107 | dst->raw_traffic = sa_path_get_raw_traffic(src); |
108 | dst->flow_label = src->flow_label; | 108 | dst->flow_label = src->flow_label; |
109 | dst->hop_limit = src->hop_limit; | 109 | dst->hop_limit = src->hop_limit; |
@@ -120,17 +120,42 @@ void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst, | |||
120 | dst->preference = src->preference; | 120 | dst->preference = src->preference; |
121 | dst->packet_life_time_selector = src->packet_life_time_selector; | 121 | dst->packet_life_time_selector = src->packet_life_time_selector; |
122 | } | 122 | } |
123 | |||
124 | void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst, | ||
125 | struct sa_path_rec *src) | ||
126 | { | ||
127 | struct sa_path_rec rec; | ||
128 | |||
129 | if (src->rec_type == SA_PATH_REC_TYPE_OPA) { | ||
130 | sa_convert_path_opa_to_ib(&rec, src); | ||
131 | __ib_copy_path_rec_to_user(dst, &rec); | ||
132 | return; | ||
133 | } | ||
134 | __ib_copy_path_rec_to_user(dst, src); | ||
135 | } | ||
123 | EXPORT_SYMBOL(ib_copy_path_rec_to_user); | 136 | EXPORT_SYMBOL(ib_copy_path_rec_to_user); |
124 | 137 | ||
125 | void ib_copy_path_rec_from_user(struct sa_path_rec *dst, | 138 | void ib_copy_path_rec_from_user(struct sa_path_rec *dst, |
126 | struct ib_user_path_rec *src) | 139 | struct ib_user_path_rec *src) |
127 | { | 140 | { |
141 | __be32 slid, dlid; | ||
142 | |||
143 | memset(dst, 0, sizeof(*dst)); | ||
144 | if ((ib_is_opa_gid((union ib_gid *)src->sgid)) || | ||
145 | (ib_is_opa_gid((union ib_gid *)src->dgid))) { | ||
146 | dst->rec_type = SA_PATH_REC_TYPE_OPA; | ||
147 | slid = htonl(opa_get_lid_from_gid((union ib_gid *)src->sgid)); | ||
148 | dlid = htonl(opa_get_lid_from_gid((union ib_gid *)src->dgid)); | ||
149 | } else { | ||
150 | dst->rec_type = SA_PATH_REC_TYPE_IB; | ||
151 | slid = htonl(ntohs(src->slid)); | ||
152 | dlid = htonl(ntohs(src->dlid)); | ||
153 | } | ||
128 | memcpy(dst->dgid.raw, src->dgid, sizeof dst->dgid); | 154 | memcpy(dst->dgid.raw, src->dgid, sizeof dst->dgid); |
129 | memcpy(dst->sgid.raw, src->sgid, sizeof dst->sgid); | 155 | memcpy(dst->sgid.raw, src->sgid, sizeof dst->sgid); |
130 | 156 | ||
131 | dst->rec_type = SA_PATH_REC_TYPE_IB; | 157 | sa_path_set_dlid(dst, dlid); |
132 | sa_path_set_dlid(dst, src->dlid); | 158 | sa_path_set_slid(dst, slid); |
133 | sa_path_set_slid(dst, src->slid); | ||
134 | sa_path_set_raw_traffic(dst, src->raw_traffic); | 159 | sa_path_set_raw_traffic(dst, src->raw_traffic); |
135 | dst->flow_label = src->flow_label; | 160 | dst->flow_label = src->flow_label; |
136 | dst->hop_limit = src->hop_limit; | 161 | dst->hop_limit = src->hop_limit; |
@@ -147,6 +172,7 @@ void ib_copy_path_rec_from_user(struct sa_path_rec *dst, | |||
147 | dst->preference = src->preference; | 172 | dst->preference = src->preference; |
148 | dst->packet_life_time_selector = src->packet_life_time_selector; | 173 | dst->packet_life_time_selector = src->packet_life_time_selector; |
149 | 174 | ||
175 | /* TODO: No need to set this */ | ||
150 | sa_path_set_dmac_zero(dst); | 176 | sa_path_set_dmac_zero(dst); |
151 | sa_path_set_ndev(dst, NULL); | 177 | sa_path_set_ndev(dst, NULL); |
152 | sa_path_set_ifindex(dst, 0); | 178 | sa_path_set_ifindex(dst, 0); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c index ba7dd530fb46..11f74cbe6660 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c | |||
@@ -219,7 +219,7 @@ static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr) | |||
219 | " DLID: 0x%04x\n" | 219 | " DLID: 0x%04x\n" |
220 | " SL: %12d\n" | 220 | " SL: %12d\n" |
221 | " rate: %8d.%d Gb/sec\n", | 221 | " rate: %8d.%d Gb/sec\n", |
222 | be16_to_cpu(sa_path_get_dlid(&path.pathrec)), | 222 | be32_to_cpu(sa_path_get_dlid(&path.pathrec)), |
223 | path.pathrec.sl, | 223 | path.pathrec.sl, |
224 | rate / 1000, rate % 1000); | 224 | rate / 1000, rate % 1000); |
225 | } | 225 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index f4c25271253c..2aab637f9d0a 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -668,9 +668,9 @@ void ipoib_mark_paths_invalid(struct net_device *dev) | |||
668 | spin_lock_irq(&priv->lock); | 668 | spin_lock_irq(&priv->lock); |
669 | 669 | ||
670 | list_for_each_entry_safe(path, tp, &priv->path_list, list) { | 670 | list_for_each_entry_safe(path, tp, &priv->path_list, list) { |
671 | ipoib_dbg(priv, "mark path LID 0x%04x GID %pI6 invalid\n", | 671 | ipoib_dbg(priv, "mark path LID 0x%08x GID %pI6 invalid\n", |
672 | be16_to_cpu(sa_path_get_dlid(&path->pathrec)), | 672 | be32_to_cpu(sa_path_get_dlid(&path->pathrec)), |
673 | path->pathrec.dgid.raw); | 673 | path->pathrec.dgid.raw); |
674 | path->valid = 0; | 674 | path->valid = 0; |
675 | } | 675 | } |
676 | 676 | ||
@@ -731,7 +731,7 @@ static void path_rec_completion(int status, | |||
731 | 731 | ||
732 | if (!status) | 732 | if (!status) |
733 | ipoib_dbg(priv, "PathRec LID 0x%04x for GID %pI6\n", | 733 | ipoib_dbg(priv, "PathRec LID 0x%04x for GID %pI6\n", |
734 | be16_to_cpu(sa_path_get_dlid(pathrec)), | 734 | be32_to_cpu(sa_path_get_dlid(pathrec)), |
735 | pathrec->dgid.raw); | 735 | pathrec->dgid.raw); |
736 | else | 736 | else |
737 | ipoib_dbg(priv, "PathRec status %d for GID %pI6\n", | 737 | ipoib_dbg(priv, "PathRec status %d for GID %pI6\n", |
@@ -755,7 +755,7 @@ static void path_rec_completion(int status, | |||
755 | path->ah = ah; | 755 | path->ah = ah; |
756 | 756 | ||
757 | ipoib_dbg(priv, "created address handle %p for LID 0x%04x, SL %d\n", | 757 | ipoib_dbg(priv, "created address handle %p for LID 0x%04x, SL %d\n", |
758 | ah, be16_to_cpu(sa_path_get_dlid(pathrec)), | 758 | ah, be32_to_cpu(sa_path_get_dlid(pathrec)), |
759 | pathrec->sl); | 759 | pathrec->sl); |
760 | 760 | ||
761 | while ((skb = __skb_dequeue(&path->queue))) | 761 | while ((skb = __skb_dequeue(&path->queue))) |
@@ -1000,8 +1000,8 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, | |||
1000 | } | 1000 | } |
1001 | 1001 | ||
1002 | if (path->ah) { | 1002 | if (path->ah) { |
1003 | ipoib_dbg(priv, "Send unicast ARP to %04x\n", | 1003 | ipoib_dbg(priv, "Send unicast ARP to %08x\n", |
1004 | be16_to_cpu(sa_path_get_dlid(&path->pathrec))); | 1004 | be32_to_cpu(sa_path_get_dlid(&path->pathrec))); |
1005 | 1005 | ||
1006 | spin_unlock_irqrestore(&priv->lock, flags); | 1006 | spin_unlock_irqrestore(&priv->lock, flags); |
1007 | path->ah->last_send = rn->send(dev, skb, path->ah->ah, | 1007 | path->ah->last_send = rn->send(dev, skb, path->ah->ah, |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 89341dde9e5b..07877a88475d 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -2400,7 +2400,7 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id, | |||
2400 | switch (event->param.rej_rcvd.reason) { | 2400 | switch (event->param.rej_rcvd.reason) { |
2401 | case IB_CM_REJ_PORT_CM_REDIRECT: | 2401 | case IB_CM_REJ_PORT_CM_REDIRECT: |
2402 | cpi = event->param.rej_rcvd.ari; | 2402 | cpi = event->param.rej_rcvd.ari; |
2403 | sa_path_set_dlid(&ch->path, cpi->redirect_lid); | 2403 | sa_path_set_dlid(&ch->path, htonl(ntohs(cpi->redirect_lid))); |
2404 | ch->path.pkey = cpi->redirect_pkey; | 2404 | ch->path.pkey = cpi->redirect_pkey; |
2405 | cm_id->remote_cm_qpn = be32_to_cpu(cpi->redirect_qp) & 0x00ffffff; | 2405 | cm_id->remote_cm_qpn = be32_to_cpu(cpi->redirect_qp) & 0x00ffffff; |
2406 | memcpy(ch->path.dgid.raw, cpi->redirect_gid, 16); | 2406 | memcpy(ch->path.dgid.raw, cpi->redirect_gid, 16); |
diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h index c72c94949617..f5f70e345318 100644 --- a/include/rdma/ib_sa.h +++ b/include/rdma/ib_sa.h | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <rdma/ib_verbs.h> | 44 | #include <rdma/ib_verbs.h> |
45 | #include <rdma/ib_mad.h> | 45 | #include <rdma/ib_mad.h> |
46 | #include <rdma/ib_addr.h> | 46 | #include <rdma/ib_addr.h> |
47 | #include <rdma/opa_addr.h> | ||
47 | 48 | ||
48 | enum { | 49 | enum { |
49 | IB_SA_CLASS_VERSION = 2, /* IB spec version 1.1/1.2 */ | 50 | IB_SA_CLASS_VERSION = 2, /* IB spec version 1.1/1.2 */ |
@@ -152,7 +153,8 @@ enum ib_sa_mc_join_states { | |||
152 | enum sa_path_rec_type { | 153 | enum sa_path_rec_type { |
153 | SA_PATH_REC_TYPE_IB, | 154 | SA_PATH_REC_TYPE_IB, |
154 | SA_PATH_REC_TYPE_ROCE_V1, | 155 | SA_PATH_REC_TYPE_ROCE_V1, |
155 | SA_PATH_REC_TYPE_ROCE_V2 | 156 | SA_PATH_REC_TYPE_ROCE_V2, |
157 | SA_PATH_REC_TYPE_OPA | ||
156 | }; | 158 | }; |
157 | 159 | ||
158 | struct sa_path_rec_ib { | 160 | struct sa_path_rec_ib { |
@@ -171,6 +173,19 @@ struct sa_path_rec_roce { | |||
171 | 173 | ||
172 | }; | 174 | }; |
173 | 175 | ||
176 | struct sa_path_rec_opa { | ||
177 | __be64 service_id; | ||
178 | __be32 dlid; | ||
179 | __be32 slid; | ||
180 | u8 raw_traffic; | ||
181 | u8 l2_8B; | ||
182 | u8 l2_10B; | ||
183 | u8 l2_9B; | ||
184 | u8 l2_16B; | ||
185 | u8 qos_type; | ||
186 | u8 qos_priority; | ||
187 | }; | ||
188 | |||
174 | struct sa_path_rec { | 189 | struct sa_path_rec { |
175 | union ib_gid dgid; | 190 | union ib_gid dgid; |
176 | union ib_gid sgid; | 191 | union ib_gid sgid; |
@@ -193,6 +208,7 @@ struct sa_path_rec { | |||
193 | union { | 208 | union { |
194 | struct sa_path_rec_ib ib; | 209 | struct sa_path_rec_ib ib; |
195 | struct sa_path_rec_roce roce; | 210 | struct sa_path_rec_roce roce; |
211 | struct sa_path_rec_opa opa; | ||
196 | }; | 212 | }; |
197 | enum sa_path_rec_type rec_type; | 213 | enum sa_path_rec_type rec_type; |
198 | }; | 214 | }; |
@@ -223,6 +239,77 @@ static inline enum sa_path_rec_type | |||
223 | } | 239 | } |
224 | } | 240 | } |
225 | 241 | ||
242 | static inline void path_conv_opa_to_ib(struct sa_path_rec *ib, | ||
243 | struct sa_path_rec *opa) | ||
244 | { | ||
245 | if ((be32_to_cpu(opa->opa.dlid) >= | ||
246 | be16_to_cpu(IB_MULTICAST_LID_BASE)) || | ||
247 | (be32_to_cpu(opa->opa.slid) >= | ||
248 | be16_to_cpu(IB_MULTICAST_LID_BASE))) { | ||
249 | /* Create OPA GID and zero out the LID */ | ||
250 | ib->dgid.global.interface_id | ||
251 | = OPA_MAKE_ID(be32_to_cpu(opa->opa.dlid)); | ||
252 | ib->dgid.global.subnet_prefix | ||
253 | = opa->dgid.global.subnet_prefix; | ||
254 | ib->sgid.global.interface_id | ||
255 | = OPA_MAKE_ID(be32_to_cpu(opa->opa.slid)); | ||
256 | ib->dgid.global.subnet_prefix | ||
257 | = opa->dgid.global.subnet_prefix; | ||
258 | ib->ib.dlid = 0; | ||
259 | |||
260 | ib->ib.slid = 0; | ||
261 | } else { | ||
262 | ib->ib.dlid = htons(ntohl(opa->opa.dlid)); | ||
263 | ib->ib.slid = htons(ntohl(opa->opa.slid)); | ||
264 | } | ||
265 | ib->ib.service_id = opa->opa.service_id; | ||
266 | ib->ib.raw_traffic = opa->opa.raw_traffic; | ||
267 | } | ||
268 | |||
269 | static inline void path_conv_ib_to_opa(struct sa_path_rec *opa, | ||
270 | struct sa_path_rec *ib) | ||
271 | { | ||
272 | __be32 slid, dlid; | ||
273 | |||
274 | if ((ib_is_opa_gid(&ib->sgid)) || | ||
275 | (ib_is_opa_gid(&ib->dgid))) { | ||
276 | slid = htonl(opa_get_lid_from_gid(&ib->sgid)); | ||
277 | dlid = htonl(opa_get_lid_from_gid(&ib->dgid)); | ||
278 | } else { | ||
279 | slid = htonl(ntohs(ib->ib.slid)); | ||
280 | dlid = htonl(ntohs(ib->ib.dlid)); | ||
281 | } | ||
282 | opa->opa.slid = slid; | ||
283 | opa->opa.dlid = dlid; | ||
284 | opa->opa.service_id = ib->ib.service_id; | ||
285 | opa->opa.raw_traffic = ib->ib.raw_traffic; | ||
286 | } | ||
287 | |||
288 | /* Convert from OPA to IB path record */ | ||
289 | static inline void sa_convert_path_opa_to_ib(struct sa_path_rec *dest, | ||
290 | struct sa_path_rec *src) | ||
291 | { | ||
292 | if (src->rec_type != SA_PATH_REC_TYPE_OPA) | ||
293 | return; | ||
294 | |||
295 | *dest = *src; | ||
296 | dest->rec_type = SA_PATH_REC_TYPE_IB; | ||
297 | path_conv_opa_to_ib(dest, src); | ||
298 | } | ||
299 | |||
300 | /* Convert from IB to OPA path record */ | ||
301 | static inline void sa_convert_path_ib_to_opa(struct sa_path_rec *dest, | ||
302 | struct sa_path_rec *src) | ||
303 | { | ||
304 | if (src->rec_type != SA_PATH_REC_TYPE_IB) | ||
305 | return; | ||
306 | |||
307 | /* Do a structure copy and overwrite the relevant fields */ | ||
308 | *dest = *src; | ||
309 | dest->rec_type = SA_PATH_REC_TYPE_OPA; | ||
310 | path_conv_ib_to_opa(dest, src); | ||
311 | } | ||
312 | |||
226 | #define IB_SA_MCMEMBER_REC_MGID IB_SA_COMP_MASK( 0) | 313 | #define IB_SA_MCMEMBER_REC_MGID IB_SA_COMP_MASK( 0) |
227 | #define IB_SA_MCMEMBER_REC_PORT_GID IB_SA_COMP_MASK( 1) | 314 | #define IB_SA_MCMEMBER_REC_PORT_GID IB_SA_COMP_MASK( 1) |
228 | #define IB_SA_MCMEMBER_REC_QKEY IB_SA_COMP_MASK( 2) | 315 | #define IB_SA_MCMEMBER_REC_QKEY IB_SA_COMP_MASK( 2) |
@@ -509,18 +596,24 @@ static inline void sa_path_set_service_id(struct sa_path_rec *rec, | |||
509 | { | 596 | { |
510 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) | 597 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) |
511 | rec->ib.service_id = service_id; | 598 | rec->ib.service_id = service_id; |
599 | else if (rec->rec_type == SA_PATH_REC_TYPE_OPA) | ||
600 | rec->opa.service_id = service_id; | ||
512 | } | 601 | } |
513 | 602 | ||
514 | static inline void sa_path_set_slid(struct sa_path_rec *rec, __be16 slid) | 603 | static inline void sa_path_set_slid(struct sa_path_rec *rec, __be32 slid) |
515 | { | 604 | { |
516 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) | 605 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) |
517 | rec->ib.slid = slid; | 606 | rec->ib.slid = htons(ntohl(slid)); |
607 | else if (rec->rec_type == SA_PATH_REC_TYPE_OPA) | ||
608 | rec->opa.slid = slid; | ||
518 | } | 609 | } |
519 | 610 | ||
520 | static inline void sa_path_set_dlid(struct sa_path_rec *rec, __be16 dlid) | 611 | static inline void sa_path_set_dlid(struct sa_path_rec *rec, __be32 dlid) |
521 | { | 612 | { |
522 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) | 613 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) |
523 | rec->ib.dlid = dlid; | 614 | rec->ib.dlid = htons(ntohl(dlid)); |
615 | else if (rec->rec_type == SA_PATH_REC_TYPE_OPA) | ||
616 | rec->opa.dlid = dlid; | ||
524 | } | 617 | } |
525 | 618 | ||
526 | static inline void sa_path_set_raw_traffic(struct sa_path_rec *rec, | 619 | static inline void sa_path_set_raw_traffic(struct sa_path_rec *rec, |
@@ -528,26 +621,34 @@ static inline void sa_path_set_raw_traffic(struct sa_path_rec *rec, | |||
528 | { | 621 | { |
529 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) | 622 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) |
530 | rec->ib.raw_traffic = raw_traffic; | 623 | rec->ib.raw_traffic = raw_traffic; |
624 | else if (rec->rec_type == SA_PATH_REC_TYPE_OPA) | ||
625 | rec->opa.raw_traffic = raw_traffic; | ||
531 | } | 626 | } |
532 | 627 | ||
533 | static inline __be64 sa_path_get_service_id(struct sa_path_rec *rec) | 628 | static inline __be64 sa_path_get_service_id(struct sa_path_rec *rec) |
534 | { | 629 | { |
535 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) | 630 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) |
536 | return rec->ib.service_id; | 631 | return rec->ib.service_id; |
632 | else if (rec->rec_type == SA_PATH_REC_TYPE_OPA) | ||
633 | return rec->opa.service_id; | ||
537 | return 0; | 634 | return 0; |
538 | } | 635 | } |
539 | 636 | ||
540 | static inline __be16 sa_path_get_slid(struct sa_path_rec *rec) | 637 | static inline __be32 sa_path_get_slid(struct sa_path_rec *rec) |
541 | { | 638 | { |
542 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) | 639 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) |
543 | return rec->ib.slid; | 640 | return htonl(ntohs(rec->ib.slid)); |
641 | else if (rec->rec_type == SA_PATH_REC_TYPE_OPA) | ||
642 | return rec->opa.slid; | ||
544 | return 0; | 643 | return 0; |
545 | } | 644 | } |
546 | 645 | ||
547 | static inline __be16 sa_path_get_dlid(struct sa_path_rec *rec) | 646 | static inline __be32 sa_path_get_dlid(struct sa_path_rec *rec) |
548 | { | 647 | { |
549 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) | 648 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) |
550 | return rec->ib.dlid; | 649 | return htonl(ntohs(rec->ib.dlid)); |
650 | else if (rec->rec_type == SA_PATH_REC_TYPE_OPA) | ||
651 | return rec->opa.dlid; | ||
551 | return 0; | 652 | return 0; |
552 | } | 653 | } |
553 | 654 | ||
@@ -555,6 +656,8 @@ static inline u8 sa_path_get_raw_traffic(struct sa_path_rec *rec) | |||
555 | { | 656 | { |
556 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) | 657 | if (rec->rec_type == SA_PATH_REC_TYPE_IB) |
557 | return rec->ib.raw_traffic; | 658 | return rec->ib.raw_traffic; |
659 | else if (rec->rec_type == SA_PATH_REC_TYPE_OPA) | ||
660 | return rec->opa.raw_traffic; | ||
558 | return 0; | 661 | return 0; |
559 | } | 662 | } |
560 | 663 | ||