1 /**************************************************************************** 2 * Driver for Solarflare network controllers and boards 3 * Copyright 2011-2013 Solarflare Communications Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published 7 * by the Free Software Foundation, incorporated herein by reference. 8 */ 9 10 #include <linux/bitops.h> 11 #include <linux/slab.h> 12 #include <linux/hwmon.h> 13 #include <linux/stat.h> 14 15 #include "net_driver.h" 16 #include "mcdi.h" 17 #include "mcdi_pcol.h" 18 #include "nic.h" 19 20 enum efx_hwmon_type { 21 EFX_HWMON_UNKNOWN, 22 EFX_HWMON_TEMP, /* temperature */ 23 EFX_HWMON_COOL, /* cooling device, probably a heatsink */ 24 EFX_HWMON_IN, /* voltage */ 25 EFX_HWMON_CURR, /* current */ 26 EFX_HWMON_POWER, /* power */ 27 }; 28 29 static const struct { 30 const char *label; 31 enum efx_hwmon_type hwmon_type; 32 int port; 33 } efx_mcdi_sensor_type[] = { 34 #define SENSOR(name, label, hwmon_type, port) \ 35 [MC_CMD_SENSOR_##name] = { label, EFX_HWMON_ ## hwmon_type, port } 36 SENSOR(CONTROLLER_TEMP, "Controller ext. temp.", TEMP, -1), 37 SENSOR(PHY_COMMON_TEMP, "PHY temp.", TEMP, -1), 38 SENSOR(CONTROLLER_COOLING, "Controller cooling", COOL, -1), 39 SENSOR(PHY0_TEMP, "PHY temp.", TEMP, 0), 40 SENSOR(PHY0_COOLING, "PHY cooling", COOL, 0), 41 SENSOR(PHY1_TEMP, "PHY temp.", TEMP, 1), 42 SENSOR(PHY1_COOLING, "PHY cooling", COOL, 1), 43 SENSOR(IN_1V0, "1.0V supply", IN, -1), 44 SENSOR(IN_1V2, "1.2V supply", IN, -1), 45 SENSOR(IN_1V8, "1.8V supply", IN, -1), 46 SENSOR(IN_2V5, "2.5V supply", IN, -1), 47 SENSOR(IN_3V3, "3.3V supply", IN, -1), 48 SENSOR(IN_12V0, "12.0V supply", IN, -1), 49 SENSOR(IN_1V2A, "1.2V analogue supply", IN, -1), 50 SENSOR(IN_VREF, "ref. voltage", IN, -1), 51 SENSOR(OUT_VAOE, "AOE power supply", IN, -1), 52 SENSOR(AOE_TEMP, "AOE temp.", TEMP, -1), 53 SENSOR(PSU_AOE_TEMP, "AOE PSU temp.", TEMP, -1), 54 SENSOR(PSU_TEMP, "Controller PSU temp.", TEMP, -1), 55 SENSOR(FAN_0, NULL, COOL, -1), 56 SENSOR(FAN_1, NULL, COOL, -1), 57 SENSOR(FAN_2, NULL, COOL, -1), 58 SENSOR(FAN_3, NULL, COOL, -1), 59 SENSOR(FAN_4, NULL, COOL, -1), 60 SENSOR(IN_VAOE, "AOE input supply", IN, -1), 61 SENSOR(OUT_IAOE, "AOE output current", CURR, -1), 62 SENSOR(IN_IAOE, "AOE input current", CURR, -1), 63 SENSOR(NIC_POWER, "Board power use", POWER, -1), 64 SENSOR(IN_0V9, "0.9V supply", IN, -1), 65 SENSOR(IN_I0V9, "0.9V input current", CURR, -1), 66 SENSOR(IN_I1V2, "1.2V input current", CURR, -1), 67 SENSOR(IN_0V9_ADC, "0.9V supply (at ADC)", IN, -1), 68 SENSOR(CONTROLLER_2_TEMP, "Controller ext. temp. 2", TEMP, -1), 69 SENSOR(VREG_INTERNAL_TEMP, "Voltage regulator temp.", TEMP, -1), 70 SENSOR(VREG_0V9_TEMP, "0.9V regulator temp.", TEMP, -1), 71 SENSOR(VREG_1V2_TEMP, "1.2V regulator temp.", TEMP, -1), 72 SENSOR(CONTROLLER_VPTAT, "Controller int. temp. raw", IN, -1), 73 SENSOR(CONTROLLER_INTERNAL_TEMP, "Controller int. temp.", TEMP, -1), 74 SENSOR(CONTROLLER_VPTAT_EXTADC, 75 "Controller int. temp. raw (at ADC)", IN, -1), 76 SENSOR(CONTROLLER_INTERNAL_TEMP_EXTADC, 77 "Controller int. temp. (via ADC)", TEMP, -1), 78 SENSOR(AMBIENT_TEMP, "Ambient temp.", TEMP, -1), 79 SENSOR(AIRFLOW, "Air flow raw", IN, -1), 80 #undef SENSOR 81 }; 82 83 static const char *const sensor_status_names[] = { 84 [MC_CMD_SENSOR_STATE_OK] = "OK", 85 [MC_CMD_SENSOR_STATE_WARNING] = "Warning", 86 [MC_CMD_SENSOR_STATE_FATAL] = "Fatal", 87 [MC_CMD_SENSOR_STATE_BROKEN] = "Device failure", 88 [MC_CMD_SENSOR_STATE_NO_READING] = "No reading", 89 }; 90 91 void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev) 92 { 93 unsigned int type, state, value; 94 const char *name = NULL, *state_txt; 95 96 type = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_MONITOR); 97 state = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_STATE); 98 value = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_VALUE); 99 100 /* Deal gracefully with the board having more drivers than we 101 * know about, but do not expect new sensor states. */ 102 if (type < ARRAY_SIZE(efx_mcdi_sensor_type)) 103 name = efx_mcdi_sensor_type[type].label; 104 if (!name) 105 name = "No sensor name available"; 106 EFX_BUG_ON_PARANOID(state >= ARRAY_SIZE(sensor_status_names)); 107 state_txt = sensor_status_names[state]; 108 109 netif_err(efx, hw, efx->net_dev, 110 "Sensor %d (%s) reports condition '%s' for raw value %d\n", 111 type, name, state_txt, value); 112 } 113 114 #ifdef CONFIG_SFC_MCDI_MON 115 116 struct efx_mcdi_mon_attribute { 117 struct device_attribute dev_attr; 118 unsigned int index; 119 unsigned int type; 120 enum efx_hwmon_type hwmon_type; 121 unsigned int limit_value; 122 char name[12]; 123 }; 124 125 static int efx_mcdi_mon_update(struct efx_nic *efx) 126 { 127 struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); 128 MCDI_DECLARE_BUF(inbuf, MC_CMD_READ_SENSORS_EXT_IN_LEN); 129 int rc; 130 131 MCDI_SET_QWORD(inbuf, READ_SENSORS_EXT_IN_DMA_ADDR, 132 hwmon->dma_buf.dma_addr); 133 MCDI_SET_DWORD(inbuf, READ_SENSORS_EXT_IN_LENGTH, hwmon->dma_buf.len); 134 135 rc = efx_mcdi_rpc(efx, MC_CMD_READ_SENSORS, 136 inbuf, sizeof(inbuf), NULL, 0, NULL); 137 if (rc == 0) 138 hwmon->last_update = jiffies; 139 return rc; 140 } 141 142 static ssize_t efx_mcdi_mon_show_name(struct device *dev, 143 struct device_attribute *attr, 144 char *buf) 145 { 146 return sprintf(buf, "%s\n", KBUILD_MODNAME); 147 } 148 149 static int efx_mcdi_mon_get_entry(struct device *dev, unsigned int index, 150 efx_dword_t *entry) 151 { 152 struct efx_nic *efx = dev_get_drvdata(dev); 153 struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); 154 int rc; 155 156 BUILD_BUG_ON(MC_CMD_READ_SENSORS_OUT_LEN != 0); 157 158 mutex_lock(&hwmon->update_lock); 159 160 /* Use cached value if last update was < 1 s ago */ 161 if (time_before(jiffies, hwmon->last_update + HZ)) 162 rc = 0; 163 else 164 rc = efx_mcdi_mon_update(efx); 165 166 /* Copy out the requested entry */ 167 *entry = ((efx_dword_t *)hwmon->dma_buf.addr)[index]; 168 169 mutex_unlock(&hwmon->update_lock); 170 171 return rc; 172 } 173 174 static ssize_t efx_mcdi_mon_show_value(struct device *dev, 175 struct device_attribute *attr, 176 char *buf) 177 { 178 struct efx_mcdi_mon_attribute *mon_attr = 179 container_of(attr, struct efx_mcdi_mon_attribute, dev_attr); 180 efx_dword_t entry; 181 unsigned int value, state; 182 int rc; 183 184 rc = efx_mcdi_mon_get_entry(dev, mon_attr->index, &entry); 185 if (rc) 186 return rc; 187 188 state = EFX_DWORD_FIELD(entry, MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE); 189 if (state == MC_CMD_SENSOR_STATE_NO_READING) 190 return -EBUSY; 191 192 value = EFX_DWORD_FIELD(entry, MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE); 193 194 switch (mon_attr->hwmon_type) { 195 case EFX_HWMON_TEMP: 196 /* Convert temperature from degrees to milli-degrees Celsius */ 197 value *= 1000; 198 break; 199 case EFX_HWMON_POWER: 200 /* Convert power from watts to microwatts */ 201 value *= 1000000; 202 break; 203 default: 204 /* No conversion needed */ 205 break; 206 } 207 208 return sprintf(buf, "%u\n", value); 209 } 210 211 static ssize_t efx_mcdi_mon_show_limit(struct device *dev, 212 struct device_attribute *attr, 213 char *buf) 214 { 215 struct efx_mcdi_mon_attribute *mon_attr = 216 container_of(attr, struct efx_mcdi_mon_attribute, dev_attr); 217 unsigned int value; 218 219 value = mon_attr->limit_value; 220 221 switch (mon_attr->hwmon_type) { 222 case EFX_HWMON_TEMP: 223 /* Convert temperature from degrees to milli-degrees Celsius */ 224 value *= 1000; 225 break; 226 case EFX_HWMON_POWER: 227 /* Convert power from watts to microwatts */ 228 value *= 1000000; 229 break; 230 default: 231 /* No conversion needed */ 232 break; 233 } 234 235 return sprintf(buf, "%u\n", value); 236 } 237 238 static ssize_t efx_mcdi_mon_show_alarm(struct device *dev, 239 struct device_attribute *attr, 240 char *buf) 241 { 242 struct efx_mcdi_mon_attribute *mon_attr = 243 container_of(attr, struct efx_mcdi_mon_attribute, dev_attr); 244 efx_dword_t entry; 245 int state; 246 int rc; 247 248 rc = efx_mcdi_mon_get_entry(dev, mon_attr->index, &entry); 249 if (rc) 250 return rc; 251 252 state = EFX_DWORD_FIELD(entry, MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE); 253 return sprintf(buf, "%d\n", state != MC_CMD_SENSOR_STATE_OK); 254 } 255 256 static ssize_t efx_mcdi_mon_show_label(struct device *dev, 257 struct device_attribute *attr, 258 char *buf) 259 { 260 struct efx_mcdi_mon_attribute *mon_attr = 261 container_of(attr, struct efx_mcdi_mon_attribute, dev_attr); 262 return sprintf(buf, "%s\n", 263 efx_mcdi_sensor_type[mon_attr->type].label); 264 } 265 266 static int 267 efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name, 268 ssize_t (*reader)(struct device *, 269 struct device_attribute *, char *), 270 unsigned int index, unsigned int type, 271 unsigned int limit_value) 272 { 273 struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); 274 struct efx_mcdi_mon_attribute *attr = &hwmon->attrs[hwmon->n_attrs]; 275 int rc; 276 277 strlcpy(attr->name, name, sizeof(attr->name)); 278 attr->index = index; 279 attr->type = type; 280 if (type < ARRAY_SIZE(efx_mcdi_sensor_type)) 281 attr->hwmon_type = efx_mcdi_sensor_type[type].hwmon_type; 282 else 283 attr->hwmon_type = EFX_HWMON_UNKNOWN; 284 attr->limit_value = limit_value; 285 sysfs_attr_init(&attr->dev_attr.attr); 286 attr->dev_attr.attr.name = attr->name; 287 attr->dev_attr.attr.mode = S_IRUGO; 288 attr->dev_attr.show = reader; 289 rc = device_create_file(&efx->pci_dev->dev, &attr->dev_attr); 290 if (rc == 0) 291 ++hwmon->n_attrs; 292 return rc; 293 } 294 295 int efx_mcdi_mon_probe(struct efx_nic *efx) 296 { 297 unsigned int n_temp = 0, n_cool = 0, n_in = 0, n_curr = 0, n_power = 0; 298 struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); 299 MCDI_DECLARE_BUF(inbuf, MC_CMD_SENSOR_INFO_EXT_IN_LEN); 300 MCDI_DECLARE_BUF(outbuf, MC_CMD_SENSOR_INFO_OUT_LENMAX); 301 unsigned int n_pages, n_sensors, n_attrs, page; 302 size_t outlen; 303 char name[12]; 304 u32 mask; 305 int rc, i, j, type; 306 307 /* Find out how many sensors are present */ 308 n_sensors = 0; 309 page = 0; 310 do { 311 MCDI_SET_DWORD(inbuf, SENSOR_INFO_EXT_IN_PAGE, page); 312 313 rc = efx_mcdi_rpc(efx, MC_CMD_SENSOR_INFO, inbuf, sizeof(inbuf), 314 outbuf, sizeof(outbuf), &outlen); 315 if (rc) 316 return rc; 317 if (outlen < MC_CMD_SENSOR_INFO_OUT_LENMIN) 318 return -EIO; 319 320 mask = MCDI_DWORD(outbuf, SENSOR_INFO_OUT_MASK); 321 n_sensors += hweight32(mask & ~(1 << MC_CMD_SENSOR_PAGE0_NEXT)); 322 ++page; 323 } while (mask & (1 << MC_CMD_SENSOR_PAGE0_NEXT)); 324 n_pages = page; 325 326 /* Don't create a device if there are none */ 327 if (n_sensors == 0) 328 return 0; 329 330 rc = efx_nic_alloc_buffer( 331 efx, &hwmon->dma_buf, 332 n_sensors * MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_LEN, 333 GFP_KERNEL); 334 if (rc) 335 return rc; 336 337 mutex_init(&hwmon->update_lock); 338 efx_mcdi_mon_update(efx); 339 340 /* Allocate space for the maximum possible number of 341 * attributes for this set of sensors: name of the driver plus 342 * value, min, max, crit, alarm and label for each sensor. 343 */ 344 n_attrs = 1 + 6 * n_sensors; 345 hwmon->attrs = kcalloc(n_attrs, sizeof(*hwmon->attrs), GFP_KERNEL); 346 if (!hwmon->attrs) { 347 rc = -ENOMEM; 348 goto fail; 349 } 350 351 hwmon->device = hwmon_device_register(&efx->pci_dev->dev); 352 if (IS_ERR(hwmon->device)) { 353 rc = PTR_ERR(hwmon->device); 354 goto fail; 355 } 356 357 rc = efx_mcdi_mon_add_attr(efx, "name", efx_mcdi_mon_show_name, 0, 0, 0); 358 if (rc) 359 goto fail; 360 361 for (i = 0, j = -1, type = -1; ; i++) { 362 enum efx_hwmon_type hwmon_type; 363 const char *hwmon_prefix; 364 unsigned hwmon_index; 365 u16 min1, max1, min2, max2; 366 367 /* Find next sensor type or exit if there is none */ 368 do { 369 type++; 370 371 if ((type % 32) == 0) { 372 page = type / 32; 373 j = -1; 374 if (page == n_pages) 375 return 0; 376 377 MCDI_SET_DWORD(inbuf, SENSOR_INFO_EXT_IN_PAGE, 378 page); 379 rc = efx_mcdi_rpc(efx, MC_CMD_SENSOR_INFO, 380 inbuf, sizeof(inbuf), 381 outbuf, sizeof(outbuf), 382 &outlen); 383 if (rc) 384 goto fail; 385 if (outlen < MC_CMD_SENSOR_INFO_OUT_LENMIN) { 386 rc = -EIO; 387 goto fail; 388 } 389 390 mask = (MCDI_DWORD(outbuf, 391 SENSOR_INFO_OUT_MASK) & 392 ~(1 << MC_CMD_SENSOR_PAGE0_NEXT)); 393 394 /* Check again for short response */ 395 if (outlen < 396 MC_CMD_SENSOR_INFO_OUT_LEN(hweight32(mask))) { 397 rc = -EIO; 398 goto fail; 399 } 400 } 401 } while (!(mask & (1 << type % 32))); 402 j++; 403 404 if (type < ARRAY_SIZE(efx_mcdi_sensor_type)) { 405 hwmon_type = efx_mcdi_sensor_type[type].hwmon_type; 406 407 /* Skip sensors specific to a different port */ 408 if (hwmon_type != EFX_HWMON_UNKNOWN && 409 efx_mcdi_sensor_type[type].port >= 0 && 410 efx_mcdi_sensor_type[type].port != 411 efx_port_num(efx)) 412 continue; 413 } else { 414 hwmon_type = EFX_HWMON_UNKNOWN; 415 } 416 417 switch (hwmon_type) { 418 case EFX_HWMON_TEMP: 419 hwmon_prefix = "temp"; 420 hwmon_index = ++n_temp; /* 1-based */ 421 break; 422 case EFX_HWMON_COOL: 423 /* This is likely to be a heatsink, but there 424 * is no convention for representing cooling 425 * devices other than fans. 426 */ 427 hwmon_prefix = "fan"; 428 hwmon_index = ++n_cool; /* 1-based */ 429 break; 430 default: 431 hwmon_prefix = "in"; 432 hwmon_index = n_in++; /* 0-based */ 433 break; 434 case EFX_HWMON_CURR: 435 hwmon_prefix = "curr"; 436 hwmon_index = ++n_curr; /* 1-based */ 437 break; 438 case EFX_HWMON_POWER: 439 hwmon_prefix = "power"; 440 hwmon_index = ++n_power; /* 1-based */ 441 break; 442 } 443 444 min1 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY, 445 SENSOR_INFO_ENTRY, j, MIN1); 446 max1 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY, 447 SENSOR_INFO_ENTRY, j, MAX1); 448 min2 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY, 449 SENSOR_INFO_ENTRY, j, MIN2); 450 max2 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY, 451 SENSOR_INFO_ENTRY, j, MAX2); 452 453 if (min1 != max1) { 454 snprintf(name, sizeof(name), "%s%u_input", 455 hwmon_prefix, hwmon_index); 456 rc = efx_mcdi_mon_add_attr( 457 efx, name, efx_mcdi_mon_show_value, i, type, 0); 458 if (rc) 459 goto fail; 460 461 if (hwmon_type != EFX_HWMON_POWER) { 462 snprintf(name, sizeof(name), "%s%u_min", 463 hwmon_prefix, hwmon_index); 464 rc = efx_mcdi_mon_add_attr( 465 efx, name, efx_mcdi_mon_show_limit, 466 i, type, min1); 467 if (rc) 468 goto fail; 469 } 470 471 snprintf(name, sizeof(name), "%s%u_max", 472 hwmon_prefix, hwmon_index); 473 rc = efx_mcdi_mon_add_attr( 474 efx, name, efx_mcdi_mon_show_limit, 475 i, type, max1); 476 if (rc) 477 goto fail; 478 479 if (min2 != max2) { 480 /* Assume max2 is critical value. 481 * But we have no good way to expose min2. 482 */ 483 snprintf(name, sizeof(name), "%s%u_crit", 484 hwmon_prefix, hwmon_index); 485 rc = efx_mcdi_mon_add_attr( 486 efx, name, efx_mcdi_mon_show_limit, 487 i, type, max2); 488 if (rc) 489 goto fail; 490 } 491 } 492 493 snprintf(name, sizeof(name), "%s%u_alarm", 494 hwmon_prefix, hwmon_index); 495 rc = efx_mcdi_mon_add_attr( 496 efx, name, efx_mcdi_mon_show_alarm, i, type, 0); 497 if (rc) 498 goto fail; 499 500 if (type < ARRAY_SIZE(efx_mcdi_sensor_type) && 501 efx_mcdi_sensor_type[type].label) { 502 snprintf(name, sizeof(name), "%s%u_label", 503 hwmon_prefix, hwmon_index); 504 rc = efx_mcdi_mon_add_attr( 505 efx, name, efx_mcdi_mon_show_label, i, type, 0); 506 if (rc) 507 goto fail; 508 } 509 } 510 511 fail: 512 efx_mcdi_mon_remove(efx); 513 return rc; 514 } 515 516 void efx_mcdi_mon_remove(struct efx_nic *efx) 517 { 518 struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); 519 unsigned int i; 520 521 for (i = 0; i < hwmon->n_attrs; i++) 522 device_remove_file(&efx->pci_dev->dev, 523 &hwmon->attrs[i].dev_attr); 524 kfree(hwmon->attrs); 525 if (hwmon->device) 526 hwmon_device_unregister(hwmon->device); 527 efx_nic_free_buffer(efx, &hwmon->dma_buf); 528 } 529 530 #endif /* CONFIG_SFC_MCDI_MON */ 531