Skip to content

Commit

Permalink
Merge branch 'mlxfw-Improve-error-reporting-and-FW-reactivate-support'
Browse files Browse the repository at this point in the history
Saeed Mahameed says:

====================
mlxfw: Improve error reporting and FW reactivate support

This patchset improves mlxfw error reporting to netlink and to
kernel log.

V2:
 - Use proper err codes, EBUSY/EIO instead of EALREADY/EREMOTEIO
 - Fix typo.

From Eran and me.

1) patch #1, Make mlxfw/mlxsw fw flash devlink status notify generic,
   and enable it for mlx5.

2) patches #2..#5 are improving mlxfw flash error messages by
reporting detailed mlxfw FSM error messages to netlink and kernel log.

3) patches #6,7 From Eran: Add FW reactivate flow to  mlxfw and mlx5
====================

Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Feb 21, 2020
2 parents b105e8e + b7331aa commit 732a0de
Show file tree
Hide file tree
Showing 5 changed files with 308 additions and 96 deletions.
40 changes: 40 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -613,13 +613,52 @@ static void mlx5_fsm_release(struct mlxfw_dev *mlxfw_dev, u32 fwhandle)
fwhandle, 0);
}

#define MLX5_FSM_REACTIVATE_TOUT 5000 /* msecs */
static int mlx5_fsm_reactivate(struct mlxfw_dev *mlxfw_dev, u8 *status)
{
unsigned long exp_time = jiffies + msecs_to_jiffies(MLX5_FSM_REACTIVATE_TOUT);
struct mlx5_mlxfw_dev *mlx5_mlxfw_dev =
container_of(mlxfw_dev, struct mlx5_mlxfw_dev, mlxfw_dev);
struct mlx5_core_dev *dev = mlx5_mlxfw_dev->mlx5_core_dev;
u32 out[MLX5_ST_SZ_DW(mirc_reg)];
u32 in[MLX5_ST_SZ_DW(mirc_reg)];
int err;

if (!MLX5_CAP_MCAM_REG2(dev, mirc))
return -EOPNOTSUPP;

memset(in, 0, sizeof(in));

err = mlx5_core_access_reg(dev, in, sizeof(in), out,
sizeof(out), MLX5_REG_MIRC, 0, 1);
if (err)
return err;

do {
memset(out, 0, sizeof(out));
err = mlx5_core_access_reg(dev, in, sizeof(in), out,
sizeof(out), MLX5_REG_MIRC, 0, 0);
if (err)
return err;

*status = MLX5_GET(mirc_reg, out, status_code);
if (*status != MLXFW_FSM_REACTIVATE_STATUS_BUSY)
return 0;

msleep(20);
} while (time_before(jiffies, exp_time));

return 0;
}

static const struct mlxfw_dev_ops mlx5_mlxfw_dev_ops = {
.component_query = mlx5_component_query,
.fsm_lock = mlx5_fsm_lock,
.fsm_component_update = mlx5_fsm_component_update,
.fsm_block_download = mlx5_fsm_block_download,
.fsm_component_verify = mlx5_fsm_component_verify,
.fsm_activate = mlx5_fsm_activate,
.fsm_reactivate = mlx5_fsm_reactivate,
.fsm_query_state = mlx5_fsm_query_state,
.fsm_cancel = mlx5_fsm_cancel,
.fsm_release = mlx5_fsm_release
Expand All @@ -634,6 +673,7 @@ int mlx5_firmware_flash(struct mlx5_core_dev *dev,
.ops = &mlx5_mlxfw_dev_ops,
.psid = dev->board_id,
.psid_size = strlen(dev->board_id),
.devlink = priv_to_devlink(dev),
},
.mlx5_core_dev = dev
};
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlxfw/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ config MLXFW
To compile this driver as a module, choose M here: the
module will be called mlxfw.
select XZ_DEC
select NET_DEVLINK
50 changes: 39 additions & 11 deletions drivers/net/ethernet/mellanox/mlxfw/mlxfw.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@

