diff options
author | Jiri Pirko | 2016-10-28 21:35:55 +0200 |
---|---|---|
committer | David S. Miller | 2016-10-30 21:50:17 +0100 |
commit | 67963a33b4fde8f77b046f80daf83afc6e126991 (patch) | |
tree | cfc60a14421cde82d9081dff8a1ec6d1f1899383 /drivers/net/ethernet/mellanox/mlxsw/core.c | |
parent | mlxsw: reg: Add local-port to Infiniband port mapping (diff) | |
download | kernel-qcow2-linux-67963a33b4fde8f77b046f80daf83afc6e126991.tar.gz kernel-qcow2-linux-67963a33b4fde8f77b046f80daf83afc6e126991.tar.xz kernel-qcow2-linux-67963a33b4fde8f77b046f80daf83afc6e126991.zip |
mlxsw: Make devlink port instances independent of spectrum/switchx2 port instances
Currently, devlink register/unregister is done directly from
spectrum/switchx2 port create/remove functions. With a need to
introduce a port type change, the devlink port instances have to be
persistent across type changes, therefore across port create/remove
function calls. So do a bit of reshuffling to achieve that.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Elad Raz <eladr@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/core.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/core.c | 82 |
1 files changed, 68 insertions, 14 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index 02183f6a8b93..b50acb1a7260 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -90,6 +90,22 @@ struct mlxsw_core_pcpu_stats { u32 port_rx_invalid; }; +struct mlxsw_core_port { + struct devlink_port devlink_port; + void *port_driver_priv; +}; + +void *mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port) +{ + return mlxsw_core_port->port_driver_priv; +} +EXPORT_SYMBOL(mlxsw_core_port_driver_priv); + +static bool mlxsw_core_port_check(struct mlxsw_core_port *mlxsw_core_port) +{ + return mlxsw_core_port->port_driver_priv != NULL; +} + struct mlxsw_core { struct mlxsw_driver *driver; const struct mlxsw_bus *bus; @@ -114,6 +130,7 @@ struct mlxsw_core { } lag; struct mlxsw_res res; struct mlxsw_hwmon *hwmon; + struct mlxsw_core_port ports[MLXSW_PORT_MAX_PORTS]; unsigned long driver_priv[0]; /* driver_priv has to be always the last item */ }; @@ -928,7 +945,8 @@ static int mlxsw_devlink_sb_port_pool_get(struct devlink_port *devlink_port, struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver; struct mlxsw_core_port *mlxsw_core_port = __dl_port(devlink_port); - if (!mlxsw_driver->sb_port_pool_get) + if (!mlxsw_driver->sb_port_pool_get || + !mlxsw_core_port_check(mlxsw_core_port)) return -EOPNOTSUPP; return mlxsw_driver->sb_port_pool_get(mlxsw_core_port, sb_index, pool_index, p_threshold); @@ -942,7 +960,8 @@ static int mlxsw_devlink_sb_port_pool_set(struct devlink_port *devlink_port, struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver; struct mlxsw_core_port *mlxsw_core_port = __dl_port(devlink_port); - if (!mlxsw_driver->sb_port_pool_set) + if (!mlxsw_driver->sb_port_pool_set || + !mlxsw_core_port_check(mlxsw_core_port)) return -EOPNOTSUPP; return mlxsw_driver->sb_port_pool_set(mlxsw_core_port, sb_index, pool_index, threshold); @@ -958,7 +977,8 @@ mlxsw_devlink_sb_tc_pool_bind_get(struct devlink_port *devlink_port, struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver; struct mlxsw_core_port *mlxsw_core_port = __dl_port(devlink_port); - if (!mlxsw_driver->sb_tc_pool_bind_get) + if (!mlxsw_driver->sb_tc_pool_bind_get || + !mlxsw_core_port_check(mlxsw_core_port)) return -EOPNOTSUPP; return mlxsw_driver->sb_tc_pool_bind_get(mlxsw_core_port, sb_index, tc_index, pool_type, @@ -975,7 +995,8 @@ mlxsw_devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port, struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver; struct mlxsw_core_port *mlxsw_core_port = __dl_port(devlink_port); - if (!mlxsw_driver->sb_tc_pool_bind_set) + if (!mlxsw_driver->sb_tc_pool_bind_set || + !mlxsw_core_port_check(mlxsw_core_port)) return -EOPNOTSUPP; return mlxsw_driver->sb_tc_pool_bind_set(mlxsw_core_port, sb_index, tc_index, pool_type, @@ -1013,7 +1034,8 @@ mlxsw_devlink_sb_occ_port_pool_get(struct devlink_port *devlink_port, struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver; struct mlxsw_core_port *mlxsw_core_port = __dl_port(devlink_port); - if (!mlxsw_driver->sb_occ_port_pool_get) + if (!mlxsw_driver->sb_occ_port_pool_get || + !mlxsw_core_port_check(mlxsw_core_port)) return -EOPNOTSUPP; return mlxsw_driver->sb_occ_port_pool_get(mlxsw_core_port, sb_index, pool_index, p_cur, p_max); @@ -1029,7 +1051,8 @@ mlxsw_devlink_sb_occ_tc_port_bind_get(struct devlink_port *devlink_port, struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver; struct mlxsw_core_port *mlxsw_core_port = __dl_port(devlink_port); - if (!mlxsw_driver->sb_occ_tc_port_bind_get) + if (!mlxsw_driver->sb_occ_tc_port_bind_get || + !mlxsw_core_port_check(mlxsw_core_port)) return -EOPNOTSUPP; return mlxsw_driver->sb_occ_tc_port_bind_get(mlxsw_core_port, sb_index, tc_index, @@ -1656,28 +1679,59 @@ u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core, } EXPORT_SYMBOL(mlxsw_core_res_get); -int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, - struct mlxsw_core_port *mlxsw_core_port, u8 local_port, - struct net_device *dev, bool split, u32 split_group) +int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port) { struct devlink *devlink = priv_to_devlink(mlxsw_core); + struct mlxsw_core_port *mlxsw_core_port = + &mlxsw_core->ports[local_port]; struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port; + int err; - if (split) - devlink_port_split_set(devlink_port, split_group); - devlink_port_type_eth_set(devlink_port, dev); - return devlink_port_register(devlink, devlink_port, local_port); + err = devlink_port_register(devlink, devlink_port, local_port); + if (err) + memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port)); + return err; } EXPORT_SYMBOL(mlxsw_core_port_init); -void mlxsw_core_port_fini(struct mlxsw_core_port *mlxsw_core_port) +void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port) { + struct mlxsw_core_port *mlxsw_core_port = + &mlxsw_core->ports[local_port]; struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port; devlink_port_unregister(devlink_port); + memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port)); } EXPORT_SYMBOL(mlxsw_core_port_fini); +void mlxsw_core_port_set(struct mlxsw_core *mlxsw_core, u8 local_port, + void *port_driver_priv, struct net_device *dev, + bool split, u32 split_group) +{ + struct mlxsw_core_port *mlxsw_core_port = + &mlxsw_core->ports[local_port]; + struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port; + + mlxsw_core_port->port_driver_priv = port_driver_priv; + if (split) + devlink_port_split_set(devlink_port, split_group); + devlink_port_type_eth_set(devlink_port, dev); +} +EXPORT_SYMBOL(mlxsw_core_port_set); + +void mlxsw_core_port_clear(struct mlxsw_core *mlxsw_core, u8 local_port, + void *port_driver_priv) +{ + struct mlxsw_core_port *mlxsw_core_port = + &mlxsw_core->ports[local_port]; + struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port; + + mlxsw_core_port->port_driver_priv = port_driver_priv; + devlink_port_type_clear(devlink_port); +} +EXPORT_SYMBOL(mlxsw_core_port_clear); + static void mlxsw_core_buf_dump_dbg(struct mlxsw_core *mlxsw_core, const char *buf, size_t size) { |