aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/cm.c34
-rw-r--r--drivers/infiniband/core/sa_query.c4
-rw-r--r--drivers/infiniband/core/ucma.c22
-rw-r--r--drivers/infiniband/core/uverbs_marshall.c40
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_fs.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c14
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c2
-rw-r--r--include/rdma/ib_sa.h121
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}
97EXPORT_SYMBOL(ib_copy_qp_attr_to_user); 97EXPORT_SYMBOL(ib_copy_qp_attr_to_user);
98 98
99void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst, 99void __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
124void 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}
123EXPORT_SYMBOL(ib_copy_path_rec_to_user); 136EXPORT_SYMBOL(ib_copy_path_rec_to_user);
124 137
125void ib_copy_path_rec_from_user(struct sa_path_rec *dst, 138void 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
48enum { 49enum {
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 {
152enum sa_path_rec_type { 153enum 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
158struct sa_path_rec_ib { 160struct sa_path_rec_ib {
@@ -171,6 +173,19 @@ struct sa_path_rec_roce {
171 173
172}; 174};
173 175
176struct 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
174struct sa_path_rec { 189struct 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
242static 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
269static 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 */
289static 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 */
301static 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
514static inline void sa_path_set_slid(struct sa_path_rec *rec, __be16 slid) 603static 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
520static inline void sa_path_set_dlid(struct sa_path_rec *rec, __be16 dlid) 611static 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
526static inline void sa_path_set_raw_traffic(struct sa_path_rec *rec, 619static 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
533static inline __be64 sa_path_get_service_id(struct sa_path_rec *rec) 628static 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
540static inline __be16 sa_path_get_slid(struct sa_path_rec *rec) 637static 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
547static inline __be16 sa_path_get_dlid(struct sa_path_rec *rec) 646static 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