diff options
author | Eli Cohen <eli@mellanox.co.il> | 2006-02-13 19:40:21 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-03-20 13:08:15 -0500 |
commit | 8ebe5077e37a0cb0da527e397460188e6bfdd3ee (patch) | |
tree | 401491fb7a94516dfbeeee027d8eeb294117cb5b /drivers/infiniband/hw/mthca/mthca_qp.c | |
parent | 8bdb0e8632e0f5061bd18b6934346cb609490135 (diff) |
IB/mthca: Support for query QP and SRQ
Implement the query_qp and query_srq methods in mthca.
Signed-off-by: Eli Cohen <eli@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_qp.c')
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_qp.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index c2d3300dace9..e99d735f5f36 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c | |||
@@ -348,6 +348,141 @@ static __be32 get_hw_access_flags(struct mthca_qp *qp, struct ib_qp_attr *attr, | |||
348 | return cpu_to_be32(hw_access_flags); | 348 | return cpu_to_be32(hw_access_flags); |
349 | } | 349 | } |
350 | 350 | ||
351 | static inline enum ib_qp_state to_ib_qp_state(int mthca_state) | ||
352 | { | ||
353 | switch (mthca_state) { | ||
354 | case MTHCA_QP_STATE_RST: return IB_QPS_RESET; | ||
355 | case MTHCA_QP_STATE_INIT: return IB_QPS_INIT; | ||
356 | case MTHCA_QP_STATE_RTR: return IB_QPS_RTR; | ||
357 | case MTHCA_QP_STATE_RTS: return IB_QPS_RTS; | ||
358 | case MTHCA_QP_STATE_DRAINING: | ||
359 | case MTHCA_QP_STATE_SQD: return IB_QPS_SQD; | ||
360 | case MTHCA_QP_STATE_SQE: return IB_QPS_SQE; | ||
361 | case MTHCA_QP_STATE_ERR: return IB_QPS_ERR; | ||
362 | default: return -1; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | static inline enum ib_mig_state to_ib_mig_state(int mthca_mig_state) | ||
367 | { | ||
368 | switch (mthca_mig_state) { | ||
369 | case 0: return IB_MIG_ARMED; | ||
370 | case 1: return IB_MIG_REARM; | ||
371 | case 3: return IB_MIG_MIGRATED; | ||
372 | default: return -1; | ||
373 | } | ||
374 | } | ||
375 | |||
376 | static int to_ib_qp_access_flags(int mthca_flags) | ||
377 | { | ||
378 | int ib_flags = 0; | ||
379 | |||
380 | if (mthca_flags & MTHCA_QP_BIT_RRE) | ||
381 | ib_flags |= IB_ACCESS_REMOTE_READ; | ||
382 | if (mthca_flags & MTHCA_QP_BIT_RWE) | ||
383 | ib_flags |= IB_ACCESS_REMOTE_WRITE; | ||
384 | if (mthca_flags & MTHCA_QP_BIT_RAE) | ||
385 | ib_flags |= IB_ACCESS_REMOTE_ATOMIC; | ||
386 | |||
387 | return ib_flags; | ||
388 | } | ||
389 | |||
390 | static void to_ib_ah_attr(struct mthca_dev *dev, struct ib_ah_attr *ib_ah_attr, | ||
391 | struct mthca_qp_path *path) | ||
392 | { | ||
393 | memset(ib_ah_attr, 0, sizeof *path); | ||
394 | ib_ah_attr->port_num = (be32_to_cpu(path->port_pkey) >> 24) & 0x3; | ||
395 | ib_ah_attr->dlid = be16_to_cpu(path->rlid); | ||
396 | ib_ah_attr->sl = be32_to_cpu(path->sl_tclass_flowlabel) >> 28; | ||
397 | ib_ah_attr->src_path_bits = path->g_mylmc & 0x7f; | ||
398 | ib_ah_attr->static_rate = path->static_rate & 0x7; | ||
399 | ib_ah_attr->ah_flags = (path->g_mylmc & (1 << 7)) ? IB_AH_GRH : 0; | ||
400 | if (ib_ah_attr->ah_flags) { | ||
401 | ib_ah_attr->grh.sgid_index = path->mgid_index & (dev->limits.gid_table_len - 1); | ||
402 | ib_ah_attr->grh.hop_limit = path->hop_limit; | ||
403 | ib_ah_attr->grh.traffic_class = | ||
404 | (be32_to_cpu(path->sl_tclass_flowlabel) >> 20) & 0xff; | ||
405 | ib_ah_attr->grh.flow_label = | ||
406 | be32_to_cpu(path->sl_tclass_flowlabel) & 0xfffff; | ||
407 | memcpy(ib_ah_attr->grh.dgid.raw, | ||
408 | path->rgid, sizeof ib_ah_attr->grh.dgid.raw); | ||
409 | } | ||
410 | } | ||
411 | |||
412 | int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask, | ||
413 | struct ib_qp_init_attr *qp_init_attr) | ||
414 | { | ||
415 | struct mthca_dev *dev = to_mdev(ibqp->device); | ||
416 | struct mthca_qp *qp = to_mqp(ibqp); | ||
417 | int err; | ||
418 | struct mthca_mailbox *mailbox; | ||
419 | struct mthca_qp_param *qp_param; | ||
420 | struct mthca_qp_context *context; | ||
421 | int mthca_state; | ||
422 | u8 status; | ||
423 | |||
424 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); | ||
425 | if (IS_ERR(mailbox)) | ||
426 | return PTR_ERR(mailbox); | ||
427 | |||
428 | err = mthca_QUERY_QP(dev, qp->qpn, 0, mailbox, &status); | ||
429 | if (err) | ||
430 | goto out; | ||
431 | if (status) { | ||
432 | mthca_warn(dev, "QUERY_QP returned status %02x\n", status); | ||
433 | err = -EINVAL; | ||
434 | goto out; | ||
435 | } | ||
436 | |||
437 | qp_param = mailbox->buf; | ||
438 | context = &qp_param->context; | ||
439 | mthca_state = be32_to_cpu(context->flags) >> 28; | ||
440 | |||
441 | qp_attr->qp_state = to_ib_qp_state(mthca_state); | ||
442 | qp_attr->cur_qp_state = qp_attr->qp_state; | ||
443 | qp_attr->path_mtu = context->mtu_msgmax >> 5; | ||
444 | qp_attr->path_mig_state = | ||
445 | to_ib_mig_state((be32_to_cpu(context->flags) >> 11) & 0x3); | ||
446 | qp_attr->qkey = be32_to_cpu(context->qkey); | ||
447 | qp_attr->rq_psn = be32_to_cpu(context->rnr_nextrecvpsn) & 0xffffff; | ||
448 | qp_attr->sq_psn = be32_to_cpu(context->next_send_psn) & 0xffffff; | ||
449 | qp_attr->dest_qp_num = be32_to_cpu(context->remote_qpn) & 0xffffff; | ||
450 | qp_attr->qp_access_flags = | ||
451 | to_ib_qp_access_flags(be32_to_cpu(context->params2)); | ||
452 | qp_attr->cap.max_send_wr = qp->sq.max; | ||
453 | qp_attr->cap.max_recv_wr = qp->rq.max; | ||
454 | qp_attr->cap.max_send_sge = qp->sq.max_gs; | ||
455 | qp_attr->cap.max_recv_sge = qp->rq.max_gs; | ||
456 | qp_attr->cap.max_inline_data = qp->max_inline_data; | ||
457 | |||
458 | to_ib_ah_attr(dev, &qp_attr->ah_attr, &context->pri_path); | ||
459 | to_ib_ah_attr(dev, &qp_attr->alt_ah_attr, &context->alt_path); | ||
460 | |||
461 | qp_attr->pkey_index = be32_to_cpu(context->pri_path.port_pkey) & 0x7f; | ||
462 | qp_attr->alt_pkey_index = be32_to_cpu(context->alt_path.port_pkey) & 0x7f; | ||
463 | |||
464 | /* qp_attr->en_sqd_async_notify is only applicable in modify qp */ | ||
465 | qp_attr->sq_draining = mthca_state == MTHCA_QP_STATE_DRAINING; | ||
466 | |||
467 | qp_attr->max_rd_atomic = 1 << ((be32_to_cpu(context->params1) >> 21) & 0x7); | ||
468 | |||
469 | qp_attr->max_dest_rd_atomic = | ||
470 | 1 << ((be32_to_cpu(context->params2) >> 21) & 0x7); | ||
471 | qp_attr->min_rnr_timer = | ||
472 | (be32_to_cpu(context->rnr_nextrecvpsn) >> 24) & 0x1f; | ||
473 | qp_attr->port_num = qp_attr->ah_attr.port_num; | ||
474 | qp_attr->timeout = context->pri_path.ackto >> 3; | ||
475 | qp_attr->retry_cnt = (be32_to_cpu(context->params1) >> 16) & 0x7; | ||
476 | qp_attr->rnr_retry = context->pri_path.rnr_retry >> 5; | ||
477 | qp_attr->alt_port_num = qp_attr->alt_ah_attr.port_num; | ||
478 | qp_attr->alt_timeout = context->alt_path.ackto >> 3; | ||
479 | qp_init_attr->cap = qp_attr->cap; | ||
480 | |||
481 | out: | ||
482 | mthca_free_mailbox(dev, mailbox); | ||
483 | return err; | ||
484 | } | ||
485 | |||
351 | static void mthca_path_set(struct ib_ah_attr *ah, struct mthca_qp_path *path) | 486 | static void mthca_path_set(struct ib_ah_attr *ah, struct mthca_qp_path *path) |
352 | { | 487 | { |
353 | path->g_mylmc = ah->src_path_bits & 0x7f; | 488 | path->g_mylmc = ah->src_path_bits & 0x7f; |