Skip to content

Commit

Permalink
Merge branch 'mlxsw-various-updates'
Browse files Browse the repository at this point in the history
Ido Schimmel says:

====================
mlxsw: Various updates

This patchset contains miscellaneous updates for mlxsw. No user visible
changes that I am aware of.

Patches #1-#5 rework registration of internal traps in preparation of
line cards support.

Patch #6 improves driver resilience against a misbehaving device.

Patch #7 prevents the driver from overwriting device internal actions.
See the commit message for more details.
====================

Link: https://lore.kernel.org/r/20220127090226.283442-1-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Jan 28, 2022
2 parents 3268ee8 + ef14c29 commit d344e55
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 110 deletions.
75 changes: 68 additions & 7 deletions drivers/net/ethernet/mellanox/mlxsw/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,29 @@ struct mlxsw_event_listener_item {
void *priv;
};

static const u8 mlxsw_core_trap_groups[] = {
MLXSW_REG_HTGT_TRAP_GROUP_EMAD,
MLXSW_REG_HTGT_TRAP_GROUP_CORE_EVENT,
};

static int mlxsw_core_trap_groups_set(struct mlxsw_core *mlxsw_core)
{
char htgt_pl[MLXSW_REG_HTGT_LEN];
int err;
int i;

for (i = 0; i < ARRAY_SIZE(mlxsw_core_trap_groups); i++) {
mlxsw_reg_htgt_pack(htgt_pl, mlxsw_core_trap_groups[i],
MLXSW_REG_HTGT_INVALID_POLICER,
MLXSW_REG_HTGT_DEFAULT_PRIORITY,
MLXSW_REG_HTGT_DEFAULT_TC);
err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl);
if (err)
return err;
}
return 0;
}

/******************
* EMAD processing
******************/
Expand Down Expand Up @@ -777,16 +800,10 @@ static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core)
if (err)
goto err_trap_register;

err = mlxsw_core->driver->basic_trap_groups_set(mlxsw_core);
if (err)
goto err_emad_trap_set;
mlxsw_core->emad.use_emad = true;

return 0;

err_emad_trap_set:
mlxsw_core_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener,
mlxsw_core);
err_trap_register:
destroy_workqueue(mlxsw_core->emad_wq);
return err;
Expand Down Expand Up @@ -1706,7 +1723,7 @@ static void mlxsw_core_health_listener_func(const struct mlxsw_reg_info *reg,
}

static const struct mlxsw_listener mlxsw_core_health_listener =
MLXSW_EVENTL(mlxsw_core_health_listener_func, MFDE, MFDE);
MLXSW_CORE_EVENTL(mlxsw_core_health_listener_func, MFDE);

static int
mlxsw_core_health_fw_fatal_dump_fatal_cause(const char *mfde_pl,
Expand Down Expand Up @@ -2122,6 +2139,10 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
}
}

err = mlxsw_core_trap_groups_set(mlxsw_core);
if (err)
goto err_trap_groups_set;

err = mlxsw_emad_init(mlxsw_core);
if (err)
goto err_emad_init;
Expand Down Expand Up @@ -2181,6 +2202,7 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
err_register_params:
mlxsw_emad_fini(mlxsw_core);
err_emad_init:
err_trap_groups_set:
kfree(mlxsw_core->lag.mapping);
err_alloc_lag_mapping:
mlxsw_ports_fini(mlxsw_core, reload);
Expand Down Expand Up @@ -2540,6 +2562,45 @@ void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core,
}
EXPORT_SYMBOL(mlxsw_core_trap_unregister);

int mlxsw_core_traps_register(struct mlxsw_core *mlxsw_core,
const struct mlxsw_listener *listeners,
size_t listeners_count, void *priv)
{
int i, err;

for (i = 0; i < listeners_count; i++) {
err = mlxsw_core_trap_register(mlxsw_core,
&listeners[i],
priv);
if (err)
goto err_listener_register;
}
return 0;

err_listener_register:
for (i--; i >= 0; i--) {
mlxsw_core_trap_unregister(mlxsw_core,
&listeners[i],
priv);
}
return err;
}
EXPORT_SYMBOL(mlxsw_core_traps_register);

void mlxsw_core_traps_unregister(struct mlxsw_core *mlxsw_core,
const struct mlxsw_listener *listeners,
size_t listeners_count, void *priv)
{
int i;

for (i = 0; i < listeners_count; i++) {
mlxsw_core_trap_unregister(mlxsw_core,
&listeners[i],
priv);
}
}
EXPORT_SYMBOL(mlxsw_core_traps_unregister);

