summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@fingolfin.org>2020-07-19 13:30:50 -0700
committerRobert Mustacchi <rm@fingolfin.org>2020-09-17 11:21:02 -0700
commit73439c833efecf3010718112f4fce6bb183a6803 (patch)
treeb0527bb9f419f1529ba9033e7ebed47a23e0127f
parentb7a7784945b3504d0b69ea02a08e1cddb5578907 (diff)
downloadillumos-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.h4
-rw-r--r--usr/src/uts/common/io/cxgbe/t4nex/t4_nexus.c105
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, &param, &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);
+}