Merge branch 'mlxsw-Expose-critical-and-emergency-module-alarms'
Ido Schimmel says: ==================== mlxsw: Expose critical and emergency module alarms Amit says: Extend hwmon interface with critical and emergency module alarms. In case that current module temperature is higher than emergency threshold, EMERGENCY alarm will be reported in sensors utility: $ sensors ... front panel 025: +55.0°C (crit = +35.0°C, emerg = +40.0°C) ALARM(EMERGENCY) In case that current module temperature is higher than critical threshold, CRIT alarm will be reported in sensors utility: $ sensors ... front panel 025: +54.0°C (crit = +35.0°C, emerg = +80.0°C) ALARM(CRIT) Patch set overview: Patches #1-#2 make several changes to make the code easier to change. Patch #3 extends the hwmon interface with the new module alarms. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
ffd923f5f8
|
@ -12,8 +12,17 @@
|
|||
#include "core.h"
|
||||
#include "core_env.h"
|
||||
|
||||
#define MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT 127
|
||||
#define MLXSW_HWMON_ATTR_COUNT (MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT * 4 + \
|
||||
#define MLXSW_HWMON_SENSORS_MAX_COUNT 64
|
||||
#define MLXSW_HWMON_MODULES_MAX_COUNT 64
|
||||
#define MLXSW_HWMON_GEARBOXES_MAX_COUNT 32
|
||||
|
||||
#define MLXSW_HWMON_ATTR_PER_SENSOR 3
|
||||
#define MLXSW_HWMON_ATTR_PER_MODULE 7
|
||||
#define MLXSW_HWMON_ATTR_PER_GEARBOX 4
|
||||
|
||||
#define MLXSW_HWMON_ATTR_COUNT (MLXSW_HWMON_SENSORS_MAX_COUNT * MLXSW_HWMON_ATTR_PER_SENSOR + \
|
||||
MLXSW_HWMON_MODULES_MAX_COUNT * MLXSW_HWMON_ATTR_PER_MODULE + \
|
||||
MLXSW_HWMON_GEARBOXES_MAX_COUNT * MLXSW_HWMON_ATTR_PER_GEARBOX + \
|
||||
MLXSW_MFCR_TACHOS_MAX + MLXSW_MFCR_PWMS_MAX)
|
||||
|
||||
struct mlxsw_hwmon_attr {
|
||||
|
@ -205,25 +214,39 @@ static ssize_t mlxsw_hwmon_pwm_store(struct device *dev,
|
|||
return len;
|
||||
}
|
||||
|
||||
static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
static int mlxsw_hwmon_module_temp_get(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
int *p_temp)
|
||||
{
|
||||
struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
char mtmp_pl[MLXSW_REG_MTMP_LEN];
|
||||
u8 module;
|
||||
int temp;
|
||||
int err;
|
||||
|
||||
module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
|
||||
mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module,
|
||||
false, false);
|
||||
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to query module temperature\n");
|
||||
return err;
|
||||
}
|
||||
mlxsw_reg_mtmp_unpack(mtmp_pl, p_temp, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int err, temp;
|
||||
|
||||
err = mlxsw_hwmon_module_temp_get(dev, attr, &temp);
|
||||
if (err)
|
||||
return err;
|
||||
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
|
||||
|
||||
return sprintf(buf, "%d\n", temp);
|
||||
}
|
||||
|
@ -270,47 +293,71 @@ static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev,
|
|||
return sprintf(buf, "%u\n", fault);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
mlxsw_hwmon_module_temp_critical_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
static int mlxsw_hwmon_module_temp_critical_get(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
int *p_temp)
|
||||
{
|
||||
struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
int temp;
|
||||
u8 module;
|
||||
int err;
|
||||
|
||||
module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
|
||||
err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
|
||||
SFP_TEMP_HIGH_WARN, &temp);
|
||||
SFP_TEMP_HIGH_WARN, p_temp);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to query module temperature thresholds\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
mlxsw_hwmon_module_temp_critical_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
int err, temp;
|
||||
|
||||
err = mlxsw_hwmon_module_temp_critical_get(dev, attr, &temp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return sprintf(buf, "%u\n", temp);
|
||||
}
|
||||
|
||||
static int mlxsw_hwmon_module_temp_emergency_get(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
int *p_temp)
|
||||
{
|
||||
struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
u8 module;
|
||||
int err;
|
||||
|
||||
module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
|
||||
err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
|
||||
SFP_TEMP_HIGH_ALARM, p_temp);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to query module temperature thresholds\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
mlxsw_hwmon_module_temp_emergency_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
u8 module;
|
||||
int temp;
|
||||
int err;
|
||||
int err, temp;
|
||||
|
||||
module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
|
||||
err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
|
||||
SFP_TEMP_HIGH_ALARM, &temp);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to query module temperature thresholds\n");
|
||||
err = mlxsw_hwmon_module_temp_emergency_get(dev, attr, &temp);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return sprintf(buf, "%u\n", temp);
|
||||
}
|
||||
|
@ -341,6 +388,53 @@ mlxsw_hwmon_gbox_temp_label_show(struct device *dev,
|
|||
return sprintf(buf, "gearbox %03u\n", index);
|
||||
}
|
||||
|
||||
static ssize_t mlxsw_hwmon_temp_critical_alarm_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int err, temp, emergency_temp, critic_temp;
|
||||
|
||||
err = mlxsw_hwmon_module_temp_get(dev, attr, &temp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (temp <= 0)
|
||||
return sprintf(buf, "%d\n", false);
|
||||
|
||||
err = mlxsw_hwmon_module_temp_emergency_get(dev, attr, &emergency_temp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (temp >= emergency_temp)
|
||||
return sprintf(buf, "%d\n", false);
|
||||
|
||||
err = mlxsw_hwmon_module_temp_critical_get(dev, attr, &critic_temp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return sprintf(buf, "%d\n", temp >= critic_temp);
|
||||
}
|
||||
|
||||
static ssize_t mlxsw_hwmon_temp_emergency_alarm_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int err, temp, emergency_temp;
|
||||
|
||||
err = mlxsw_hwmon_module_temp_get(dev, attr, &temp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (temp <= 0)
|
||||
return sprintf(buf, "%d\n", false);
|
||||
|
||||
err = mlxsw_hwmon_module_temp_emergency_get(dev, attr, &emergency_temp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return sprintf(buf, "%d\n", temp >= emergency_temp);
|
||||
}
|
||||
|
||||
enum mlxsw_hwmon_attr_type {
|
||||
MLXSW_HWMON_ATTR_TYPE_TEMP,
|
||||
MLXSW_HWMON_ATTR_TYPE_TEMP_MAX,
|
||||
|
@ -354,6 +448,8 @@ enum mlxsw_hwmon_attr_type {
|
|||
MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG,
|
||||
MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL,
|
||||
MLXSW_HWMON_ATTR_TYPE_TEMP_GBOX_LABEL,
|
||||
MLXSW_HWMON_ATTR_TYPE_TEMP_CRIT_ALARM,
|
||||
MLXSW_HWMON_ATTR_TYPE_TEMP_EMERGENCY_ALARM,
|
||||
};
|
||||
|
||||
static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
|
||||
|
@ -444,6 +540,20 @@ static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
|
|||
snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
|
||||
"temp%u_label", num + 1);
|
||||
break;
|
||||
case MLXSW_HWMON_ATTR_TYPE_TEMP_CRIT_ALARM:
|
||||
mlxsw_hwmon_attr->dev_attr.show =
|
||||
mlxsw_hwmon_temp_critical_alarm_show;
|
||||
mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
|
||||
snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
|
||||
"temp%u_crit_alarm", num + 1);
|
||||
break;
|
||||
case MLXSW_HWMON_ATTR_TYPE_TEMP_EMERGENCY_ALARM:
|
||||
mlxsw_hwmon_attr->dev_attr.show =
|
||||
mlxsw_hwmon_temp_emergency_alarm_show;
|
||||
mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
|
||||
snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
|
||||
"temp%u_emergency_alarm", num + 1);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
@ -566,6 +676,12 @@ static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
|
|||
mlxsw_hwmon_attr_add(mlxsw_hwmon,
|
||||
MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL,
|
||||
i, i);
|
||||
mlxsw_hwmon_attr_add(mlxsw_hwmon,
|
||||
MLXSW_HWMON_ATTR_TYPE_TEMP_CRIT_ALARM,
|
||||
i, i);
|
||||
mlxsw_hwmon_attr_add(mlxsw_hwmon,
|
||||
MLXSW_HWMON_ATTR_TYPE_TEMP_EMERGENCY_ALARM,
|
||||
i, i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче