aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorDotan Barak <dotanb@mellanox.co.il>2006-01-06 16:23:58 -0500
committerRoland Dreier <rolandd@cisco.com>2006-01-06 16:23:58 -0500
commit4de144bf721e46e7ccc8fed45b20a640cc364904 (patch)
tree2a1c8e592d21a5ee03533fe6e01ceda82f068715 /drivers/infiniband/hw
parent0f8e8f9607d77ffc1f9820446dfcf781e96fdfd4 (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>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c57
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
552static 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
552int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) 571int 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);