1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */ 3 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> 9 #include <linux/err.h> 10 #include <linux/sfp.h> 11 12 #include "core.h" 13 #include "core_env.h" 14 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 + \ 26 MLXSW_MFCR_TACHOS_MAX + MLXSW_MFCR_PWMS_MAX) 27 28 struct mlxsw_hwmon_attr { 29 struct device_attribute dev_attr; 30 struct mlxsw_hwmon *hwmon; 31 unsigned int type_index; 32 char name[32]; 33 }; 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 } 42 43 struct mlxsw_hwmon { 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; 52 u8 sensor_count; 53 u8 module_sensor_max; 54 }; 55 56 static ssize_t mlxsw_hwmon_temp_show(struct device *dev, 57 struct device_attribute *attr, 58 char *buf) 59 { 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]; 64 int temp, index; 65 int err; 66 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); 71 if (err) { 72 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n"); 73 return err; 74 } 75 mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL, NULL, NULL); 76 return sprintf(buf, "%d\n", temp); 77 } 78 79 static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev, 80 struct device_attribute *attr, 81 char *buf) 82 { 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]; 87 int temp_max, index; 88 int err; 89 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); 94 if (err) { 95 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n"); 96 return err; 97 } 98 mlxsw_reg_mtmp_unpack(mtmp_pl, NULL, &temp_max, NULL, NULL, NULL); 99 return sprintf(buf, "%d\n", temp_max); 100 } 101 102 static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev, 103 struct device_attribute *attr, 104 const char *buf, size_t len) 105 { 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}; 110 unsigned long val; 111 int index; 112 int err; 113 114 err = kstrtoul(buf, 10, &val); 115 if (err) 116 return err; 117 if (val != 1) 118 return -EINVAL; 119 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); 129 err = mlxsw_reg_write(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl); 130 if (err) { 131 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to reset temp sensor history\n"); 132 return err; 133 } 134 return len; 135 } 136 137 static ssize_t mlxsw_hwmon_fan_rpm_show(struct device *dev, 138 struct device_attribute *attr, 139 char *buf) 140 { 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]; 145 int err; 146 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); 149 if (err) { 150 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query fan\n"); 151 return err; 152 } 153 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); 175 } 176 177 static ssize_t mlxsw_hwmon_pwm_show(struct device *dev, 178 struct device_attribute *attr, 179 char *buf) 180 { 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]; 185 int err; 186 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); 189 if (err) { 190 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query PWM\n"); 191 return err; 192 } 193 return sprintf(buf, "%u\n", 194 mlxsw_reg_mfsc_pwm_duty_cycle_get(mfsc_pl)); 195 } 196 197 static ssize_t mlxsw_hwmon_pwm_store(struct device *dev, 198 struct device_attribute *attr, 199 const char *buf, size_t len) 200 { 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]; 205 unsigned long val; 206 int err; 207 208 err = kstrtoul(buf, 10, &val); 209 if (err) 210 return err; 211 if (val > 255) 212 return -EINVAL; 213 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); 216 if (err) { 217 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to write PWM\n"); 218 return err; 219 } 220 return len; 221 } 222 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, 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 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, 459 }; 460 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; 466 467 attr_index = mlxsw_hwmon->attrs_count; 468 mlxsw_hwmon_attr = &mlxsw_hwmon->hwmon_attrs[attr_index]; 469 470 switch (attr_type) { 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); 476 break; 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); 482 break; 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); 488 break; 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); 494 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; 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), 506 "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); 562 break; 563 default: 564 WARN_ON(1); 565 } 566 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); 571 572 mlxsw_hwmon->attrs[attr_index] = &mlxsw_hwmon_attr->dev_attr.attr; 573 mlxsw_hwmon->attrs_count++; 574 } 575 576 static int mlxsw_hwmon_temp_init(struct mlxsw_hwmon *mlxsw_hwmon) 577 { 578 char mtcap_pl[MLXSW_REG_MTCAP_LEN] = {0}; 579 int i; 580 int err; 581 582 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtcap), mtcap_pl); 583 if (err) { 584 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to get number of temp sensors\n"); 585 return err; 586 } 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); 598 err = mlxsw_reg_write(mlxsw_hwmon->core, 599 MLXSW_REG(mtmp), mtmp_pl); 600 if (err) { 601 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to setup temp sensor number %d\n", 602 i); 603 return err; 604 } 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); 611 } 612 return 0; 613 } 614 615 static int mlxsw_hwmon_fans_init(struct mlxsw_hwmon *mlxsw_hwmon) 616 { 617 char mfcr_pl[MLXSW_REG_MFCR_LEN] = {0}; 618 enum mlxsw_reg_mfcr_pwm_frequency freq; 619 unsigned int type_index; 620 unsigned int num; 621 u16 tacho_active; 622 u8 pwm_active; 623 int err; 624 625 err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mfcr), mfcr_pl); 626 if (err) { 627 dev_err(mlxsw_hwmon->bus_info->dev, "Failed to get to probe PWMs and Tachometers\n"); 628 return err; 629 } 630 mlxsw_reg_mfcr_unpack(mfcr_pl, &freq, &tacho_active, &pwm_active); 631 num = 0; 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, 636 type_index, num); 637 mlxsw_hwmon_attr_add(mlxsw_hwmon, 638 MLXSW_HWMON_ATTR_TYPE_FAN_FAULT, 639 type_index, num++); 640 } 641 } 642 num = 0; 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, 647 type_index, num++); 648 } 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 749 return 0; 750 } 751 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) 755 { 756 struct mlxsw_hwmon *mlxsw_hwmon; 757 struct device *hwmon_dev; 758 int err; 759 760 mlxsw_hwmon = kzalloc(sizeof(*mlxsw_hwmon), GFP_KERNEL); 761 if (!mlxsw_hwmon) 762 return -ENOMEM; 763 mlxsw_hwmon->core = mlxsw_core; 764 mlxsw_hwmon->bus_info = mlxsw_bus_info; 765 766 err = mlxsw_hwmon_temp_init(mlxsw_hwmon); 767 if (err) 768 goto err_temp_init; 769 770 err = mlxsw_hwmon_fans_init(mlxsw_hwmon); 771 if (err) 772 goto err_fans_init; 773 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 782 mlxsw_hwmon->groups[0] = &mlxsw_hwmon->group; 783 mlxsw_hwmon->group.attrs = mlxsw_hwmon->attrs; 784 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; 791 } 792 793 mlxsw_hwmon->hwmon_dev = hwmon_dev; 794 *p_hwmon = mlxsw_hwmon; 795 return 0; 796 797 err_hwmon_register: 798 err_temp_gearbox_init: 799 err_temp_module_init: 800 err_fans_init: 801 err_temp_init: 802 kfree(mlxsw_hwmon); 803 return err; 804 } 805 806 void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon) 807 { 808 hwmon_device_unregister(mlxsw_hwmon->hwmon_dev); 809 kfree(mlxsw_hwmon); 810 } 811