mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 10:29:37 +00:00
mlxsw: spectrum: Add infrastructure for parsing configuration
Spectrum ASICs have a configurable limit on how deep into the packet they parse. By default, the limit is 96 bytes. There are several cases where this parsing depth is not enough and there is a need to increase it. Currently, increasing parsing depth is maintained as part of VxLAN module, because the MPRS register which configures parsing depth also configures UDP destination port number used for VxLAN encapsulation and decapsulation. Add an API for increasing parsing depth as part of spectrum.c code, so that it will be possible to use it from other modules. In addition, add an API for setting UDP destination port and protect it using a dedicated lock for saving parsing configurations. The lock is needed as not all the callers hold RTNL lock. Maintain a counter for increased parsing depth consumers. For first consumer subscription, increase the parsing depth and for last consumer unsubscription, set parsing depth to default value. Signed-off-by: Amit Cohen <amcohen@nvidia.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
809159ee59
commit
2d91f0803b
2 changed files with 94 additions and 0 deletions
|
@ -2717,6 +2717,22 @@ mlxsw_sp_sample_trigger_params_unset(struct mlxsw_sp *mlxsw_sp,
|
||||||
static int mlxsw_sp_netdevice_event(struct notifier_block *unused,
|
static int mlxsw_sp_netdevice_event(struct notifier_block *unused,
|
||||||
unsigned long event, void *ptr);
|
unsigned long event, void *ptr);
|
||||||
|
|
||||||
|
#define MLXSW_SP_DEFAULT_PARSING_DEPTH 96
|
||||||
|
#define MLXSW_SP_INCREASED_PARSING_DEPTH 128
|
||||||
|
#define MLXSW_SP_DEFAULT_VXLAN_UDP_DPORT 4789
|
||||||
|
|
||||||
|
static void mlxsw_sp_parsing_init(struct mlxsw_sp *mlxsw_sp)
|
||||||
|
{
|
||||||
|
mlxsw_sp->parsing.parsing_depth = MLXSW_SP_DEFAULT_PARSING_DEPTH;
|
||||||
|
mlxsw_sp->parsing.vxlan_udp_dport = MLXSW_SP_DEFAULT_VXLAN_UDP_DPORT;
|
||||||
|
mutex_init(&mlxsw_sp->parsing.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mlxsw_sp_parsing_fini(struct mlxsw_sp *mlxsw_sp)
|
||||||
|
{
|
||||||
|
mutex_destroy(&mlxsw_sp->parsing.lock);
|
||||||
|
}
|
||||||
|
|
||||||
static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
|
static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
|
||||||
const struct mlxsw_bus_info *mlxsw_bus_info,
|
const struct mlxsw_bus_info *mlxsw_bus_info,
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
|
@ -2727,6 +2743,7 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
|
||||||
mlxsw_sp->core = mlxsw_core;
|
mlxsw_sp->core = mlxsw_core;
|
||||||
mlxsw_sp->bus_info = mlxsw_bus_info;
|
mlxsw_sp->bus_info = mlxsw_bus_info;
|
||||||
|
|
||||||
|
mlxsw_sp_parsing_init(mlxsw_sp);
|
||||||
mlxsw_core_emad_string_tlv_enable(mlxsw_core);
|
mlxsw_core_emad_string_tlv_enable(mlxsw_core);
|
||||||
|
|
||||||
err = mlxsw_sp_base_mac_get(mlxsw_sp);
|
err = mlxsw_sp_base_mac_get(mlxsw_sp);
|
||||||
|
@ -2926,6 +2943,7 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
|
||||||
mlxsw_sp_fids_fini(mlxsw_sp);
|
mlxsw_sp_fids_fini(mlxsw_sp);
|
||||||
err_fids_init:
|
err_fids_init:
|
||||||
mlxsw_sp_kvdl_fini(mlxsw_sp);
|
mlxsw_sp_kvdl_fini(mlxsw_sp);
|
||||||
|
mlxsw_sp_parsing_fini(mlxsw_sp);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3046,6 +3064,7 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
|
||||||
mlxsw_sp_policers_fini(mlxsw_sp);
|
mlxsw_sp_policers_fini(mlxsw_sp);
|
||||||
mlxsw_sp_fids_fini(mlxsw_sp);
|
mlxsw_sp_fids_fini(mlxsw_sp);
|
||||||
mlxsw_sp_kvdl_fini(mlxsw_sp);
|
mlxsw_sp_kvdl_fini(mlxsw_sp);
|
||||||
|
mlxsw_sp_parsing_fini(mlxsw_sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Per-FID flood tables are used for both "true" 802.1D FIDs and emulated
|
/* Per-FID flood tables are used for both "true" 802.1D FIDs and emulated
|
||||||
|
@ -3611,6 +3630,69 @@ void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port)
|
||||||
dev_put(mlxsw_sp_port->dev);
|
dev_put(mlxsw_sp_port->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mlxsw_sp_parsing_depth_inc(struct mlxsw_sp *mlxsw_sp)
|
||||||
|
{
|
||||||
|
char mprs_pl[MLXSW_REG_MPRS_LEN];
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
mutex_lock(&mlxsw_sp->parsing.lock);
|
||||||
|
|
||||||
|
if (refcount_inc_not_zero(&mlxsw_sp->parsing.parsing_depth_ref))
|
||||||
|
goto out_unlock;
|
||||||
|
|
||||||
|
mlxsw_reg_mprs_pack(mprs_pl, MLXSW_SP_INCREASED_PARSING_DEPTH,
|
||||||
|
mlxsw_sp->parsing.vxlan_udp_dport);
|
||||||
|
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mprs), mprs_pl);
|
||||||
|
if (err)
|
||||||
|
goto out_unlock;
|
||||||
|
|
||||||
|
mlxsw_sp->parsing.parsing_depth = MLXSW_SP_INCREASED_PARSING_DEPTH;
|
||||||
|
refcount_set(&mlxsw_sp->parsing.parsing_depth_ref, 1);
|
||||||
|
|
||||||
|
out_unlock:
|
||||||
|
mutex_unlock(&mlxsw_sp->parsing.lock);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mlxsw_sp_parsing_depth_dec(struct mlxsw_sp *mlxsw_sp)
|
||||||
|
{
|
||||||
|
char mprs_pl[MLXSW_REG_MPRS_LEN];
|
||||||
|
|
||||||
|
mutex_lock(&mlxsw_sp->parsing.lock);
|
||||||
|
|
||||||
|
if (!refcount_dec_and_test(&mlxsw_sp->parsing.parsing_depth_ref))
|
||||||
|
goto out_unlock;
|
||||||
|
|
||||||
|
mlxsw_reg_mprs_pack(mprs_pl, MLXSW_SP_DEFAULT_PARSING_DEPTH,
|
||||||
|
mlxsw_sp->parsing.vxlan_udp_dport);
|
||||||
|
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mprs), mprs_pl);
|
||||||
|
mlxsw_sp->parsing.parsing_depth = MLXSW_SP_DEFAULT_PARSING_DEPTH;
|
||||||
|
|
||||||
|
out_unlock:
|
||||||
|
mutex_unlock(&mlxsw_sp->parsing.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mlxsw_sp_parsing_vxlan_udp_dport_set(struct mlxsw_sp *mlxsw_sp,
|
||||||
|
__be16 udp_dport)
|
||||||
|
{
|
||||||
|
char mprs_pl[MLXSW_REG_MPRS_LEN];
|
||||||
|
int err;
|
||||||
|
|
||||||
|
mutex_lock(&mlxsw_sp->parsing.lock);
|
||||||
|
|
||||||
|
mlxsw_reg_mprs_pack(mprs_pl, mlxsw_sp->parsing.parsing_depth,
|
||||||
|
be16_to_cpu(udp_dport));
|
||||||
|
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mprs), mprs_pl);
|
||||||
|
if (err)
|
||||||
|
goto out_unlock;
|
||||||
|
|
||||||
|
mlxsw_sp->parsing.vxlan_udp_dport = be16_to_cpu(udp_dport);
|
||||||
|
|
||||||
|
out_unlock:
|
||||||
|
mutex_unlock(&mlxsw_sp->parsing.lock);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mlxsw_sp_port_lag_uppers_cleanup(struct mlxsw_sp_port *mlxsw_sp_port,
|
mlxsw_sp_port_lag_uppers_cleanup(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
struct net_device *lag_dev)
|
struct net_device *lag_dev)
|
||||||
|
|
|
@ -148,6 +148,13 @@ struct mlxsw_sp_port_mapping {
|
||||||
u8 lane;
|
u8 lane;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mlxsw_sp_parsing {
|
||||||
|
refcount_t parsing_depth_ref;
|
||||||
|
u16 parsing_depth;
|
||||||
|
u16 vxlan_udp_dport;
|
||||||
|
struct mutex lock; /* Protects parsing configuration */
|
||||||
|
};
|
||||||
|
|
||||||
struct mlxsw_sp {
|
struct mlxsw_sp {
|
||||||
struct mlxsw_sp_port **ports;
|
struct mlxsw_sp_port **ports;
|
||||||
struct mlxsw_core *core;
|
struct mlxsw_core *core;
|
||||||
|
@ -173,6 +180,7 @@ struct mlxsw_sp {
|
||||||
struct mlxsw_sp_counter_pool *counter_pool;
|
struct mlxsw_sp_counter_pool *counter_pool;
|
||||||
struct mlxsw_sp_span *span;
|
struct mlxsw_sp_span *span;
|
||||||
struct mlxsw_sp_trap *trap;
|
struct mlxsw_sp_trap *trap;
|
||||||
|
struct mlxsw_sp_parsing parsing;
|
||||||
const struct mlxsw_sp_switchdev_ops *switchdev_ops;
|
const struct mlxsw_sp_switchdev_ops *switchdev_ops;
|
||||||
const struct mlxsw_sp_kvdl_ops *kvdl_ops;
|
const struct mlxsw_sp_kvdl_ops *kvdl_ops;
|
||||||
const struct mlxsw_afa_ops *afa_ops;
|
const struct mlxsw_afa_ops *afa_ops;
|
||||||
|
@ -652,6 +660,10 @@ struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev);
|
||||||
struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev);
|
struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev);
|
||||||
void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port);
|
void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port);
|
||||||
struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev);
|
struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev);
|
||||||
|
int mlxsw_sp_parsing_depth_inc(struct mlxsw_sp *mlxsw_sp);
|
||||||
|
void mlxsw_sp_parsing_depth_dec(struct mlxsw_sp *mlxsw_sp);
|
||||||
|
int mlxsw_sp_parsing_vxlan_udp_dport_set(struct mlxsw_sp *mlxsw_sp,
|
||||||
|
__be16 udp_dport);
|
||||||
|
|
||||||
/* spectrum_dcb.c */
|
/* spectrum_dcb.c */
|
||||||
#ifdef CONFIG_MLXSW_SPECTRUM_DCB
|
#ifdef CONFIG_MLXSW_SPECTRUM_DCB
|
||||||
|
|
Loading…
Reference in a new issue