aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com>2017-04-27 19:06:00 -0400
committerDoug Ledford <dledford@redhat.com>2017-05-01 14:38:19 -0400
commit9fdca4da4d8c83caefb9f2fd897d6a7bc355dfe6 (patch)
tree002153e16e28b8817c25082e00ab2cc397fe9c34
parentdfa834e1d97e24c7d6b7c5b102728d69d6361501 (diff)
IB/SA: Split struct sa_path_rec based on IB and ROCE specific fields
sa_path_rec now contains a union of sa_path_rec_ib and sa_path_rec_roce based on the type of the path record. Note that fields applicable to path record type ROCE v1 and ROCE v2 fall under sa_path_rec_roce. Accessor functions are added to these fields so the caller doesn't have to know the type. Reviewed-by: Don Hiatt <don.hiatt@intel.com> Reviewed-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Dasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/core/cm.c62
-rw-r--r--drivers/infiniband/core/cma.c22
-rw-r--r--drivers/infiniband/core/sa_query.c39
-rw-r--r--drivers/infiniband/core/uverbs_marshall.c20
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_fs.c6
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c11
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c7
-rw-r--r--include/rdma/ib_sa.h147
8 files changed, 230 insertions, 84 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 39e306a09f96..ca742e84e68b 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -1203,8 +1203,8 @@ 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 = pri_path->slid; 1206 req_msg->primary_local_lid = sa_path_get_slid(pri_path);
1207 req_msg->primary_remote_lid = pri_path->dlid; 1207 req_msg->primary_remote_lid = sa_path_get_dlid(pri_path);
1208 } else { 1208 } else {
1209 /* Work-around until there's a way to obtain remote LID info */ 1209 /* Work-around until there's a way to obtain remote LID info */
1210 req_msg->primary_local_lid = IB_LID_PERMISSIVE; 1210 req_msg->primary_local_lid = IB_LID_PERMISSIVE;
@@ -1224,8 +1224,8 @@ static void cm_format_req(struct cm_req_msg *req_msg,
1224 1224
1225 if (alt_path) { 1225 if (alt_path) {
1226 if (alt_path->hop_limit <= 1) { 1226 if (alt_path->hop_limit <= 1) {
1227 req_msg->alt_local_lid = alt_path->slid; 1227 req_msg->alt_local_lid = sa_path_get_slid(alt_path);
1228 req_msg->alt_remote_lid = alt_path->dlid; 1228 req_msg->alt_remote_lid = sa_path_get_dlid(alt_path);
1229 } else { 1229 } else {
1230 req_msg->alt_local_lid = IB_LID_PERMISSIVE; 1230 req_msg->alt_local_lid = IB_LID_PERMISSIVE;
1231 req_msg->alt_remote_lid = IB_LID_PERMISSIVE; 1231 req_msg->alt_remote_lid = IB_LID_PERMISSIVE;
@@ -1405,11 +1405,10 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
1405 struct sa_path_rec *primary_path, 1405 struct sa_path_rec *primary_path,
1406 struct sa_path_rec *alt_path) 1406 struct sa_path_rec *alt_path)
1407{ 1407{
1408 memset(primary_path, 0, sizeof(*primary_path));
1409 primary_path->dgid = req_msg->primary_local_gid; 1408 primary_path->dgid = req_msg->primary_local_gid;
1410 primary_path->sgid = req_msg->primary_remote_gid; 1409 primary_path->sgid = req_msg->primary_remote_gid;
1411 primary_path->dlid = req_msg->primary_local_lid; 1410 sa_path_set_dlid(primary_path, req_msg->primary_local_lid);
1412 primary_path->slid = req_msg->primary_remote_lid; 1411 sa_path_set_slid(primary_path, req_msg->primary_remote_lid);
1413 primary_path->flow_label = cm_req_get_primary_flow_label(req_msg); 1412 primary_path->flow_label = cm_req_get_primary_flow_label(req_msg);
1414 primary_path->hop_limit = req_msg->primary_hop_limit; 1413 primary_path->hop_limit = req_msg->primary_hop_limit;
1415 primary_path->traffic_class = req_msg->primary_traffic_class; 1414 primary_path->traffic_class = req_msg->primary_traffic_class;
@@ -1424,14 +1423,13 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
1424 primary_path->packet_life_time = 1423 primary_path->packet_life_time =
1425 cm_req_get_primary_local_ack_timeout(req_msg); 1424 cm_req_get_primary_local_ack_timeout(req_msg);
1426 primary_path->packet_life_time -= (primary_path->packet_life_time > 0); 1425 primary_path->packet_life_time -= (primary_path->packet_life_time > 0);
1427 primary_path->service_id = req_msg->service_id; 1426 sa_path_set_service_id(primary_path, req_msg->service_id);
1428 1427
1429 if (req_msg->alt_local_lid) { 1428 if (req_msg->alt_local_lid) {
1430 memset(alt_path, 0, sizeof(*alt_path));
1431 alt_path->dgid = req_msg->alt_local_gid; 1429 alt_path->dgid = req_msg->alt_local_gid;
1432 alt_path->sgid = req_msg->alt_remote_gid; 1430 alt_path->sgid = req_msg->alt_remote_gid;
1433 alt_path->dlid = req_msg->alt_local_lid; 1431 sa_path_set_dlid(alt_path, req_msg->alt_local_lid);
1434 alt_path->slid = req_msg->alt_remote_lid; 1432 sa_path_set_slid(alt_path, req_msg->alt_remote_lid);
1435 alt_path->flow_label = cm_req_get_alt_flow_label(req_msg); 1433 alt_path->flow_label = cm_req_get_alt_flow_label(req_msg);
1436 alt_path->hop_limit = req_msg->alt_hop_limit; 1434 alt_path->hop_limit = req_msg->alt_hop_limit;
1437 alt_path->traffic_class = req_msg->alt_traffic_class; 1435 alt_path->traffic_class = req_msg->alt_traffic_class;
@@ -1446,7 +1444,7 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
1446 alt_path->packet_life_time = 1444 alt_path->packet_life_time =
1447 cm_req_get_alt_local_ack_timeout(req_msg); 1445 cm_req_get_alt_local_ack_timeout(req_msg);
1448 alt_path->packet_life_time -= (alt_path->packet_life_time > 0); 1446 alt_path->packet_life_time -= (alt_path->packet_life_time > 0);
1449 alt_path->service_id = req_msg->service_id; 1447 sa_path_set_service_id(alt_path, req_msg->service_id);
1450 } 1448 }
1451} 1449}
1452 1450
@@ -1760,27 +1758,34 @@ static int cm_req_handler(struct cm_work *work)
1760 cm_id_priv->id.service_mask = ~cpu_to_be64(0); 1758 cm_id_priv->id.service_mask = ~cpu_to_be64(0);
1761 1759
1762 cm_process_routed_req(req_msg, work->mad_recv_wc->wc); 1760 cm_process_routed_req(req_msg, work->mad_recv_wc->wc);
1763 cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
1764 1761
1765 if (cm_id_priv->av.ah_attr.type == RDMA_AH_ATTR_TYPE_ROCE) 1762 memset(&work->path[0], 0, sizeof(work->path[0]));
1766 memcpy(work->path[0].dmac, cm_id_priv->av.ah_attr.roce.dmac, 1763 memset(&work->path[1], 0, sizeof(work->path[1]));
1767 ETH_ALEN);
1768 grh = rdma_ah_read_grh(&cm_id_priv->av.ah_attr); 1764 grh = rdma_ah_read_grh(&cm_id_priv->av.ah_attr);
1769 work->path[0].hop_limit = grh->hop_limit;
1770 ret = ib_get_cached_gid(work->port->cm_dev->ib_device, 1765 ret = ib_get_cached_gid(work->port->cm_dev->ib_device,
1771 work->port->port_num, 1766 work->port->port_num,
1772 grh->sgid_index, 1767 grh->sgid_index,
1773 &gid, &gid_attr); 1768 &gid, &gid_attr);
1774 if (!ret) { 1769 if (!ret) {
1775 if (gid_attr.ndev) { 1770 if (gid_attr.ndev) {
1776 work->path[0].ifindex = gid_attr.ndev->ifindex;
1777 work->path[0].net = dev_net(gid_attr.ndev);
1778 dev_put(gid_attr.ndev);
1779 work->path[0].rec_type = 1771 work->path[0].rec_type =
1780 sa_conv_gid_to_pathrec_type(gid_attr.gid_type); 1772 sa_conv_gid_to_pathrec_type(gid_attr.gid_type);
1773 sa_path_set_ifindex(&work->path[0],
1774 gid_attr.ndev->ifindex);
1775 sa_path_set_ndev(&work->path[0],
1776 dev_net(gid_attr.ndev));
1777 dev_put(gid_attr.ndev);
1781 } else { 1778 } else {
1782 work->path[0].rec_type = SA_PATH_REC_TYPE_IB; 1779 work->path[0].rec_type = SA_PATH_REC_TYPE_IB;
1783 } 1780 }
1781 if (req_msg->alt_local_lid)
1782 work->path[1].rec_type = work->path[0].rec_type;
1783 cm_format_paths_from_req(req_msg, &work->path[0],
1784 &work->path[1]);
1785 if (cm_id_priv->av.ah_attr.type == RDMA_AH_ATTR_TYPE_ROCE)
1786 sa_path_set_dmac(&work->path[0],
1787 cm_id_priv->av.ah_attr.roce.dmac);
1788 work->path[0].hop_limit = grh->hop_limit;
1784 ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av, 1789 ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av,
1785 cm_id_priv); 1790 cm_id_priv);
1786 } 1791 }
@@ -1790,11 +1795,13 @@ static int cm_req_handler(struct cm_work *work)
1790 &work->path[0].sgid, 1795 &work->path[0].sgid,
1791 &gid_attr); 1796 &gid_attr);
1792 if (!err && gid_attr.ndev) { 1797 if (!err && gid_attr.ndev) {
1793 work->path[0].ifindex = gid_attr.ndev->ifindex;
1794 work->path[0].net = dev_net(gid_attr.ndev);
1795 dev_put(gid_attr.ndev);
1796 work->path[0].rec_type = 1798 work->path[0].rec_type =
1797 sa_conv_gid_to_pathrec_type(gid_attr.gid_type); 1799 sa_conv_gid_to_pathrec_type(gid_attr.gid_type);
1800 sa_path_set_ifindex(&work->path[0],
1801 gid_attr.ndev->ifindex);
1802 sa_path_set_ndev(&work->path[0],
1803 dev_net(gid_attr.ndev));
1804 dev_put(gid_attr.ndev);
1798 } else { 1805 } else {
1799 work->path[0].rec_type = SA_PATH_REC_TYPE_IB; 1806 work->path[0].rec_type = SA_PATH_REC_TYPE_IB;
1800 } 1807 }
@@ -2835,8 +2842,8 @@ static void cm_format_lap(struct cm_lap_msg *lap_msg,
2835 cm_lap_set_remote_qpn(lap_msg, cm_id_priv->remote_qpn); 2842 cm_lap_set_remote_qpn(lap_msg, cm_id_priv->remote_qpn);
2836 /* todo: need remote CM response timeout */ 2843 /* todo: need remote CM response timeout */
2837 cm_lap_set_remote_resp_timeout(lap_msg, 0x1F); 2844 cm_lap_set_remote_resp_timeout(lap_msg, 0x1F);
2838 lap_msg->alt_local_lid = alternate_path->slid; 2845 lap_msg->alt_local_lid = sa_path_get_slid(alternate_path);
2839 lap_msg->alt_remote_lid = alternate_path->dlid; 2846 lap_msg->alt_remote_lid = sa_path_get_dlid(alternate_path);
2840 lap_msg->alt_local_gid = alternate_path->sgid; 2847 lap_msg->alt_local_gid = alternate_path->sgid;
2841 lap_msg->alt_remote_gid = alternate_path->dgid; 2848 lap_msg->alt_remote_gid = alternate_path->dgid;
2842 cm_lap_set_flow_label(lap_msg, alternate_path->flow_label); 2849 cm_lap_set_flow_label(lap_msg, alternate_path->flow_label);
@@ -2912,10 +2919,11 @@ static void cm_format_path_from_lap(struct cm_id_private *cm_id_priv,
2912 struct cm_lap_msg *lap_msg) 2919 struct cm_lap_msg *lap_msg)
2913{ 2920{
2914 memset(path, 0, sizeof *path); 2921 memset(path, 0, sizeof *path);
2922 path->rec_type = SA_PATH_REC_TYPE_IB;
2915 path->dgid = lap_msg->alt_local_gid; 2923 path->dgid = lap_msg->alt_local_gid;
2916 path->sgid = lap_msg->alt_remote_gid; 2924 path->sgid = lap_msg->alt_remote_gid;
2917 path->dlid = lap_msg->alt_local_lid; 2925 sa_path_set_dlid(path, lap_msg->alt_local_lid);
2918 path->slid = lap_msg->alt_remote_lid; 2926 sa_path_set_slid(path, lap_msg->alt_remote_lid);
2919 path->flow_label = cm_lap_get_flow_label(lap_msg); 2927 path->flow_label = cm_lap_get_flow_label(lap_msg);
2920 path->hop_limit = lap_msg->alt_hop_limit; 2928 path->hop_limit = lap_msg->alt_hop_limit;
2921 path->traffic_class = cm_lap_get_traffic_class(lap_msg); 2929 path->traffic_class = cm_lap_get_traffic_class(lap_msg);
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 16c82a65b812..653e0051d328 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1140,7 +1140,7 @@ static void cma_save_ib_info(struct sockaddr *src_addr,
1140 ib->sib_pkey = path->pkey; 1140 ib->sib_pkey = path->pkey;
1141 ib->sib_flowinfo = path->flow_label; 1141 ib->sib_flowinfo = path->flow_label;
1142 memcpy(&ib->sib_addr, &path->sgid, 16); 1142 memcpy(&ib->sib_addr, &path->sgid, 16);
1143 ib->sib_sid = path->service_id; 1143 ib->sib_sid = sa_path_get_service_id(path);
1144 ib->sib_scope_id = 0; 1144 ib->sib_scope_id = 0;
1145 } else { 1145 } else {
1146 ib->sib_pkey = listen_ib->sib_pkey; 1146 ib->sib_pkey = listen_ib->sib_pkey;
@@ -1274,7 +1274,8 @@ static int cma_save_req_info(const struct ib_cm_event *ib_event,
1274 memcpy(&req->local_gid, &req_param->primary_path->sgid, 1274 memcpy(&req->local_gid, &req_param->primary_path->sgid,
1275 sizeof(req->local_gid)); 1275 sizeof(req->local_gid));
1276 req->has_gid = true; 1276 req->has_gid = true;
1277 req->service_id = req_param->primary_path->service_id; 1277 req->service_id =
1278 sa_path_get_service_id(req_param->primary_path);
1278 req->pkey = be16_to_cpu(req_param->primary_path->pkey); 1279 req->pkey = be16_to_cpu(req_param->primary_path->pkey);
1279 if (req->pkey != req_param->bth_pkey) 1280 if (req->pkey != req_param->bth_pkey)
1280 pr_warn_ratelimited("RDMA CMA: got different BTH P_Key (0x%x) and primary path P_Key (0x%x)\n" 1281 pr_warn_ratelimited("RDMA CMA: got different BTH P_Key (0x%x) and primary path P_Key (0x%x)\n"
@@ -1825,8 +1826,8 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
1825 struct rdma_cm_id *id; 1826 struct rdma_cm_id *id;
1826 struct rdma_route *rt; 1827 struct rdma_route *rt;
1827 const sa_family_t ss_family = listen_id->route.addr.src_addr.ss_family; 1828 const sa_family_t ss_family = listen_id->route.addr.src_addr.ss_family;
1828 const __be64 service_id = 1829 struct sa_path_rec *path = ib_event->param.req_rcvd.primary_path;
1829 ib_event->param.req_rcvd.primary_path->service_id; 1830 const __be64 service_id = sa_path_get_service_id(path);
1830 int ret; 1831 int ret;
1831 1832
1832 id = rdma_create_id(listen_id->route.addr.dev_addr.net, 1833 id = rdma_create_id(listen_id->route.addr.dev_addr.net,
@@ -1848,7 +1849,7 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
1848 if (!rt->path_rec) 1849 if (!rt->path_rec)
1849 goto err; 1850 goto err;
1850 1851
1851 rt->path_rec[0] = *ib_event->param.req_rcvd.primary_path; 1852 rt->path_rec[0] = *path;
1852 if (rt->num_paths == 2) 1853 if (rt->num_paths == 2)
1853 rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path; 1854 rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path;
1854 1855
@@ -2334,12 +2335,15 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
2334 struct sockaddr_ib *sib; 2335 struct sockaddr_ib *sib;
2335 2336
2336 memset(&path_rec, 0, sizeof path_rec); 2337 memset(&path_rec, 0, sizeof path_rec);
2338 path_rec.rec_type = SA_PATH_REC_TYPE_IB;
2337 rdma_addr_get_sgid(dev_addr, &path_rec.sgid); 2339 rdma_addr_get_sgid(dev_addr, &path_rec.sgid);
2338 rdma_addr_get_dgid(dev_addr, &path_rec.dgid); 2340 rdma_addr_get_dgid(dev_addr, &path_rec.dgid);
2339 path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr)); 2341 path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr));
2340 path_rec.numb_path = 1; 2342 path_rec.numb_path = 1;
2341 path_rec.reversible = 1; 2343 path_rec.reversible = 1;
2342 path_rec.service_id = rdma_get_service_id(&id_priv->id, cma_dst_addr(id_priv)); 2344 sa_path_set_service_id(&path_rec,
2345 rdma_get_service_id(&id_priv->id,
2346 cma_dst_addr(id_priv)));
2343 2347
2344 comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID | 2348 comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID |
2345 IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH | 2349 IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH |
@@ -2577,8 +2581,6 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
2577 } 2581 }
2578 } 2582 }
2579 2583
2580 route->path_rec->net = &init_net;
2581 route->path_rec->ifindex = ndev->ifindex;
2582 supported_gids = roce_gid_type_mask_support(id_priv->id.device, 2584 supported_gids = roce_gid_type_mask_support(id_priv->id.device,
2583 id_priv->id.port_num); 2585 id_priv->id.port_num);
2584 gid_type = cma_route_gid_type(addr->dev_addr.network, 2586 gid_type = cma_route_gid_type(addr->dev_addr.network,
@@ -2586,13 +2588,15 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
2586 id_priv->gid_type); 2588 id_priv->gid_type);
2587 route->path_rec->rec_type = 2589 route->path_rec->rec_type =
2588 sa_conv_gid_to_pathrec_type(gid_type); 2590 sa_conv_gid_to_pathrec_type(gid_type);
2591 sa_path_set_ndev(route->path_rec, &init_net);
2592 sa_path_set_ifindex(route->path_rec, ndev->ifindex);
2589 } 2593 }
2590 if (!ndev) { 2594 if (!ndev) {
2591 ret = -ENODEV; 2595 ret = -ENODEV;
2592 goto err2; 2596 goto err2;
2593 } 2597 }
2594 2598
2595 memcpy(route->path_rec->dmac, addr->dev_addr.dst_dev_addr, ETH_ALEN); 2599 sa_path_set_dmac(route->path_rec, addr->dev_addr.dst_dev_addr);
2596 2600
2597 rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr, 2601 rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr,
2598 &route->path_rec->sgid); 2602 &route->path_rec->sgid);
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index e16536b31422..88361c164d73 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -193,7 +193,7 @@ static u32 tid;
193 .field_name = "sa_path_rec:" #field 193 .field_name = "sa_path_rec:" #field
194 194
195static const struct ib_field path_rec_table[] = { 195static const struct ib_field path_rec_table[] = {
196 { PATH_REC_FIELD(service_id), 196 { PATH_REC_FIELD(ib.service_id),
197 .offset_words = 0, 197 .offset_words = 0,
198 .offset_bits = 0, 198 .offset_bits = 0,
199 .size_bits = 64 }, 199 .size_bits = 64 },
@@ -205,15 +205,15 @@ static const struct ib_field path_rec_table[] = {
205 .offset_words = 6, 205 .offset_words = 6,
206 .offset_bits = 0, 206 .offset_bits = 0,
207 .size_bits = 128 }, 207 .size_bits = 128 },
208 { PATH_REC_FIELD(dlid), 208 { PATH_REC_FIELD(ib.dlid),
209 .offset_words = 10, 209 .offset_words = 10,
210 .offset_bits = 0, 210 .offset_bits = 0,
211 .size_bits = 16 }, 211 .size_bits = 16 },
212 { PATH_REC_FIELD(slid), 212 { PATH_REC_FIELD(ib.slid),
213 .offset_words = 10, 213 .offset_words = 10,
214 .offset_bits = 16, 214 .offset_bits = 16,
215 .size_bits = 16 }, 215 .size_bits = 16 },
216 { PATH_REC_FIELD(raw_traffic), 216 { PATH_REC_FIELD(ib.raw_traffic),
217 .offset_words = 11, 217 .offset_words = 11,
218 .offset_bits = 0, 218 .offset_bits = 0,
219 .size_bits = 1 }, 219 .size_bits = 1 },
@@ -643,7 +643,7 @@ static void ib_nl_set_path_rec_attrs(struct sk_buff *skb,
643 643
644 /* Now build the attributes */ 644 /* Now build the attributes */
645 if (comp_mask & IB_SA_PATH_REC_SERVICE_ID) { 645 if (comp_mask & IB_SA_PATH_REC_SERVICE_ID) {
646 val64 = be64_to_cpu(sa_rec->service_id); 646 val64 = be64_to_cpu(sa_path_get_service_id(sa_rec));
647 nla_put(skb, RDMA_NLA_F_MANDATORY | LS_NLA_TYPE_SERVICE_ID, 647 nla_put(skb, RDMA_NLA_F_MANDATORY | LS_NLA_TYPE_SERVICE_ID,
648 sizeof(val64), &val64); 648 sizeof(val64), &val64);
649 } 649 }
@@ -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(rec->dlid)); 1113 rdma_ah_set_dlid(ah_attr, be16_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(rec->slid) & 1115 rdma_ah_set_path_bits(ah_attr, be16_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);
@@ -1121,9 +1121,13 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
1121 if (use_roce) { 1121 if (use_roce) {
1122 struct net_device *idev; 1122 struct net_device *idev;
1123 struct net_device *resolved_dev; 1123 struct net_device *resolved_dev;
1124 struct rdma_dev_addr dev_addr = {.bound_dev_if = rec->ifindex, 1124 struct rdma_dev_addr dev_addr = {
1125 .net = rec->net ? rec->net : 1125 .bound_dev_if = ((sa_path_get_ifindex(rec) >= 0) ?
1126 &init_net}; 1126 sa_path_get_ifindex(rec) : 0),
1127 .net = sa_path_get_ndev(rec) ?
1128 sa_path_get_ndev(rec) :
1129 &init_net
1130 };
1127 union { 1131 union {
1128 struct sockaddr _sockaddr; 1132 struct sockaddr _sockaddr;
1129 struct sockaddr_in _sockaddr_in; 1133 struct sockaddr_in _sockaddr_in;
@@ -1193,8 +1197,13 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
1193 dev_put(ndev); 1197 dev_put(ndev);
1194 } 1198 }
1195 1199
1196 if (use_roce) 1200 if (use_roce) {
1197 memcpy(ah_attr->roce.dmac, rec->dmac, ETH_ALEN); 1201 u8 *dmac = sa_path_get_dmac(rec);
1202
1203 if (!dmac)
1204 return -EINVAL;
1205 memcpy(ah_attr->roce.dmac, dmac, ETH_ALEN);
1206 }
1198 1207
1199 return 0; 1208 return 0;
1200} 1209}
@@ -1326,10 +1335,10 @@ static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
1326 1335
1327 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), 1336 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table),
1328 mad->data, &rec); 1337 mad->data, &rec);
1329 rec.net = NULL;
1330 rec.ifindex = 0;
1331 rec.rec_type = SA_PATH_REC_TYPE_IB; 1338 rec.rec_type = SA_PATH_REC_TYPE_IB;
1332 eth_zero_addr(rec.dmac); 1339 sa_path_set_ndev(&rec, NULL);
1340 sa_path_set_ifindex(&rec, 0);
1341 sa_path_set_dmac_zero(&rec);
1333 query->callback(status, &rec, query->context); 1342 query->callback(status, &rec, query->context);
1334 } else 1343 } else
1335 query->callback(status, NULL, query->context); 1344 query->callback(status, NULL, query->context);
diff --git a/drivers/infiniband/core/uverbs_marshall.c b/drivers/infiniband/core/uverbs_marshall.c
index b4e9ce888c3e..50575b63905c 100644
--- a/drivers/infiniband/core/uverbs_marshall.c
+++ b/drivers/infiniband/core/uverbs_marshall.c
@@ -102,9 +102,9 @@ void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst,
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 = src->dlid; 105 dst->dlid = sa_path_get_dlid(src);
106 dst->slid = src->slid; 106 dst->slid = sa_path_get_slid(src);
107 dst->raw_traffic = src->raw_traffic; 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;
110 dst->traffic_class = src->traffic_class; 110 dst->traffic_class = src->traffic_class;
@@ -128,9 +128,10 @@ void ib_copy_path_rec_from_user(struct sa_path_rec *dst,
128 memcpy(dst->dgid.raw, src->dgid, sizeof dst->dgid); 128 memcpy(dst->dgid.raw, src->dgid, sizeof dst->dgid);
129 memcpy(dst->sgid.raw, src->sgid, sizeof dst->sgid); 129 memcpy(dst->sgid.raw, src->sgid, sizeof dst->sgid);
130 130
131 dst->dlid = src->dlid; 131 dst->rec_type = SA_PATH_REC_TYPE_IB;
132 dst->slid = src->slid; 132 sa_path_set_dlid(dst, src->dlid);
133 dst->raw_traffic = src->raw_traffic; 133 sa_path_set_slid(dst, src->slid);
134 sa_path_set_raw_traffic(dst, src->raw_traffic);
134 dst->flow_label = src->flow_label; 135 dst->flow_label = src->flow_label;
135 dst->hop_limit = src->hop_limit; 136 dst->hop_limit = src->hop_limit;
136 dst->traffic_class = src->traffic_class; 137 dst->traffic_class = src->traffic_class;
@@ -146,9 +147,8 @@ void ib_copy_path_rec_from_user(struct sa_path_rec *dst,
146 dst->preference = src->preference; 147 dst->preference = src->preference;
147 dst->packet_life_time_selector = src->packet_life_time_selector; 148 dst->packet_life_time_selector = src->packet_life_time_selector;
148 149
149 memset(dst->dmac, 0, sizeof(dst->dmac)); 150 sa_path_set_dmac_zero(dst);
150 dst->net = NULL; 151 sa_path_set_ndev(dst, NULL);
151 dst->ifindex = 0; 152 sa_path_set_ifindex(dst, 0);
152 dst->rec_type = SA_PATH_REC_TYPE_IB;
153} 153}
154EXPORT_SYMBOL(ib_copy_path_rec_from_user); 154EXPORT_SYMBOL(ib_copy_path_rec_from_user);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
index a15664b880ed..ba7dd530fb46 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
@@ -210,16 +210,16 @@ static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr)
210 seq_printf(file, 210 seq_printf(file,
211 "GID: %s\n" 211 "GID: %s\n"
212 " complete: %6s\n", 212 " complete: %6s\n",
213 gid_buf, path.pathrec.dlid ? "yes" : "no"); 213 gid_buf, sa_path_get_dlid(&path.pathrec) ? "yes" : "no");
214 214
215 if (path.pathrec.dlid) { 215 if (sa_path_get_dlid(&path.pathrec)) {
216 rate = ib_rate_to_mbps(path.pathrec.rate); 216 rate = ib_rate_to_mbps(path.pathrec.rate);
217 217
218 seq_printf(file, 218 seq_printf(file,
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(path.pathrec.dlid), 222 be16_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 535621ff7f6e..f4c25271253c 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -669,7 +669,7 @@ void ipoib_mark_paths_invalid(struct net_device *dev)
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%04x GID %pI6 invalid\n",
672 be16_to_cpu(path->pathrec.dlid), 672 be16_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 }
@@ -731,7 +731,8 @@ 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(pathrec->dlid), pathrec->dgid.raw); 734 be16_to_cpu(sa_path_get_dlid(pathrec)),
735 pathrec->dgid.raw);
735 else 736 else
736 ipoib_dbg(priv, "PathRec status %d for GID %pI6\n", 737 ipoib_dbg(priv, "PathRec status %d for GID %pI6\n",
737 status, path->pathrec.dgid.raw); 738 status, path->pathrec.dgid.raw);
@@ -754,7 +755,8 @@ static void path_rec_completion(int status,
754 path->ah = ah; 755 path->ah = ah;
755 756
756 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",
757 ah, be16_to_cpu(pathrec->dlid), pathrec->sl); 758 ah, be16_to_cpu(sa_path_get_dlid(pathrec)),
759 pathrec->sl);
758 760
759 while ((skb = __skb_dequeue(&path->queue))) 761 while ((skb = __skb_dequeue(&path->queue)))
760 __skb_queue_tail(&skqueue, skb); 762 __skb_queue_tail(&skqueue, skb);
@@ -830,6 +832,7 @@ static struct ipoib_path *path_rec_create(struct net_device *dev, void *gid)
830 832
831 INIT_LIST_HEAD(&path->neigh_list); 833 INIT_LIST_HEAD(&path->neigh_list);
832 834
835 path->pathrec.rec_type = SA_PATH_REC_TYPE_IB;
833 memcpy(path->pathrec.dgid.raw, gid, sizeof (union ib_gid)); 836 memcpy(path->pathrec.dgid.raw, gid, sizeof (union ib_gid));
834 path->pathrec.sgid = priv->local_gid; 837 path->pathrec.sgid = priv->local_gid;
835 path->pathrec.pkey = cpu_to_be16(priv->pkey); 838 path->pathrec.pkey = cpu_to_be16(priv->pkey);
@@ -998,7 +1001,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
998 1001
999 if (path->ah) { 1002 if (path->ah) {
1000 ipoib_dbg(priv, "Send unicast ARP to %04x\n", 1003 ipoib_dbg(priv, "Send unicast ARP to %04x\n",
1001 be16_to_cpu(path->pathrec.dlid)); 1004 be16_to_cpu(sa_path_get_dlid(&path->pathrec)));
1002 1005
1003 spin_unlock_irqrestore(&priv->lock, flags); 1006 spin_unlock_irqrestore(&priv->lock, flags);
1004 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 ded9b9afbac0..89341dde9e5b 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -312,10 +312,11 @@ static int srp_new_cm_id(struct srp_rdma_ch *ch)
312 if (ch->cm_id) 312 if (ch->cm_id)
313 ib_destroy_cm_id(ch->cm_id); 313 ib_destroy_cm_id(ch->cm_id);
314 ch->cm_id = new_cm_id; 314 ch->cm_id = new_cm_id;
315 ch->path.rec_type = SA_PATH_REC_TYPE_IB;
315 ch->path.sgid = target->sgid; 316 ch->path.sgid = target->sgid;
316 ch->path.dgid = target->orig_dgid; 317 ch->path.dgid = target->orig_dgid;
317 ch->path.pkey = target->pkey; 318 ch->path.pkey = target->pkey;
318 ch->path.service_id = target->service_id; 319 sa_path_set_service_id(&ch->path, target->service_id);
319 320
320 return 0; 321 return 0;
321} 322}
@@ -2399,12 +2400,12 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id,
2399 switch (event->param.rej_rcvd.reason) { 2400 switch (event->param.rej_rcvd.reason) {
2400 case IB_CM_REJ_PORT_CM_REDIRECT: 2401 case IB_CM_REJ_PORT_CM_REDIRECT:
2401 cpi = event->param.rej_rcvd.ari; 2402 cpi = event->param.rej_rcvd.ari;
2402 ch->path.dlid = cpi->redirect_lid; 2403 sa_path_set_dlid(&ch->path, cpi->redirect_lid);
2403 ch->path.pkey = cpi->redirect_pkey; 2404 ch->path.pkey = cpi->redirect_pkey;
2404 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;
2405 memcpy(ch->path.dgid.raw, cpi->redirect_gid, 16); 2406 memcpy(ch->path.dgid.raw, cpi->redirect_gid, 16);
2406 2407
2407 ch->status = ch->path.dlid ? 2408 ch->status = sa_path_get_dlid(&ch->path) ?
2408 SRP_DLID_REDIRECT : SRP_PORT_REDIRECT; 2409 SRP_DLID_REDIRECT : SRP_PORT_REDIRECT;
2409 break; 2410 break;
2410 2411
diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h
index c00914783e12..c72c94949617 100644
--- a/include/rdma/ib_sa.h
+++ b/include/rdma/ib_sa.h
@@ -43,6 +43,7 @@
43 43
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 47
47enum { 48enum {
48 IB_SA_CLASS_VERSION = 2, /* IB spec version 1.1/1.2 */ 49 IB_SA_CLASS_VERSION = 2, /* IB spec version 1.1/1.2 */
@@ -147,19 +148,32 @@ enum ib_sa_mc_join_states {
147#define IB_SA_PATH_REC_PACKET_LIFE_TIME_SELECTOR IB_SA_COMP_MASK(20) 148#define IB_SA_PATH_REC_PACKET_LIFE_TIME_SELECTOR IB_SA_COMP_MASK(20)
148#define IB_SA_PATH_REC_PACKET_LIFE_TIME IB_SA_COMP_MASK(21) 149#define IB_SA_PATH_REC_PACKET_LIFE_TIME IB_SA_COMP_MASK(21)
149#define IB_SA_PATH_REC_PREFERENCE IB_SA_COMP_MASK(22) 150#define IB_SA_PATH_REC_PREFERENCE IB_SA_COMP_MASK(22)
151
150enum sa_path_rec_type { 152enum sa_path_rec_type {
151 SA_PATH_REC_TYPE_IB, 153 SA_PATH_REC_TYPE_IB,
152 SA_PATH_REC_TYPE_ROCE_V1, 154 SA_PATH_REC_TYPE_ROCE_V1,
153 SA_PATH_REC_TYPE_ROCE_V2 155 SA_PATH_REC_TYPE_ROCE_V2
154}; 156};
155 157
156struct sa_path_rec { 158struct sa_path_rec_ib {
157 __be64 service_id; 159 __be64 service_id;
158 union ib_gid dgid;
159 union ib_gid sgid;
160 __be16 dlid; 160 __be16 dlid;
161 __be16 slid; 161 __be16 slid;
162 u8 raw_traffic; 162 u8 raw_traffic;
163};
164
165struct sa_path_rec_roce {
166 u8 dmac[ETH_ALEN];
167 /* ignored in IB */
168 int ifindex;
169 /* ignored in IB */
170 struct net *net;
171
172};
173
174struct sa_path_rec {
175 union ib_gid dgid;
176 union ib_gid sgid;
163 /* reserved */ 177 /* reserved */
164 __be32 flow_label; 178 __be32 flow_label;
165 u8 hop_limit; 179 u8 hop_limit;
@@ -176,19 +190,13 @@ struct sa_path_rec {
176 u8 packet_life_time_selector; 190 u8 packet_life_time_selector;
177 u8 packet_life_time; 191 u8 packet_life_time;
178 u8 preference; 192 u8 preference;
179 u8 dmac[ETH_ALEN]; 193 union {
180 /* ignored in IB */ 194 struct sa_path_rec_ib ib;
181 int ifindex; 195 struct sa_path_rec_roce roce;
182 /* ignored in IB */ 196 };
183 struct net *net;
184 enum sa_path_rec_type rec_type; 197 enum sa_path_rec_type rec_type;
185}; 198};
186 199
187static inline struct net_device *ib_get_ndev_from_path(struct sa_path_rec *rec)
188{
189 return rec->net ? dev_get_by_index(rec->net, rec->ifindex) : NULL;
190}
191
192static inline enum ib_gid_type 200static inline enum ib_gid_type
193 sa_conv_pathrec_to_gid_type(struct sa_path_rec *rec) 201 sa_conv_pathrec_to_gid_type(struct sa_path_rec *rec)
194{ 202{
@@ -490,4 +498,117 @@ bool ib_sa_sendonly_fullmem_support(struct ib_sa_client *client,
490 struct ib_device *device, 498 struct ib_device *device,
491 u8 port_num); 499 u8 port_num);
492 500
501static inline bool sa_path_is_roce(struct sa_path_rec *rec)
502{
503 return ((rec->rec_type == SA_PATH_REC_TYPE_ROCE_V1) ||
504 (rec->rec_type == SA_PATH_REC_TYPE_ROCE_V2));
505}
506
507static inline void sa_path_set_service_id(struct sa_path_rec *rec,
508 __be64 service_id)
509{
510 if (rec->rec_type == SA_PATH_REC_TYPE_IB)
511 rec->ib.service_id = service_id;
512}
513
514static inline void sa_path_set_slid(struct sa_path_rec *rec, __be16 slid)
515{
516 if (rec->rec_type == SA_PATH_REC_TYPE_IB)
517 rec->ib.slid = slid;
518}
519
520static inline void sa_path_set_dlid(struct sa_path_rec *rec, __be16 dlid)
521{
522 if (rec->rec_type == SA_PATH_REC_TYPE_IB)
523 rec->ib.dlid = dlid;
524}
525
526static inline void sa_path_set_raw_traffic(struct sa_path_rec *rec,
527 u8 raw_traffic)
528{
529 if (rec->rec_type == SA_PATH_REC_TYPE_IB)
530 rec->ib.raw_traffic = raw_traffic;
531}
532
533static inline __be64 sa_path_get_service_id(struct sa_path_rec *rec)
534{
535 if (rec->rec_type == SA_PATH_REC_TYPE_IB)
536 return rec->ib.service_id;
537 return 0;
538}
539
540static inline __be16 sa_path_get_slid(struct sa_path_rec *rec)
541{
542 if (rec->rec_type == SA_PATH_REC_TYPE_IB)
543 return rec->ib.slid;
544 return 0;
545}
546
547static inline __be16 sa_path_get_dlid(struct sa_path_rec *rec)
548{
549 if (rec->rec_type == SA_PATH_REC_TYPE_IB)
550 return rec->ib.dlid;
551 return 0;
552}
553
554static inline u8 sa_path_get_raw_traffic(struct sa_path_rec *rec)
555{
556 if (rec->rec_type == SA_PATH_REC_TYPE_IB)
557 return rec->ib.raw_traffic;
558 return 0;
559}
560
561static inline void sa_path_set_dmac(struct sa_path_rec *rec, u8 *dmac)
562{
563 if (sa_path_is_roce(rec))
564 memcpy(rec->roce.dmac, dmac, ETH_ALEN);
565}
566
567static inline void sa_path_set_dmac_zero(struct sa_path_rec *rec)
568{
569 if (sa_path_is_roce(rec))
570 eth_zero_addr(rec->roce.dmac);
571}
572
573static inline void sa_path_set_ifindex(struct sa_path_rec *rec, int ifindex)
574{
575 if (sa_path_is_roce(rec))
576 rec->roce.ifindex = ifindex;
577}
578
579static inline void sa_path_set_ndev(struct sa_path_rec *rec, struct net *net)
580{
581 if (sa_path_is_roce(rec))
582 rec->roce.net = net;
583}
584
585static inline u8 *sa_path_get_dmac(struct sa_path_rec *rec)
586{
587 if (sa_path_is_roce(rec))
588 return rec->roce.dmac;
589 return NULL;
590}
591
592static inline int sa_path_get_ifindex(struct sa_path_rec *rec)
593{
594 if (sa_path_is_roce(rec))
595 return rec->roce.ifindex;
596 return 0;
597}
598
599static inline struct net *sa_path_get_ndev(struct sa_path_rec *rec)
600{
601 if (sa_path_is_roce(rec))
602 return rec->roce.net;
603 return NULL;
604}
605
606static inline struct net_device *ib_get_ndev_from_path(struct sa_path_rec *rec)
607{
608 return sa_path_get_ndev(rec) ?
609 dev_get_by_index(sa_path_get_ndev(rec),
610 sa_path_get_ifindex(rec))
611 : NULL;
612}
613
493#endif /* IB_SA_H */ 614#endif /* IB_SA_H */