Skip to content

Commit

Permalink
mlxsw: Update transceiver_overheat counter according to MTWE
Browse files Browse the repository at this point in the history
MTWE (Management Temperature Warning Event) is triggered when module's
temperature is higher than its threshold.

Register for MTWE events and increase the module's overheat counter when
its corresponding sensor goes above the configured threshold.

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 0652ac0 commit 943585c
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 0 deletions.
5 changes: 5 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ bool mlxsw_core_res_query_enabled(const struct mlxsw_core *mlxsw_core)
}
EXPORT_SYMBOL(mlxsw_core_res_query_enabled);

bool mlxsw_core_temp_warn_enabled(const struct mlxsw_core *mlxsw_core)
{
return mlxsw_core->driver->temp_warn_enabled;
}

bool
mlxsw_core_fw_rev_minor_subminor_validate(const struct mlxsw_fw_rev *rev,
const struct mlxsw_fw_rev *req_rev)
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core);

bool mlxsw_core_res_query_enabled(const struct mlxsw_core *mlxsw_core);

bool mlxsw_core_temp_warn_enabled(const struct mlxsw_core *mlxsw_core);

bool
mlxsw_core_fw_rev_minor_subminor_validate(const struct mlxsw_fw_rev *rev,
const struct mlxsw_fw_rev *req_rev);
Expand Down Expand Up @@ -373,6 +375,7 @@ struct mlxsw_driver {
const struct mlxsw_config_profile *profile;
bool res_query_enabled;
bool fw_fatal_enabled;
bool temp_warn_enabled;
};

int mlxsw_core_kvd_sizes_get(struct mlxsw_core *mlxsw_core,
Expand Down
77 changes: 77 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core_env.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,74 @@ int mlxsw_env_get_module_eeprom(struct net_device *netdev,
}
EXPORT_SYMBOL(mlxsw_env_get_module_eeprom);

static void mlxsw_env_mtwe_event_func(const struct mlxsw_reg_info *reg,
char *mtwe_pl, void *priv)
{
struct mlxsw_env *mlxsw_env = priv;
int i, sensor_warning;
bool is_overheat;

for (i = 0; i < mlxsw_env->module_count; i++) {
/* 64-127 of sensor_index are mapped to the port modules
* sequentially (module 0 is mapped to sensor_index 64,
* module 1 to sensor_index 65 and so on)
*/
sensor_warning =
mlxsw_reg_mtwe_sensor_warning_get(mtwe_pl,
i + MLXSW_REG_MTMP_MODULE_INDEX_MIN);
spin_lock(&mlxsw_env->module_info_lock);
is_overheat =
mlxsw_env->module_info[i].is_overheat;

if ((is_overheat && sensor_warning) ||
(!is_overheat && !sensor_warning)) {
/* Current state is "warning" and MTWE still reports
* warning OR current state in "no warning" and MTWE
* does not report warning.
*/
spin_unlock(&mlxsw_env->module_info_lock);
continue;
} else if (is_overheat && !sensor_warning) {
/* MTWE reports "no warning", turn is_overheat off.
*/
mlxsw_env->module_info[i].is_overheat = false;
spin_unlock(&mlxsw_env->module_info_lock);
} else {
/* Current state is "no warning" and MTWE reports
* "warning", increase the counter and turn is_overheat
* on.
*/
mlxsw_env->module_info[i].is_overheat = true;
mlxsw_env->module_info[i].module_overheat_counter++;
spin_unlock(&mlxsw_env->module_info_lock);
}
}
}

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

static int mlxsw_env_temp_warn_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_temp_warn_listener,
mlxsw_env);
}

static void mlxsw_env_temp_warn_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_temp_warn_listener, mlxsw_env);
}

int
mlxsw_env_module_overheat_counter_get(struct mlxsw_core *mlxsw_core, u8 module,
u64 *p_counter)
Expand Down Expand Up @@ -352,10 +420,19 @@ int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)
env->module_count = module_count;
*p_env = env;

err = mlxsw_env_temp_warn_event_register(mlxsw_core);
if (err)
goto err_temp_warn_event_register;

return 0;

err_temp_warn_event_register:
kfree(env);
return err;
}

void mlxsw_env_fini(struct mlxsw_env *env)
{
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 @@ -5682,6 +5682,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_SP_STP,
MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP,
MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP,
Expand Down
11 changes: 11 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.c
Original file line number Diff line number Diff line change
Expand Up @@ -2440,6 +2440,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_MTWE,
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 Expand Up @@ -3197,6 +3205,7 @@ static struct mlxsw_driver mlxsw_sp1_driver = {
.profile = &mlxsw_sp1_config_profile,
.res_query_enabled = true,
.fw_fatal_enabled = true,
.temp_warn_enabled = true,
};

static struct mlxsw_driver mlxsw_sp2_driver = {
Expand Down Expand Up @@ -3237,6 +3246,7 @@ static struct mlxsw_driver mlxsw_sp2_driver = {
.profile = &mlxsw_sp2_config_profile,
.res_query_enabled = true,
.fw_fatal_enabled = true,
.temp_warn_enabled = true,
};

static struct mlxsw_driver mlxsw_sp3_driver = {
Expand Down Expand Up @@ -3277,6 +3287,7 @@ static struct mlxsw_driver mlxsw_sp3_driver = {
.profile = &mlxsw_sp2_config_profile,
.res_query_enabled = true,
.fw_fatal_enabled = true,
.temp_warn_enabled = true,
};

bool mlxsw_sp_port_dev_check(const struct net_device *dev)
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,
/* Temperature Warning event generated by hardware */
MLXSW_TRAP_ID_MTWE = 0xC,
/* PTP Ingress FIFO has a new entry */
MLXSW_TRAP_ID_PTP_ING_FIFO = 0x2D,
/* PTP Egress FIFO has a new entry */
Expand Down

0 comments on commit 943585c

Please sign in to comment.