aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/cma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/core/cma.c')
-rw-r--r--drivers/infiniband/core/cma.c60
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}
489EXPORT_SYMBOL(rdma_destroy_qp); 489EXPORT_SYMBOL(rdma_destroy_qp);
490 490
491static int cma_modify_qp_rtr(struct rdma_id_private *id_priv) 491static 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);
518out: 521out:
519 mutex_unlock(&id_priv->qp_mutex); 522 mutex_unlock(&id_priv->qp_mutex);
520 return ret; 523 return ret;
521} 524}
522 525
523static int cma_modify_qp_rts(struct rdma_id_private *id_priv) 526static 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);
540out: 546out:
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}