int mlxsw_core_trap_state_set(struct mlxsw_core *mlxsw_core,
const struct mlxsw_listener *listener,
bool enabled)
Expand Down
10 changes: 9 additions & 1 deletion drivers/net/ethernet/mellanox/mlxsw/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ struct mlxsw_listener {
.enabled_on_register = true, \
}

#define MLXSW_CORE_EVENTL(_func, _trap_id) \
MLXSW_EVENTL(_func, _trap_id, CORE_EVENT)

int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core,
const struct mlxsw_rx_listener *rxl,
void *priv, bool enabled);
Expand All @@ -181,6 +184,12 @@ int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core,
void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core,
const struct mlxsw_listener *listener,
void *priv);
int mlxsw_core_traps_register(struct mlxsw_core *mlxsw_core,
const struct mlxsw_listener *listeners,
size_t listeners_count, void *priv);
void mlxsw_core_traps_unregister(struct mlxsw_core *mlxsw_core,
const struct mlxsw_listener *listeners,
size_t listeners_count, void *priv);
int mlxsw_core_trap_state_set(struct mlxsw_core *mlxsw_core,
const struct mlxsw_listener *listener,
bool enabled);
Expand Down Expand Up @@ -315,7 +324,6 @@ struct mlxsw_driver {
const struct mlxsw_bus_info *mlxsw_bus_info,
struct netlink_ext_ack *extack);
void (*fini)(struct mlxsw_core *mlxsw_core);
int (*basic_trap_groups_set)(struct mlxsw_core *mlxsw_core);
int (*port_type_set)(struct mlxsw_core *mlxsw_core, u16 local_port,
enum devlink_port_type new_type);
int (*port_split)(struct mlxsw_core *mlxsw_core, u16 local_port,
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/mellanox/mlxsw/core_env.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,7 @@ mlxsw_env_mtwe_listener_func(const struct mlxsw_reg_info *reg, char *mtwe_pl,
}

static const struct mlxsw_listener mlxsw_env_temp_warn_listener =
MLXSW_EVENTL(mlxsw_env_mtwe_listener_func, MTWE, MTWE);
MLXSW_CORE_EVENTL(mlxsw_env_mtwe_listener_func, MTWE);

static int mlxsw_env_temp_warn_event_register(struct mlxsw_core *mlxsw_core)
{
Expand Down Expand Up @@ -915,7 +915,7 @@ mlxsw_env_pmpe_listener_func(const struct mlxsw_reg_info *reg, char *pmpe_pl,
}

static const struct mlxsw_listener mlxsw_env_module_plug_listener =
MLXSW_EVENTL(mlxsw_env_pmpe_listener_func, PMPE, PMPE);
MLXSW_CORE_EVENTL(mlxsw_env_pmpe_listener_func, PMPE);

static int
mlxsw_env_module_plug_event_register(struct mlxsw_core *mlxsw_core)
Expand Down
4 changes: 1 addition & 3 deletions drivers/net/ethernet/mellanox/mlxsw/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -6141,9 +6141,7 @@ MLXSW_ITEM32(reg, htgt, type, 0x00, 8, 4);

enum mlxsw_reg_htgt_trap_group {
MLXSW_REG_HTGT_TRAP_GROUP_EMAD,
MLXSW_REG_HTGT_TRAP_GROUP_MFDE,
MLXSW_REG_HTGT_TRAP_GROUP_MTWE,
MLXSW_REG_HTGT_TRAP_GROUP_PMPE,
MLXSW_REG_HTGT_TRAP_GROUP_CORE_EVENT,
MLXSW_REG_HTGT_TRAP_GROUP_SP_STP,
MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP,
MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP,
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ enum mlxsw_res_id {
MLXSW_RES_ID_ACL_MAX_REGIONS,
MLXSW_RES_ID_ACL_MAX_GROUPS,
MLXSW_RES_ID_ACL_MAX_GROUP_SIZE,
MLXSW_RES_ID_ACL_MAX_DEFAULT_ACTIONS,
MLXSW_RES_ID_ACL_FLEX_KEYS,
MLXSW_RES_ID_ACL_MAX_ACTION_PER_RULE,
MLXSW_RES_ID_ACL_ACTIONS_PER_SET,
Expand Down Expand Up @@ -90,6 +91,7 @@ static u16 mlxsw_res_ids[] = {
[MLXSW_RES_ID_ACL_MAX_REGIONS] = 0x2903,
[MLXSW_RES_ID_ACL_MAX_GROUPS] = 0x2904,
[MLXSW_RES_ID_ACL_MAX_GROUP_SIZE] = 0x2905,
[MLXSW_RES_ID_ACL_MAX_DEFAULT_ACTIONS] = 0x2908,
[MLXSW_RES_ID_ACL_FLEX_KEYS] = 0x2910,
[MLXSW_RES_ID_ACL_MAX_ACTION_PER_RULE] = 0x2911,
[MLXSW_RES_ID_ACL_ACTIONS_PER_SET] = 0x2912,
Expand Down
106 changes: 14 additions & 92 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.c
Original file line number Diff line number Diff line change
Expand Up @@ -2148,13 +2148,11 @@ static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg,
struct mlxsw_sp *mlxsw_sp = priv;
struct mlxsw_sp_port *mlxsw_sp_port;
enum mlxsw_reg_pude_oper_status status;
unsigned int max_ports;
u16 local_port;

max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
local_port = mlxsw_reg_pude_local_port_get(pude_pl);

if (WARN_ON_ONCE(!local_port || local_port >= max_ports))
if (WARN_ON_ONCE(!mlxsw_sp_local_port_is_valid(mlxsw_sp, local_port)))
return;
mlxsw_sp_port = mlxsw_sp->ports[local_port];
if (!mlxsw_sp_port)
Expand Down Expand Up @@ -2393,45 +2391,6 @@ static int mlxsw_sp_trap_groups_set(struct mlxsw_core *mlxsw_core)
return 0;
}

static int mlxsw_sp_traps_register(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_listener listeners[],
size_t listeners_count)
{
int i;
int err;

for (i = 0; i < listeners_count; i++) {
err = mlxsw_core_trap_register(mlxsw_sp->core,
&listeners[i],
mlxsw_sp);
if (err)
goto err_listener_register;

}
return 0;

err_listener_register:
for (i--; i >= 0; i--) {
mlxsw_core_trap_unregister(mlxsw_sp->core,
&listeners[i],
mlxsw_sp);
}
return err;
}

static void mlxsw_sp_traps_unregister(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_listener listeners[],
size_t listeners_count)
{
int i;

for (i = 0; i < listeners_count; i++) {
mlxsw_core_trap_unregister(mlxsw_sp->core,
&listeners[i],
mlxsw_sp);
}
}

static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp)
{
struct mlxsw_sp_trap *trap;
Expand All @@ -2456,21 +2415,23 @@ static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp)
if (err)
goto err_trap_groups_set;

err = mlxsw_sp_traps_register(mlxsw_sp, mlxsw_sp_listener,
ARRAY_SIZE(mlxsw_sp_listener));
err = mlxsw_core_traps_register(mlxsw_sp->core, mlxsw_sp_listener,
ARRAY_SIZE(mlxsw_sp_listener),
mlxsw_sp);
if (err)
goto err_traps_register;

err = mlxsw_sp_traps_register(mlxsw_sp, mlxsw_sp->listeners,
mlxsw_sp->listeners_count);
err = mlxsw_core_traps_register(mlxsw_sp->core, mlxsw_sp->listeners,
mlxsw_sp->listeners_count, mlxsw_sp);
if (err)
goto err_extra_traps_init;

return 0;

err_extra_traps_init:
mlxsw_sp_traps_unregister(mlxsw_sp, mlxsw_sp_listener,
ARRAY_SIZE(mlxsw_sp_listener));
mlxsw_core_traps_unregister(mlxsw_sp->core, mlxsw_sp_listener,
ARRAY_SIZE(mlxsw_sp_listener),
mlxsw_sp);
err_traps_register:
err_trap_groups_set:
err_cpu_policers_set:
Expand All @@ -2480,10 +2441,11 @@ static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp)

static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp)
{
mlxsw_sp_traps_unregister(mlxsw_sp, mlxsw_sp->listeners,
mlxsw_sp->listeners_count);
mlxsw_sp_traps_unregister(mlxsw_sp, mlxsw_sp_listener,
ARRAY_SIZE(mlxsw_sp_listener));
mlxsw_core_traps_unregister(mlxsw_sp->core, mlxsw_sp->listeners,
mlxsw_sp->listeners_count,
mlxsw_sp);
mlxsw_core_traps_unregister(mlxsw_sp->core, mlxsw_sp_listener,
ARRAY_SIZE(mlxsw_sp_listener), mlxsw_sp);
kfree(mlxsw_sp->trap);
}

Expand Down Expand Up @@ -2528,42 +2490,6 @@ static void mlxsw_sp_lag_fini(struct mlxsw_sp *mlxsw_sp)
kfree(mlxsw_sp->lags);
}

