|
@@ -248,6 +248,9 @@ void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (event_type == IB_EVENT_PATH_MIG)
|
|
|
|
+ qp->port = qp->alt_port;
|
|
|
|
+
|
|
event.device = &dev->ib_dev;
|
|
event.device = &dev->ib_dev;
|
|
event.event = event_type;
|
|
event.event = event_type;
|
|
event.element.qp = &qp->ibqp;
|
|
event.element.qp = &qp->ibqp;
|
|
@@ -392,10 +395,16 @@ static void to_ib_ah_attr(struct mthca_dev *dev, struct ib_ah_attr *ib_ah_attr,
|
|
{
|
|
{
|
|
memset(ib_ah_attr, 0, sizeof *path);
|
|
memset(ib_ah_attr, 0, sizeof *path);
|
|
ib_ah_attr->port_num = (be32_to_cpu(path->port_pkey) >> 24) & 0x3;
|
|
ib_ah_attr->port_num = (be32_to_cpu(path->port_pkey) >> 24) & 0x3;
|
|
|
|
+
|
|
|
|
+ if (ib_ah_attr->port_num == 0 || ib_ah_attr->port_num > dev->limits.num_ports)
|
|
|
|
+ return;
|
|
|
|
+
|
|
ib_ah_attr->dlid = be16_to_cpu(path->rlid);
|
|
ib_ah_attr->dlid = be16_to_cpu(path->rlid);
|
|
ib_ah_attr->sl = be32_to_cpu(path->sl_tclass_flowlabel) >> 28;
|
|
ib_ah_attr->sl = be32_to_cpu(path->sl_tclass_flowlabel) >> 28;
|
|
ib_ah_attr->src_path_bits = path->g_mylmc & 0x7f;
|
|
ib_ah_attr->src_path_bits = path->g_mylmc & 0x7f;
|
|
- ib_ah_attr->static_rate = path->static_rate & 0x7;
|
|
|
|
|
|
+ ib_ah_attr->static_rate = mthca_rate_to_ib(dev,
|
|
|
|
+ path->static_rate & 0x7,
|
|
|
|
+ ib_ah_attr->port_num);
|
|
ib_ah_attr->ah_flags = (path->g_mylmc & (1 << 7)) ? IB_AH_GRH : 0;
|
|
ib_ah_attr->ah_flags = (path->g_mylmc & (1 << 7)) ? IB_AH_GRH : 0;
|
|
if (ib_ah_attr->ah_flags) {
|
|
if (ib_ah_attr->ah_flags) {
|
|
ib_ah_attr->grh.sgid_index = path->mgid_index & (dev->limits.gid_table_len - 1);
|
|
ib_ah_attr->grh.sgid_index = path->mgid_index & (dev->limits.gid_table_len - 1);
|
|
@@ -455,8 +464,10 @@ int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_m
|
|
qp_attr->cap.max_recv_sge = qp->rq.max_gs;
|
|
qp_attr->cap.max_recv_sge = qp->rq.max_gs;
|
|
qp_attr->cap.max_inline_data = qp->max_inline_data;
|
|
qp_attr->cap.max_inline_data = qp->max_inline_data;
|
|
|
|
|
|
- to_ib_ah_attr(dev, &qp_attr->ah_attr, &context->pri_path);
|
|
|
|
- to_ib_ah_attr(dev, &qp_attr->alt_ah_attr, &context->alt_path);
|
|
|
|
|
|
+ if (qp->transport == RC || qp->transport == UC) {
|
|
|
|
+ to_ib_ah_attr(dev, &qp_attr->ah_attr, &context->pri_path);
|
|
|
|
+ to_ib_ah_attr(dev, &qp_attr->alt_ah_attr, &context->alt_path);
|
|
|
|
+ }
|
|
|
|
|
|
qp_attr->pkey_index = be32_to_cpu(context->pri_path.port_pkey) & 0x7f;
|
|
qp_attr->pkey_index = be32_to_cpu(context->pri_path.port_pkey) & 0x7f;
|
|
qp_attr->alt_pkey_index = be32_to_cpu(context->alt_path.port_pkey) & 0x7f;
|
|
qp_attr->alt_pkey_index = be32_to_cpu(context->alt_path.port_pkey) & 0x7f;
|
|
@@ -484,11 +495,11 @@ out:
|
|
}
|
|
}
|
|
|
|
|
|
static int mthca_path_set(struct mthca_dev *dev, struct ib_ah_attr *ah,
|
|
static int mthca_path_set(struct mthca_dev *dev, struct ib_ah_attr *ah,
|
|
- struct mthca_qp_path *path)
|
|
|
|
|
|
+ struct mthca_qp_path *path, u8 port)
|
|
{
|
|
{
|
|
path->g_mylmc = ah->src_path_bits & 0x7f;
|
|
path->g_mylmc = ah->src_path_bits & 0x7f;
|
|
path->rlid = cpu_to_be16(ah->dlid);
|
|
path->rlid = cpu_to_be16(ah->dlid);
|
|
- path->static_rate = !!ah->static_rate;
|
|
|
|
|
|
+ path->static_rate = mthca_get_rate(dev, ah->static_rate, port);
|
|
|
|
|
|
if (ah->ah_flags & IB_AH_GRH) {
|
|
if (ah->ah_flags & IB_AH_GRH) {
|
|
if (ah->grh.sgid_index >= dev->limits.gid_table_len) {
|
|
if (ah->grh.sgid_index >= dev->limits.gid_table_len) {
|
|
@@ -634,7 +645,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
|
|
|
|
|
|
if (qp->transport == MLX)
|
|
if (qp->transport == MLX)
|
|
qp_context->pri_path.port_pkey |=
|
|
qp_context->pri_path.port_pkey |=
|
|
- cpu_to_be32(to_msqp(qp)->port << 24);
|
|
|
|
|
|
+ cpu_to_be32(qp->port << 24);
|
|
else {
|
|
else {
|
|
if (attr_mask & IB_QP_PORT) {
|
|
if (attr_mask & IB_QP_PORT) {
|
|
qp_context->pri_path.port_pkey |=
|
|
qp_context->pri_path.port_pkey |=
|
|
@@ -657,7 +668,8 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
|
|
}
|
|
}
|
|
|
|
|
|
if (attr_mask & IB_QP_AV) {
|
|
if (attr_mask & IB_QP_AV) {
|
|
- if (mthca_path_set(dev, &attr->ah_attr, &qp_context->pri_path))
|
|
|
|
|
|
+ if (mthca_path_set(dev, &attr->ah_attr, &qp_context->pri_path,
|
|
|
|
+ attr_mask & IB_QP_PORT ? attr->port_num : qp->port))
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH);
|
|
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH);
|
|
@@ -681,7 +693,8 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
|
|
- if (mthca_path_set(dev, &attr->alt_ah_attr, &qp_context->alt_path))
|
|
|
|
|
|
+ if (mthca_path_set(dev, &attr->alt_ah_attr, &qp_context->alt_path,
|
|
|
|
+ attr->alt_ah_attr.port_num))
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
qp_context->alt_path.port_pkey |= cpu_to_be32(attr->alt_pkey_index |
|
|
qp_context->alt_path.port_pkey |= cpu_to_be32(attr->alt_pkey_index |
|
|
@@ -791,6 +804,10 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
|
|
qp->atomic_rd_en = attr->qp_access_flags;
|
|
qp->atomic_rd_en = attr->qp_access_flags;
|
|
if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
|
|
if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
|
|
qp->resp_depth = attr->max_dest_rd_atomic;
|
|
qp->resp_depth = attr->max_dest_rd_atomic;
|
|
|
|
+ if (attr_mask & IB_QP_PORT)
|
|
|
|
+ qp->port = attr->port_num;
|
|
|
|
+ if (attr_mask & IB_QP_ALT_PATH)
|
|
|
|
+ qp->alt_port = attr->alt_port_num;
|
|
|
|
|
|
if (is_sqp(dev, qp))
|
|
if (is_sqp(dev, qp))
|
|
store_attrs(to_msqp(qp), attr, attr_mask);
|
|
store_attrs(to_msqp(qp), attr, attr_mask);
|
|
@@ -802,13 +819,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
|
|
if (is_qp0(dev, qp)) {
|
|
if (is_qp0(dev, qp)) {
|
|
if (cur_state != IB_QPS_RTR &&
|
|
if (cur_state != IB_QPS_RTR &&
|
|
new_state == IB_QPS_RTR)
|
|
new_state == IB_QPS_RTR)
|
|
- init_port(dev, to_msqp(qp)->port);
|
|
|
|
|
|
+ init_port(dev, qp->port);
|
|
|
|
|
|
if (cur_state != IB_QPS_RESET &&
|
|
if (cur_state != IB_QPS_RESET &&
|
|
cur_state != IB_QPS_ERR &&
|
|
cur_state != IB_QPS_ERR &&
|
|
(new_state == IB_QPS_RESET ||
|
|
(new_state == IB_QPS_RESET ||
|
|
new_state == IB_QPS_ERR))
|
|
new_state == IB_QPS_ERR))
|
|
- mthca_CLOSE_IB(dev, to_msqp(qp)->port, &status);
|
|
|
|
|
|
+ mthca_CLOSE_IB(dev, qp->port, &status);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1212,6 +1229,9 @@ int mthca_alloc_qp(struct mthca_dev *dev,
|
|
if (qp->qpn == -1)
|
|
if (qp->qpn == -1)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
+ /* initialize port to zero for error-catching. */
|
|
|
|
+ qp->port = 0;
|
|
|
|
+
|
|
err = mthca_alloc_qp_common(dev, pd, send_cq, recv_cq,
|
|
err = mthca_alloc_qp_common(dev, pd, send_cq, recv_cq,
|
|
send_policy, qp);
|
|
send_policy, qp);
|
|
if (err) {
|
|
if (err) {
|
|
@@ -1261,7 +1281,7 @@ int mthca_alloc_sqp(struct mthca_dev *dev,
|
|
if (err)
|
|
if (err)
|
|
goto err_out;
|
|
goto err_out;
|
|
|
|
|
|
- sqp->port = port;
|
|
|
|
|
|
+ sqp->qp.port = port;
|
|
sqp->qp.qpn = mqpn;
|
|
sqp->qp.qpn = mqpn;
|
|
sqp->qp.transport = MLX;
|
|
sqp->qp.transport = MLX;
|
|
|
|
|
|
@@ -1404,10 +1424,10 @@ static int build_mlx_header(struct mthca_dev *dev, struct mthca_sqp *sqp,
|
|
sqp->ud_header.lrh.source_lid = IB_LID_PERMISSIVE;
|
|
sqp->ud_header.lrh.source_lid = IB_LID_PERMISSIVE;
|
|
sqp->ud_header.bth.solicited_event = !!(wr->send_flags & IB_SEND_SOLICITED);
|
|
sqp->ud_header.bth.solicited_event = !!(wr->send_flags & IB_SEND_SOLICITED);
|
|
if (!sqp->qp.ibqp.qp_num)
|
|
if (!sqp->qp.ibqp.qp_num)
|
|
- ib_get_cached_pkey(&dev->ib_dev, sqp->port,
|
|
|
|
|
|
+ ib_get_cached_pkey(&dev->ib_dev, sqp->qp.port,
|
|
sqp->pkey_index, &pkey);
|
|
sqp->pkey_index, &pkey);
|
|
else
|
|
else
|
|
- ib_get_cached_pkey(&dev->ib_dev, sqp->port,
|
|
|
|
|
|
+ ib_get_cached_pkey(&dev->ib_dev, sqp->qp.port,
|
|
wr->wr.ud.pkey_index, &pkey);
|
|
wr->wr.ud.pkey_index, &pkey);
|
|
sqp->ud_header.bth.pkey = cpu_to_be16(pkey);
|
|
sqp->ud_header.bth.pkey = cpu_to_be16(pkey);
|
|
sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->wr.ud.remote_qpn);
|
|
sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->wr.ud.remote_qpn);
|