Skip to content

Commit

Permalink
mlxsw: Update module's settings when module is plugged in
Browse files Browse the repository at this point in the history
Module temperature warning events are enabled for modules that have a
temperature sensor and configured according to the temperature
thresholds queried from the module.

When a module is unplugged we are guaranteed not to get temperature
warning events. However, when a module is plugged in we need to
potentially update its current settings (i.e., event enablement and
thresholds).

Register to port module plug/unplug events and update module's settings
upon plug in events.

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>
  • Loading branch information
Amit Cohen authored and David S. Miller committed Sep 27, 2020
1 parent 3bdbab3 commit 05cf582
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 0 deletions.
126 changes: 126 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core_env.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,117 @@ static void mlxsw_env_temp_warn_event_unregister(struct mlxsw_env *mlxsw_env)
&mlxsw_env_temp_warn_listener, mlxsw_env);
}

struct mlxsw_env_module_plug_unplug_event {
struct mlxsw_env *mlxsw_env;
u8 module;
struct work_struct work;
};

static void mlxsw_env_pmpe_event_work(struct work_struct *work)
{
struct mlxsw_env_module_plug_unplug_event *event;
struct mlxsw_env *mlxsw_env;
bool has_temp_sensor;
u16 sensor_index;
int err;

event = container_of(work, struct mlxsw_env_module_plug_unplug_event,
work);
mlxsw_env = event->mlxsw_env;

spin_lock_bh(&mlxsw_env->module_info_lock);
mlxsw_env->module_info[event->module].is_overheat = false;
spin_unlock_bh(&mlxsw_env->module_info_lock);

err = mlxsw_env_module_has_temp_sensor(mlxsw_env->core, event->module,
&has_temp_sensor);
/* Do not disable events on modules without sensors or faulty sensors
* because FW returns errors.
*/
if (err)
goto out;

if (!has_temp_sensor)
goto out;

sensor_index = event->module + MLXSW_REG_MTMP_MODULE_INDEX_MIN;
mlxsw_env_temp_event_set(mlxsw_env->core, sensor_index, true);

out:
kfree(event);
}

static void
mlxsw_env_pmpe_listener_func(const struct mlxsw_reg_info *reg, char *pmpe_pl,
void *priv)
{
struct mlxsw_env_module_plug_unplug_event *event;
enum mlxsw_reg_pmpe_module_status module_status;
u8 module = mlxsw_reg_pmpe_module_get(pmpe_pl);
struct mlxsw_env *mlxsw_env = priv;

if (WARN_ON_ONCE(module >= mlxsw_env->module_count))
return;

module_status = mlxsw_reg_pmpe_module_status_get(pmpe_pl);
if (module_status != MLXSW_REG_PMPE_MODULE_STATUS_PLUGGED_ENABLED)
return;

event = kmalloc(sizeof(*event), GFP_ATOMIC);
if (!event)
return;

event->mlxsw_env = mlxsw_env;
event->module = module;
INIT_WORK(&event->work, mlxsw_env_pmpe_event_work);
mlxsw_core_schedule_work(&event->work);
}

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

static int
mlxsw_env_module_plug_event_register(struct mlxsw_core *mlxsw_core)
{
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);

if (!mlxsw_core_temp_warn_enabled(mlxsw_core))
return 0;

return mlxsw_core_trap_register(mlxsw_core,
&mlxsw_env_module_plug_listener,
mlxsw_env);
}

static void
mlxsw_env_module_plug_event_unregister(struct mlxsw_env *mlxsw_env)
{
if (!mlxsw_core_temp_warn_enabled(mlxsw_env->core))
return;

mlxsw_core_trap_unregister(mlxsw_env->core,
&mlxsw_env_module_plug_listener,
mlxsw_env);
}

static int
mlxsw_env_module_oper_state_event_enable(struct mlxsw_core *mlxsw_core,
u8 module_count)
{
int i, err;

for (i = 0; i < module_count; i++) {
char pmaos_pl[MLXSW_REG_PMAOS_LEN];

mlxsw_reg_pmaos_pack(pmaos_pl, i,
MLXSW_REG_PMAOS_E_GENERATE_EVENT);
err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(pmaos), pmaos_pl);
if (err)
return err;
}
return 0;
}

int
mlxsw_env_module_overheat_counter_get(struct mlxsw_core *mlxsw_core, u8 module,
u64 *p_counter)
Expand Down Expand Up @@ -517,13 +628,25 @@ int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)
if (err)
goto err_temp_warn_event_register;

err = mlxsw_env_module_plug_event_register(mlxsw_core);
if (err)
goto err_module_plug_event_register;

err = mlxsw_env_module_oper_state_event_enable(mlxsw_core,
env->module_count);
if (err)
goto err_oper_state_event_enable;

err = mlxsw_env_module_temp_event_enable(mlxsw_core, env->module_count);
if (err)
goto err_temp_event_enable;

return 0;

err_temp_event_enable:
err_oper_state_event_enable:
mlxsw_env_module_plug_event_unregister(env);
err_module_plug_event_register:
mlxsw_env_temp_warn_event_unregister(env);
err_temp_warn_event_register:
kfree(env);
Expand All @@ -532,6 +655,9 @@ int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)

void mlxsw_env_fini(struct mlxsw_env *env)
{
mlxsw_env_module_plug_event_unregister(env);
/* Make sure there is no more event work scheduled. */
mlxsw_core_flush_owq();
mlxsw_env_temp_warn_event_unregister(env);
kfree(env);
}
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlxsw/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -5683,6 +5683,7 @@ 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_SP_STP,
MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP,
MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP,
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.c
Original file line number Diff line number Diff line change
Expand Up @@ -2473,6 +2473,14 @@ static int mlxsw_sp_basic_trap_groups_set(struct mlxsw_core *mlxsw_core)
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);
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/trap.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ enum mlxsw_event_trap_id {
MLXSW_TRAP_ID_MFDE = 0x3,
/* Port Up/Down event generated by hardware */
MLXSW_TRAP_ID_PUDE = 0x8,
/* Port Module Plug/Unplug Event generated by hardware */
MLXSW_TRAP_ID_PMPE = 0x9,
/* Temperature Warning event generated by hardware */
MLXSW_TRAP_ID_MTWE = 0xC,
/* PTP Ingress FIFO has a new entry */
Expand Down

0 comments on commit 05cf582

Please sign in to comment.