static int mlxsw_sp_basic_trap_groups_set(struct mlxsw_core *mlxsw_core)
{
char htgt_pl[MLXSW_REG_HTGT_LEN];
int err;

mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_EMAD,
MLXSW_REG_HTGT_INVALID_POLICER,
MLXSW_REG_HTGT_DEFAULT_PRIORITY,
MLXSW_REG_HTGT_DEFAULT_TC);
err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl);
if (err)
return err;

mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_MFDE,
MLXSW_REG_HTGT_INVALID_POLICER,
MLXSW_REG_HTGT_DEFAULT_PRIORITY,
MLXSW_REG_HTGT_DEFAULT_TC);
err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl);
if (err)
return err;

mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_MTWE,
MLXSW_REG_HTGT_INVALID_POLICER,
MLXSW_REG_HTGT_DEFAULT_PRIORITY,
MLXSW_REG_HTGT_DEFAULT_TC);
err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl);
if (err)
return err;

mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_PMPE,
MLXSW_REG_HTGT_INVALID_POLICER,
MLXSW_REG_HTGT_DEFAULT_PRIORITY,
MLXSW_REG_HTGT_DEFAULT_TC);
return mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl);
}

static const struct mlxsw_sp_ptp_ops mlxsw_sp1_ptp_ops = {
.clock_init = mlxsw_sp1_ptp_clock_init,
.clock_fini = mlxsw_sp1_ptp_clock_fini,
Expand Down Expand Up @@ -3677,7 +3603,6 @@ static struct mlxsw_driver mlxsw_sp1_driver = {
.fw_filename = MLXSW_SP1_FW_FILENAME,
.init = mlxsw_sp1_init,
.fini = mlxsw_sp_fini,
.basic_trap_groups_set = mlxsw_sp_basic_trap_groups_set,
.port_split = mlxsw_sp_port_split,
.port_unsplit = mlxsw_sp_port_unsplit,
.sb_pool_get = mlxsw_sp_sb_pool_get,
Expand Down Expand Up @@ -3717,7 +3642,6 @@ static struct mlxsw_driver mlxsw_sp2_driver = {
.fw_filename = MLXSW_SP2_FW_FILENAME,
.init = mlxsw_sp2_init,
.fini = mlxsw_sp_fini,
.basic_trap_groups_set = mlxsw_sp_basic_trap_groups_set,
.port_split = mlxsw_sp_port_split,
.port_unsplit = mlxsw_sp_port_unsplit,
.sb_pool_get = mlxsw_sp_sb_pool_get,
Expand Down Expand Up @@ -3758,7 +3682,6 @@ static struct mlxsw_driver mlxsw_sp3_driver = {
.fw_filename = MLXSW_SP3_FW_FILENAME,
.init = mlxsw_sp3_init,
.fini = mlxsw_sp_fini,
.basic_trap_groups_set = mlxsw_sp_basic_trap_groups_set,
.port_split = mlxsw_sp_port_split,
.port_unsplit = mlxsw_sp_port_unsplit,
.sb_pool_get = mlxsw_sp_sb_pool_get,
Expand Down Expand Up @@ -3797,7 +3720,6 @@ static struct mlxsw_driver mlxsw_sp4_driver = {
.priv_size = sizeof(struct mlxsw_sp),
.init = mlxsw_sp4_init,
.fini = mlxsw_sp_fini,
.basic_trap_groups_set = mlxsw_sp_basic_trap_groups_set,
.port_split = mlxsw_sp_port_split,
.port_unsplit = mlxsw_sp_port_unsplit,
.sb_pool_get = mlxsw_sp_sb_pool_get,
Expand Down
7 changes: 7 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.h
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,13 @@ int
mlxsw_sp_port_vlan_classification_set(struct mlxsw_sp_port *mlxsw_sp_port,
bool is_8021ad_tagged,
bool is_8021q_tagged);
static inline bool
mlxsw_sp_local_port_is_valid(struct mlxsw_sp *mlxsw_sp, u16 local_port)
{
unsigned int max_ports = mlxsw_core_max_ports(mlxsw_sp->core);

return local_port < max_ports && local_port;
}

/* spectrum_buffers.c */
struct mlxsw_sp_hdroom_prio {
Expand Down
Loading

0 comments on commit d344e55

Please sign in to comment.