mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-27 21:03:32 +00:00
mlxsw: Register physical ports as a devlink resource
The switch ASIC has a limited capacity of physical ('flavour physical' in devlink terminology) ports that it can support. While each system is brought up with a different number of ports, this number can be increased via splitting up to the ASIC's limit. Expose physical ports as a devlink resource so that user space will have visibility to the maximum number of ports that can be supported and the current occupancy. In addition, add a "Generic Resources" section in devlink-resource documentation so the different drivers will be aligned by the same resource name when exposing to user space. Signed-off-by: Danielle Ratson <danieller@nvidia.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
351876424e
commit
321f7ab0d4
6 changed files with 93 additions and 11 deletions
|
@ -23,6 +23,20 @@ current size and related sub resources. To access a sub resource, you
|
||||||
specify the path of the resource. For example ``/IPv4/fib`` is the id for
|
specify the path of the resource. For example ``/IPv4/fib`` is the id for
|
||||||
the ``fib`` sub-resource under the ``IPv4`` resource.
|
the ``fib`` sub-resource under the ``IPv4`` resource.
|
||||||
|
|
||||||
|
Generic Resources
|
||||||
|
=================
|
||||||
|
|
||||||
|
Generic resources are used to describe resources that can be shared by multiple
|
||||||
|
device drivers and their description must be added to the following table:
|
||||||
|
|
||||||
|
.. list-table:: List of Generic Resources
|
||||||
|
:widths: 10 90
|
||||||
|
|
||||||
|
* - Name
|
||||||
|
- Description
|
||||||
|
* - ``physical_ports``
|
||||||
|
- A limited capacity of physical ports that the switch ASIC can support
|
||||||
|
|
||||||
example usage
|
example usage
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,7 @@ struct mlxsw_core {
|
||||||
struct mlxsw_thermal *thermal;
|
struct mlxsw_thermal *thermal;
|
||||||
struct mlxsw_core_port *ports;
|
struct mlxsw_core_port *ports;
|
||||||
unsigned int max_ports;
|
unsigned int max_ports;
|
||||||
|
atomic_t active_ports_count;
|
||||||
bool fw_flash_in_progress;
|
bool fw_flash_in_progress;
|
||||||
struct {
|
struct {
|
||||||
struct devlink_health_reporter *fw_fatal;
|
struct devlink_health_reporter *fw_fatal;
|
||||||
|
@ -96,8 +97,36 @@ struct mlxsw_core {
|
||||||
|
|
||||||
#define MLXSW_PORT_MAX_PORTS_DEFAULT 0x40
|
#define MLXSW_PORT_MAX_PORTS_DEFAULT 0x40
|
||||||
|
|
||||||
static int mlxsw_ports_init(struct mlxsw_core *mlxsw_core)
|
static u64 mlxsw_ports_occ_get(void *priv)
|
||||||
{
|
{
|
||||||
|
struct mlxsw_core *mlxsw_core = priv;
|
||||||
|
|
||||||
|
return atomic_read(&mlxsw_core->active_ports_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mlxsw_core_resources_ports_register(struct mlxsw_core *mlxsw_core)
|
||||||
|
{
|
||||||
|
struct devlink *devlink = priv_to_devlink(mlxsw_core);
|
||||||
|
struct devlink_resource_size_params ports_num_params;
|
||||||
|
u32 max_ports;
|
||||||
|
|
||||||
|
max_ports = mlxsw_core->max_ports - 1;
|
||||||
|
devlink_resource_size_params_init(&ports_num_params, max_ports,
|
||||||
|
max_ports, 1,
|
||||||
|
DEVLINK_RESOURCE_UNIT_ENTRY);
|
||||||
|
|
||||||
|
return devlink_resource_register(devlink,
|
||||||
|
DEVLINK_RESOURCE_GENERIC_NAME_PORTS,
|
||||||
|
max_ports, MLXSW_CORE_RESOURCE_PORTS,
|
||||||
|
DEVLINK_RESOURCE_ID_PARENT_TOP,
|
||||||
|
&ports_num_params);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mlxsw_ports_init(struct mlxsw_core *mlxsw_core, bool reload)
|
||||||
|
{
|
||||||
|
struct devlink *devlink = priv_to_devlink(mlxsw_core);
|
||||||
|
int err;
|
||||||
|
|
||||||
/* Switch ports are numbered from 1 to queried value */
|
/* Switch ports are numbered from 1 to queried value */
|
||||||
if (MLXSW_CORE_RES_VALID(mlxsw_core, MAX_SYSTEM_PORT))
|
if (MLXSW_CORE_RES_VALID(mlxsw_core, MAX_SYSTEM_PORT))
|
||||||
mlxsw_core->max_ports = MLXSW_CORE_RES_GET(mlxsw_core,
|
mlxsw_core->max_ports = MLXSW_CORE_RES_GET(mlxsw_core,
|
||||||
|
@ -110,11 +139,30 @@ static int mlxsw_ports_init(struct mlxsw_core *mlxsw_core)
|
||||||
if (!mlxsw_core->ports)
|
if (!mlxsw_core->ports)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (!reload) {
|
||||||
|
err = mlxsw_core_resources_ports_register(mlxsw_core);
|
||||||
|
if (err)
|
||||||
|
goto err_resources_ports_register;
|
||||||
|
}
|
||||||
|
atomic_set(&mlxsw_core->active_ports_count, 0);
|
||||||
|
devlink_resource_occ_get_register(devlink, MLXSW_CORE_RESOURCE_PORTS,
|
||||||
|
mlxsw_ports_occ_get, mlxsw_core);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_resources_ports_register:
|
||||||
|
kfree(mlxsw_core->ports);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mlxsw_ports_fini(struct mlxsw_core *mlxsw_core)
|
static void mlxsw_ports_fini(struct mlxsw_core *mlxsw_core, bool reload)
|
||||||
{
|
{
|
||||||
|
struct devlink *devlink = priv_to_devlink(mlxsw_core);
|
||||||
|
|
||||||
|
devlink_resource_occ_get_unregister(devlink, MLXSW_CORE_RESOURCE_PORTS);
|
||||||
|
if (!reload)
|
||||||
|
devlink_resources_unregister(priv_to_devlink(mlxsw_core), NULL);
|
||||||
|
|
||||||
kfree(mlxsw_core->ports);
|
kfree(mlxsw_core->ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1897,7 +1945,7 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
|
||||||
goto err_register_resources;
|
goto err_register_resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mlxsw_ports_init(mlxsw_core);
|
err = mlxsw_ports_init(mlxsw_core, reload);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_ports_init;
|
goto err_ports_init;
|
||||||
|
|
||||||
|
@ -1986,7 +2034,7 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
|
||||||
err_emad_init:
|
err_emad_init:
|
||||||
kfree(mlxsw_core->lag.mapping);
|
kfree(mlxsw_core->lag.mapping);
|
||||||
err_alloc_lag_mapping:
|
err_alloc_lag_mapping:
|
||||||
mlxsw_ports_fini(mlxsw_core);
|
mlxsw_ports_fini(mlxsw_core, reload);
|
||||||
err_ports_init:
|
err_ports_init:
|
||||||
if (!reload)
|
if (!reload)
|
||||||
devlink_resources_unregister(devlink, NULL);
|
devlink_resources_unregister(devlink, NULL);
|
||||||
|
@ -2056,7 +2104,7 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core,
|
||||||
devlink_unregister(devlink);
|
devlink_unregister(devlink);
|
||||||
mlxsw_emad_fini(mlxsw_core);
|
mlxsw_emad_fini(mlxsw_core);
|
||||||
kfree(mlxsw_core->lag.mapping);
|
kfree(mlxsw_core->lag.mapping);
|
||||||
mlxsw_ports_fini(mlxsw_core);
|
mlxsw_ports_fini(mlxsw_core, reload);
|
||||||
if (!reload)
|
if (!reload)
|
||||||
devlink_resources_unregister(devlink, NULL);
|
devlink_resources_unregister(devlink, NULL);
|
||||||
mlxsw_core->bus->fini(mlxsw_core->bus_priv);
|
mlxsw_core->bus->fini(mlxsw_core->bus_priv);
|
||||||
|
@ -2755,16 +2803,25 @@ int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
|
||||||
const unsigned char *switch_id,
|
const unsigned char *switch_id,
|
||||||
unsigned char switch_id_len)
|
unsigned char switch_id_len)
|
||||||
{
|
{
|
||||||
return __mlxsw_core_port_init(mlxsw_core, local_port,
|
int err;
|
||||||
DEVLINK_PORT_FLAVOUR_PHYSICAL,
|
|
||||||
port_number, split, split_port_subnumber,
|
err = __mlxsw_core_port_init(mlxsw_core, local_port,
|
||||||
splittable, lanes,
|
DEVLINK_PORT_FLAVOUR_PHYSICAL,
|
||||||
switch_id, switch_id_len);
|
port_number, split, split_port_subnumber,
|
||||||
|
splittable, lanes,
|
||||||
|
switch_id, switch_id_len);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
atomic_inc(&mlxsw_core->active_ports_count);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mlxsw_core_port_init);
|
EXPORT_SYMBOL(mlxsw_core_port_init);
|
||||||
|
|
||||||
void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
|
void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
|
||||||
{
|
{
|
||||||
|
atomic_dec(&mlxsw_core->active_ports_count);
|
||||||
|
|
||||||
__mlxsw_core_port_fini(mlxsw_core, local_port);
|
__mlxsw_core_port_fini(mlxsw_core, local_port);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mlxsw_core_port_fini);
|
EXPORT_SYMBOL(mlxsw_core_port_fini);
|
||||||
|
|
|
@ -19,6 +19,11 @@
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
#include "resources.h"
|
#include "resources.h"
|
||||||
|
|
||||||
|
enum mlxsw_core_resource_id {
|
||||||
|
MLXSW_CORE_RESOURCE_PORTS = 1,
|
||||||
|
MLXSW_CORE_RESOURCE_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
struct mlxsw_core;
|
struct mlxsw_core;
|
||||||
struct mlxsw_core_port;
|
struct mlxsw_core_port;
|
||||||
struct mlxsw_driver;
|
struct mlxsw_driver;
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
#define MLXSW_SP_RESOURCE_NAME_COUNTERS_RIF "rif"
|
#define MLXSW_SP_RESOURCE_NAME_COUNTERS_RIF "rif"
|
||||||
|
|
||||||
enum mlxsw_sp_resource_id {
|
enum mlxsw_sp_resource_id {
|
||||||
MLXSW_SP_RESOURCE_KVD = 1,
|
MLXSW_SP_RESOURCE_KVD = MLXSW_CORE_RESOURCE_MAX,
|
||||||
MLXSW_SP_RESOURCE_KVD_LINEAR,
|
MLXSW_SP_RESOURCE_KVD_LINEAR,
|
||||||
MLXSW_SP_RESOURCE_KVD_HASH_SINGLE,
|
MLXSW_SP_RESOURCE_KVD_HASH_SINGLE,
|
||||||
MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE,
|
MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE,
|
||||||
|
|
|
@ -380,6 +380,8 @@ struct devlink_resource {
|
||||||
|
|
||||||
#define DEVLINK_RESOURCE_ID_PARENT_TOP 0
|
#define DEVLINK_RESOURCE_ID_PARENT_TOP 0
|
||||||
|
|
||||||
|
#define DEVLINK_RESOURCE_GENERIC_NAME_PORTS "physical_ports"
|
||||||
|
|
||||||
#define __DEVLINK_PARAM_MAX_STRING_VALUE 32
|
#define __DEVLINK_PARAM_MAX_STRING_VALUE 32
|
||||||
enum devlink_param_type {
|
enum devlink_param_type {
|
||||||
DEVLINK_PARAM_TYPE_U8,
|
DEVLINK_PARAM_TYPE_U8,
|
||||||
|
|
|
@ -8617,6 +8617,10 @@ EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
|
||||||
* @resource_id: resource's id
|
* @resource_id: resource's id
|
||||||
* @parent_resource_id: resource's parent id
|
* @parent_resource_id: resource's parent id
|
||||||
* @size_params: size parameters
|
* @size_params: size parameters
|
||||||
|
*
|
||||||
|
* Generic resources should reuse the same names across drivers.
|
||||||
|
* Please see the generic resources list at:
|
||||||
|
* Documentation/networking/devlink/devlink-resource.rst
|
||||||
*/
|
*/
|
||||||
int devlink_resource_register(struct devlink *devlink,
|
int devlink_resource_register(struct devlink *devlink,
|
||||||
const char *resource_name,
|
const char *resource_name,
|
||||||
|
|
Loading…
Reference in a new issue