mlxsw: core: Extend driver ops by remove selected ports op
authorJiri Pirko <jiri@nvidia.com>
Mon, 18 Apr 2022 06:42:39 +0000 (09:42 +0300)
committerDavid S. Miller <davem@davemloft.net>
Mon, 18 Apr 2022 10:00:19 +0000 (11:00 +0100)
In case of line card implementation, the core has to have a way to
remove relevant ports manually. Extend the Spectrum driver ops by an op
that implements port removal of selected ports upon request.

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>
drivers/net/ethernet/mellanox/mlxsw/core.c
drivers/net/ethernet/mellanox/mlxsw/core.h
drivers/net/ethernet/mellanox/mlxsw/spectrum.c

index 5e1855f..9b5c2c6 100644 (file)
@@ -3143,6 +3143,15 @@ bool mlxsw_core_port_is_xm(const struct mlxsw_core *mlxsw_core, u16 local_port)
 }
 EXPORT_SYMBOL(mlxsw_core_port_is_xm);
 
+void mlxsw_core_ports_remove_selected(struct mlxsw_core *mlxsw_core,
+                                     bool (*selector)(void *priv, u16 local_port),
+                                     void *priv)
+{
+       if (WARN_ON_ONCE(!mlxsw_core->driver->ports_remove_selected))
+               return;
+       mlxsw_core->driver->ports_remove_selected(mlxsw_core, selector, priv);
+}
+
 struct mlxsw_env *mlxsw_core_env(const struct mlxsw_core *mlxsw_core)
 {
        return mlxsw_core->env;
index 7d6f8f3..865252e 100644 (file)
@@ -258,6 +258,10 @@ struct devlink_port *
 mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core,
                                 u16 local_port);
 bool mlxsw_core_port_is_xm(const struct mlxsw_core *mlxsw_core, u16 local_port);
+void mlxsw_core_ports_remove_selected(struct mlxsw_core *mlxsw_core,
+                                     bool (*selector)(void *priv,
+                                                      u16 local_port),
+                                     void *priv);
 struct mlxsw_env *mlxsw_core_env(const struct mlxsw_core *mlxsw_core);
 
 int mlxsw_core_schedule_dw(struct delayed_work *dwork, unsigned long delay);
@@ -331,6 +335,10 @@ struct mlxsw_driver {
                          unsigned int count, struct netlink_ext_ack *extack);
        int (*port_unsplit)(struct mlxsw_core *mlxsw_core, u16 local_port,
                            struct netlink_ext_ack *extack);
+       void (*ports_remove_selected)(struct mlxsw_core *mlxsw_core,
+                                     bool (*selector)(void *priv,
+                                                      u16 local_port),
+                                     void *priv);
        int (*sb_pool_get)(struct mlxsw_core *mlxsw_core,
                           unsigned int sb_index, u16 pool_index,
                           struct devlink_sb_pool_info *pool_info);
index b4e064b..c3b9e24 100644 (file)
@@ -1999,6 +1999,20 @@ static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp)
        mlxsw_sp->ports = NULL;
 }
 
+static void
+mlxsw_sp_ports_remove_selected(struct mlxsw_core *mlxsw_core,
+                              bool (*selector)(void *priv, u16 local_port),
+                              void *priv)
+{
+       struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
+       unsigned int max_ports = mlxsw_core_max_ports(mlxsw_core);
+       int i;
+
+       for (i = 1; i < max_ports; i++)
+               if (mlxsw_sp_port_created(mlxsw_sp, i) && selector(priv, i))
+                       mlxsw_sp_port_remove(mlxsw_sp, i);
+}
+
 static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
 {
        unsigned int max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
@@ -3785,6 +3799,7 @@ static struct mlxsw_driver mlxsw_sp2_driver = {
        .fini                           = mlxsw_sp_fini,
        .port_split                     = mlxsw_sp_port_split,
        .port_unsplit                   = mlxsw_sp_port_unsplit,
+       .ports_remove_selected          = mlxsw_sp_ports_remove_selected,
        .sb_pool_get                    = mlxsw_sp_sb_pool_get,
        .sb_pool_set                    = mlxsw_sp_sb_pool_set,
        .sb_port_pool_get               = mlxsw_sp_sb_port_pool_get,
@@ -3822,6 +3837,7 @@ static struct mlxsw_driver mlxsw_sp3_driver = {
        .fini                           = mlxsw_sp_fini,
        .port_split                     = mlxsw_sp_port_split,
        .port_unsplit                   = mlxsw_sp_port_unsplit,
+       .ports_remove_selected          = mlxsw_sp_ports_remove_selected,
        .sb_pool_get                    = mlxsw_sp_sb_pool_get,
        .sb_pool_set                    = mlxsw_sp_sb_pool_set,
        .sb_port_pool_get               = mlxsw_sp_sb_port_pool_get,
@@ -3857,6 +3873,7 @@ static struct mlxsw_driver mlxsw_sp4_driver = {
        .fini                           = mlxsw_sp_fini,
        .port_split                     = mlxsw_sp_port_split,
        .port_unsplit                   = mlxsw_sp_port_unsplit,
+       .ports_remove_selected          = mlxsw_sp_ports_remove_selected,
        .sb_pool_get                    = mlxsw_sp_sb_pool_get,
        .sb_pool_set                    = mlxsw_sp_sb_pool_set,
        .sb_port_pool_get               = mlxsw_sp_sb_port_pool_get,