diff options
author | Eli Cohen <eli@dev.mellanox.co.il> | 2013-10-23 02:53:20 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2013-11-08 17:43:00 -0500 |
commit | 87b8de492da34942fc554f2958a570ce0642296a (patch) | |
tree | 5fe03a23cd2a785eba1a20280354abe5bc8218f2 /drivers/net | |
parent | bf0bf77f6519e5dcd57a77b47e1d151c1e81b7ec (diff) |
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>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/main.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index bc0f5fb66e24..40a9f5ed814d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c | |||
@@ -159,6 +159,36 @@ struct mlx5_reg_host_endianess { | |||
159 | u8 rsvd[15]; | 159 | u8 rsvd[15]; |
160 | }; | 160 | }; |
161 | 161 | ||
162 | |||
163 | #define CAP_MASK(pos, size) ((u64)((1 << (size)) - 1) << (pos)) | ||
164 | |||
165 | enum { | ||
166 | MLX5_CAP_BITS_RW_MASK = CAP_MASK(MLX5_CAP_OFF_CMDIF_CSUM, 2) | | ||
167 | CAP_MASK(MLX5_CAP_OFF_DCT, 1), | ||
168 | }; | ||
169 | |||
170 | /* selectively copy writable fields clearing any reserved area | ||
171 | */ | ||
172 | static void copy_rw_fields(struct mlx5_hca_cap *to, struct mlx5_hca_cap *from) | ||
173 | { | ||
174 | u64 v64; | ||
175 | |||
176 | to->log_max_qp = from->log_max_qp & 0x1f; | ||
177 | to->log_max_ra_req_dc = from->log_max_ra_req_dc & 0x3f; | ||
178 | to->log_max_ra_res_dc = from->log_max_ra_res_dc & 0x3f; | ||
179 | to->log_max_ra_req_qp = from->log_max_ra_req_qp & 0x3f; | ||
180 | to->log_max_ra_res_qp = from->log_max_ra_res_qp & 0x3f; | ||
181 | to->log_max_atomic_size_qp = from->log_max_atomic_size_qp; | ||
182 | to->log_max_atomic_size_dc = from->log_max_atomic_size_dc; | ||
183 | v64 = be64_to_cpu(from->flags) & MLX5_CAP_BITS_RW_MASK; | ||
184 | to->flags = cpu_to_be64(v64); | ||
185 | } | ||
186 | |||
187 | enum { | ||
188 | HCA_CAP_OPMOD_GET_MAX = 0, | ||
189 | HCA_CAP_OPMOD_GET_CUR = 1, | ||
190 | }; | ||
191 | |||
162 | static int handle_hca_cap(struct mlx5_core_dev *dev) | 192 | static int handle_hca_cap(struct mlx5_core_dev *dev) |
163 | { | 193 | { |
164 | struct mlx5_cmd_query_hca_cap_mbox_out *query_out = NULL; | 194 | 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) | |||
180 | } | 210 | } |
181 | 211 | ||
182 | query_ctx.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_HCA_CAP); | 212 | query_ctx.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_HCA_CAP); |
183 | query_ctx.hdr.opmod = cpu_to_be16(0x1); | 213 | query_ctx.hdr.opmod = cpu_to_be16(HCA_CAP_OPMOD_GET_CUR); |
184 | err = mlx5_cmd_exec(dev, &query_ctx, sizeof(query_ctx), | 214 | err = mlx5_cmd_exec(dev, &query_ctx, sizeof(query_ctx), |
185 | query_out, sizeof(*query_out)); | 215 | query_out, sizeof(*query_out)); |
186 | if (err) | 216 | if (err) |
@@ -192,8 +222,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev) | |||
192 | goto query_ex; | 222 | goto query_ex; |
193 | } | 223 | } |
194 | 224 | ||
195 | memcpy(&set_ctx->hca_cap, &query_out->hca_cap, | 225 | copy_rw_fields(&set_ctx->hca_cap, &query_out->hca_cap); |
196 | sizeof(set_ctx->hca_cap)); | ||
197 | 226 | ||
198 | if (dev->profile->mask & MLX5_PROF_MASK_QP_SIZE) | 227 | if (dev->profile->mask & MLX5_PROF_MASK_QP_SIZE) |
199 | set_ctx->hca_cap.log_max_qp = dev->profile->log_max_qp; | 228 | set_ctx->hca_cap.log_max_qp = dev->profile->log_max_qp; |