#include <linux/firmware.h>
#include <linux/netlink.h>
#include <linux/device.h>
#include <net/devlink.h>

struct mlxfw_dev {
const struct mlxfw_dev_ops *ops;
const char *psid;
u16 psid_size;
struct devlink *devlink;
};

static inline
struct device *mlxfw_dev_dev(struct mlxfw_dev *mlxfw_dev)
{
return mlxfw_dev->devlink->dev;
}

#define MLXFW_PRFX "mlxfw: "

#define mlxfw_info(mlxfw_dev, fmt, ...) \
dev_info(mlxfw_dev_dev(mlxfw_dev), MLXFW_PRFX fmt, ## __VA_ARGS__)
#define mlxfw_err(mlxfw_dev, fmt, ...) \
dev_err(mlxfw_dev_dev(mlxfw_dev), MLXFW_PRFX fmt, ## __VA_ARGS__)
#define mlxfw_dbg(mlxfw_dev, fmt, ...) \
dev_dbg(mlxfw_dev_dev(mlxfw_dev), MLXFW_PRFX fmt, ## __VA_ARGS__)

enum mlxfw_fsm_state {
MLXFW_FSM_STATE_IDLE,
Expand All @@ -31,7 +55,19 @@ enum mlxfw_fsm_state_err {
MLXFW_FSM_STATE_ERR_MAX,
};

struct mlxfw_dev;
enum mlxfw_fsm_reactivate_status {
MLXFW_FSM_REACTIVATE_STATUS_OK,
MLXFW_FSM_REACTIVATE_STATUS_BUSY,
MLXFW_FSM_REACTIVATE_STATUS_PROHIBITED_FW_VER_ERR,
MLXFW_FSM_REACTIVATE_STATUS_FIRST_PAGE_COPY_FAILED,
MLXFW_FSM_REACTIVATE_STATUS_FIRST_PAGE_ERASE_FAILED,
MLXFW_FSM_REACTIVATE_STATUS_FIRST_PAGE_RESTORE_FAILED,
MLXFW_FSM_REACTIVATE_STATUS_CANDIDATE_FW_DEACTIVATION_FAILED,
MLXFW_FSM_REACTIVATE_STATUS_FW_ALREADY_ACTIVATED,
MLXFW_FSM_REACTIVATE_STATUS_ERR_DEVICE_RESET_REQUIRED,
MLXFW_FSM_REACTIVATE_STATUS_ERR_FW_PROGRAMMING_NEEDED,
MLXFW_FSM_REACTIVATE_STATUS_MAX,
};

struct mlxfw_dev_ops {
int (*component_query)(struct mlxfw_dev *mlxfw_dev, u16 component_index,
Expand All @@ -51,23 +87,15 @@ struct mlxfw_dev_ops {

int (*fsm_activate)(struct mlxfw_dev *mlxfw_dev, u32 fwhandle);

int (*fsm_reactivate)(struct mlxfw_dev *mlxfw_dev, u8 *status);

int (*fsm_query_state)(struct mlxfw_dev *mlxfw_dev, u32 fwhandle,
enum mlxfw_fsm_state *fsm_state,
enum mlxfw_fsm_state_err *fsm_state_err);

void (*fsm_cancel)(struct mlxfw_dev *mlxfw_dev, u32 fwhandle);

void (*fsm_release)(struct mlxfw_dev *mlxfw_dev, u32 fwhandle);

void (*status_notify)(struct mlxfw_dev *mlxfw_dev,
const char *msg, const char *comp_name,
u32 done_bytes, u32 total_bytes);
};

struct mlxfw_dev {
const struct mlxfw_dev_ops *ops;
const char *psid;
u16 psid_size;
};

#if IS_REACHABLE(CONFIG_MLXFW)
Expand Down
Loading

0 comments on commit 732a0de

Please sign in to comment.