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

Commit 9c71172c authored by Yishai Hadas's avatar Yishai Hadas Committed by Jason Gunthorpe
Browse files

IB/mlx4: Report TSO capabilities



Report to the user area the TSO device capabilities, it includes the
max_tso size and the QP types that support it.

The TSO is applicable only when when of the ports is ETH and the device
supports it.

uresp logic around rss_caps is updated to fix a till-now harmless bug
computing the length of the structure to copy. The code did not handle the
implicit padding before rss_caps correctly. This is necessay to copy
tss_caps successfully.

Reviewed-by: default avatarMark Bloch <markb@mellanox.com>
Signed-off-by: default avatarYishai Hadas <yishaih@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 546b1452
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -429,6 +429,9 @@ int mlx4_ib_gid_index_to_real_index(struct mlx4_ib_dev *ibdev,
	return real_index;
}

#define field_avail(type, fld, sz) (offsetof(type, fld) + \
				    sizeof(((type *)0)->fld) <= (sz))

static int mlx4_ib_query_device(struct ib_device *ibdev,
				struct ib_device_attr *props,
				struct ib_udata *uhw)
@@ -587,8 +590,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
			sizeof(struct mlx4_wqe_data_seg);
	}

	if (uhw->outlen >= resp.response_length + sizeof(resp.rss_caps)) {
		resp.response_length += sizeof(resp.rss_caps);
	if (field_avail(typeof(resp), rss_caps, uhw->outlen)) {
		if (props->rss_caps.supported_qpts) {
			resp.rss_caps.rx_hash_function =
				MLX4_IB_RX_HASH_FUNC_TOEPLITZ;
@@ -608,6 +610,22 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
				resp.rss_caps.rx_hash_fields_mask |=
					MLX4_IB_RX_HASH_INNER;
		}
		resp.response_length = offsetof(typeof(resp), rss_caps) +
				       sizeof(resp.rss_caps);
	}

	if (field_avail(typeof(resp), tso_caps, uhw->outlen)) {
		if (dev->dev->caps.max_gso_sz &&
		    ((mlx4_ib_port_link_layer(ibdev, 1) ==
		    IB_LINK_LAYER_ETHERNET) ||
		    (mlx4_ib_port_link_layer(ibdev, 2) ==
		    IB_LINK_LAYER_ETHERNET))) {
			resp.tso_caps.max_tso = dev->dev->caps.max_gso_sz;
			resp.tso_caps.supported_qpts |=
				1 << IB_QPT_RAW_PACKET;
		}
		resp.response_length = offsetof(typeof(resp), tso_caps) +
				       sizeof(resp.tso_caps);
	}

	if (uhw->outlen) {
+9 −0
Original line number Diff line number Diff line
@@ -170,12 +170,21 @@ enum query_device_resp_mask {
	MLX4_IB_QUERY_DEV_RESP_MASK_CORE_CLOCK_OFFSET = 1UL << 0,
};

struct mlx4_ib_tso_caps {
	__u32 max_tso; /* Maximum tso payload size in bytes */
	/* Corresponding bit will be set if qp type from
	 * 'enum ib_qp_type' is supported.
	 */
	__u32 supported_qpts;
};

struct mlx4_uverbs_ex_query_device_resp {
	__u32			comp_mask;
	__u32			response_length;
	__u64			hca_core_clock_offset;
	__u32			max_inl_recv_sz;
	struct mlx4_ib_rss_caps	rss_caps;
	struct mlx4_ib_tso_caps tso_caps;
};

#endif /* MLX4_ABI_USER_H */