Commit 4fd310c7 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'implement-dev-info-and-dev-flash-for-line-cards'

Jiri Pirko says:

====================
Implement dev info and dev flash for line cards

This patchset implements two features:
1) "devlink dev info" is exposed for line card (patches 6-9)
2) "devlink dev flash" is implemented for line card gearbox
   flashing (patch 10)

For every line card, "a nested" auxiliary device is created which
allows to bind the features mentioned above (patch 4).

The relationship between line card and its auxiliary dev devlink
is carried over extra line card netlink attribute (patches 3 and 5).

The first patch removes devlink_mutex from devlink_register/unregister()
which eliminates possible deadlock during devlink reload command. The
second patchset follows up with putting net pointer check into new
helper.

Examples:

$ devlink lc show pci/0000:01:00.0 lc 1
pci/0000:01:00.0:
  lc 1 state active type 16x100G nested_devlink auxiliary/mlxsw_core.lc.0
    supported_types:
       16x100G

$ devlink dev show auxiliary/mlxsw_core.lc.0
auxiliary/mlxsw_core.lc.0

$ devlink dev info auxiliary/mlxsw_core.lc.0
auxiliary/mlxsw_core.lc.0:
  versions:
      fixed:
        hw.revision 0
        fw.psid MT_0000000749
      running:
        ini.version 4
        fw 19.2010.1312

$ devlink dev flash auxiliary/mlxsw_core.lc.0 file mellanox/fw-AGB-rel-19_2010_1312-022-EVB.mfa2
====================

