diff options
Diffstat (limited to 'drivers/infiniband/core/cma.c')
-rw-r--r-- | drivers/infiniband/core/cma.c | 60 |
1 files changed, 33 insertions, 27 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 0751697ef984..637efead97a0 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -488,7 +488,8 @@ void rdma_destroy_qp(struct rdma_cm_id *id) | |||
488 | } | 488 | } |
489 | EXPORT_SYMBOL(rdma_destroy_qp); | 489 | EXPORT_SYMBOL(rdma_destroy_qp); |
490 | 490 | ||
491 | static int cma_modify_qp_rtr(struct rdma_id_private *id_priv) | 491 | static int cma_modify_qp_rtr(struct rdma_id_private *id_priv, |
492 | struct rdma_conn_param *conn_param) | ||
492 | { | 493 | { |
493 | struct ib_qp_attr qp_attr; | 494 | struct ib_qp_attr qp_attr; |
494 | int qp_attr_mask, ret; | 495 | int qp_attr_mask, ret; |
@@ -514,13 +515,16 @@ static int cma_modify_qp_rtr(struct rdma_id_private *id_priv) | |||
514 | if (ret) | 515 | if (ret) |
515 | goto out; | 516 | goto out; |
516 | 517 | ||
518 | if (conn_param) | ||
519 | qp_attr.max_dest_rd_atomic = conn_param->responder_resources; | ||
517 | ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask); | 520 | ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask); |
518 | out: | 521 | out: |
519 | mutex_unlock(&id_priv->qp_mutex); | 522 | mutex_unlock(&id_priv->qp_mutex); |
520 | return ret; | 523 | return ret; |
521 | } | 524 | } |
522 | 525 | ||
523 | static int cma_modify_qp_rts(struct rdma_id_private *id_priv) | 526 | static int cma_modify_qp_rts(struct rdma_id_private *id_priv, |
527 | struct rdma_conn_param *conn_param) | ||
524 | { | 528 | { |
525 | struct ib_qp_attr qp_attr; | 529 | struct ib_qp_attr qp_attr; |
526 | int qp_attr_mask, ret; | 530 | int qp_attr_mask, ret; |
@@ -536,6 +540,8 @@ static int cma_modify_qp_rts(struct rdma_id_private *id_priv) | |||
536 | if (ret) | 540 | if (ret) |
537 | goto out; | 541 | goto out; |
538 | 542 | ||
543 | if (conn_param) | ||
544 | qp_attr.max_rd_atomic = conn_param->initiator_depth; | ||
539 | ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask); | 545 | ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask); |
540 | out: | 546 | out: |
541 | mutex_unlock(&id_priv->qp_mutex); | 547 | mutex_unlock(&id_priv->qp_mutex); |
@@ -866,11 +872,11 @@ static int cma_rep_recv(struct rdma_id_private *id_priv) | |||
866 | { | 872 | { |
867 | int ret; | 873 | int ret; |
868 | 874 | ||
869 | ret = cma_modify_qp_rtr(id_priv); | 875 | ret = cma_modify_qp_rtr(id_priv, NULL); |
870 | if (ret) | 876 | if (ret) |
871 | goto reject; | 877 | goto reject; |
872 | 878 | ||
873 | ret = cma_modify_qp_rts(id_priv); | 879 | ret = cma_modify_qp_rts(id_priv, NULL); |
874 | if (ret) | 880 | if (ret) |
875 | goto reject; | 881 | goto reject; |
876 | 882 | ||
@@ -1122,8 +1128,10 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
1122 | cm_id->cm_handler = cma_ib_handler; | 1128 | cm_id->cm_handler = cma_ib_handler; |
1123 | 1129 | ||
1124 | ret = conn_id->id.event_handler(&conn_id->id, &event); | 1130 | ret = conn_id->id.event_handler(&conn_id->id, &event); |
1125 | if (!ret) | 1131 | if (!ret) { |
1132 | cma_enable_remove(conn_id); | ||
1126 | goto out; | 1133 | goto out; |
1134 | } | ||
1127 | 1135 | ||
1128 | /* Destroy the CM ID by returning a non-zero value. */ | 1136 | /* Destroy the CM ID by returning a non-zero value. */ |
1129 | conn_id->cm_id.ib = NULL; | 1137 | conn_id->cm_id.ib = NULL; |
@@ -1262,6 +1270,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, | |||
1262 | struct net_device *dev = NULL; | 1270 | struct net_device *dev = NULL; |
1263 | struct rdma_cm_event event; | 1271 | struct rdma_cm_event event; |
1264 | int ret; | 1272 | int ret; |
1273 | struct ib_device_attr attr; | ||
1265 | 1274 | ||
1266 | listen_id = cm_id->context; | 1275 | listen_id = cm_id->context; |
1267 | if (cma_disable_remove(listen_id, CMA_LISTEN)) | 1276 | if (cma_disable_remove(listen_id, CMA_LISTEN)) |
@@ -1311,10 +1320,19 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, | |||
1311 | sin = (struct sockaddr_in *) &new_cm_id->route.addr.dst_addr; | 1320 | sin = (struct sockaddr_in *) &new_cm_id->route.addr.dst_addr; |
1312 | *sin = iw_event->remote_addr; | 1321 | *sin = iw_event->remote_addr; |
1313 | 1322 | ||
1323 | ret = ib_query_device(conn_id->id.device, &attr); | ||
1324 | if (ret) { | ||
1325 | cma_enable_remove(conn_id); | ||
1326 | rdma_destroy_id(new_cm_id); | ||
1327 | goto out; | ||
1328 | } | ||
1329 | |||
1314 | memset(&event, 0, sizeof event); | 1330 | memset(&event, 0, sizeof event); |
1315 | event.event = RDMA_CM_EVENT_CONNECT_REQUEST; | 1331 | event.event = RDMA_CM_EVENT_CONNECT_REQUEST; |
1316 | event.param.conn.private_data = iw_event->private_data; | 1332 | event.param.conn.private_data = iw_event->private_data; |
1317 | event.param.conn.private_data_len = iw_event->private_data_len; | 1333 | event.param.conn.private_data_len = iw_event->private_data_len; |
1334 | event.param.conn.initiator_depth = attr.max_qp_init_rd_atom; | ||
1335 | event.param.conn.responder_resources = attr.max_qp_rd_atom; | ||
1318 | ret = conn_id->id.event_handler(&conn_id->id, &event); | 1336 | ret = conn_id->id.event_handler(&conn_id->id, &event); |
1319 | if (ret) { | 1337 | if (ret) { |
1320 | /* User wants to destroy the CM ID */ | 1338 | /* User wants to destroy the CM ID */ |
@@ -2272,7 +2290,7 @@ static int cma_connect_iw(struct rdma_id_private *id_priv, | |||
2272 | sin = (struct sockaddr_in*) &id_priv->id.route.addr.dst_addr; | 2290 | sin = (struct sockaddr_in*) &id_priv->id.route.addr.dst_addr; |
2273 | cm_id->remote_addr = *sin; | 2291 | cm_id->remote_addr = *sin; |
2274 | 2292 | ||
2275 | ret = cma_modify_qp_rtr(id_priv); | 2293 | ret = cma_modify_qp_rtr(id_priv, conn_param); |
2276 | if (ret) | 2294 | if (ret) |
2277 | goto out; | 2295 | goto out; |
2278 | 2296 | ||
@@ -2335,25 +2353,15 @@ static int cma_accept_ib(struct rdma_id_private *id_priv, | |||
2335 | struct rdma_conn_param *conn_param) | 2353 | struct rdma_conn_param *conn_param) |
2336 | { | 2354 | { |
2337 | struct ib_cm_rep_param rep; | 2355 | struct ib_cm_rep_param rep; |
2338 | struct ib_qp_attr qp_attr; | 2356 | int ret; |
2339 | int qp_attr_mask, ret; | ||
2340 | |||
2341 | if (id_priv->id.qp) { | ||
2342 | ret = cma_modify_qp_rtr(id_priv); | ||
2343 | if (ret) | ||
2344 | goto out; | ||
2345 | 2357 | ||
2346 | qp_attr.qp_state = IB_QPS_RTS; | 2358 | ret = cma_modify_qp_rtr(id_priv, conn_param); |
2347 | ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, &qp_attr, | 2359 | if (ret) |
2348 | &qp_attr_mask); | 2360 | goto out; |
2349 | if (ret) | ||
2350 | goto out; | ||
2351 | 2361 | ||
2352 | qp_attr.max_rd_atomic = conn_param->initiator_depth; | 2362 | ret = cma_modify_qp_rts(id_priv, conn_param); |
2353 | ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask); | 2363 | if (ret) |
2354 | if (ret) | 2364 | goto out; |
2355 | goto out; | ||
2356 | } | ||
2357 | 2365 | ||
2358 | memset(&rep, 0, sizeof rep); | 2366 | memset(&rep, 0, sizeof rep); |
2359 | rep.qp_num = id_priv->qp_num; | 2367 | rep.qp_num = id_priv->qp_num; |
@@ -2378,7 +2386,7 @@ static int cma_accept_iw(struct rdma_id_private *id_priv, | |||
2378 | struct iw_cm_conn_param iw_param; | 2386 | struct iw_cm_conn_param iw_param; |
2379 | int ret; | 2387 | int ret; |
2380 | 2388 | ||
2381 | ret = cma_modify_qp_rtr(id_priv); | 2389 | ret = cma_modify_qp_rtr(id_priv, conn_param); |
2382 | if (ret) | 2390 | if (ret) |
2383 | return ret; | 2391 | return ret; |
2384 | 2392 | ||
@@ -2598,11 +2606,9 @@ static void cma_set_mgid(struct rdma_id_private *id_priv, | |||
2598 | /* IPv6 address is an SA assigned MGID. */ | 2606 | /* IPv6 address is an SA assigned MGID. */ |
2599 | memcpy(mgid, &sin6->sin6_addr, sizeof *mgid); | 2607 | memcpy(mgid, &sin6->sin6_addr, sizeof *mgid); |
2600 | } else { | 2608 | } else { |
2601 | ip_ib_mc_map(sin->sin_addr.s_addr, mc_map); | 2609 | ip_ib_mc_map(sin->sin_addr.s_addr, dev_addr->broadcast, mc_map); |
2602 | if (id_priv->id.ps == RDMA_PS_UDP) | 2610 | if (id_priv->id.ps == RDMA_PS_UDP) |
2603 | mc_map[7] = 0x01; /* Use RDMA CM signature */ | 2611 | mc_map[7] = 0x01; /* Use RDMA CM signature */ |
2604 | mc_map[8] = ib_addr_get_pkey(dev_addr) >> 8; | ||
2605 | mc_map[9] = (unsigned char) ib_addr_get_pkey(dev_addr); | ||
2606 | *mgid = *(union ib_gid *) (mc_map + 4); | 2612 | *mgid = *(union ib_gid *) (mc_map + 4); |
2607 | } | 2613 | } |
2608 | } | 2614 | } |