Commit ffd923f5 authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 7544abd9 91df5d3a
...@@ -12,8 +12,17 @@ ...@@ -12,8 +12,17 @@
#include "core.h" #include "core.h"
#include "core_env.h" #include "core_env.h"
#define MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT 127 #define MLXSW_HWMON_SENSORS_MAX_COUNT 64
#define MLXSW_HWMON_ATTR_COUNT (MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT * 4 + \ #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) MLXSW_MFCR_TACHOS_MAX + MLXSW_MFCR_PWMS_MAX)
struct mlxsw_hwmon_attr { struct mlxsw_hwmon_attr {
...@@ -205,25 +214,39 @@ static ssize_t mlxsw_hwmon_pwm_store(struct device *dev, ...@@ -205,25 +214,39 @@ static ssize_t mlxsw_hwmon_pwm_store(struct device *dev,
return len; return len;
} }
static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev, static int mlxsw_hwmon_module_temp_get(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) int *p_temp)
{ {
struct mlxsw_hwmon_attr *mlwsw_hwmon_attr = struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
container_of(attr, struct mlxsw_hwmon_attr, dev_attr); container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon; struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
char mtmp_pl[MLXSW_REG_MTMP_LEN]; char mtmp_pl[MLXSW_REG_MTMP_LEN];
u8 module; u8 module;
int temp;
int err; int err;
module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count; module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module, mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module,
false, false); false, false);
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl); 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) if (err)
return err; return err;
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
return sprintf(buf, "%d\n", temp); return sprintf(buf, "%d\n", temp);
} }
...@@ -270,48 +293,72 @@ static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev, ...@@ -270,48 +293,72 @@ static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev,
return sprintf(buf, "%u\n", fault); return sprintf(buf, "%u\n", fault);
} }
static ssize_t static int mlxsw_hwmon_module_temp_critical_get(struct device *dev,
mlxsw_hwmon_module_temp_critical_show(struct device *dev, struct device_attribute *attr,
struct device_attribute *attr, char *buf) int *p_temp)
{ {
struct mlxsw_hwmon_attr *mlwsw_hwmon_attr = struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
container_of(attr, struct mlxsw_hwmon_attr, dev_attr); container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon; struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
int temp;
u8 module; u8 module;
int err; int err;
module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count; module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module, err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
SFP_TEMP_HIGH_WARN, &temp); SFP_TEMP_HIGH_WARN, p_temp);
if (err) { if (err) {
dev_err(dev, "Failed to query module temperature thresholds\n"); dev_err(dev, "Failed to query module temperature thresholds\n");
return err; return err;
} }
return sprintf(buf, "%u\n", temp); return 0;
} }
static ssize_t static ssize_t
mlxsw_hwmon_module_temp_emergency_show(struct device *dev, mlxsw_hwmon_module_temp_critical_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr, char *buf)
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 = struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
container_of(attr, struct mlxsw_hwmon_attr, dev_attr); container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon; struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
u8 module; u8 module;
int temp;
int err; int err;
module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count; module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module, err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
SFP_TEMP_HIGH_ALARM, &temp); SFP_TEMP_HIGH_ALARM, p_temp);
if (err) { if (err) {
dev_err(dev, "Failed to query module temperature thresholds\n"); dev_err(dev, "Failed to query module temperature thresholds\n");
return err; return err;
} }
return 0;
}
static ssize_t
mlxsw_hwmon_module_temp_emergency_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
int err, temp;
err = mlxsw_hwmon_module_temp_emergency_get(dev, attr, &temp);
if (err)
return err;
return sprintf(buf, "%u\n", temp); return sprintf(buf, "%u\n", temp);
} }
...@@ -341,6 +388,53 @@ mlxsw_hwmon_gbox_temp_label_show(struct device *dev, ...@@ -341,6 +388,53 @@ mlxsw_hwmon_gbox_temp_label_show(struct device *dev,
return sprintf(buf, "gearbox %03u\n", index); 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 { enum mlxsw_hwmon_attr_type {
MLXSW_HWMON_ATTR_TYPE_TEMP, MLXSW_HWMON_ATTR_TYPE_TEMP,
MLXSW_HWMON_ATTR_TYPE_TEMP_MAX, MLXSW_HWMON_ATTR_TYPE_TEMP_MAX,
...@@ -354,6 +448,8 @@ enum mlxsw_hwmon_attr_type { ...@@ -354,6 +448,8 @@ enum mlxsw_hwmon_attr_type {
MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG, MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG,
MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL, MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL,
MLXSW_HWMON_ATTR_TYPE_TEMP_GBOX_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, 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, ...@@ -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), snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
"temp%u_label", num + 1); "temp%u_label", num + 1);
break; 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: default:
WARN_ON(1); WARN_ON(1);
} }
...@@ -566,6 +676,12 @@ static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon) ...@@ -566,6 +676,12 @@ static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
mlxsw_hwmon_attr_add(mlxsw_hwmon, mlxsw_hwmon_attr_add(mlxsw_hwmon,
MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL, MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL,
i, i); 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; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment