aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2011-08-02 14:08:22 -0400
committerRoland Dreier <roland@purestorage.com>2011-10-13 12:38:35 -0400
commitef70044647b260cb6b7863f392384a06670d0b2a (patch)
tree8f916d6155e93dfe02886e20c23fccb480aae5f2
parentd26a360b776d527429cf13300837711b0b2fde20 (diff)
IB/cm: Update XRC support based on XRC annex errata
The XRC annex was updated to have XRC behave more like RD. Specifically, the XRC TGT QPN moves from the local QPN to local EECN field. Lookup of SRQN is done using the REQ/REP protocol. Signed-off-by: Sean Hefty <sean.hefty@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/core/cm.c15
-rw-r--r--drivers/infiniband/core/cm_msgs.h19
2 files changed, 26 insertions, 8 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index d2e1cfb206b..42a7a9bae44 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -1605,7 +1605,6 @@ static void cm_format_rep(struct cm_rep_msg *rep_msg,
1605 cm_format_mad_hdr(&rep_msg->hdr, CM_REP_ATTR_ID, cm_id_priv->tid); 1605 cm_format_mad_hdr(&rep_msg->hdr, CM_REP_ATTR_ID, cm_id_priv->tid);
1606 rep_msg->local_comm_id = cm_id_priv->id.local_id; 1606 rep_msg->local_comm_id = cm_id_priv->id.local_id;
1607 rep_msg->remote_comm_id = cm_id_priv->id.remote_id; 1607 rep_msg->remote_comm_id = cm_id_priv->id.remote_id;
1608 cm_rep_set_local_qpn(rep_msg, cpu_to_be32(param->qp_num));
1609 cm_rep_set_starting_psn(rep_msg, cpu_to_be32(param->starting_psn)); 1608 cm_rep_set_starting_psn(rep_msg, cpu_to_be32(param->starting_psn));
1610 rep_msg->resp_resources = param->responder_resources; 1609 rep_msg->resp_resources = param->responder_resources;
1611 cm_rep_set_target_ack_delay(rep_msg, 1610 cm_rep_set_target_ack_delay(rep_msg,
@@ -1618,8 +1617,10 @@ static void cm_format_rep(struct cm_rep_msg *rep_msg,
1618 rep_msg->initiator_depth = param->initiator_depth; 1617 rep_msg->initiator_depth = param->initiator_depth;
1619 cm_rep_set_flow_ctrl(rep_msg, param->flow_control); 1618 cm_rep_set_flow_ctrl(rep_msg, param->flow_control);
1620 cm_rep_set_srq(rep_msg, param->srq); 1619 cm_rep_set_srq(rep_msg, param->srq);
1620 cm_rep_set_local_qpn(rep_msg, cpu_to_be32(param->qp_num));
1621 } else { 1621 } else {
1622 cm_rep_set_srq(rep_msg, 1); 1622 cm_rep_set_srq(rep_msg, 1);
1623 cm_rep_set_local_eecn(rep_msg, cpu_to_be32(param->qp_num));
1623 } 1624 }
1624 1625
1625 if (param->private_data && param->private_data_len) 1626 if (param->private_data && param->private_data_len)
@@ -1669,7 +1670,7 @@ int ib_send_cm_rep(struct ib_cm_id *cm_id,
1669 cm_id_priv->initiator_depth = param->initiator_depth; 1670 cm_id_priv->initiator_depth = param->initiator_depth;
1670 cm_id_priv->responder_resources = param->responder_resources; 1671 cm_id_priv->responder_resources = param->responder_resources;
1671 cm_id_priv->rq_psn = cm_rep_get_starting_psn(rep_msg); 1672 cm_id_priv->rq_psn = cm_rep_get_starting_psn(rep_msg);
1672 cm_id_priv->local_qpn = cm_rep_get_local_qpn(rep_msg); 1673 cm_id_priv->local_qpn = cpu_to_be32(param->qp_num & 0xFFFFFF);
1673 1674
1674out: spin_unlock_irqrestore(&cm_id_priv->lock, flags); 1675out: spin_unlock_irqrestore(&cm_id_priv->lock, flags);
1675 return ret; 1676 return ret;
@@ -1740,7 +1741,7 @@ error: spin_unlock_irqrestore(&cm_id_priv->lock, flags);
1740} 1741}
1741EXPORT_SYMBOL(ib_send_cm_rtu); 1742EXPORT_SYMBOL(ib_send_cm_rtu);
1742 1743
1743static void cm_format_rep_event(struct cm_work *work) 1744static void cm_format_rep_event(struct cm_work *work, enum ib_qp_type qp_type)
1744{ 1745{
1745 struct cm_rep_msg *rep_msg; 1746 struct cm_rep_msg *rep_msg;
1746 struct ib_cm_rep_event_param *param; 1747 struct ib_cm_rep_event_param *param;
@@ -1749,7 +1750,7 @@ static void cm_format_rep_event(struct cm_work *work)
1749 param = &work->cm_event.param.rep_rcvd; 1750 param = &work->cm_event.param.rep_rcvd;
1750 param->remote_ca_guid = rep_msg->local_ca_guid; 1751 param->remote_ca_guid = rep_msg->local_ca_guid;
1751 param->remote_qkey = be32_to_cpu(rep_msg->local_qkey); 1752 param->remote_qkey = be32_to_cpu(rep_msg->local_qkey);
1752 param->remote_qpn = be32_to_cpu(cm_rep_get_local_qpn(rep_msg)); 1753 param->remote_qpn = be32_to_cpu(cm_rep_get_qpn(rep_msg, qp_type));
1753 param->starting_psn = be32_to_cpu(cm_rep_get_starting_psn(rep_msg)); 1754 param->starting_psn = be32_to_cpu(cm_rep_get_starting_psn(rep_msg));
1754 param->responder_resources = rep_msg->initiator_depth; 1755 param->responder_resources = rep_msg->initiator_depth;
1755 param->initiator_depth = rep_msg->resp_resources; 1756 param->initiator_depth = rep_msg->resp_resources;
@@ -1817,7 +1818,7 @@ static int cm_rep_handler(struct cm_work *work)
1817 return -EINVAL; 1818 return -EINVAL;
1818 } 1819 }
1819 1820
1820 cm_format_rep_event(work); 1821 cm_format_rep_event(work, cm_id_priv->qp_type);
1821 1822
1822 spin_lock_irq(&cm_id_priv->lock); 1823 spin_lock_irq(&cm_id_priv->lock);
1823 switch (cm_id_priv->id.state) { 1824 switch (cm_id_priv->id.state) {
@@ -1832,7 +1833,7 @@ static int cm_rep_handler(struct cm_work *work)
1832 1833
1833 cm_id_priv->timewait_info->work.remote_id = rep_msg->local_comm_id; 1834 cm_id_priv->timewait_info->work.remote_id = rep_msg->local_comm_id;
1834 cm_id_priv->timewait_info->remote_ca_guid = rep_msg->local_ca_guid; 1835 cm_id_priv->timewait_info->remote_ca_guid = rep_msg->local_ca_guid;
1835 cm_id_priv->timewait_info->remote_qpn = cm_rep_get_local_qpn(rep_msg); 1836 cm_id_priv->timewait_info->remote_qpn = cm_rep_get_qpn(rep_msg, cm_id_priv->qp_type);
1836 1837
1837 spin_lock(&cm.lock); 1838 spin_lock(&cm.lock);
1838 /* Check for duplicate REP. */ 1839 /* Check for duplicate REP. */
@@ -1859,7 +1860,7 @@ static int cm_rep_handler(struct cm_work *work)
1859 1860
1860 cm_id_priv->id.state = IB_CM_REP_RCVD; 1861 cm_id_priv->id.state = IB_CM_REP_RCVD;
1861 cm_id_priv->id.remote_id = rep_msg->local_comm_id; 1862 cm_id_priv->id.remote_id = rep_msg->local_comm_id;
1862 cm_id_priv->remote_qpn = cm_rep_get_local_qpn(rep_msg); 1863 cm_id_priv->remote_qpn = cm_rep_get_qpn(rep_msg, cm_id_priv->qp_type);
1863 cm_id_priv->initiator_depth = rep_msg->resp_resources; 1864 cm_id_priv->initiator_depth = rep_msg->resp_resources;
1864 cm_id_priv->responder_resources = rep_msg->initiator_depth; 1865 cm_id_priv->responder_resources = rep_msg->initiator_depth;
1865 cm_id_priv->sq_psn = cm_rep_get_starting_psn(rep_msg); 1866 cm_id_priv->sq_psn = cm_rep_get_starting_psn(rep_msg);
diff --git a/drivers/infiniband/core/cm_msgs.h b/drivers/infiniband/core/cm_msgs.h
index 3ade3202597..505db2a59e7 100644
--- a/drivers/infiniband/core/cm_msgs.h
+++ b/drivers/infiniband/core/cm_msgs.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2004 Intel Corporation. All rights reserved. 2 * Copyright (c) 2004, 2011 Intel Corporation. All rights reserved.
3 * Copyright (c) 2004 Topspin Corporation. All rights reserved. 3 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
4 * Copyright (c) 2004 Voltaire Corporation. All rights reserved. 4 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.
5 * 5 *
@@ -538,6 +538,23 @@ static inline void cm_rep_set_local_qpn(struct cm_rep_msg *rep_msg, __be32 qpn)
538 (be32_to_cpu(rep_msg->offset12) & 0x000000FF)); 538 (be32_to_cpu(rep_msg->offset12) & 0x000000FF));
539} 539}
540 540
541static inline __be32 cm_rep_get_local_eecn(struct cm_rep_msg *rep_msg)
542{
543 return cpu_to_be32(be32_to_cpu(rep_msg->offset16) >> 8);
544}
545
546static inline void cm_rep_set_local_eecn(struct cm_rep_msg *rep_msg, __be32 eecn)
547{
548 rep_msg->offset16 = cpu_to_be32((be32_to_cpu(eecn) << 8) |
549 (be32_to_cpu(rep_msg->offset16) & 0x000000FF));
550}
551
552static inline __be32 cm_rep_get_qpn(struct cm_rep_msg *rep_msg, enum ib_qp_type qp_type)
553{
554 return (qp_type == IB_QPT_XRC_INI) ?
555 cm_rep_get_local_eecn(rep_msg) : cm_rep_get_local_qpn(rep_msg);
556}
557
541static inline __be32 cm_rep_get_starting_psn(struct cm_rep_msg *rep_msg) 558static inline __be32 cm_rep_get_starting_psn(struct cm_rep_msg *rep_msg)
542{ 559{
543 return cpu_to_be32(be32_to_cpu(rep_msg->offset20) >> 8); 560 return cpu_to_be32(be32_to_cpu(rep_msg->offset20) >> 8);