#include <rdma/ib_cache.h>
#include <rdma/ib_cm.h>
#include "cm_msgs.h"
+#include "core_priv.h"
MODULE_AUTHOR("Sean Hefty");
MODULE_DESCRIPTION("InfiniBand CM");
rb_erase(&timewait_info->remote_qp_node, &cm.remote_qp_table);
timewait_info->inserted_remote_qp = 0;
}
+
+ /* Clean-up the overloaded MBIT */
+ if (timewait_info->remote_ca_guid & IB_GUID_MBIT)
+ timewait_info->remote_ca_guid &= ~IB_GUID_MBIT;
}
static struct cm_timewait_info * cm_create_timewait_info(__be32 local_id)
hdr->tid = tid;
}
+#define SIF_DEVICES 6
+const u32 sif_family_vendor_part_id[SIF_DEVICES] = {
+ 0x2088, 0x2089, 0x2188, 0x2189, 0x2198, 0x2199};
+
+static inline bool is_vendor_sif_family(u32 part_id)
+{
+ int i;
+
+ for (i = 0; i < SIF_DEVICES; i++) {
+ if (part_id == sif_family_vendor_part_id[i])
+ return true;
+ }
+ return false;
+}
+
static void cm_format_req(struct cm_req_msg *req_msg,
struct cm_id_private *cm_id_priv,
struct ib_cm_req_param *param)
{
struct ib_sa_path_rec *pri_path = param->primary_path;
struct ib_sa_path_rec *alt_path = param->alternate_path;
+ struct ib_device_attr attr;
+ u32 vendor_part_id;
+
+ if (ib_query_device(cm_id_priv->id.device, &attr))
+ vendor_part_id = 0;
+ else
+ vendor_part_id = attr.vendor_part_id;
cm_format_mad_hdr(&req_msg->hdr, CM_REQ_ATTR_ID,
cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_REQ));
req_msg->local_comm_id = cm_id_priv->id.local_id;
req_msg->service_id = param->service_id;
- req_msg->local_ca_guid = cm_id_priv->id.device->node_guid;
+
+ if (is_vendor_sif_family(vendor_part_id))
+ req_msg->local_ca_guid = cm_id_priv->id.device->node_guid | IB_GUID_MBIT;
+ else
+ req_msg->local_ca_guid = cm_id_priv->id.device->node_guid;
+
cm_req_set_local_qpn(req_msg, cpu_to_be32(param->qp_num));
cm_req_set_init_depth(req_msg, param->initiator_depth);
cm_req_set_remote_resp_timeout(req_msg,
struct cm_id_private *cm_id_priv,
struct ib_cm_rep_param *param)
{
+ struct ib_device_attr attr;
+ u32 vendor_part_id;
+
+ if (ib_query_device(cm_id_priv->id.device, &attr))
+ vendor_part_id = 0;
+ else
+ vendor_part_id = attr.vendor_part_id;
+
cm_format_mad_hdr(&rep_msg->hdr, CM_REP_ATTR_ID, cm_id_priv->tid);
rep_msg->local_comm_id = cm_id_priv->id.local_id;
rep_msg->remote_comm_id = cm_id_priv->id.remote_id;
cm_id_priv->av.port->cm_dev->ack_delay);
cm_rep_set_failover(rep_msg, param->failover_accepted);
cm_rep_set_rnr_retry_count(rep_msg, param->rnr_retry_count);
- rep_msg->local_ca_guid = cm_id_priv->id.device->node_guid;
+
+ if (is_vendor_sif_family(vendor_part_id))
+ rep_msg->local_ca_guid = cm_id_priv->id.device->node_guid | IB_GUID_MBIT;
+ else
+ rep_msg->local_ca_guid = cm_id_priv->id.device->node_guid;
if (cm_id_priv->qp_type != IB_QPT_XRC_TGT) {
rep_msg->initiator_depth = param->initiator_depth;
{
unsigned long flags;
int ret;
+ u64 remote_guid;
+
+ remote_guid = cm_id_priv->timewait_info->remote_ca_guid;
spin_lock_irqsave(&cm_id_priv->lock, flags);
switch (cm_id_priv->id.state) {
case IB_CM_ESTABLISHED:
*qp_attr_mask = IB_QP_STATE | IB_QP_ACCESS_FLAGS |
IB_QP_PKEY_INDEX | IB_QP_PORT;
+
qp_attr->qp_access_flags = IB_ACCESS_REMOTE_WRITE;
+
+ if (remote_guid & IB_GUID_MBIT)
+ qp_attr->qp_access_flags |= IB_GUID_RNR_TWEAK;
+
if (cm_id_priv->responder_resources)
qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_READ |
IB_ACCESS_REMOTE_ATOMIC;
module_init(ib_cm_init);
module_exit(ib_cm_cleanup);
-
return ret ? ret : in_len;
}
+const u8 ib_uverbs_rnr_timeout_sif[32] = {
+ 0, 18, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
ret = ib_resolve_eth_l2_attrs(qp, attr, &cmd.attr_mask);
if (ret)
goto release_qp;
+
+ if ((cmd.attr_mask & IB_QP_STATE) &&
+ (attr->qp_state == IB_QPS_INIT) &&
+ (attr->qp_access_flags & IB_GUID_RNR_TWEAK))
+ qp->qp_flag |= IB_GUID_RNR_TWEAK;
+
+ if ((qp->qp_flag & IB_GUID_RNR_TWEAK) &&
+ (cmd.attr_mask & IB_QP_MIN_RNR_TIMER))
+ attr->min_rnr_timer = ib_uverbs_rnr_timeout_sif[attr->min_rnr_timer];
+
ret = qp->device->modify_qp(qp, attr, cmd.attr_mask, &udata);
} else {
ret = ib_modify_qp(qp, attr, cmd.attr_mask);
}
EXPORT_SYMBOL(ib_resolve_eth_l2_attrs);
+const u8 ib_rnr_timeout_sif[32] = {
+ 0, 18, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
int ib_modify_qp(struct ib_qp *qp,
struct ib_qp_attr *qp_attr,
int qp_attr_mask)
{
+ u8 idx = qp_attr->min_rnr_timer;
int ret;
ret = ib_resolve_eth_l2_attrs(qp, qp_attr, &qp_attr_mask);
if (ret)
return ret;
+ if ((qp_attr_mask & IB_QP_STATE) &&
+ (qp_attr->qp_state == IB_QPS_INIT) &&
+ (qp_attr->qp_access_flags & IB_GUID_RNR_TWEAK))
+ qp->qp_flag |= IB_GUID_RNR_TWEAK;
+
+ if ((qp->qp_flag & IB_GUID_RNR_TWEAK) &&
+ (qp_attr_mask & IB_QP_MIN_RNR_TIMER))
+ qp_attr->min_rnr_timer = ib_rnr_timeout_sif[idx];
+
return qp->device->modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL);
}
EXPORT_SYMBOL(ib_modify_qp);