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

Commit f91e6d89 authored by Eran Ben Elisha's avatar Eran Ben Elisha Committed by Doug Ledford
Browse files

net/mlx5_core: Add setting ATOMIC endian mode



HW is capable of 2 requestor endianness modes for standard 8 Bytes
atomic: BE (0x0) and host endianness (0x1). Read the supported modes
from hca atomic capabilities and configure HW to host endianness mode if
supported.

Signed-off-by: default avatarEran Ben Elisha <eranbe@mellanox.com>
Reviewed-by: default avatarYishai Hadas <yishaih@mellanox.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 67f1aee6
Loading
Loading
Loading
Loading
+55 −2
Original line number Diff line number Diff line
@@ -74,6 +74,11 @@ struct mlx5_device_context {
	void		       *context;
};

enum {
	MLX5_ATOMIC_REQ_MODE_BE = 0x0,
	MLX5_ATOMIC_REQ_MODE_HOST_ENDIANNESS = 0x1,
};

static struct mlx5_profile profile[] = {
	[0] = {
		.mask           = 0,
@@ -383,7 +388,7 @@ int mlx5_core_get_caps(struct mlx5_core_dev *dev, enum mlx5_cap_type cap_type,
	return err;
}

static int set_caps(struct mlx5_core_dev *dev, void *in, int in_sz)
static int set_caps(struct mlx5_core_dev *dev, void *in, int in_sz, int opmod)
{
	u32 out[MLX5_ST_SZ_DW(set_hca_cap_out)];
	int err;
@@ -391,6 +396,7 @@ static int set_caps(struct mlx5_core_dev *dev, void *in, int in_sz)
	memset(out, 0, sizeof(out));

	MLX5_SET(set_hca_cap_in, in, opcode, MLX5_CMD_OP_SET_HCA_CAP);
	MLX5_SET(set_hca_cap_in, in, op_mod, opmod << 1);
	err = mlx5_cmd_exec(dev, in, in_sz, out, sizeof(out));
	if (err)
		return err;
@@ -400,6 +406,46 @@ static int set_caps(struct mlx5_core_dev *dev, void *in, int in_sz)
	return err;
}

static int handle_hca_cap_atomic(struct mlx5_core_dev *dev)
{
	void *set_ctx;
	void *set_hca_cap;
	int set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in);
	int req_endianness;
	int err;

	if (MLX5_CAP_GEN(dev, atomic)) {
		err = mlx5_core_get_caps(dev, MLX5_CAP_ATOMIC,
					 HCA_CAP_OPMOD_GET_CUR);
		if (err)
			return err;
	} else {
		return 0;
	}

	req_endianness =
		MLX5_CAP_ATOMIC(dev,
				supported_atomic_req_8B_endianess_mode_1);

	if (req_endianness != MLX5_ATOMIC_REQ_MODE_HOST_ENDIANNESS)
		return 0;

	set_ctx = kzalloc(set_sz, GFP_KERNEL);
	if (!set_ctx)
		return -ENOMEM;

	set_hca_cap = MLX5_ADDR_OF(set_hca_cap_in, set_ctx, capability);

	/* Set requestor to host endianness */
	MLX5_SET(atomic_caps, set_hca_cap, atomic_req_8B_endianess_mode,
		 MLX5_ATOMIC_REQ_MODE_HOST_ENDIANNESS);

	err = set_caps(dev, set_ctx, set_sz, MLX5_SET_HCA_CAP_OP_MOD_ATOMIC);

	kfree(set_ctx);
	return err;
}

static int handle_hca_cap(struct mlx5_core_dev *dev)
{
	void *set_ctx = NULL;
@@ -441,7 +487,8 @@ static int handle_hca_cap(struct mlx5_core_dev *dev)

	MLX5_SET(cmd_hca_cap, set_hca_cap, log_uar_page_sz, PAGE_SHIFT - 12);

	err = set_caps(dev, set_ctx, set_sz);
	err = set_caps(dev, set_ctx, set_sz,
		       MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE);

query_ex:
	kfree(set_ctx);
@@ -974,6 +1021,12 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
		goto reclaim_boot_pages;
	}

	err = handle_hca_cap_atomic(dev);
	if (err) {
		dev_err(&pdev->dev, "handle_hca_cap_atomic failed\n");
		goto reclaim_boot_pages;
	}

	err = mlx5_satisfy_startup_pages(dev, 0);
	if (err) {
		dev_err(&pdev->dev, "failed to allocate init pages\n");
+15 −7
Original line number Diff line number Diff line
@@ -66,6 +66,11 @@ enum {
	MLX5_MODIFY_TIR_BITMASK_TUNNELED_OFFLOAD_EN   = 0x3
};

enum {
	MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE        = 0x0,
	MLX5_SET_HCA_CAP_OP_MOD_ATOMIC                = 0x3,
};

enum {
	MLX5_CMD_OP_QUERY_HCA_CAP                 = 0x100,
	MLX5_CMD_OP_QUERY_ADAPTER                 = 0x101,
@@ -527,21 +532,24 @@ enum {
struct mlx5_ifc_atomic_caps_bits {
	u8         reserved_0[0x40];

	u8         atomic_req_endianness[0x1];
	u8         reserved_1[0x1f];
	u8         atomic_req_8B_endianess_mode[0x2];
	u8         reserved_1[0x4];
	u8         supported_atomic_req_8B_endianess_mode_1[0x1];

	u8         reserved_2[0x20];
	u8         reserved_2[0x19];

	u8         reserved_3[0x10];
	u8         atomic_operations[0x10];
	u8         reserved_3[0x20];

	u8         reserved_4[0x10];
	u8         atomic_size_qp[0x10];
	u8         atomic_operations[0x10];

	u8         reserved_5[0x10];
	u8         atomic_size_qp[0x10];

	u8         reserved_6[0x10];
	u8         atomic_size_dc[0x10];

	u8         reserved_6[0x720];
	u8         reserved_7[0x720];
};

struct mlx5_ifc_odp_cap_bits {