diff options
author | Dotan Barak <dotanb@mellanox.co.il> | 2006-01-06 16:23:58 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-01-06 16:23:58 -0500 |
commit | 4de144bf721e46e7ccc8fed45b20a640cc364904 (patch) | |
tree | 2a1c8e592d21a5ee03533fe6e01ceda82f068715 | |
parent | 0f8e8f9607d77ffc1f9820446dfcf781e96fdfd4 (diff) |
IB/mthca: Add support for automatic path migration (APM)
Add code to modify QP operation to handle setting alternate paths for
connected QPs.
Signed-off-by: Dotan Barak <dotanb@mellanox.co.il>
Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_qp.c | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index ff2def3e9dd1..564b6d51c394 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c | |||
@@ -549,6 +549,25 @@ static __be32 get_hw_access_flags(struct mthca_qp *qp, struct ib_qp_attr *attr, | |||
549 | return cpu_to_be32(hw_access_flags); | 549 | return cpu_to_be32(hw_access_flags); |
550 | } | 550 | } |
551 | 551 | ||
552 | static void mthca_path_set(struct ib_ah_attr *ah, struct mthca_qp_path *path) | ||
553 | { | ||
554 | path->g_mylmc = ah->src_path_bits & 0x7f; | ||
555 | path->rlid = cpu_to_be16(ah->dlid); | ||
556 | path->static_rate = !!ah->static_rate; | ||
557 | |||
558 | if (ah->ah_flags & IB_AH_GRH) { | ||
559 | path->g_mylmc |= 1 << 7; | ||
560 | path->mgid_index = ah->grh.sgid_index; | ||
561 | path->hop_limit = ah->grh.hop_limit; | ||
562 | path->sl_tclass_flowlabel = | ||
563 | cpu_to_be32((ah->sl << 28) | | ||
564 | (ah->grh.traffic_class << 20) | | ||
565 | (ah->grh.flow_label)); | ||
566 | memcpy(path->rgid, ah->grh.dgid.raw, 16); | ||
567 | } else | ||
568 | path->sl_tclass_flowlabel = cpu_to_be32(ah->sl << 28); | ||
569 | } | ||
570 | |||
552 | int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | 571 | int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) |
553 | { | 572 | { |
554 | struct mthca_dev *dev = to_mdev(ibqp->device); | 573 | struct mthca_dev *dev = to_mdev(ibqp->device); |
@@ -712,28 +731,14 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
712 | } | 731 | } |
713 | 732 | ||
714 | if (attr_mask & IB_QP_RNR_RETRY) { | 733 | if (attr_mask & IB_QP_RNR_RETRY) { |
715 | qp_context->pri_path.rnr_retry = attr->rnr_retry << 5; | 734 | qp_context->alt_path.rnr_retry = qp_context->pri_path.rnr_retry = |
716 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY); | 735 | attr->rnr_retry << 5; |
736 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY | | ||
737 | MTHCA_QP_OPTPAR_ALT_RNR_RETRY); | ||
717 | } | 738 | } |
718 | 739 | ||
719 | if (attr_mask & IB_QP_AV) { | 740 | if (attr_mask & IB_QP_AV) { |
720 | qp_context->pri_path.g_mylmc = attr->ah_attr.src_path_bits & 0x7f; | 741 | mthca_path_set(&attr->ah_attr, &qp_context->pri_path); |
721 | qp_context->pri_path.rlid = cpu_to_be16(attr->ah_attr.dlid); | ||
722 | qp_context->pri_path.static_rate = !!attr->ah_attr.static_rate; | ||
723 | if (attr->ah_attr.ah_flags & IB_AH_GRH) { | ||
724 | qp_context->pri_path.g_mylmc |= 1 << 7; | ||
725 | qp_context->pri_path.mgid_index = attr->ah_attr.grh.sgid_index; | ||
726 | qp_context->pri_path.hop_limit = attr->ah_attr.grh.hop_limit; | ||
727 | qp_context->pri_path.sl_tclass_flowlabel = | ||
728 | cpu_to_be32((attr->ah_attr.sl << 28) | | ||
729 | (attr->ah_attr.grh.traffic_class << 20) | | ||
730 | (attr->ah_attr.grh.flow_label)); | ||
731 | memcpy(qp_context->pri_path.rgid, | ||
732 | attr->ah_attr.grh.dgid.raw, 16); | ||
733 | } else { | ||
734 | qp_context->pri_path.sl_tclass_flowlabel = | ||
735 | cpu_to_be32(attr->ah_attr.sl << 28); | ||
736 | } | ||
737 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH); | 742 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH); |
738 | } | 743 | } |
739 | 744 | ||
@@ -742,7 +747,19 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
742 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT); | 747 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT); |
743 | } | 748 | } |
744 | 749 | ||
745 | /* XXX alt_path */ | 750 | if (attr_mask & IB_QP_ALT_PATH) { |
751 | if (attr->alt_port_num == 0 || attr->alt_port_num > dev->limits.num_ports) { | ||
752 | mthca_dbg(dev, "Alternate port number (%u) is invalid\n", | ||
753 | attr->alt_port_num); | ||
754 | return -EINVAL; | ||
755 | } | ||
756 | |||
757 | mthca_path_set(&attr->alt_ah_attr, &qp_context->alt_path); | ||
758 | qp_context->alt_path.port_pkey |= cpu_to_be32(attr->alt_pkey_index | | ||
759 | attr->alt_port_num << 24); | ||
760 | qp_context->alt_path.ackto = attr->alt_timeout << 3; | ||
761 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ALT_ADDR_PATH); | ||
762 | } | ||
746 | 763 | ||
747 | /* leave rdd as 0 */ | 764 | /* leave rdd as 0 */ |
748 | qp_context->pd = cpu_to_be32(to_mpd(ibqp->pd)->pd_num); | 765 | qp_context->pd = cpu_to_be32(to_mpd(ibqp->pd)->pd_num); |