Commit ef70044647b260cb6b7863f392384a06670d0b2a

Authored by Sean Hefty
Committed by Roland Dreier
1 parent d26a360b77

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>

Showing 2 changed files with 26 additions and 8 deletions Side-by-side Diff

drivers/infiniband/core/cm.c
... ... @@ -1605,7 +1605,6 @@
1605 1605 cm_format_mad_hdr(&rep_msg->hdr, CM_REP_ATTR_ID, cm_id_priv->tid);
1606 1606 rep_msg->local_comm_id = cm_id_priv->id.local_id;
1607 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 1608 cm_rep_set_starting_psn(rep_msg, cpu_to_be32(param->starting_psn));
1610 1609 rep_msg->resp_resources = param->responder_resources;
1611 1610 cm_rep_set_target_ack_delay(rep_msg,
1612 1611  
... ... @@ -1618,8 +1617,10 @@
1618 1617 rep_msg->initiator_depth = param->initiator_depth;
1619 1618 cm_rep_set_flow_ctrl(rep_msg, param->flow_control);
1620 1619 cm_rep_set_srq(rep_msg, param->srq);
  1620 + cm_rep_set_local_qpn(rep_msg, cpu_to_be32(param->qp_num));
1621 1621 } else {
1622 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 1626 if (param->private_data && param->private_data_len)
... ... @@ -1669,7 +1670,7 @@
1669 1670 cm_id_priv->initiator_depth = param->initiator_depth;
1670 1671 cm_id_priv->responder_resources = param->responder_resources;
1671 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  
1674 1675 out: spin_unlock_irqrestore(&cm_id_priv->lock, flags);
1675 1676 return ret;
... ... @@ -1740,7 +1741,7 @@
1740 1741 }
1741 1742 EXPORT_SYMBOL(ib_send_cm_rtu);
1742 1743  
1743   -static void cm_format_rep_event(struct cm_work *work)
  1744 +static void cm_format_rep_event(struct cm_work *work, enum ib_qp_type qp_type)
1744 1745 {
1745 1746 struct cm_rep_msg *rep_msg;
1746 1747 struct ib_cm_rep_event_param *param;
... ... @@ -1749,7 +1750,7 @@
1749 1750 param = &work->cm_event.param.rep_rcvd;
1750 1751 param->remote_ca_guid = rep_msg->local_ca_guid;
1751 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 1754 param->starting_psn = be32_to_cpu(cm_rep_get_starting_psn(rep_msg));
1754 1755 param->responder_resources = rep_msg->initiator_depth;
1755 1756 param->initiator_depth = rep_msg->resp_resources;
... ... @@ -1817,7 +1818,7 @@
1817 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 1823 spin_lock_irq(&cm_id_priv->lock);
1823 1824 switch (cm_id_priv->id.state) {
... ... @@ -1832,7 +1833,7 @@
1832 1833  
1833 1834 cm_id_priv->timewait_info->work.remote_id = rep_msg->local_comm_id;
1834 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 1838 spin_lock(&cm.lock);
1838 1839 /* Check for duplicate REP. */
... ... @@ -1859,7 +1860,7 @@
1859 1860  
1860 1861 cm_id_priv->id.state = IB_CM_REP_RCVD;
1861 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 1864 cm_id_priv->initiator_depth = rep_msg->resp_resources;
1864 1865 cm_id_priv->responder_resources = rep_msg->initiator_depth;
1865 1866 cm_id_priv->sq_psn = cm_rep_get_starting_psn(rep_msg);
drivers/infiniband/core/cm_msgs.h
1 1 /*
2   - * Copyright (c) 2004 Intel Corporation. All rights reserved.
  2 + * Copyright (c) 2004, 2011 Intel Corporation. All rights reserved.
3 3 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
4 4 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.
5 5 *
... ... @@ -536,6 +536,23 @@
536 536 {
537 537 rep_msg->offset12 = cpu_to_be32((be32_to_cpu(qpn) << 8) |
538 538 (be32_to_cpu(rep_msg->offset12) & 0x000000FF));
  539 +}
  540 +
  541 +static 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 +
  546 +static 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 +
  552 +static 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);
539 556 }
540 557  
541 558 static inline __be32 cm_rep_get_starting_psn(struct cm_rep_msg *rep_msg)