diff options
author | Robert Mustacchi <rm@fingolfin.org> | 2020-07-19 13:30:50 -0700 |
---|---|---|
committer | Robert Mustacchi <rm@fingolfin.org> | 2020-09-17 11:21:02 -0700 |
commit | 73439c833efecf3010718112f4fce6bb183a6803 (patch) | |
tree | b0527bb9f419f1529ba9033e7ebed47a23e0127f | |
parent | b7a7784945b3504d0b69ea02a08e1cddb5578907 (diff) | |
download | illumos-joyent-73439c833efecf3010718112f4fce6bb183a6803.tar.gz |
13080 Add support for cxgbe temp/volt sensor
Reviewed by: Andy Fiddaman <andy@omniosce.org>
Reviewed by: Paul Winder <paul@winder.uk.net>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r-- | usr/src/uts/common/io/cxgbe/t4nex/adapter.h | 4 | ||||
-rw-r--r-- | usr/src/uts/common/io/cxgbe/t4nex/t4_nexus.c | 105 |
2 files changed, 108 insertions, 1 deletions
diff --git a/usr/src/uts/common/io/cxgbe/t4nex/adapter.h b/usr/src/uts/common/io/cxgbe/t4nex/adapter.h index 48edc44341..1192eeb43e 100644 --- a/usr/src/uts/common/io/cxgbe/t4nex/adapter.h +++ b/usr/src/uts/common/io/cxgbe/t4nex/adapter.h @@ -559,6 +559,10 @@ struct adapter { kmutex_t sfl_lock; /* same cache-line as sc_lock? but that's ok */ TAILQ_HEAD(, sge_fl) sfl; timeout_id_t sfl_timer; + + /* Sensors */ + id_t temp_sensor; + id_t volt_sensor; }; enum { diff --git a/usr/src/uts/common/io/cxgbe/t4nex/t4_nexus.c b/usr/src/uts/common/io/cxgbe/t4nex/t4_nexus.c index ec590228b6..05732e47a1 100644 --- a/usr/src/uts/common/io/cxgbe/t4nex/t4_nexus.c +++ b/usr/src/uts/common/io/cxgbe/t4nex/t4_nexus.c @@ -37,6 +37,7 @@ #include <sys/mkdev.h> #include <sys/queue.h> #include <sys/containerof.h> +#include <sys/sensors.h> #include "version.h" #include "common/common.h" @@ -180,6 +181,18 @@ static kmutex_t t4_uld_list_lock; static SLIST_HEAD(, uld_info) t4_uld_list; #endif +static int t4_temperature_read(void *, sensor_ioctl_scalar_t *); +static int t4_voltage_read(void *, sensor_ioctl_scalar_t *); +static const ksensor_ops_t t4_temp_ops = { + .kso_kind = ksensor_kind_temperature, + .kso_scalar = t4_temperature_read +}; + +static const ksensor_ops_t t4_volt_ops = { + .kso_kind = ksensor_kind_voltage, + .kso_scalar = t4_voltage_read +}; + int _init(void) { @@ -758,7 +771,23 @@ ofld_queues: } sc->flags |= INTR_ALLOCATED; - ASSERT(rc == DDI_SUCCESS); + if ((rc = ksensor_create_scalar_pcidev(dip, SENSOR_KIND_TEMPERATURE, + &t4_temp_ops, sc, "temp", &sc->temp_sensor)) != 0) { + cxgb_printf(dip, CE_WARN, "failed to create temperature " + "sensor: %d", rc); + rc = DDI_FAILURE; + goto done; + } + + if ((rc = ksensor_create_scalar_pcidev(dip, SENSOR_KIND_VOLTAGE, + &t4_volt_ops, sc, "vdd", &sc->volt_sensor)) != 0) { + cxgb_printf(dip, CE_WARN, "failed to create voltage " + "sensor: %d", rc); + rc = DDI_FAILURE; + goto done; + } + + ddi_report_dev(dip); /* @@ -849,6 +878,7 @@ t4_devo_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) } /* Safe to call no matter what */ + (void) ksensor_remove(dip, KSENSOR_ALL_IDS); ddi_prop_remove_all(dip); ddi_remove_minor_node(dip, NULL); @@ -2919,3 +2949,76 @@ t4_iterate(void (*func)(int, void *), void *arg) } #endif + +static int +t4_sensor_read(struct adapter *sc, uint32_t diag, uint32_t *valp) +{ + int rc; + struct port_info *pi = sc->port[0]; + uint32_t param, val; + + rc = begin_synchronized_op(pi, 1, 1); + if (rc != 0) { + return (rc); + } + param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | + V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_DIAG) | + V_FW_PARAMS_PARAM_Y(diag); + rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 1, ¶m, &val); + end_synchronized_op(pi, 1); + + if (rc != 0) { + return (rc); + } + + if (val == 0) { + return (EIO); + } + + *valp = val; + return (0); +} + +static int +t4_temperature_read(void *arg, sensor_ioctl_scalar_t *scalar) +{ + int ret; + struct adapter *sc = arg; + uint32_t val; + + ret = t4_sensor_read(sc, FW_PARAM_DEV_DIAG_TMP, &val); + if (ret != 0) { + return (ret); + } + + /* + * The device measures temperature in units of 1 degree Celsius. We + * don't know its precision. + */ + scalar->sis_unit = SENSOR_UNIT_CELSIUS; + scalar->sis_gran = 1; + scalar->sis_prec = 0; + scalar->sis_value = val; + + return (0); +} + +static int +t4_voltage_read(void *arg, sensor_ioctl_scalar_t *scalar) +{ + int ret; + struct adapter *sc = arg; + uint32_t val; + + ret = t4_sensor_read(sc, FW_PARAM_DEV_DIAG_VDD, &val); + if (ret != 0) { + return (ret); + } + + scalar->sis_unit = SENSOR_UNIT_VOLTS; + scalar->sis_gran = 1000; + scalar->sis_prec = 0; + scalar->sis_value = val; + + return (0); +} |