Link: https://lore.kernel.org/r/20220725082925.366455-1-jiri@resnulli.usSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 35d099da 949c84f0
......@@ -58,6 +58,30 @@ The ``mlxsw`` driver reports the following versions
- running
- Three digit firmware version
Line card auxiliary device info versions
========================================
The ``mlxsw`` driver reports the following versions for line card auxiliary device
.. list-table:: devlink info versions implemented
:widths: 5 5 90
* - Name
- Type
- Description
* - ``hw.revision``
- fixed
- The hardware revision for this line card
* - ``ini.version``
- running
- Version of line card INI loaded
* - ``fw.psid``
- fixed
- Line card device PSID
* - ``fw.version``
- running
- Three digit firmware version of line card device
Driver-specific Traps
=====================
......
......@@ -7,6 +7,7 @@ config MLXSW_CORE
tristate "Mellanox Technologies Switch ASICs support"
select NET_DEVLINK
select MLXFW
select AUXILIARY_BUS
help
This driver supports Mellanox Technologies Switch ASICs family.
......
......@@ -2,7 +2,7 @@
obj-$(CONFIG_MLXSW_CORE) += mlxsw_core.o
mlxsw_core-objs := core.o core_acl_flex_keys.o \
core_acl_flex_actions.o core_env.o \
core_linecards.o
core_linecards.o core_linecard_dev.o
mlxsw_core-$(CONFIG_MLXSW_CORE_HWMON) += core_hwmon.o
mlxsw_core-$(CONFIG_MLXSW_CORE_THERMAL) += core_thermal.o
obj-$(CONFIG_MLXSW_PCI) += mlxsw_pci.o
......
......@@ -951,6 +951,20 @@ static struct mlxsw_driver *mlxsw_core_driver_get(const char *kind)
return mlxsw_driver;
}
int mlxsw_core_fw_flash(struct mlxsw_core *mlxsw_core,
struct mlxfw_dev *mlxfw_dev,
const struct firmware *firmware,
struct netlink_ext_ack *extack)
{
int err;
mlxsw_core->fw_flash_in_progress = true;
err = mlxfw_firmware_flash(mlxfw_dev, firmware, extack);
mlxsw_core->fw_flash_in_progress = false;
return err;
}
struct mlxsw_core_fw_info {
struct mlxfw_dev mlxfw_dev;
struct mlxsw_core *mlxsw_core;
......@@ -1105,7 +1119,8 @@ static const struct mlxfw_dev_ops mlxsw_core_fw_mlxsw_dev_ops = {
.fsm_release = mlxsw_core_fw_fsm_release,
};
static int mlxsw_core_fw_flash(struct mlxsw_core *mlxsw_core, const struct firmware *firmware,
static int mlxsw_core_dev_fw_flash(struct mlxsw_core *mlxsw_core,
const struct firmware *firmware,
struct netlink_ext_ack *extack)
{
struct mlxsw_core_fw_info mlxsw_core_fw_info = {
......@@ -1117,13 +1132,9 @@ static int mlxsw_core_fw_flash(struct mlxsw_core *mlxsw_core, const struct firmw
},
.mlxsw_core = mlxsw_core
};
int err;
mlxsw_core->fw_flash_in_progress = true;
err = mlxfw_firmware_flash(&mlxsw_core_fw_info.mlxfw_dev, firmware, extack);
mlxsw_core->fw_flash_in_progress = false;
return err;
return mlxsw_core_fw_flash(mlxsw_core, &mlxsw_core_fw_info.mlxfw_dev,
firmware, extack);
}
static int mlxsw_core_fw_rev_validate(struct mlxsw_core *mlxsw_core,
......@@ -1169,7 +1180,7 @@ static int mlxsw_core_fw_rev_validate(struct mlxsw_core *mlxsw_core,
return err;
}
err = mlxsw_core_fw_flash(mlxsw_core, firmware, NULL);
err = mlxsw_core_dev_fw_flash(mlxsw_core, firmware, NULL);
release_firmware(firmware);
if (err)
dev_err(mlxsw_bus_info->dev, "Could not upgrade firmware\n");
......@@ -1187,7 +1198,7 @@ static int mlxsw_core_fw_flash_update(struct mlxsw_core *mlxsw_core,
struct devlink_flash_update_params *params,
struct netlink_ext_ack *extack)
{
return mlxsw_core_fw_flash(mlxsw_core, params->fw, extack);
return mlxsw_core_dev_fw_flash(mlxsw_core, params->fw, extack);
}
static int mlxsw_core_devlink_param_fw_load_policy_validate(struct devlink *devlink, u32 id,
......@@ -3334,9 +3345,15 @@ static int __init mlxsw_core_module_init(void)
{
int err;
err = mlxsw_linecard_driver_register();
if (err)
return err;
mlxsw_wq = alloc_workqueue(mlxsw_core_driver_name, 0, 0);
if (!mlxsw_wq)
return -ENOMEM;
if (!mlxsw_wq) {
err = -ENOMEM;
goto err_alloc_workqueue;
}
mlxsw_owq = alloc_ordered_workqueue("%s_ordered", 0,
mlxsw_core_driver_name);
if (!mlxsw_owq) {
......@@ -3347,6 +3364,8 @@ static int __init mlxsw_core_module_init(void)
err_alloc_ordered_workqueue:
destroy_workqueue(mlxsw_wq);
err_alloc_workqueue:
mlxsw_linecard_driver_unregister();
return err;
}
......@@ -3354,6 +3373,7 @@ static void __exit mlxsw_core_module_exit(void)
{
destroy_workqueue(mlxsw_owq);
destroy_workqueue(mlxsw_wq);
mlxsw_linecard_driver_unregister();
}
module_init(mlxsw_core_module_init);
......
......@@ -12,12 +12,14 @@
#include <linux/skbuff.h>
#include <linux/workqueue.h>
#include <linux/net_namespace.h>
#include <linux/auxiliary_bus.h>
#include <net/devlink.h>
#include "trap.h"
#include "reg.h"
#include "cmd.h"
#include "resources.h"
#include "../mlxfw/mlxfw.h"
enum mlxsw_core_resource_id {
MLXSW_CORE_RESOURCE_PORTS = 1,
......@@ -47,6 +49,11 @@ mlxsw_core_fw_rev_minor_subminor_validate(const struct mlxsw_fw_rev *rev,
int mlxsw_core_driver_register(struct mlxsw_driver *mlxsw_driver);
void mlxsw_core_driver_unregister(struct mlxsw_driver *mlxsw_driver);
int mlxsw_core_fw_flash(struct mlxsw_core *mlxsw_core,
struct mlxfw_dev *mlxfw_dev,
const struct firmware *firmware,
struct netlink_ext_ack *extack);
int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
const struct mlxsw_bus *mlxsw_bus,
void *bus_priv, bool reload,
......@@ -563,6 +570,15 @@ enum mlxsw_linecard_status_event_type {
MLXSW_LINECARD_STATUS_EVENT_TYPE_UNPROVISION,
};
struct mlxsw_linecard_bdev;
struct mlxsw_linecard_device_info {
u16 fw_major;
u16 fw_minor;
u16 fw_sub_minor;
char psid[MLXSW_REG_MGIR_FW_INFO_PSID_SIZE];
};
struct mlxsw_linecard {
u8 slot_index;
struct mlxsw_linecards *linecards;
......@@ -577,6 +593,11 @@ struct mlxsw_linecard {
active:1;
u16 hw_revision;
u16 ini_version;
struct mlxsw_linecard_bdev *bdev;
struct {
struct mlxsw_linecard_device_info info;
u8 index;
} device;
};
struct mlxsw_linecard_types_info;
......@@ -597,6 +618,14 @@ mlxsw_linecard_get(struct mlxsw_linecards *linecards, u8 slot_index)
return &linecards->linecards[slot_index - 1];
}
int mlxsw_linecard_devlink_info_get(struct mlxsw_linecard *linecard,
struct devlink_info_req *req,
struct netlink_ext_ack *extack);
int mlxsw_linecard_flash_update(struct devlink *linecard_devlink,
struct mlxsw_linecard *linecard,
const struct firmware *firmware,
struct netlink_ext_ack *extack);
int mlxsw_linecards_init(struct mlxsw_core *mlxsw_core,
const struct mlxsw_bus_info *bus_info);
void mlxsw_linecards_fini(struct mlxsw_core *mlxsw_core);
......@@ -616,4 +645,10 @@ void mlxsw_linecards_event_ops_unregister(struct mlxsw_core *mlxsw_core,
struct mlxsw_linecards_event_ops *ops,
void *priv);
int mlxsw_linecard_bdev_add(struct mlxsw_linecard *linecard);
void mlxsw_linecard_bdev_del(struct mlxsw_linecard *linecard);
int mlxsw_linecard_driver_register(void);
void mlxsw_linecard_driver_unregister(void);
#endif
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/* Copyright (c) 2022 NVIDIA Corporation and Mellanox Technologies. All rights reserved */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/types.h>
#include <linux/err.h>
#include <linux/auxiliary_bus.h>
#include <linux/idr.h>
#include <linux/gfp.h>
#include <linux/slab.h>
#include <net/devlink.h>
#include "core.h"
#define MLXSW_LINECARD_DEV_ID_NAME "lc"
struct mlxsw_linecard_dev {
struct mlxsw_linecard *linecard;
};
struct mlxsw_linecard_bdev {
struct auxiliary_device adev;
struct mlxsw_linecard *linecard;
struct mlxsw_linecard_dev *linecard_dev;
};
static DEFINE_IDA(mlxsw_linecard_bdev_ida);
static int mlxsw_linecard_bdev_id_alloc(void)
{
return ida_alloc(&mlxsw_linecard_bdev_ida, GFP_KERNEL);
}
static void mlxsw_linecard_bdev_id_free(int id)
{
ida_free(&mlxsw_linecard_bdev_ida, id);
}
static void mlxsw_linecard_bdev_release(struct device *device)
{
struct auxiliary_device *adev =
container_of(device, struct auxiliary_device, dev);
struct mlxsw_linecard_bdev *linecard_bdev =
container_of(adev, struct mlxsw_linecard_bdev, adev);
mlxsw_linecard_bdev_id_free(adev->id);
kfree(linecard_bdev);
}
int mlxsw_linecard_bdev_add(struct mlxsw_linecard *linecard)
{
struct mlxsw_linecard_bdev *linecard_bdev;
int err;
int id;
id = mlxsw_linecard_bdev_id_alloc();
if (id < 0)
return id;
linecard_bdev = kzalloc(sizeof(*linecard_bdev), GFP_KERNEL);
if (!linecard_bdev) {
mlxsw_linecard_bdev_id_free(id);
return -ENOMEM;
}
linecard_bdev->adev.id = id;
linecard_bdev->adev.name = MLXSW_LINECARD_DEV_ID_NAME;
linecard_bdev->adev.dev.release = mlxsw_linecard_bdev_release;
linecard_bdev->adev.dev.parent = linecard->linecards->bus_info->dev;
linecard_bdev->linecard = linecard;
err = auxiliary_device_init(&linecard_bdev->adev);
if (err) {
mlxsw_linecard_bdev_id_free(id);
kfree(linecard_bdev);
return err;
}
err = auxiliary_device_add(&linecard_bdev->adev);
if (err) {
auxiliary_device_uninit(&linecard_bdev->adev);
return err;
}
linecard->bdev = linecard_bdev;
return 0;
}
void mlxsw_linecard_bdev_del(struct mlxsw_linecard *linecard)
{
struct mlxsw_linecard_bdev *linecard_bdev = linecard->bdev;
if (!linecard_bdev)
/* Unprovisioned line cards do not have an auxiliary device. */
return;
auxiliary_device_delete(&linecard_bdev->adev);
auxiliary_device_uninit(&linecard_bdev->adev);
linecard->bdev = NULL;
}
static int mlxsw_linecard_dev_devlink_info_get(struct devlink *devlink,
struct devlink_info_req *req,
struct netlink_ext_ack *extack)
{
struct mlxsw_linecard_dev *linecard_dev = devlink_priv(devlink);
struct mlxsw_linecard *linecard = linecard_dev->linecard;
return mlxsw_linecard_devlink_info_get(linecard, req, extack);
}
static int
mlxsw_linecard_dev_devlink_flash_update(struct devlink *devlink,
struct devlink_flash_update_params *params,
struct netlink_ext_ack *extack)
{
struct mlxsw_linecard_dev *linecard_dev = devlink_priv(devlink);
struct mlxsw_linecard *linecard = linecard_dev->linecard;
return mlxsw_linecard_flash_update(devlink, linecard,
params->fw, extack);
}
static const struct devlink_ops mlxsw_linecard_dev_devlink_ops = {
.info_get = mlxsw_linecard_dev_devlink_info_get,
.flash_update = mlxsw_linecard_dev_devlink_flash_update,
};
static int mlxsw_linecard_bdev_probe(struct auxiliary_device *adev,
const struct auxiliary_device_id *id)
{
struct mlxsw_linecard_bdev *linecard_bdev =
container_of(adev, struct mlxsw_linecard_bdev, adev);
struct mlxsw_linecard *linecard = linecard_bdev->linecard;
struct mlxsw_linecard_dev *linecard_dev;
struct devlink *devlink;
devlink = devlink_alloc(&mlxsw_linecard_dev_devlink_ops,
sizeof(*linecard_dev), &adev->dev);
if (!devlink)
return -ENOMEM;
linecard_dev = devlink_priv(devlink);
linecard_dev->linecard = linecard_bdev->linecard;
linecard_bdev->linecard_dev = linecard_dev;
devlink_register(devlink);
devlink_linecard_nested_dl_set(linecard->devlink_linecard, devlink);
return 0;
}
static void mlxsw_linecard_bdev_remove(struct auxiliary_device *adev)
{
struct mlxsw_linecard_bdev *linecard_bdev =
container_of(adev, struct mlxsw_linecard_bdev, adev);
struct devlink *devlink = priv_to_devlink(linecard_bdev->linecard_dev);
struct mlxsw_linecard *linecard = linecard_bdev->linecard;
devlink_linecard_nested_dl_set(linecard->devlink_linecard, NULL);
devlink_unregister(devlink);
devlink_free(devlink);
}
static const struct auxiliary_device_id mlxsw_linecard_bdev_id_table[] = {
{ .name = KBUILD_MODNAME "." MLXSW_LINECARD_DEV_ID_NAME },
{},
};
MODULE_DEVICE_TABLE(auxiliary, mlxsw_linecard_bdev_id_table);
static struct auxiliary_driver mlxsw_linecard_driver = {
.name = MLXSW_LINECARD_DEV_ID_NAME,
.probe = mlxsw_linecard_bdev_probe,
.remove = mlxsw_linecard_bdev_remove,
.id_table = mlxsw_linecard_bdev_id_table,
};
int mlxsw_linecard_driver_register(void)
{
return auxiliary_driver_register(&mlxsw_linecard_driver);
}
void mlxsw_linecard_driver_unregister(void)
{
auxiliary_driver_unregister(&mlxsw_linecard_driver);
}
......@@ -11364,6 +11364,95 @@ mlxsw_reg_mbct_unpack(const char *payload, u8 *p_slot_index,
*p_fsm_state = mlxsw_reg_mbct_fsm_state_get(payload);
}
/* MDDT - Management DownStream Device Tunneling Register
* ------------------------------------------------------
* This register allows to deliver query and request messages (PRM registers,
* commands) to a DownStream device.
*/
#define MLXSW_REG_MDDT_ID 0x9160
#define MLXSW_REG_MDDT_LEN 0x110
MLXSW_REG_DEFINE(mddt, MLXSW_REG_MDDT_ID, MLXSW_REG_MDDT_LEN);
/* reg_mddt_slot_index
* Slot index.
* Access: Index
*/
MLXSW_ITEM32(reg, mddt, slot_index, 0x00, 8, 4);
/* reg_mddt_device_index
* Device index.
* Access: Index
*/
MLXSW_ITEM32(reg, mddt, device_index, 0x00, 0, 8);
/* reg_mddt_read_size
* Read size in D-Words.
* Access: OP
*/
MLXSW_ITEM32(reg, mddt, read_size, 0x04, 24, 8);
/* reg_mddt_write_size
* Write size in D-Words.
* Access: OP
*/
MLXSW_ITEM32(reg, mddt, write_size, 0x04, 16, 8);
enum mlxsw_reg_mddt_status {
MLXSW_REG_MDDT_STATUS_OK,
};
/* reg_mddt_status
* Return code of the Downstream Device to the register that was sent.
* Access: RO
*/
MLXSW_ITEM32(reg, mddt, status, 0x0C, 24, 8);
enum mlxsw_reg_mddt_method {
MLXSW_REG_MDDT_METHOD_QUERY,
MLXSW_REG_MDDT_METHOD_WRITE,
};
/* reg_mddt_method
* Access: OP
*/
MLXSW_ITEM32(reg, mddt, method, 0x0C, 22, 2);
/* reg_mddt_register_id
* Access: Index
*/
MLXSW_ITEM32(reg, mddt, register_id, 0x0C, 0, 16);
#define MLXSW_REG_MDDT_PAYLOAD_OFFSET 0x0C
#define MLXSW_REG_MDDT_PRM_REGISTER_HEADER_LEN 4
static inline char *mlxsw_reg_mddt_inner_payload(char *payload)
{
return payload + MLXSW_REG_MDDT_PAYLOAD_OFFSET +
MLXSW_REG_MDDT_PRM_REGISTER_HEADER_LEN;
}
static inline void mlxsw_reg_mddt_pack(char *payload, u8 slot_index,
u8 device_index,
enum mlxsw_reg_mddt_method method,
const struct mlxsw_reg_info *reg,
char **inner_payload)
{
int len = reg->len + MLXSW_REG_MDDT_PRM_REGISTER_HEADER_LEN;
if (WARN_ON(len + MLXSW_REG_MDDT_PAYLOAD_OFFSET > MLXSW_REG_MDDT_LEN))
len = MLXSW_REG_MDDT_LEN - MLXSW_REG_MDDT_PAYLOAD_OFFSET;
MLXSW_REG_ZERO(mddt, payload);
mlxsw_reg_mddt_slot_index_set(payload, slot_index);
mlxsw_reg_mddt_device_index_set(payload, device_index);
mlxsw_reg_mddt_method_set(payload, method);
mlxsw_reg_mddt_register_id_set(payload, reg->id);
mlxsw_reg_mddt_read_size_set(payload, len / 4);
mlxsw_reg_mddt_write_size_set(payload, len / 4);
*inner_payload = mlxsw_reg_mddt_inner_payload(payload);
}
/* MDDQ - Management DownStream Device Query Register
* --------------------------------------------------
* This register allows to query the DownStream device properties. The desired
......@@ -11385,7 +11474,11 @@ MLXSW_ITEM32(reg, mddq, sie, 0x00, 31, 1);
enum mlxsw_reg_mddq_query_type {
MLXSW_REG_MDDQ_QUERY_TYPE_SLOT_INFO = 1,
MLXSW_REG_MDDQ_QUERY_TYPE_SLOT_NAME = 3,
MLXSW_REG_MDDQ_QUERY_TYPE_DEVICE_INFO, /* If there are no devices
* on the slot, data_valid
* will be '0'.
*/
MLXSW_REG_MDDQ_QUERY_TYPE_SLOT_NAME,
};
/* reg_mddq_query_type
......@@ -11399,6 +11492,28 @@ MLXSW_ITEM32(reg, mddq, query_type, 0x00, 16, 8);
*/
MLXSW_ITEM32(reg, mddq, slot_index, 0x00, 0, 4);
/* reg_mddq_response_msg_seq
* Response message sequential number. For a specific request, the response
* message sequential number is the following one. In addition, the last
* message should be 0.
* Access: RO
*/
MLXSW_ITEM32(reg, mddq, response_msg_seq, 0x04, 16, 8);
/* reg_mddq_request_msg_seq
* Request message sequential number.
* The first message number should be 0.
* Access: Index
*/
MLXSW_ITEM32(reg, mddq, request_msg_seq, 0x04, 0, 8);
/* reg_mddq_data_valid
* If set, the data in the data field is valid and contain the information
* for the queried index.
* Access: RO
*/
MLXSW_ITEM32(reg, mddq, data_valid, 0x08, 31, 1);
/* reg_mddq_slot_info_provisioned
* If set, the INI file is applied and the card is provisioned.
* Access: RO
......@@ -11485,6 +11600,61 @@ mlxsw_reg_mddq_slot_info_unpack(const char *payload, u8 *p_slot_index,
*p_card_type = mlxsw_reg_mddq_slot_info_card_type_get(payload);
}
/* reg_mddq_device_info_flash_owner
* If set, the device is the flash owner. Otherwise, a shared flash
* is used by this device (another device is the flash owner).
* Access: RO
*/
MLXSW_ITEM32(reg, mddq, device_info_flash_owner, 0x10, 30, 1);
/* reg_mddq_device_info_device_index
* Device index. The first device should number 0.
* Access: RO
*/
MLXSW_ITEM32(reg, mddq, device_info_device_index, 0x10, 0, 8);
/* reg_mddq_device_info_fw_major
* Major FW version number.
* Access: RO
*/
MLXSW_ITEM32(reg, mddq, device_info_fw_major, 0x14, 16, 16);
/* reg_mddq_device_info_fw_minor
* Minor FW version number.
* Access: RO
*/
MLXSW_ITEM32(reg, mddq, device_info_fw_minor, 0x18, 16, 16);
/* reg_mddq_device_info_fw_sub_minor
* Sub-minor FW version number.
* Access: RO
*/
MLXSW_ITEM32(reg, mddq, device_info_fw_sub_minor, 0x18, 0, 16);
static inline void
mlxsw_reg_mddq_device_info_pack(char *payload, u8 slot_index,
u8 request_msg_seq)
{
__mlxsw_reg_mddq_pack(payload, slot_index,
MLXSW_REG_MDDQ_QUERY_TYPE_DEVICE_INFO);
mlxsw_reg_mddq_request_msg_seq_set(payload, request_msg_seq);
}
static inline void
mlxsw_reg_mddq_device_info_unpack(const char *payload, u8 *p_response_msg_seq,
bool *p_data_valid, bool *p_flash_owner,
u8 *p_device_index, u16 *p_fw_major,
u16 *p_fw_minor, u16 *p_fw_sub_minor)
{
*p_response_msg_seq = mlxsw_reg_mddq_response_msg_seq_get(payload);
*p_data_valid = mlxsw_reg_mddq_data_valid_get(payload);
*p_flash_owner = mlxsw_reg_mddq_device_info_flash_owner_get(payload);
*p_device_index = mlxsw_reg_mddq_device_info_device_index_get(payload);
*p_fw_major = mlxsw_reg_mddq_device_info_fw_major_get(payload);
*p_fw_minor = mlxsw_reg_mddq_device_info_fw_minor_get(payload);
*p_fw_sub_minor = mlxsw_reg_mddq_device_info_fw_sub_minor_get(payload);
}
#define MLXSW_REG_MDDQ_SLOT_ASCII_NAME_LEN 20
/* reg_mddq_slot_ascii_name
......@@ -12862,6 +13032,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
MLXSW_REG(mfgd),
MLXSW_REG(mgpir),
MLXSW_REG(mbct),
MLXSW_REG(mddt),
MLXSW_REG(mddq),
MLXSW_REG(mddc),
MLXSW_REG(mfde),
......
......@@ -1580,6 +1580,8 @@ void devlink_linecard_provision_clear(struct devlink_linecard *linecard);
void devlink_linecard_provision_fail(struct devlink_linecard *linecard);
void devlink_linecard_activate(struct devlink_linecard *linecard);
void devlink_linecard_deactivate(struct devlink_linecard *linecard);
void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
struct devlink *nested_devlink);
int devl_sb_register(struct devlink *devlink, unsigned int sb_index,
u32 size, u16 ingress_pools_count,
u16 egress_pools_count, u16 ingress_tc_count,
......
......@@ -576,6 +576,8 @@ enum devlink_attr {
DEVLINK_ATTR_LINECARD_TYPE, /* string */
DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES, /* nested */
DEVLINK_ATTR_NESTED_DEVLINK, /* nested */
/* add new attributes above here, update the policy in devlink.c */
__DEVLINK_ATTR_MAX,
......
This diff is collapsed.
......@@ -84,6 +84,13 @@ lc_wait_until_port_count_is()
busywait "$timeout" until_lc_port_count_is "$port_count" lc_port_count_get "$lc"
}
lc_nested_devlink_dev_get()
{
local lc=$1
devlink lc show $DEVLINK_DEV lc $lc -j | jq -e -r ".[][][].nested_devlink"
}
PROV_UNPROV_TIMEOUT=8000 # ms
POST_PROV_ACT_TIMEOUT=2000 # ms
PROV_PORTS_INSTANTIATION_TIMEOUT=15000 # ms
......@@ -191,12 +198,30 @@ ports_check()
check_err $? "Unexpected port count linecard $lc (got $port_count, expected $expected_port_count)"
}
lc_dev_info_provisioned_check()
{
local lc=$1
local nested_devlink_dev=$2
local fixed_hw_revision
local running_ini_version
fixed_hw_revision=$(devlink dev info $nested_devlink_dev -j | \
jq -e -r '.[][].versions.fixed."hw.revision"')
check_err $? "Failed to get linecard $lc fixed.hw.revision"
log_info "Linecard $lc fixed.hw.revision: \"$fixed_hw_revision\""
running_ini_version=$(devlink dev info $nested_devlink_dev -j | \
jq -e -r '.[][].versions.running."ini.version"')
check_err $? "Failed to get linecard $lc running.ini.version"
log_info "Linecard $lc running.ini.version: \"$running_ini_version\""
}
provision_test()
{
RET=0
local lc
local type
local state
local nested_devlink_dev
lc=$LC_SLOT
supported_types_check $lc
......@@ -207,6 +232,11 @@ provision_test()
fi
provision_one $lc $LC_16X100G_TYPE
ports_check $lc $LC_16X100G_PORT_COUNT
nested_devlink_dev=$(lc_nested_devlink_dev_get $lc)
check_err $? "Failed to get nested devlink handle of linecard $lc"
lc_dev_info_provisioned_check $lc $nested_devlink_dev
log_test "Provision"
}
......@@ -220,12 +250,32 @@ interface_check()
setup_wait
}
lc_dev_info_active_check()
{
local lc=$1
local nested_devlink_dev=$2
local fixed_device_fw_psid
local running_device_fw
fixed_device_fw_psid=$(devlink dev info $nested_devlink_dev -j | \
jq -e -r ".[][].versions.fixed" | \
jq -e -r '."fw.psid"')
check_err $? "Failed to get linecard $lc fixed fw PSID"
log_info "Linecard $lc fixed.fw.psid: \"$fixed_device_fw_psid\""
running_device_fw=$(devlink dev info $nested_devlink_dev -j | \
jq -e -r ".[][].versions.running.fw")
check_err $? "Failed to get linecard $lc running.fw.version"
log_info "Linecard $lc running.fw: \"$running_device_fw\""
}
activation_16x100G_test()
{
RET=0
local lc
local type
local state
local nested_devlink_dev
lc=$LC_SLOT
type=$LC_16X100G_TYPE
......@@ -238,6 +288,10 @@ activation_16x100G_test()
interface_check
nested_devlink_dev=$(lc_nested_devlink_dev_get $lc)
check_err $? "Failed to get nested devlink handle of linecard $lc"
lc_dev_info_active_check $lc $nested_devlink_dev
log_test "Activation 16x100G"
}
......
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