Commit e90d0b3d authored by Joachim Fenkes's avatar Joachim Fenkes Committed by Roland Dreier

IB/ehca: Path migration support

Fix some modify_qp() issues related to path migration.
Signed-off-by: default avatarJoachim Fenkes <fenkes@de.ibm.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent b708fba3
...@@ -294,8 +294,8 @@ static void parse_identifier(struct ehca_shca *shca, u64 eqe) ...@@ -294,8 +294,8 @@ static void parse_identifier(struct ehca_shca *shca, u64 eqe)
case 0x11: /* unaffiliated access error */ case 0x11: /* unaffiliated access error */
ehca_err(&shca->ib_device, "Unaffiliated access error."); ehca_err(&shca->ib_device, "Unaffiliated access error.");
break; break;
case 0x12: /* path migrating error */ case 0x12: /* path migrating */
ehca_err(&shca->ib_device, "Path migration error."); ehca_err(&shca->ib_device, "Path migrating.");
break; break;
case 0x13: /* interface trace stopped */ case 0x13: /* interface trace stopped */
ehca_err(&shca->ib_device, "Interface trace stopped."); ehca_err(&shca->ib_device, "Interface trace stopped.");
......
...@@ -1165,6 +1165,13 @@ static int internal_modify_qp(struct ib_qp *ibqp, ...@@ -1165,6 +1165,13 @@ static int internal_modify_qp(struct ib_qp *ibqp,
} }
if (attr_mask & IB_QP_PKEY_INDEX) { if (attr_mask & IB_QP_PKEY_INDEX) {
if (attr->pkey_index >= 16) {
ret = -EINVAL;
ehca_err(ibqp->device, "Invalid pkey_index=%x. "
"ehca_qp=%p qp_num=%x max_pkey_index=f",
attr->pkey_index, my_qp, ibqp->qp_num);
goto modify_qp_exit2;
}
mqpcb->prim_p_key_idx = attr->pkey_index; mqpcb->prim_p_key_idx = attr->pkey_index;
update_mask |= EHCA_BMASK_SET(MQPCB_MASK_PRIM_P_KEY_IDX, 1); update_mask |= EHCA_BMASK_SET(MQPCB_MASK_PRIM_P_KEY_IDX, 1);
} }
...@@ -1273,50 +1280,78 @@ static int internal_modify_qp(struct ib_qp *ibqp, ...@@ -1273,50 +1280,78 @@ static int internal_modify_qp(struct ib_qp *ibqp,
int ehca_mult = ib_rate_to_mult( int ehca_mult = ib_rate_to_mult(
shca->sport[my_qp->init_attr.port_num].rate); shca->sport[my_qp->init_attr.port_num].rate);
if (attr->alt_port_num < 1
|| attr->alt_port_num > shca->num_ports) {
ret = -EINVAL;
ehca_err(ibqp->device, "Invalid alt_port=%x. "
"ehca_qp=%p qp_num=%x num_ports=%x",
attr->alt_port_num, my_qp, ibqp->qp_num,
shca->num_ports);
goto modify_qp_exit2;
}
mqpcb->alt_phys_port = attr->alt_port_num;
if (attr->alt_pkey_index >= 16) {
ret = -EINVAL;
ehca_err(ibqp->device, "Invalid alt_pkey_index=%x. "
"ehca_qp=%p qp_num=%x max_pkey_index=f",
attr->pkey_index, my_qp, ibqp->qp_num);
goto modify_qp_exit2;
}
mqpcb->alt_p_key_idx = attr->alt_pkey_index;
mqpcb->timeout_al = attr->alt_timeout;
mqpcb->dlid_al = attr->alt_ah_attr.dlid; mqpcb->dlid_al = attr->alt_ah_attr.dlid;
update_mask |= EHCA_BMASK_SET(MQPCB_MASK_DLID_AL, 1);
mqpcb->source_path_bits_al = attr->alt_ah_attr.src_path_bits; mqpcb->source_path_bits_al = attr->alt_ah_attr.src_path_bits;
update_mask |=
EHCA_BMASK_SET(MQPCB_MASK_SOURCE_PATH_BITS_AL, 1);
mqpcb->service_level_al = attr->alt_ah_attr.sl; mqpcb->service_level_al = attr->alt_ah_attr.sl;
update_mask |= EHCA_BMASK_SET(MQPCB_MASK_SERVICE_LEVEL_AL, 1);
if (ah_mult < ehca_mult) if (ah_mult > 0 && ah_mult < ehca_mult)
mqpcb->max_static_rate = (ah_mult > 0) ? mqpcb->max_static_rate_al = (ehca_mult - 1) / ah_mult;
((ehca_mult - 1) / ah_mult) : 0;
else else
mqpcb->max_static_rate_al = 0; mqpcb->max_static_rate_al = 0;
update_mask |= EHCA_BMASK_SET(MQPCB_MASK_MAX_STATIC_RATE_AL, 1); /* OpenIB doesn't support alternate retry counts - copy them */
mqpcb->retry_count_al = mqpcb->retry_count;
mqpcb->rnr_retry_count_al = mqpcb->rnr_retry_count;
update_mask |= EHCA_BMASK_SET(MQPCB_MASK_ALT_PHYS_PORT, 1)
| EHCA_BMASK_SET(MQPCB_MASK_ALT_P_KEY_IDX, 1)
| EHCA_BMASK_SET(MQPCB_MASK_TIMEOUT_AL, 1)
| EHCA_BMASK_SET(MQPCB_MASK_DLID_AL, 1)
| EHCA_BMASK_SET(MQPCB_MASK_SOURCE_PATH_BITS_AL, 1)
| EHCA_BMASK_SET(MQPCB_MASK_SERVICE_LEVEL_AL, 1)
| EHCA_BMASK_SET(MQPCB_MASK_MAX_STATIC_RATE_AL, 1)
| EHCA_BMASK_SET(MQPCB_MASK_RETRY_COUNT_AL, 1)
| EHCA_BMASK_SET(MQPCB_MASK_RNR_RETRY_COUNT_AL, 1);
/*
* Always supply the GRH flag, even if it's zero, to give the
* hypervisor a clear "yes" or "no" instead of a "perhaps"
*/
update_mask |= EHCA_BMASK_SET(MQPCB_MASK_SEND_GRH_FLAG_AL, 1);
/* /*
* only if GRH is TRUE we might consider SOURCE_GID_IDX * only if GRH is TRUE we might consider SOURCE_GID_IDX
* and DEST_GID otherwise phype will return H_ATTR_PARM!!! * and DEST_GID otherwise phype will return H_ATTR_PARM!!!
*/ */
if (attr->alt_ah_attr.ah_flags == IB_AH_GRH) { if (attr->alt_ah_attr.ah_flags == IB_AH_GRH) {
mqpcb->send_grh_flag_al = 1 << 31; mqpcb->send_grh_flag_al = 1;
update_mask |=
EHCA_BMASK_SET(MQPCB_MASK_SEND_GRH_FLAG_AL, 1);
mqpcb->source_gid_idx_al =
attr->alt_ah_attr.grh.sgid_index;
update_mask |=
EHCA_BMASK_SET(MQPCB_MASK_SOURCE_GID_IDX_AL, 1);
for (cnt = 0; cnt < 16; cnt++) for (cnt = 0; cnt < 16; cnt++)
mqpcb->dest_gid_al.byte[cnt] = mqpcb->dest_gid_al.byte[cnt] =
attr->alt_ah_attr.grh.dgid.raw[cnt]; attr->alt_ah_attr.grh.dgid.raw[cnt];
mqpcb->source_gid_idx_al =
update_mask |= attr->alt_ah_attr.grh.sgid_index;
EHCA_BMASK_SET(MQPCB_MASK_DEST_GID_AL, 1);
mqpcb->flow_label_al = attr->alt_ah_attr.grh.flow_label; mqpcb->flow_label_al = attr->alt_ah_attr.grh.flow_label;
update_mask |=
EHCA_BMASK_SET(MQPCB_MASK_FLOW_LABEL_AL, 1);
mqpcb->hop_limit_al = attr->alt_ah_attr.grh.hop_limit; mqpcb->hop_limit_al = attr->alt_ah_attr.grh.hop_limit;
update_mask |=
EHCA_BMASK_SET(MQPCB_MASK_HOP_LIMIT_AL, 1);
mqpcb->traffic_class_al = mqpcb->traffic_class_al =
attr->alt_ah_attr.grh.traffic_class; attr->alt_ah_attr.grh.traffic_class;
update_mask |= update_mask |=
EHCA_BMASK_SET(MQPCB_MASK_SOURCE_GID_IDX_AL, 1)
| EHCA_BMASK_SET(MQPCB_MASK_DEST_GID_AL, 1)
| EHCA_BMASK_SET(MQPCB_MASK_FLOW_LABEL_AL, 1)
| EHCA_BMASK_SET(MQPCB_MASK_HOP_LIMIT_AL, 1) |
EHCA_BMASK_SET(MQPCB_MASK_TRAFFIC_CLASS_AL, 1); EHCA_BMASK_SET(MQPCB_MASK_TRAFFIC_CLASS_AL, 1);
} }
} }
...@@ -1338,7 +1373,14 @@ static int internal_modify_qp(struct ib_qp *ibqp, ...@@ -1338,7 +1373,14 @@ static int internal_modify_qp(struct ib_qp *ibqp,
} }
if (attr_mask & IB_QP_PATH_MIG_STATE) { if (attr_mask & IB_QP_PATH_MIG_STATE) {
mqpcb->path_migration_state = attr->path_mig_state; if (attr->path_mig_state != IB_MIG_REARM
&& attr->path_mig_state != IB_MIG_MIGRATED) {
ret = -EINVAL;
ehca_err(ibqp->device, "Invalid mig_state=%x",
attr->path_mig_state);
goto modify_qp_exit2;
}
mqpcb->path_migration_state = attr->path_mig_state + 1;
update_mask |= update_mask |=
EHCA_BMASK_SET(MQPCB_MASK_PATH_MIGRATION_STATE, 1); EHCA_BMASK_SET(MQPCB_MASK_PATH_MIGRATION_STATE, 1);
} }
...@@ -1506,7 +1548,7 @@ int ehca_query_qp(struct ib_qp *qp, ...@@ -1506,7 +1548,7 @@ int ehca_query_qp(struct ib_qp *qp,
qp_attr->qkey = qpcb->qkey; qp_attr->qkey = qpcb->qkey;
qp_attr->path_mtu = qpcb->path_mtu; qp_attr->path_mtu = qpcb->path_mtu;
qp_attr->path_mig_state = qpcb->path_migration_state; qp_attr->path_mig_state = qpcb->path_migration_state - 1;
qp_attr->rq_psn = qpcb->receive_psn; qp_attr->rq_psn = qpcb->receive_psn;
qp_attr->sq_psn = qpcb->send_psn; qp_attr->sq_psn = qpcb->send_psn;
qp_attr->min_rnr_timer = qpcb->min_rnr_nak_timer_field; qp_attr->min_rnr_timer = qpcb->min_rnr_nak_timer_field;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment