forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
kernel/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
....@@ -7,11 +7,22 @@
77 #include <linux/sysfs.h>
88 #include <linux/hwmon.h>
99 #include <linux/err.h>
10
+#include <linux/sfp.h>
1011
1112 #include "core.h"
13
+#include "core_env.h"
1214
13
-#define MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT 127
14
-#define MLXSW_HWMON_ATTR_COUNT (MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT * 4 + \
15
+#define MLXSW_HWMON_SENSORS_MAX_COUNT 64
16
+#define MLXSW_HWMON_MODULES_MAX_COUNT 64
17
+#define MLXSW_HWMON_GEARBOXES_MAX_COUNT 32
18
+
19
+#define MLXSW_HWMON_ATTR_PER_SENSOR 3
20
+#define MLXSW_HWMON_ATTR_PER_MODULE 7
21
+#define MLXSW_HWMON_ATTR_PER_GEARBOX 4
22
+
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 + \
1526 MLXSW_MFCR_TACHOS_MAX + MLXSW_MFCR_PWMS_MAX)
1627
1728 struct mlxsw_hwmon_attr {
....@@ -20,6 +31,14 @@
2031 unsigned int type_index;
2132 char name[32];
2233 };
34
+
35
+static int mlxsw_hwmon_get_attr_index(int index, int count)
36
+{
37
+ if (index >= count)
38
+ return index % count + MLXSW_REG_MTMP_GBOX_INDEX_MIN;
39
+
40
+ return index;
41
+}
2342
2443 struct mlxsw_hwmon {
2544 struct mlxsw_core *core;
....@@ -30,6 +49,8 @@
3049 struct attribute *attrs[MLXSW_HWMON_ATTR_COUNT + 1];
3150 struct mlxsw_hwmon_attr hwmon_attrs[MLXSW_HWMON_ATTR_COUNT];
3251 unsigned int attrs_count;
52
+ u8 sensor_count;
53
+ u8 module_sensor_max;
3354 };
3455
3556 static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
....@@ -40,18 +61,19 @@
4061 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
4162 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
4263 char mtmp_pl[MLXSW_REG_MTMP_LEN];
43
- unsigned int temp;
64
+ int temp, index;
4465 int err;
4566
46
- mlxsw_reg_mtmp_pack(mtmp_pl, mlwsw_hwmon_attr->type_index,
47
- false, false);
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);
4870 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
4971 if (err) {
5072 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n");
5173 return err;
5274 }
5375 mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
54
- return sprintf(buf, "%u\n", temp);
76
+ return sprintf(buf, "%d\n", temp);
5577 }
5678
5779 static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
....@@ -62,18 +84,19 @@
6284 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
6385 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
6486 char mtmp_pl[MLXSW_REG_MTMP_LEN];
65
- unsigned int temp_max;
87
+ int temp_max, index;
6688 int err;
6789
68
- mlxsw_reg_mtmp_pack(mtmp_pl, mlwsw_hwmon_attr->type_index,
69
- false, false);
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);
7093 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
7194 if (err) {
7295 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n");
7396 return err;
7497 }
7598 mlxsw_reg_mtmp_unpack(mtmp_pl, NULL, &temp_max, NULL);
76
- return sprintf(buf, "%u\n", temp_max);
99
+ return sprintf(buf, "%d\n", temp_max);
77100 }
78101
79102 static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev,
....@@ -83,8 +106,9 @@
83106 struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
84107 container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
85108 struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
86
- char mtmp_pl[MLXSW_REG_MTMP_LEN];
109
+ char mtmp_pl[MLXSW_REG_MTMP_LEN] = {0};
87110 unsigned long val;
111
+ int index;
88112 int err;
89113
90114 err = kstrtoul(buf, 10, &val);
....@@ -93,7 +117,15 @@
93117 if (val != 1)
94118 return -EINVAL;
95119
96
- mlxsw_reg_mtmp_pack(mtmp_pl, mlwsw_hwmon_attr->type_index, true, true);
120
+ index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
121
+ mlxsw_hwmon->module_sensor_max);
122
+
123
+ mlxsw_reg_mtmp_sensor_index_set(mtmp_pl, index);
124
+ err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
125
+ if (err)
126
+ return err;
127
+ mlxsw_reg_mtmp_mte_set(mtmp_pl, true);
128
+ mlxsw_reg_mtmp_mtr_set(mtmp_pl, true);
97129 err = mlxsw_reg_write(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
98130 if (err) {
99131 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to reset temp sensor history\n");
....@@ -119,6 +151,27 @@
119151 return err;
120152 }
121153 return sprintf(buf, "%u\n", mlxsw_reg_mfsm_rpm_get(mfsm_pl));
154
+}
155
+
156
+static ssize_t mlxsw_hwmon_fan_fault_show(struct device *dev,
157
+ struct device_attribute *attr,
158
+ char *buf)
159
+{
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];
164
+ bool fault;
165
+ int err;
166
+
167
+ err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(fore), fore_pl);
168
+ if (err) {
169
+ dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query fan\n");
170
+ return err;
171
+ }
172
+ mlxsw_reg_fore_unpack(fore_pl, mlwsw_hwmon_attr->type_index, &fault);
173
+
174
+ return sprintf(buf, "%u\n", fault);
122175 }
123176
124177 static ssize_t mlxsw_hwmon_pwm_show(struct device *dev,
....@@ -167,12 +220,242 @@
167220 return len;
168221 }
169222
223
+static int mlxsw_hwmon_module_temp_get(struct device *dev,
224
+ struct device_attribute *attr,
225
+ int *p_temp)
226
+{
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];
231
+ u8 module;
232
+ int err;
233
+
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,
236
+ false, false);
237
+ err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
238
+ if (err) {
239
+ dev_err(dev, "Failed to query module temperature\n");
240
+ return err;
241
+ }
242
+ mlxsw_reg_mtmp_unpack(mtmp_pl, p_temp, NULL, NULL);
243
+
244
+ return 0;
245
+}
246
+
247
+static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev,
248
+ struct device_attribute *attr,
249
+ char *buf)
250
+{
251
+ int err, temp;
252
+
253
+ err = mlxsw_hwmon_module_temp_get(dev, attr, &temp);
254
+ if (err)
255
+ return err;
256
+
257
+ return sprintf(buf, "%d\n", temp);
258
+}
259
+
260
+static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev,
261
+ struct device_attribute *attr,
262
+ char *buf)
263
+{
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};
268
+ u8 module, fault;
269
+ u16 temp;
270
+ int err;
271
+
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,
274
+ 1);
275
+ err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtbr), mtbr_pl);
276
+ if (err) {
277
+ dev_err(dev, "Failed to query module temperature sensor\n");
278
+ return err;
279
+ }
280
+
281
+ mlxsw_reg_mtbr_temp_unpack(mtbr_pl, 0, &temp, NULL);
282
+
283
+ /* Update status and temperature cache. */
284
+ switch (temp) {
285
+ case MLXSW_REG_MTBR_BAD_SENS_INFO:
286
+ /* Untrusted cable is connected. Reading temperature from its
287
+ * sensor is faulty.
288
+ */
289
+ fault = 1;
290
+ break;
291
+ case MLXSW_REG_MTBR_NO_CONN:
292
+ case MLXSW_REG_MTBR_NO_TEMP_SENS:
293
+ case MLXSW_REG_MTBR_INDEX_NA:
294
+ default:
295
+ fault = 0;
296
+ break;
297
+ }
298
+
299
+ return sprintf(buf, "%u\n", fault);
300
+}
301
+
302
+static int mlxsw_hwmon_module_temp_critical_get(struct device *dev,
303
+ struct device_attribute *attr,
304
+ int *p_temp)
305
+{
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;
309
+ u8 module;
310
+ int err;
311
+
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);
315
+ if (err) {
316
+ dev_err(dev, "Failed to query module temperature thresholds\n");
317
+ return err;
318
+ }
319
+
320
+ return 0;
321
+}
322
+
323
+static ssize_t
324
+mlxsw_hwmon_module_temp_critical_show(struct device *dev,
325
+ struct device_attribute *attr, char *buf)
326
+{
327
+ int err, temp;
328
+
329
+ err = mlxsw_hwmon_module_temp_critical_get(dev, attr, &temp);
330
+ if (err)
331
+ return err;
332
+
333
+ return sprintf(buf, "%u\n", temp);
334
+}
335
+
336
+static int mlxsw_hwmon_module_temp_emergency_get(struct device *dev,
337
+ struct device_attribute *attr,
338
+ int *p_temp)
339
+{
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;
343
+ u8 module;
344
+ int err;
345
+
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);
349
+ if (err) {
350
+ dev_err(dev, "Failed to query module temperature thresholds\n");
351
+ return err;
352
+ }
353
+
354
+ return 0;
355
+}
356
+
357
+static ssize_t
358
+mlxsw_hwmon_module_temp_emergency_show(struct device *dev,
359
+ struct device_attribute *attr,
360
+ char *buf)
361
+{
362
+ int err, temp;
363
+
364
+ err = mlxsw_hwmon_module_temp_emergency_get(dev, attr, &temp);
365
+ if (err)
366
+ return err;
367
+
368
+ return sprintf(buf, "%u\n", temp);
369
+}
370
+
371
+static ssize_t
372
+mlxsw_hwmon_module_temp_label_show(struct device *dev,
373
+ struct device_attribute *attr,
374
+ char *buf)
375
+{
376
+ struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
377
+ container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
378
+
379
+ return sprintf(buf, "front panel %03u\n",
380
+ mlwsw_hwmon_attr->type_index);
381
+}
382
+
383
+static ssize_t
384
+mlxsw_hwmon_gbox_temp_label_show(struct device *dev,
385
+ struct device_attribute *attr,
386
+ char *buf)
387
+{
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;
393
+
394
+ return sprintf(buf, "gearbox %03u\n", index);
395
+}
396
+
397
+static ssize_t mlxsw_hwmon_temp_critical_alarm_show(struct device *dev,
398
+ struct device_attribute *attr,
399
+ char *buf)
400
+{
401
+ int err, temp, emergency_temp, critic_temp;
402
+
403
+ err = mlxsw_hwmon_module_temp_get(dev, attr, &temp);
404
+ if (err)
405
+ return err;
406
+
407
+ if (temp <= 0)
408
+ return sprintf(buf, "%d\n", false);
409
+
410
+ err = mlxsw_hwmon_module_temp_emergency_get(dev, attr, &emergency_temp);
411
+ if (err)
412
+ return err;
413
+
414
+ if (temp >= emergency_temp)
415
+ return sprintf(buf, "%d\n", false);
416
+
417
+ err = mlxsw_hwmon_module_temp_critical_get(dev, attr, &critic_temp);
418
+ if (err)
419
+ return err;
420
+
421
+ return sprintf(buf, "%d\n", temp >= critic_temp);
422
+}
423
+
424
+static ssize_t mlxsw_hwmon_temp_emergency_alarm_show(struct device *dev,
425
+ struct device_attribute *attr,
426
+ char *buf)
427
+{
428
+ int err, temp, emergency_temp;
429
+
430
+ err = mlxsw_hwmon_module_temp_get(dev, attr, &temp);
431
+ if (err)
432
+ return err;
433
+
434
+ if (temp <= 0)
435
+ return sprintf(buf, "%d\n", false);
436
+
437
+ err = mlxsw_hwmon_module_temp_emergency_get(dev, attr, &emergency_temp);
438
+ if (err)
439
+ return err;
440
+
441
+ return sprintf(buf, "%d\n", temp >= emergency_temp);
442
+}
443
+
170444 enum mlxsw_hwmon_attr_type {
171445 MLXSW_HWMON_ATTR_TYPE_TEMP,
172446 MLXSW_HWMON_ATTR_TYPE_TEMP_MAX,
173447 MLXSW_HWMON_ATTR_TYPE_TEMP_RST,
174448 MLXSW_HWMON_ATTR_TYPE_FAN_RPM,
449
+ MLXSW_HWMON_ATTR_TYPE_FAN_FAULT,
175450 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,
176459 };
177460
178461 static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
....@@ -209,12 +492,73 @@
209492 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
210493 "fan%u_input", num + 1);
211494 break;
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);
500
+ break;
212501 case MLXSW_HWMON_ATTR_TYPE_PWM:
213502 mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_pwm_show;
214503 mlxsw_hwmon_attr->dev_attr.store = mlxsw_hwmon_pwm_store;
215504 mlxsw_hwmon_attr->dev_attr.attr.mode = 0644;
216505 snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
217506 "pwm%u", num + 1);
507
+ break;
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);
513
+ break;
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);
520
+ break;
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);
527
+ break;
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);
534
+ break;
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);
541
+ break;
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);
548
+ break;
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);
555
+ break;
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);
218562 break;
219563 default:
220564 WARN_ON(1);
....@@ -232,8 +576,6 @@
232576 static int mlxsw_hwmon_temp_init(struct mlxsw_hwmon *mlxsw_hwmon)
233577 {
234578 char mtcap_pl[MLXSW_REG_MTCAP_LEN] = {0};
235
- char mtmp_pl[MLXSW_REG_MTMP_LEN];
236
- u8 sensor_count;
237579 int i;
238580 int err;
239581
....@@ -242,9 +584,17 @@
242584 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to get number of temp sensors\n");
243585 return err;
244586 }
245
- sensor_count = mlxsw_reg_mtcap_sensor_count_get(mtcap_pl);
246
- for (i = 0; i < sensor_count; i++) {
247
- mlxsw_reg_mtmp_pack(mtmp_pl, i, true, true);
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};
590
+
591
+ mlxsw_reg_mtmp_sensor_index_set(mtmp_pl, i);
592
+ err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp),
593
+ mtmp_pl);
594
+ if (err)
595
+ return err;
596
+ mlxsw_reg_mtmp_mte_set(mtmp_pl, true);
597
+ mlxsw_reg_mtmp_mtr_set(mtmp_pl, true);
248598 err = mlxsw_reg_write(mlxsw_hwmon->core,
249599 MLXSW_REG(mtmp), mtmp_pl);
250600 if (err) {
....@@ -280,10 +630,14 @@
280630 mlxsw_reg_mfcr_unpack(mfcr_pl, &freq, &tacho_active, &pwm_active);
281631 num = 0;
282632 for (type_index = 0; type_index < MLXSW_MFCR_TACHOS_MAX; type_index++) {
283
- if (tacho_active & BIT(type_index))
633
+ if (tacho_active & BIT(type_index)) {
284634 mlxsw_hwmon_attr_add(mlxsw_hwmon,
285635 MLXSW_HWMON_ATTR_TYPE_FAN_RPM,
636
+ type_index, num);
637
+ mlxsw_hwmon_attr_add(mlxsw_hwmon,
638
+ MLXSW_HWMON_ATTR_TYPE_FAN_FAULT,
286639 type_index, num++);
640
+ }
287641 }
288642 num = 0;
289643 for (type_index = 0; type_index < MLXSW_MFCR_PWMS_MAX; type_index++) {
....@@ -292,6 +646,106 @@
292646 MLXSW_HWMON_ATTR_TYPE_PWM,
293647 type_index, num++);
294648 }
649
+ return 0;
650
+}
651
+
652
+static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
653
+{
654
+ char mgpir_pl[MLXSW_REG_MGPIR_LEN];
655
+ u8 module_sensor_max;
656
+ int i, err;
657
+
658
+ if (!mlxsw_core_res_query_enabled(mlxsw_hwmon->core))
659
+ return 0;
660
+
661
+ mlxsw_reg_mgpir_pack(mgpir_pl);
662
+ err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mgpir), mgpir_pl);
663
+ if (err)
664
+ return err;
665
+
666
+ mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL,
667
+ &module_sensor_max);
668
+
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().
673
+ */
674
+ mlxsw_hwmon->module_sensor_max = mlxsw_hwmon->sensor_count +
675
+ module_sensor_max;
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,
682
+ i, i);
683
+ mlxsw_hwmon_attr_add(mlxsw_hwmon,
684
+ MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_CRIT, i,
685
+ i);
686
+ mlxsw_hwmon_attr_add(mlxsw_hwmon,
687
+ MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG,
688
+ i, i);
689
+ mlxsw_hwmon_attr_add(mlxsw_hwmon,
690
+ MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL,
691
+ i, i);
692
+ mlxsw_hwmon_attr_add(mlxsw_hwmon,
693
+ MLXSW_HWMON_ATTR_TYPE_TEMP_CRIT_ALARM,
694
+ i, i);
695
+ mlxsw_hwmon_attr_add(mlxsw_hwmon,
696
+ MLXSW_HWMON_ATTR_TYPE_TEMP_EMERGENCY_ALARM,
697
+ i, i);
698
+ }
699
+
700
+ return 0;
701
+}
702
+
703
+static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
704
+{
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];
709
+ u8 gbox_num;
710
+ int err;
711
+
712
+ mlxsw_reg_mgpir_pack(mgpir_pl);
713
+ err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mgpir), mgpir_pl);
714
+ if (err)
715
+ return err;
716
+
717
+ mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, &device_type, NULL, NULL);
718
+ if (device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE ||
719
+ !gbox_num)
720
+ return 0;
721
+
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);
730
+ if (err) {
731
+ dev_err(mlxsw_hwmon->bus_info->dev, "Failed to setup temp sensor number %d\n",
732
+ sensor_index);
733
+ return err;
734
+ }
735
+ mlxsw_hwmon_attr_add(mlxsw_hwmon, MLXSW_HWMON_ATTR_TYPE_TEMP,
736
+ index, index);
737
+ mlxsw_hwmon_attr_add(mlxsw_hwmon,
738
+ MLXSW_HWMON_ATTR_TYPE_TEMP_MAX, index,
739
+ index);
740
+ mlxsw_hwmon_attr_add(mlxsw_hwmon,
741
+ MLXSW_HWMON_ATTR_TYPE_TEMP_RST, index,
742
+ index);
743
+ mlxsw_hwmon_attr_add(mlxsw_hwmon,
744
+ MLXSW_HWMON_ATTR_TYPE_TEMP_GBOX_LABEL,
745
+ index, index);
746
+ index++;
747
+ }
748
+
295749 return 0;
296750 }
297751
....@@ -317,6 +771,14 @@
317771 if (err)
318772 goto err_fans_init;
319773
774
+ err = mlxsw_hwmon_module_init(mlxsw_hwmon);
775
+ if (err)
776
+ goto err_temp_module_init;
777
+
778
+ err = mlxsw_hwmon_gearbox_init(mlxsw_hwmon);
779
+ if (err)
780
+ goto err_temp_gearbox_init;
781
+
320782 mlxsw_hwmon->groups[0] = &mlxsw_hwmon->group;
321783 mlxsw_hwmon->group.attrs = mlxsw_hwmon->attrs;
322784
....@@ -333,6 +795,8 @@
333795 return 0;
334796
335797 err_hwmon_register:
798
+err_temp_gearbox_init:
799
+err_temp_module_init:
336800 err_fans_init:
337801 err_temp_init:
338802 kfree(mlxsw_hwmon);