Commit f7936ddd authored by Eran Ben Elisha's avatar Eran Ben Elisha Committed by Saeed Mahameed

net/mlx5: Avoid processing commands before cmdif is ready

When driver is reloading during recovery flow, it can't get new commands
till command interface is up again. Otherwise we may get to null pointer
trying to access non initialized command structures.

Add cmdif state to avoid processing commands while cmdif is not ready.

Fixes: e126ba97 ("mlx5: Add driver for Mellanox Connect-IB adapters")
Signed-off-by: default avatarEran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: default avatarMoshe Shemesh <moshe@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent d43b7007
...@@ -923,6 +923,7 @@ static void cmd_work_handler(struct work_struct *work) ...@@ -923,6 +923,7 @@ static void cmd_work_handler(struct work_struct *work)
/* Skip sending command to fw if internal error */ /* Skip sending command to fw if internal error */
if (pci_channel_offline(dev->pdev) || if (pci_channel_offline(dev->pdev) ||
dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR || dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR ||
cmd->state != MLX5_CMDIF_STATE_UP ||
!opcode_allowed(&dev->cmd, ent->op)) { !opcode_allowed(&dev->cmd, ent->op)) {
u8 status = 0; u8 status = 0;
u32 drv_synd; u32 drv_synd;
...@@ -1712,6 +1713,7 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out, ...@@ -1712,6 +1713,7 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out,
opcode = MLX5_GET(mbox_in, in, opcode); opcode = MLX5_GET(mbox_in, in, opcode);
if (pci_channel_offline(dev->pdev) || if (pci_channel_offline(dev->pdev) ||
dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR || dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR ||
dev->cmd.state != MLX5_CMDIF_STATE_UP ||
!opcode_allowed(&dev->cmd, opcode)) { !opcode_allowed(&dev->cmd, opcode)) {
err = mlx5_internal_err_ret_value(dev, opcode, &drv_synd, &status); err = mlx5_internal_err_ret_value(dev, opcode, &drv_synd, &status);
MLX5_SET(mbox_out, out, status, status); MLX5_SET(mbox_out, out, status, status);
...@@ -1977,6 +1979,7 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev) ...@@ -1977,6 +1979,7 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev)
goto err_free_page; goto err_free_page;
} }
cmd->state = MLX5_CMDIF_STATE_DOWN;
cmd->checksum_disabled = 1; cmd->checksum_disabled = 1;
cmd->max_reg_cmds = (1 << cmd->log_sz) - 1; cmd->max_reg_cmds = (1 << cmd->log_sz) - 1;
cmd->bitmask = (1UL << cmd->max_reg_cmds) - 1; cmd->bitmask = (1UL << cmd->max_reg_cmds) - 1;
...@@ -2054,3 +2057,10 @@ void mlx5_cmd_cleanup(struct mlx5_core_dev *dev) ...@@ -2054,3 +2057,10 @@ void mlx5_cmd_cleanup(struct mlx5_core_dev *dev)
dma_pool_destroy(cmd->pool); dma_pool_destroy(cmd->pool);
} }
EXPORT_SYMBOL(mlx5_cmd_cleanup); EXPORT_SYMBOL(mlx5_cmd_cleanup);
void mlx5_cmd_set_state(struct mlx5_core_dev *dev,
enum mlx5_cmdif_state cmdif_state)
{
dev->cmd.state = cmdif_state;
}
EXPORT_SYMBOL(mlx5_cmd_set_state);
...@@ -965,6 +965,8 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot) ...@@ -965,6 +965,8 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot)
goto err_cmd_cleanup; goto err_cmd_cleanup;
} }
mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_UP);
err = mlx5_core_enable_hca(dev, 0); err = mlx5_core_enable_hca(dev, 0);
if (err) { if (err) {
mlx5_core_err(dev, "enable hca failed\n"); mlx5_core_err(dev, "enable hca failed\n");
...@@ -1026,6 +1028,7 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot) ...@@ -1026,6 +1028,7 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot)
err_disable_hca: err_disable_hca:
mlx5_core_disable_hca(dev, 0); mlx5_core_disable_hca(dev, 0);
err_cmd_cleanup: err_cmd_cleanup:
mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN);
mlx5_cmd_cleanup(dev); mlx5_cmd_cleanup(dev);
return err; return err;
...@@ -1043,6 +1046,7 @@ static int mlx5_function_teardown(struct mlx5_core_dev *dev, bool boot) ...@@ -1043,6 +1046,7 @@ static int mlx5_function_teardown(struct mlx5_core_dev *dev, bool boot)
} }
mlx5_reclaim_startup_pages(dev); mlx5_reclaim_startup_pages(dev);
mlx5_core_disable_hca(dev, 0); mlx5_core_disable_hca(dev, 0);
mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN);
mlx5_cmd_cleanup(dev); mlx5_cmd_cleanup(dev);
return 0; return 0;
......
...@@ -213,6 +213,12 @@ enum mlx5_port_status { ...@@ -213,6 +213,12 @@ enum mlx5_port_status {
MLX5_PORT_DOWN = 2, MLX5_PORT_DOWN = 2,
}; };
enum mlx5_cmdif_state {
MLX5_CMDIF_STATE_UNINITIALIZED,
MLX5_CMDIF_STATE_UP,
MLX5_CMDIF_STATE_DOWN,
};
struct mlx5_cmd_first { struct mlx5_cmd_first {
__be32 data[4]; __be32 data[4];
}; };
...@@ -258,6 +264,7 @@ struct mlx5_cmd_stats { ...@@ -258,6 +264,7 @@ struct mlx5_cmd_stats {
struct mlx5_cmd { struct mlx5_cmd {
struct mlx5_nb nb; struct mlx5_nb nb;
enum mlx5_cmdif_state state;
void *cmd_alloc_buf; void *cmd_alloc_buf;
dma_addr_t alloc_dma; dma_addr_t alloc_dma;
int alloc_size; int alloc_size;
...@@ -882,6 +889,8 @@ enum { ...@@ -882,6 +889,8 @@ enum {
int mlx5_cmd_init(struct mlx5_core_dev *dev); int mlx5_cmd_init(struct mlx5_core_dev *dev);
void mlx5_cmd_cleanup(struct mlx5_core_dev *dev); void mlx5_cmd_cleanup(struct mlx5_core_dev *dev);
void mlx5_cmd_set_state(struct mlx5_core_dev *dev,
enum mlx5_cmdif_state cmdif_state);
void mlx5_cmd_use_events(struct mlx5_core_dev *dev); void mlx5_cmd_use_events(struct mlx5_core_dev *dev);
void mlx5_cmd_use_polling(struct mlx5_core_dev *dev); void mlx5_cmd_use_polling(struct mlx5_core_dev *dev);
void mlx5_cmd_allowed_opcode(struct mlx5_core_dev *dev, u16 opcode); void mlx5_cmd_allowed_opcode(struct mlx5_core_dev *dev, u16 opcode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment