drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
Extension
.c
Size
27265 bytes
Lines
949
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct mlx5_fw_reset {
	struct mlx5_core_dev *dev;
	struct mlx5_nb nb;
	struct workqueue_struct *wq;
	struct work_struct fw_live_patch_work;
	struct work_struct reset_request_work;
	struct work_struct reset_unload_work;
	struct work_struct reset_reload_work;
	struct work_struct reset_now_work;
	struct work_struct reset_abort_work;
	struct delayed_work reset_timeout_work;
	unsigned long reset_flags;
	u8 reset_method;
	struct timer_list timer;
	struct completion done;
	int ret;
};

enum {
	MLX5_FW_RST_STATE_IDLE = 0,
	MLX5_FW_RST_STATE_TOGGLE_REQ = 4,
	MLX5_FW_RST_STATE_DROP_MODE = 5,
};

enum {
	MLX5_RST_STATE_BIT_NUM = 12,
	MLX5_RST_ACK_BIT_NUM = 22,
};

static u8 mlx5_get_fw_rst_state(struct mlx5_core_dev *dev)
{
	return (ioread32be(&dev->iseg->initializing) >> MLX5_RST_STATE_BIT_NUM) & 0xF;
}

static void mlx5_set_fw_rst_ack(struct mlx5_core_dev *dev)
{
	iowrite32be(BIT(MLX5_RST_ACK_BIT_NUM), &dev->iseg->initializing);
}

static int mlx5_fw_reset_enable_remote_dev_reset_set(struct devlink *devlink, u32 id,
						     struct devlink_param_gset_ctx *ctx,
						     struct netlink_ext_ack *extack)
{
	struct mlx5_core_dev *dev = devlink_priv(devlink);
	struct mlx5_fw_reset *fw_reset;

	fw_reset = dev->priv.fw_reset;

	if (ctx->val.vbool)
		clear_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags);
	else
		set_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags);
	return 0;
}

static int mlx5_fw_reset_enable_remote_dev_reset_get(struct devlink *devlink, u32 id,
						     struct devlink_param_gset_ctx *ctx,
						     struct netlink_ext_ack *extack)
{
	struct mlx5_core_dev *dev = devlink_priv(devlink);
	struct mlx5_fw_reset *fw_reset;

	fw_reset = dev->priv.fw_reset;

	ctx->val.vbool = !test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
				   &fw_reset->reset_flags);
	return 0;
}

static int mlx5_reg_mfrl_set(struct mlx5_core_dev *dev, u8 reset_level,
			     u8 reset_type_sel, u8 sync_resp, bool sync_start)
{
	u32 out[MLX5_ST_SZ_DW(mfrl_reg)] = {};
	u32 in[MLX5_ST_SZ_DW(mfrl_reg)] = {};

	MLX5_SET(mfrl_reg, in, reset_level, reset_level);
	MLX5_SET(mfrl_reg, in, rst_type_sel, reset_type_sel);
	MLX5_SET(mfrl_reg, in, pci_sync_for_fw_update_resp, sync_resp);
	MLX5_SET(mfrl_reg, in, pci_sync_for_fw_update_start, sync_start);

	return mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out), MLX5_REG_MFRL, 0, 1);
}

static int mlx5_reg_mfrl_query(struct mlx5_core_dev *dev, u8 *reset_level,
			       u8 *reset_type, u8 *reset_state, u8 *reset_method)
{
	u32 out[MLX5_ST_SZ_DW(mfrl_reg)] = {};
	u32 in[MLX5_ST_SZ_DW(mfrl_reg)] = {};
	int err;

Annotation

Implementation Notes