1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */
4 #include <linux/kernel.h>
5 #include <linux/types.h>
6 #include <linux/device.h>
7 #include <linux/sysfs.h>
8 #include <linux/hwmon.h>
10 #include <linux/sfp.h>
15 #define MLXSW_HWMON_SENSORS_MAX_COUNT 64
16 #define MLXSW_HWMON_MODULES_MAX_COUNT 64
17 #define MLXSW_HWMON_GEARBOXES_MAX_COUNT 32
19 #define MLXSW_HWMON_ATTR_PER_SENSOR 3
20 #define MLXSW_HWMON_ATTR_PER_MODULE 7
21 #define MLXSW_HWMON_ATTR_PER_GEARBOX 4
23 #define MLXSW_HWMON_ATTR_COUNT (MLXSW_HWMON_SENSORS_MAX_COUNT * MLXSW_HWMON_ATTR_PER_SENSOR + \
24 MLXSW_HWMON_MODULES_MAX_COUNT * MLXSW_HWMON_ATTR_PER_MODULE + \
25 MLXSW_HWMON_GEARBOXES_MAX_COUNT * MLXSW_HWMON_ATTR_PER_GEARBOX + \
26 MLXSW_MFCR_TACHOS_MAX + MLXSW_MFCR_PWMS_MAX)
28 struct mlxsw_hwmon_attr {
29 struct device_attribute dev_attr;
30 struct mlxsw_hwmon *hwmon;
31 unsigned int type_index;
35 static int mlxsw_hwmon_get_attr_index(int index, int count)
38 return index % count + MLXSW_REG_MTMP_GBOX_INDEX_MIN;
44 struct mlxsw_core *core;
45 const struct mlxsw_bus_info *bus_info;
46 struct device *hwmon_dev;
47 struct attribute_group group;
48 const struct attribute_group *groups[2];
49 struct attribute *attrs[MLXSW_HWMON_ATTR_COUNT + 1];
50 struct mlxsw_hwmon_attr hwmon_attrs[MLXSW_HWMON_ATTR_COUNT];
51 unsigned int attrs_count;
56 static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
57 struct device_attribute *attr,
60 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
61 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
62 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
63 char mtmp_pl[MLXSW_REG_MTMP_LEN];
67 index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
68 mlxsw_hwmon->module_sensor_max);
69 mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
70 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
72 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n");
75 mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
76 return sprintf(buf, "%d\n", temp);
79 static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
80 struct device_attribute *attr,
83 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
84 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
85 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
86 char mtmp_pl[MLXSW_REG_MTMP_LEN];
90 index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
91 mlxsw_hwmon->module_sensor_max);
92 mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
93 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
95 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n");
98 mlxsw_reg_mtmp_unpack(mtmp_pl, NULL, &temp_max, NULL);
99 return sprintf(buf, "%d\n", temp_max);
102 static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev,
103 struct device_attribute *attr,
104 const char *buf, size_t len)
106 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
107 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
108 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
109 char mtmp_pl[MLXSW_REG_MTMP_LEN] = {0};
114 err = kstrtoul(buf, 10, &val);
120 index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
121 mlxsw_hwmon->module_sensor_max);
123 mlxsw_reg_mtmp_sensor_index_set(mtmp_pl, index);
124 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
127 mlxsw_reg_mtmp_mte_set(mtmp_pl, true);
128 mlxsw_reg_mtmp_mtr_set(mtmp_pl, true);
129 err = mlxsw_reg_write(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
131 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to reset temp sensor history\n");
137 static ssize_t mlxsw_hwmon_fan_rpm_show(struct device *dev,
138 struct device_attribute *attr,
141 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
142 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
143 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
144 char mfsm_pl[MLXSW_REG_MFSM_LEN];
147 mlxsw_reg_mfsm_pack(mfsm_pl, mlwsw_hwmon_attr->type_index);
148 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mfsm), mfsm_pl);
150 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query fan\n");
153 return sprintf(buf, "%u\n", mlxsw_reg_mfsm_rpm_get(mfsm_pl));
156 static ssize_t mlxsw_hwmon_fan_fault_show(struct device *dev,
157 struct device_attribute *attr,
160 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
161 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
162 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
163 char fore_pl[MLXSW_REG_FORE_LEN];
167 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(fore), fore_pl);
169 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query fan\n");
172 mlxsw_reg_fore_unpack(fore_pl, mlwsw_hwmon_attr->type_index, &fault);
174 return sprintf(buf, "%u\n", fault);
177 static ssize_t mlxsw_hwmon_pwm_show(struct device *dev,
178 struct device_attribute *attr,
181 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
182 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
183 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
184 char mfsc_pl[MLXSW_REG_MFSC_LEN];
187 mlxsw_reg_mfsc_pack(mfsc_pl, mlwsw_hwmon_attr->type_index, 0);
188 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mfsc), mfsc_pl);
190 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query PWM\n");
193 return sprintf(buf, "%u\n",
194 mlxsw_reg_mfsc_pwm_duty_cycle_get(mfsc_pl));
197 static ssize_t mlxsw_hwmon_pwm_store(struct device *dev,
198 struct device_attribute *attr,
199 const char *buf, size_t len)
201 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
202 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
203 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
204 char mfsc_pl[MLXSW_REG_MFSC_LEN];
208 err = kstrtoul(buf, 10, &val);
214 mlxsw_reg_mfsc_pack(mfsc_pl, mlwsw_hwmon_attr->type_index, val);
215 err = mlxsw_reg_write(mlxsw_hwmon->core, MLXSW_REG(mfsc), mfsc_pl);
217 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to write PWM\n");
223 static int mlxsw_hwmon_module_temp_get(struct device *dev,
224 struct device_attribute *attr,
227 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
228 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
229 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
230 char mtmp_pl[MLXSW_REG_MTMP_LEN];
234 module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
235 mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module,
237 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
239 dev_err(dev, "Failed to query module temperature\n");
242 mlxsw_reg_mtmp_unpack(mtmp_pl, p_temp, NULL, NULL);
247 static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev,
248 struct device_attribute *attr,
253 err = mlxsw_hwmon_module_temp_get(dev, attr, &temp);
257 return sprintf(buf, "%d\n", temp);
260 static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev,
261 struct device_attribute *attr,
264 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
265 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
266 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
267 char mtbr_pl[MLXSW_REG_MTBR_LEN] = {0};
272 module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
273 mlxsw_reg_mtbr_pack(mtbr_pl, MLXSW_REG_MTBR_BASE_MODULE_INDEX + module,
275 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtbr), mtbr_pl);
277 dev_err(dev, "Failed to query module temperature sensor\n");
281 mlxsw_reg_mtbr_temp_unpack(mtbr_pl, 0, &temp, NULL);
283 /* Update status and temperature cache. */
285 case MLXSW_REG_MTBR_BAD_SENS_INFO:
286 /* Untrusted cable is connected. Reading temperature from its
291 case MLXSW_REG_MTBR_NO_CONN:
292 case MLXSW_REG_MTBR_NO_TEMP_SENS:
293 case MLXSW_REG_MTBR_INDEX_NA:
299 return sprintf(buf, "%u\n", fault);
302 static int mlxsw_hwmon_module_temp_critical_get(struct device *dev,
303 struct device_attribute *attr,
306 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
307 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
308 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
312 module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
313 err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
314 SFP_TEMP_HIGH_WARN, p_temp);
316 dev_err(dev, "Failed to query module temperature thresholds\n");
324 mlxsw_hwmon_module_temp_critical_show(struct device *dev,
325 struct device_attribute *attr, char *buf)
329 err = mlxsw_hwmon_module_temp_critical_get(dev, attr, &temp);
333 return sprintf(buf, "%u\n", temp);
336 static int mlxsw_hwmon_module_temp_emergency_get(struct device *dev,
337 struct device_attribute *attr,
340 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
341 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
342 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
346 module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
347 err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
348 SFP_TEMP_HIGH_ALARM, p_temp);
350 dev_err(dev, "Failed to query module temperature thresholds\n");
358 mlxsw_hwmon_module_temp_emergency_show(struct device *dev,
359 struct device_attribute *attr,
364 err = mlxsw_hwmon_module_temp_emergency_get(dev, attr, &temp);
368 return sprintf(buf, "%u\n", temp);
372 mlxsw_hwmon_module_temp_label_show(struct device *dev,
373 struct device_attribute *attr,
376 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
377 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
379 return sprintf(buf, "front panel %03u\n",
380 mlwsw_hwmon_attr->type_index);
384 mlxsw_hwmon_gbox_temp_label_show(struct device *dev,
385 struct device_attribute *attr,
388 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
389 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
390 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
391 int index = mlwsw_hwmon_attr->type_index -
392 mlxsw_hwmon->module_sensor_max + 1;
394 return sprintf(buf, "gearbox %03u\n", index);
397 static ssize_t mlxsw_hwmon_temp_critical_alarm_show(struct device *dev,
398 struct device_attribute *attr,
401 int err, temp, emergency_temp, critic_temp;
403 err = mlxsw_hwmon_module_temp_get(dev, attr, &temp);
408 return sprintf(buf, "%d\n", false);
410 err = mlxsw_hwmon_module_temp_emergency_get(dev, attr, &emergency_temp);
414 if (temp >= emergency_temp)
415 return sprintf(buf, "%d\n", false);
417 err = mlxsw_hwmon_module_temp_critical_get(dev, attr, &critic_temp);
421 return sprintf(buf, "%d\n", temp >= critic_temp);
424 static ssize_t mlxsw_hwmon_temp_emergency_alarm_show(struct device *dev,
425 struct device_attribute *attr,
428 int err, temp, emergency_temp;
430 err = mlxsw_hwmon_module_temp_get(dev, attr, &temp);
435 return sprintf(buf, "%d\n", false);
437 err = mlxsw_hwmon_module_temp_emergency_get(dev, attr, &emergency_temp);
441 return sprintf(buf, "%d\n", temp >= emergency_temp);
444 enum mlxsw_hwmon_attr_type {
445 MLXSW_HWMON_ATTR_TYPE_TEMP,
446 MLXSW_HWMON_ATTR_TYPE_TEMP_MAX,
447 MLXSW_HWMON_ATTR_TYPE_TEMP_RST,
448 MLXSW_HWMON_ATTR_TYPE_FAN_RPM,
449 MLXSW_HWMON_ATTR_TYPE_FAN_FAULT,
450 MLXSW_HWMON_ATTR_TYPE_PWM,
451 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE,
452 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_FAULT,
453 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_CRIT,
454 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG,
455 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL,
456 MLXSW_HWMON_ATTR_TYPE_TEMP_GBOX_LABEL,
457 MLXSW_HWMON_ATTR_TYPE_TEMP_CRIT_ALARM,
458 MLXSW_HWMON_ATTR_TYPE_TEMP_EMERGENCY_ALARM,
461 static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
462 enum mlxsw_hwmon_attr_type attr_type,
463 unsigned int type_index, unsigned int num) {
464 struct mlxsw_hwmon_attr *mlxsw_hwmon_attr;
465 unsigned int attr_index;
467 attr_index = mlxsw_hwmon->attrs_count;
468 mlxsw_hwmon_attr = &mlxsw_hwmon->hwmon_attrs[attr_index];
471 case MLXSW_HWMON_ATTR_TYPE_TEMP:
472 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_show;
473 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
474 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
475 "temp%u_input", num + 1);
477 case MLXSW_HWMON_ATTR_TYPE_TEMP_MAX:
478 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_max_show;
479 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
480 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
481 "temp%u_highest", num + 1);
483 case MLXSW_HWMON_ATTR_TYPE_TEMP_RST:
484 mlxsw_hwmon_attr->dev_attr.store = mlxsw_hwmon_temp_rst_store;
485 mlxsw_hwmon_attr->dev_attr.attr.mode = 0200;
486 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
487 "temp%u_reset_history", num + 1);
489 case MLXSW_HWMON_ATTR_TYPE_FAN_RPM:
490 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_fan_rpm_show;
491 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
492 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
493 "fan%u_input", num + 1);
495 case MLXSW_HWMON_ATTR_TYPE_FAN_FAULT:
496 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_fan_fault_show;
497 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
498 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
499 "fan%u_fault", num + 1);
501 case MLXSW_HWMON_ATTR_TYPE_PWM:
502 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_pwm_show;
503 mlxsw_hwmon_attr->dev_attr.store = mlxsw_hwmon_pwm_store;
504 mlxsw_hwmon_attr->dev_attr.attr.mode = 0644;
505 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
508 case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE:
509 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_module_temp_show;
510 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
511 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
512 "temp%u_input", num + 1);
514 case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_FAULT:
515 mlxsw_hwmon_attr->dev_attr.show =
516 mlxsw_hwmon_module_temp_fault_show;
517 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
518 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
519 "temp%u_fault", num + 1);
521 case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_CRIT:
522 mlxsw_hwmon_attr->dev_attr.show =
523 mlxsw_hwmon_module_temp_critical_show;
524 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
525 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
526 "temp%u_crit", num + 1);
528 case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG:
529 mlxsw_hwmon_attr->dev_attr.show =
530 mlxsw_hwmon_module_temp_emergency_show;
531 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
532 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
533 "temp%u_emergency", num + 1);
535 case MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL:
536 mlxsw_hwmon_attr->dev_attr.show =
537 mlxsw_hwmon_module_temp_label_show;
538 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
539 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
540 "temp%u_label", num + 1);
542 case MLXSW_HWMON_ATTR_TYPE_TEMP_GBOX_LABEL:
543 mlxsw_hwmon_attr->dev_attr.show =
544 mlxsw_hwmon_gbox_temp_label_show;
545 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
546 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
547 "temp%u_label", num + 1);
549 case MLXSW_HWMON_ATTR_TYPE_TEMP_CRIT_ALARM:
550 mlxsw_hwmon_attr->dev_attr.show =
551 mlxsw_hwmon_temp_critical_alarm_show;
552 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
553 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
554 "temp%u_crit_alarm", num + 1);
556 case MLXSW_HWMON_ATTR_TYPE_TEMP_EMERGENCY_ALARM:
557 mlxsw_hwmon_attr->dev_attr.show =
558 mlxsw_hwmon_temp_emergency_alarm_show;
559 mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
560 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
561 "temp%u_emergency_alarm", num + 1);
567 mlxsw_hwmon_attr->type_index = type_index;
568 mlxsw_hwmon_attr->hwmon = mlxsw_hwmon;
569 mlxsw_hwmon_attr->dev_attr.attr.name = mlxsw_hwmon_attr->name;
570 sysfs_attr_init(&mlxsw_hwmon_attr->dev_attr.attr);
572 mlxsw_hwmon->attrs[attr_index] = &mlxsw_hwmon_attr->dev_attr.attr;
573 mlxsw_hwmon->attrs_count++;
576 static int mlxsw_hwmon_temp_init(struct mlxsw_hwmon *mlxsw_hwmon)
578 char mtcap_pl[MLXSW_REG_MTCAP_LEN] = {0};
582 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtcap), mtcap_pl);
584 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to get number of temp sensors\n");
587 mlxsw_hwmon->sensor_count = mlxsw_reg_mtcap_sensor_count_get(mtcap_pl);
588 for (i = 0; i < mlxsw_hwmon->sensor_count; i++) {
589 char mtmp_pl[MLXSW_REG_MTMP_LEN] = {0};
591 mlxsw_reg_mtmp_sensor_index_set(mtmp_pl, i);
592 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp),
596 mlxsw_reg_mtmp_mte_set(mtmp_pl, true);
597 mlxsw_reg_mtmp_mtr_set(mtmp_pl, true);
598 err = mlxsw_reg_write(mlxsw_hwmon->core,
599 MLXSW_REG(mtmp), mtmp_pl);
601 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to setup temp sensor number %d\n",
605 mlxsw_hwmon_attr_add(mlxsw_hwmon,
606 MLXSW_HWMON_ATTR_TYPE_TEMP, i, i);
607 mlxsw_hwmon_attr_add(mlxsw_hwmon,
608 MLXSW_HWMON_ATTR_TYPE_TEMP_MAX, i, i);
609 mlxsw_hwmon_attr_add(mlxsw_hwmon,
610 MLXSW_HWMON_ATTR_TYPE_TEMP_RST, i, i);
615 static int mlxsw_hwmon_fans_init(struct mlxsw_hwmon *mlxsw_hwmon)
617 char mfcr_pl[MLXSW_REG_MFCR_LEN] = {0};
618 enum mlxsw_reg_mfcr_pwm_frequency freq;
619 unsigned int type_index;
625 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mfcr), mfcr_pl);
627 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to get to probe PWMs and Tachometers\n");
630 mlxsw_reg_mfcr_unpack(mfcr_pl, &freq, &tacho_active, &pwm_active);
632 for (type_index = 0; type_index < MLXSW_MFCR_TACHOS_MAX; type_index++) {
633 if (tacho_active & BIT(type_index)) {
634 mlxsw_hwmon_attr_add(mlxsw_hwmon,
635 MLXSW_HWMON_ATTR_TYPE_FAN_RPM,
637 mlxsw_hwmon_attr_add(mlxsw_hwmon,
638 MLXSW_HWMON_ATTR_TYPE_FAN_FAULT,
643 for (type_index = 0; type_index < MLXSW_MFCR_PWMS_MAX; type_index++) {
644 if (pwm_active & BIT(type_index))
645 mlxsw_hwmon_attr_add(mlxsw_hwmon,
646 MLXSW_HWMON_ATTR_TYPE_PWM,
652 static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
654 char mgpir_pl[MLXSW_REG_MGPIR_LEN];
655 u8 module_sensor_max;
658 if (!mlxsw_core_res_query_enabled(mlxsw_hwmon->core))
661 mlxsw_reg_mgpir_pack(mgpir_pl);
662 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mgpir), mgpir_pl);
666 mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL,
669 /* Add extra attributes for module temperature. Sensor index is
670 * assigned to sensor_count value, while all indexed before
671 * sensor_count are already utilized by the sensors connected through
672 * mtmp register by mlxsw_hwmon_temp_init().
674 mlxsw_hwmon->module_sensor_max = mlxsw_hwmon->sensor_count +
676 for (i = mlxsw_hwmon->sensor_count;
677 i < mlxsw_hwmon->module_sensor_max; i++) {
678 mlxsw_hwmon_attr_add(mlxsw_hwmon,
679 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE, i, i);
680 mlxsw_hwmon_attr_add(mlxsw_hwmon,
681 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_FAULT,
683 mlxsw_hwmon_attr_add(mlxsw_hwmon,
684 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_CRIT, i,
686 mlxsw_hwmon_attr_add(mlxsw_hwmon,
687 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG,
689 mlxsw_hwmon_attr_add(mlxsw_hwmon,
690 MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL,
692 mlxsw_hwmon_attr_add(mlxsw_hwmon,
693 MLXSW_HWMON_ATTR_TYPE_TEMP_CRIT_ALARM,
695 mlxsw_hwmon_attr_add(mlxsw_hwmon,
696 MLXSW_HWMON_ATTR_TYPE_TEMP_EMERGENCY_ALARM,
703 static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
705 enum mlxsw_reg_mgpir_device_type device_type;
706 int index, max_index, sensor_index;
707 char mgpir_pl[MLXSW_REG_MGPIR_LEN];
708 char mtmp_pl[MLXSW_REG_MTMP_LEN];
712 mlxsw_reg_mgpir_pack(mgpir_pl);
713 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mgpir), mgpir_pl);
717 mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, &device_type, NULL, NULL);
718 if (device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE ||
722 index = mlxsw_hwmon->module_sensor_max;
723 max_index = mlxsw_hwmon->module_sensor_max + gbox_num;
724 while (index < max_index) {
725 sensor_index = index % mlxsw_hwmon->module_sensor_max +
726 MLXSW_REG_MTMP_GBOX_INDEX_MIN;
727 mlxsw_reg_mtmp_pack(mtmp_pl, sensor_index, true, true);
728 err = mlxsw_reg_write(mlxsw_hwmon->core,
729 MLXSW_REG(mtmp), mtmp_pl);
731 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to setup temp sensor number %d\n",
735 mlxsw_hwmon_attr_add(mlxsw_hwmon, MLXSW_HWMON_ATTR_TYPE_TEMP,
737 mlxsw_hwmon_attr_add(mlxsw_hwmon,
738 MLXSW_HWMON_ATTR_TYPE_TEMP_MAX, index,
740 mlxsw_hwmon_attr_add(mlxsw_hwmon,
741 MLXSW_HWMON_ATTR_TYPE_TEMP_RST, index,
743 mlxsw_hwmon_attr_add(mlxsw_hwmon,
744 MLXSW_HWMON_ATTR_TYPE_TEMP_GBOX_LABEL,
752 int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
753 const struct mlxsw_bus_info *mlxsw_bus_info,
754 struct mlxsw_hwmon **p_hwmon)
756 struct mlxsw_hwmon *mlxsw_hwmon;
757 struct device *hwmon_dev;
760 mlxsw_hwmon = kzalloc(sizeof(*mlxsw_hwmon), GFP_KERNEL);
763 mlxsw_hwmon->core = mlxsw_core;
764 mlxsw_hwmon->bus_info = mlxsw_bus_info;
766 err = mlxsw_hwmon_temp_init(mlxsw_hwmon);
770 err = mlxsw_hwmon_fans_init(mlxsw_hwmon);
774 err = mlxsw_hwmon_module_init(mlxsw_hwmon);
776 goto err_temp_module_init;
778 err = mlxsw_hwmon_gearbox_init(mlxsw_hwmon);
780 goto err_temp_gearbox_init;
782 mlxsw_hwmon->groups[0] = &mlxsw_hwmon->group;
783 mlxsw_hwmon->group.attrs = mlxsw_hwmon->attrs;
785 hwmon_dev = hwmon_device_register_with_groups(mlxsw_bus_info->dev,
786 "mlxsw", mlxsw_hwmon,
787 mlxsw_hwmon->groups);
788 if (IS_ERR(hwmon_dev)) {
789 err = PTR_ERR(hwmon_dev);
790 goto err_hwmon_register;
793 mlxsw_hwmon->hwmon_dev = hwmon_dev;
794 *p_hwmon = mlxsw_hwmon;
798 err_temp_gearbox_init:
799 err_temp_module_init:
806 void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
808 hwmon_device_unregister(mlxsw_hwmon->hwmon_dev);