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

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

IB/ehca: Construct MAD redirect replies from request MAD



The old code used a lot of hard-coded values, which might not be valid
in all environments (especially routed fabrics or partitioned
subnets).  Copy as much information as possible from the incoming
request to correct that.

Signed-off-by: default avatarJoachim Fenkes <fenkes@de.ibm.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 50d40b8e
Loading
Loading
Loading
Loading
+41 −6
Original line number Diff line number Diff line
@@ -125,14 +125,30 @@ struct ib_perf {
	u8 data[192];
} __attribute__ ((packed));

/* TC/SL/FL packed into 32 bits, as in ClassPortInfo */
struct tcslfl {
	u32 tc:8;
	u32 sl:4;
	u32 fl:20;
} __attribute__ ((packed));

/* IP Version/TC/FL packed into 32 bits, as in GRH */
struct vertcfl {
	u32 ver:4;
	u32 tc:8;
	u32 fl:20;
} __attribute__ ((packed));

static int ehca_process_perf(struct ib_device *ibdev, u8 port_num,
			     struct ib_wc *in_wc, struct ib_grh *in_grh,
			     struct ib_mad *in_mad, struct ib_mad *out_mad)
{
	struct ib_perf *in_perf = (struct ib_perf *)in_mad;
	struct ib_perf *out_perf = (struct ib_perf *)out_mad;
	struct ib_class_port_info *poi =
		(struct ib_class_port_info *)out_perf->data;
	struct tcslfl *tcslfl =
		(struct tcslfl *)&poi->redirect_tcslfl;
	struct ehca_shca *shca =
		container_of(ibdev, struct ehca_shca, ib_device);
	struct ehca_sport *sport = &shca->sport[port_num - 1];
@@ -158,10 +174,29 @@ static int ehca_process_perf(struct ib_device *ibdev, u8 port_num,
		poi->base_version = 1;
		poi->class_version = 1;
		poi->resp_time_value = 18;
		poi->redirect_lid = sport->saved_attr.lid;

		/* copy local routing information from WC where applicable */
		tcslfl->sl         = in_wc->sl;
		poi->redirect_lid  =
			sport->saved_attr.lid | in_wc->dlid_path_bits;
		poi->redirect_qp   = sport->pma_qp_nr;
		poi->redirect_qkey = IB_QP1_QKEY;
		poi->redirect_pkey = IB_DEFAULT_PKEY_FULL;

		ehca_query_pkey(ibdev, port_num, in_wc->pkey_index,
				&poi->redirect_pkey);

		/* if request was globally routed, copy route info */
		if (in_grh) {
			struct vertcfl *vertcfl =
				(struct vertcfl *)&in_grh->version_tclass_flow;
			memcpy(poi->redirect_gid, in_grh->dgid.raw,
			       sizeof(poi->redirect_gid));
			tcslfl->tc        = vertcfl->tc;
			tcslfl->fl        = vertcfl->fl;
		} else
			/* else only fill in default GID */
			ehca_query_gid(ibdev, port_num, 0,
				       (union ib_gid *)&poi->redirect_gid);

		ehca_dbg(ibdev, "ehca_pma_lid=%x ehca_pma_qp=%x",
			 sport->saved_attr.lid, sport->pma_qp_nr);
@@ -183,8 +218,7 @@ static int ehca_process_perf(struct ib_device *ibdev, u8 port_num,

int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
		     struct ib_wc *in_wc, struct ib_grh *in_grh,
		     struct ib_mad *in_mad,
		     struct ib_mad *out_mad)
		     struct ib_mad *in_mad, struct ib_mad *out_mad)
{
	int ret;

@@ -196,7 +230,8 @@ int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
		return IB_MAD_RESULT_SUCCESS;

	ehca_dbg(ibdev, "port_num=%x src_qp=%x", port_num, in_wc->src_qp);
	ret = ehca_process_perf(ibdev, port_num, in_mad, out_mad);
	ret = ehca_process_perf(ibdev, port_num, in_wc, in_grh,
				in_mad, out_mad);

	return ret;
}