Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -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.");
+66 −24
Original line number Original line Diff line number Diff line
@@ -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,
		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,
	}
	}


	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,


	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;