diff options
author | Roland Dreier <rolandd@cisco.com> | 2007-06-08 02:24:36 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-06-08 02:24:36 -0400 |
commit | fe40900f408642e772739088d30636e2f3f7d0d8 (patch) | |
tree | e4fb317dcfd9c7145ab8a6a75f7e6c5a64e429d9 /drivers/net | |
parent | 3e1db334dca97df9034ebeec4657329a2b37a811 (diff) |
mlx4_core: Check firmware command interface revision
HCA firmware with incompatible changes to the FW commmand interface is
coming soon. Add a check of the interface revision during
initialization and bail out if the firmware advertises a revision that
the driver doesn't know about. This will avoid strange failures later
if the driver goes on using the wrong interface revision.
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/mlx4/fw.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index ab259b2e11a5..e7ca118c8dfd 100644 --- a/drivers/net/mlx4/fw.c +++ b/drivers/net/mlx4/fw.c | |||
@@ -37,6 +37,10 @@ | |||
37 | #include "fw.h" | 37 | #include "fw.h" |
38 | #include "icm.h" | 38 | #include "icm.h" |
39 | 39 | ||
40 | enum { | ||
41 | MLX4_COMMAND_INTERFACE_REV = 1 | ||
42 | }; | ||
43 | |||
40 | extern void __buggy_use_of_MLX4_GET(void); | 44 | extern void __buggy_use_of_MLX4_GET(void); |
41 | extern void __buggy_use_of_MLX4_PUT(void); | 45 | extern void __buggy_use_of_MLX4_PUT(void); |
42 | 46 | ||
@@ -452,10 +456,12 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev) | |||
452 | u32 *outbox; | 456 | u32 *outbox; |
453 | int err = 0; | 457 | int err = 0; |
454 | u64 fw_ver; | 458 | u64 fw_ver; |
459 | u16 cmd_if_rev; | ||
455 | u8 lg; | 460 | u8 lg; |
456 | 461 | ||
457 | #define QUERY_FW_OUT_SIZE 0x100 | 462 | #define QUERY_FW_OUT_SIZE 0x100 |
458 | #define QUERY_FW_VER_OFFSET 0x00 | 463 | #define QUERY_FW_VER_OFFSET 0x00 |
464 | #define QUERY_FW_CMD_IF_REV_OFFSET 0x0a | ||
459 | #define QUERY_FW_MAX_CMD_OFFSET 0x0f | 465 | #define QUERY_FW_MAX_CMD_OFFSET 0x0f |
460 | #define QUERY_FW_ERR_START_OFFSET 0x30 | 466 | #define QUERY_FW_ERR_START_OFFSET 0x30 |
461 | #define QUERY_FW_ERR_SIZE_OFFSET 0x38 | 467 | #define QUERY_FW_ERR_SIZE_OFFSET 0x38 |
@@ -484,14 +490,29 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev) | |||
484 | ((fw_ver & 0xffff0000ull) >> 16) | | 490 | ((fw_ver & 0xffff0000ull) >> 16) | |
485 | ((fw_ver & 0x0000ffffull) << 16); | 491 | ((fw_ver & 0x0000ffffull) << 16); |
486 | 492 | ||
493 | MLX4_GET(cmd_if_rev, outbox, QUERY_FW_CMD_IF_REV_OFFSET); | ||
494 | if (cmd_if_rev != MLX4_COMMAND_INTERFACE_REV) { | ||
495 | mlx4_err(dev, "Installed FW has unsupported " | ||
496 | "command interface revision %d.\n", | ||
497 | cmd_if_rev); | ||
498 | mlx4_err(dev, "(Installed FW version is %d.%d.%03d)\n", | ||
499 | (int) (dev->caps.fw_ver >> 32), | ||
500 | (int) (dev->caps.fw_ver >> 16) & 0xffff, | ||
501 | (int) dev->caps.fw_ver & 0xffff); | ||
502 | mlx4_err(dev, "This driver version supports only revision %d.\n", | ||
503 | MLX4_COMMAND_INTERFACE_REV); | ||
504 | err = -ENODEV; | ||
505 | goto out; | ||
506 | } | ||
507 | |||
487 | MLX4_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET); | 508 | MLX4_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET); |
488 | cmd->max_cmds = 1 << lg; | 509 | cmd->max_cmds = 1 << lg; |
489 | 510 | ||
490 | mlx4_dbg(dev, "FW version %d.%d.%03d, max commands %d\n", | 511 | mlx4_dbg(dev, "FW version %d.%d.%03d (cmd intf rev %d), max commands %d\n", |
491 | (int) (dev->caps.fw_ver >> 32), | 512 | (int) (dev->caps.fw_ver >> 32), |
492 | (int) (dev->caps.fw_ver >> 16) & 0xffff, | 513 | (int) (dev->caps.fw_ver >> 16) & 0xffff, |
493 | (int) dev->caps.fw_ver & 0xffff, | 514 | (int) dev->caps.fw_ver & 0xffff, |
494 | cmd->max_cmds); | 515 | cmd_if_rev, cmd->max_cmds); |
495 | 516 | ||
496 | MLX4_GET(fw->catas_offset, outbox, QUERY_FW_ERR_START_OFFSET); | 517 | MLX4_GET(fw->catas_offset, outbox, QUERY_FW_ERR_START_OFFSET); |
497 | MLX4_GET(fw->catas_size, outbox, QUERY_FW_ERR_SIZE_OFFSET); | 518 | MLX4_GET(fw->catas_size, outbox, QUERY_FW_ERR_SIZE_OFFSET); |