mlx5: Clear reserved area in set_hca_cap()

Firmware spec requires reserved fields to be cleared when calling
set_hca_cap.  Current code queries and copy to the set area, possibly
resulting in reserved bits not cleared. This patch copies only
writable fields to the set area.

Fix also typo - msx => max

Signed-off-by: Eli Cohen <eli@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
Eli Cohen 2013-10-23 09:53:20 +03:00 committed by Roland Dreier
parent bf0bf77f65
commit 87b8de492d
2 changed files with 39 additions and 5 deletions

View File

@ -159,6 +159,36 @@ struct mlx5_reg_host_endianess {
u8 rsvd[15];
};
#define CAP_MASK(pos, size) ((u64)((1 << (size)) - 1) << (pos))
enum {
MLX5_CAP_BITS_RW_MASK = CAP_MASK(MLX5_CAP_OFF_CMDIF_CSUM, 2) |
CAP_MASK(MLX5_CAP_OFF_DCT, 1),
};
/* selectively copy writable fields clearing any reserved area
*/
static void copy_rw_fields(struct mlx5_hca_cap *to, struct mlx5_hca_cap *from)
{
u64 v64;
to->log_max_qp = from->log_max_qp & 0x1f;
to->log_max_ra_req_dc = from->log_max_ra_req_dc & 0x3f;
to->log_max_ra_res_dc = from->log_max_ra_res_dc & 0x3f;
to->log_max_ra_req_qp = from->log_max_ra_req_qp & 0x3f;
to->log_max_ra_res_qp = from->log_max_ra_res_qp & 0x3f;
to->log_max_atomic_size_qp = from->log_max_atomic_size_qp;
to->log_max_atomic_size_dc = from->log_max_atomic_size_dc;
v64 = be64_to_cpu(from->flags) & MLX5_CAP_BITS_RW_MASK;
to->flags = cpu_to_be64(v64);
}
enum {
HCA_CAP_OPMOD_GET_MAX = 0,
HCA_CAP_OPMOD_GET_CUR = 1,
};
static int handle_hca_cap(struct mlx5_core_dev *dev)
{
struct mlx5_cmd_query_hca_cap_mbox_out *query_out = NULL;
@ -180,7 +210,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev)
}
query_ctx.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_HCA_CAP);
query_ctx.hdr.opmod = cpu_to_be16(0x1);
query_ctx.hdr.opmod = cpu_to_be16(HCA_CAP_OPMOD_GET_CUR);
err = mlx5_cmd_exec(dev, &query_ctx, sizeof(query_ctx),
query_out, sizeof(*query_out));
if (err)
@ -192,8 +222,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev)
goto query_ex;
}
memcpy(&set_ctx->hca_cap, &query_out->hca_cap,
sizeof(set_ctx->hca_cap));
copy_rw_fields(&set_ctx->hca_cap, &query_out->hca_cap);
if (dev->profile->mask & MLX5_PROF_MASK_QP_SIZE)
set_ctx->hca_cap.log_max_qp = dev->profile->log_max_qp;

View File

@ -230,6 +230,11 @@ enum {
MLX5_MAX_PAGE_SHIFT = 31
};
enum {
MLX5_CAP_OFF_DCT = 41,
MLX5_CAP_OFF_CMDIF_CSUM = 46,
};
struct mlx5_inbox_hdr {
__be16 opcode;
u8 rsvd[4];
@ -319,9 +324,9 @@ struct mlx5_hca_cap {
u8 rsvd25[42];
__be16 log_uar_page_sz;
u8 rsvd26[28];
u8 log_msx_atomic_size_qp;
u8 log_max_atomic_size_qp;
u8 rsvd27[2];
u8 log_msx_atomic_size_dc;
u8 log_max_atomic_size_dc;
u8 rsvd28[76];
};