mlxsw: core_linecards: Expose device FW version over device info
Extend MDDQ to obtain FW version of line card device and implement device_info_get() op to fill up the info with that. Signed-off-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
c38e9bf338
Коммит
e932b4bdbd
|
@ -76,6 +76,21 @@ The ``mlxsw`` driver reports the following versions for line cards
|
|||
- running
|
||||
- Version of line card INI loaded
|
||||
|
||||
Line card device info versions
|
||||
==============================
|
||||
|
||||
The ``mlxsw`` driver reports the following versions for line card devices
|
||||
|
||||
.. list-table:: devlink line card device info versions implemented
|
||||
:widths: 5 5 90
|
||||
|
||||
* - Name
|
||||
- Type
|
||||
- Description
|
||||
* - ``fw.version``
|
||||
- running
|
||||
- Three digit firmware version
|
||||
|
||||
Driver-specific Traps
|
||||
=====================
|
||||
|
||||
|
|
|
@ -87,13 +87,31 @@ static const char *mlxsw_linecard_type_name(struct mlxsw_linecard *linecard)
|
|||
return linecard->name;
|
||||
}
|
||||
|
||||
struct mlxsw_linecard_device_info {
|
||||
u16 fw_major;
|
||||
u16 fw_minor;
|
||||
u16 fw_sub_minor;
|
||||
};
|
||||
|
||||
struct mlxsw_linecard_device {
|
||||
struct list_head list;
|
||||
u8 index;
|
||||
struct mlxsw_linecard *linecard;
|
||||
struct devlink_linecard_device *devlink_device;
|
||||
struct mlxsw_linecard_device_info info;
|
||||
};
|
||||
|
||||
static struct mlxsw_linecard_device *
|
||||
mlxsw_linecard_device_lookup(struct mlxsw_linecard *linecard, u8 index)
|
||||
{
|
||||
struct mlxsw_linecard_device *device;
|
||||
|
||||
list_for_each_entry(device, &linecard->device_list, list)
|
||||
if (device->index == index)
|
||||
return device;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int mlxsw_linecard_device_attach(struct mlxsw_core *mlxsw_core,
|
||||
struct mlxsw_linecard *linecard,
|
||||
u8 device_index, bool flash_owner)
|
||||
|
@ -108,7 +126,7 @@ static int mlxsw_linecard_device_attach(struct mlxsw_core *mlxsw_core,
|
|||
device->linecard = linecard;
|
||||
|
||||
device->devlink_device = devlink_linecard_device_create(linecard->devlink_linecard,
|
||||
device_index, NULL);
|
||||
device_index, device);
|
||||
if (IS_ERR(device->devlink_device)) {
|
||||
err = PTR_ERR(device->devlink_device);
|
||||
goto err_devlink_linecard_device_attach;
|
||||
|
@ -177,6 +195,77 @@ rollback:
|
|||
return err;
|
||||
}
|
||||
|
||||
static void mlxsw_linecard_device_update(struct mlxsw_linecard *linecard,
|
||||
u8 device_index,
|
||||
struct mlxsw_linecard_device_info *info)
|
||||
{
|
||||
struct mlxsw_linecard_device *device;
|
||||
|
||||
device = mlxsw_linecard_device_lookup(linecard, device_index);
|
||||
if (!device)
|
||||
return;
|
||||
device->info = *info;
|
||||
}
|
||||
|
||||
static int mlxsw_linecard_devices_update(struct mlxsw_linecard *linecard)
|
||||
{
|
||||
struct mlxsw_core *mlxsw_core = linecard->linecards->mlxsw_core;
|
||||
u8 msg_seq = 0;
|
||||
|
||||
do {
|
||||
struct mlxsw_linecard_device_info info;
|
||||
char mddq_pl[MLXSW_REG_MDDQ_LEN];
|
||||
bool data_valid;
|
||||
u8 device_index;
|
||||
int err;
|
||||
|
||||
mlxsw_reg_mddq_device_info_pack(mddq_pl, linecard->slot_index,
|
||||
msg_seq);
|
||||
err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mddq), mddq_pl);
|
||||
if (err)
|
||||
return err;
|
||||
mlxsw_reg_mddq_device_info_unpack(mddq_pl, &msg_seq,
|
||||
&data_valid, NULL,
|
||||
&device_index,
|
||||
&info.fw_major,
|
||||
&info.fw_minor,
|
||||
&info.fw_sub_minor);
|
||||
if (!data_valid)
|
||||
break;
|
||||
mlxsw_linecard_device_update(linecard, device_index, &info);
|
||||
} while (msg_seq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_linecard_device_info_get(struct devlink_linecard_device *devlink_linecard_device,
|
||||
void *priv, struct devlink_info_req *req,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mlxsw_linecard_device *device = priv;
|
||||
struct mlxsw_linecard_device_info *info;
|
||||
struct mlxsw_linecard *linecard;
|
||||
char buf[32];
|
||||
|
||||
linecard = device->linecard;
|
||||
mutex_lock(&linecard->lock);
|
||||
if (!linecard->active) {
|
||||
mutex_unlock(&linecard->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
info = &device->info;
|
||||
|
||||
sprintf(buf, "%u.%u.%u", info->fw_major, info->fw_minor,
|
||||
info->fw_sub_minor);
|
||||
mutex_unlock(&linecard->lock);
|
||||
|
||||
return devlink_info_version_running_put(req,
|
||||
DEVLINK_INFO_VERSION_GENERIC_FW,
|
||||
buf);
|
||||
}
|
||||
|
||||
static void mlxsw_linecard_provision_fail(struct mlxsw_linecard *linecard)
|
||||
{
|
||||
linecard->provisioned = false;
|
||||
|
@ -390,11 +479,18 @@ static int mlxsw_linecard_ready_clear(struct mlxsw_linecard *linecard)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void mlxsw_linecard_active_set(struct mlxsw_linecard *linecard)
|
||||
static int mlxsw_linecard_active_set(struct mlxsw_linecard *linecard)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = mlxsw_linecard_devices_update(linecard);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
mlxsw_linecard_active_ops_call(linecard);
|
||||
linecard->active = true;
|
||||
devlink_linecard_activate(linecard->devlink_linecard);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mlxsw_linecard_active_clear(struct mlxsw_linecard *linecard)
|
||||
|
@ -443,8 +539,11 @@ static int mlxsw_linecard_status_process(struct mlxsw_linecards *linecards,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (active && linecard->active != active)
|
||||
mlxsw_linecard_active_set(linecard);
|
||||
if (active && linecard->active != active) {
|
||||
err = mlxsw_linecard_active_set(linecard);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!active && linecard->active != active)
|
||||
mlxsw_linecard_active_clear(linecard);
|
||||
|
@ -872,6 +971,7 @@ static const struct devlink_linecard_ops mlxsw_linecard_ops = {
|
|||
.types_count = mlxsw_linecard_types_count,
|
||||
.types_get = mlxsw_linecard_types_get,
|
||||
.info_get = mlxsw_linecard_info_get,
|
||||
.device_info_get = mlxsw_linecard_device_info_get,
|
||||
};
|
||||
|
||||
struct mlxsw_linecard_status_event {
|
||||
|
|
Загрузка…
Ссылка в новой задаче