summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@fingolfin.org>2020-07-30 19:11:57 -0700
committerRobert Mustacchi <rm@fingolfin.org>2020-09-14 08:27:50 -0700
commit1718c31669d146508ea805e88322f5b74d892762 (patch)
tree7942658359b720bfa4ad60f4456c974a87a6fe0d /usr/src
parent1045e13a248d94941f864998aa859970ae3a4154 (diff)
downloadillumos-joyent-1718c31669d146508ea805e88322f5b74d892762.tar.gz
13081 add mlxcx temp sensor
Reviewed by: Alex Wilson <alex@cooperi.net> Reviewed by: Andy Fiddaman <andy@omniosce.org> Reviewed by: Paul Winder <paul@winder.uk.net> Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/man/man7d/mlxcx.7d4
-rw-r--r--usr/src/uts/common/Makefile.files2
-rw-r--r--usr/src/uts/common/io/mlxcx/mlxcx.c10
-rw-r--r--usr/src/uts/common/io/mlxcx/mlxcx.h22
-rw-r--r--usr/src/uts/common/io/mlxcx/mlxcx_cmd.c10
-rw-r--r--usr/src/uts/common/io/mlxcx/mlxcx_reg.h28
-rw-r--r--usr/src/uts/common/io/mlxcx/mlxcx_sensor.c126
7 files changed, 200 insertions, 2 deletions
diff --git a/usr/src/man/man7d/mlxcx.7d b/usr/src/man/man7d/mlxcx.7d
index d7b0cf8ad9..ccbc257641 100644
--- a/usr/src/man/man7d/mlxcx.7d
+++ b/usr/src/man/man7d/mlxcx.7d
@@ -11,7 +11,7 @@
.\"
.\" Copyright 2020 the University of Queensland
.\"
-.Dd April 9, 2020
+.Dd August 27, 2020
.Dt MLXCX 7D
.Os
.Sh NAME
@@ -44,6 +44,8 @@ Promiscuous access via
LED control
.It
Transceiver information
+.It
+Internal temperature sensors
.El
.Pp
At this time, the driver does not support Large Send Offload (LSO), energy
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index 4a44510cb8..5f38c6eb5f 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -2284,4 +2284,4 @@ BNX_OBJS += \
# mlxcx(7D)
#
MLXCX_OBJS += mlxcx.o mlxcx_dma.o mlxcx_cmd.o mlxcx_intr.o mlxcx_gld.o \
- mlxcx_ring.o
+ mlxcx_ring.o mlxcx_sensor.o
diff --git a/usr/src/uts/common/io/mlxcx/mlxcx.c b/usr/src/uts/common/io/mlxcx/mlxcx.c
index 6421b47126..90964d2fd1 100644
--- a/usr/src/uts/common/io/mlxcx/mlxcx.c
+++ b/usr/src/uts/common/io/mlxcx/mlxcx.c
@@ -1066,6 +1066,11 @@ mlxcx_teardown(mlxcx_t *mlxp)
mlxcx_intr_disable(mlxp);
}
+ if (mlxp->mlx_attach & MLXCX_ATTACH_SENSORS) {
+ mlxcx_teardown_sensors(mlxp);
+ mlxp->mlx_attach &= ~MLXCX_ATTACH_SENSORS;
+ }
+
if (mlxp->mlx_attach & MLXCX_ATTACH_CHKTIMERS) {
mlxcx_teardown_checktimers(mlxp);
mlxp->mlx_attach &= ~MLXCX_ATTACH_CHKTIMERS;
@@ -2869,6 +2874,11 @@ mlxcx_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
}
mlxp->mlx_attach |= MLXCX_ATTACH_CHKTIMERS;
+ if (!mlxcx_setup_sensors(mlxp)) {
+ goto err;
+ }
+ mlxp->mlx_attach |= MLXCX_ATTACH_SENSORS;
+
/*
* Finally, tell MAC that we exist!
*/
diff --git a/usr/src/uts/common/io/mlxcx/mlxcx.h b/usr/src/uts/common/io/mlxcx/mlxcx.h
index dd91ea3734..e28fe89806 100644
--- a/usr/src/uts/common/io/mlxcx/mlxcx.h
+++ b/usr/src/uts/common/io/mlxcx/mlxcx.h
@@ -1009,6 +1009,15 @@ typedef struct {
uint64_t mldp_wq_check_interval_sec;
} mlxcx_drv_props_t;
+typedef struct {
+ mlxcx_t *mlts_mlx;
+ uint8_t mlts_index;
+ id_t mlts_ksensor;
+ int16_t mlts_value;
+ int16_t mlts_max_value;
+ uint8_t mlts_name[MLXCX_MTMP_NAMELEN];
+} mlxcx_temp_sensor_t;
+
typedef enum {
MLXCX_ATTACH_FM = 1 << 0,
MLXCX_ATTACH_PCI_CONFIG = 1 << 1,
@@ -1028,6 +1037,7 @@ typedef enum {
MLXCX_ATTACH_CAPS = 1 << 15,
MLXCX_ATTACH_CHKTIMERS = 1 << 16,
MLXCX_ATTACH_ASYNC_TQ = 1 << 17,
+ MLXCX_ATTACH_SENSORS = 1 << 18
} mlxcx_attach_progress_t;
struct mlxcx {
@@ -1172,6 +1182,12 @@ struct mlxcx {
ddi_periodic_t mlx_eq_checktimer;
ddi_periodic_t mlx_cq_checktimer;
ddi_periodic_t mlx_wq_checktimer;
+
+ /*
+ * Sensors
+ */
+ uint8_t mlx_temp_nsensors;
+ mlxcx_temp_sensor_t *mlx_temp_sensors;
};
/*
@@ -1447,6 +1463,12 @@ extern const char *mlxcx_port_status_string(mlxcx_port_status_t);
extern const char *mlxcx_event_name(mlxcx_event_t);
+/*
+ * Sensor Functions
+ */
+extern boolean_t mlxcx_setup_sensors(mlxcx_t *);
+extern void mlxcx_teardown_sensors(mlxcx_t *);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c b/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c
index 3cb531df39..32c40ec3ea 100644
--- a/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c
+++ b/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c
@@ -1688,6 +1688,10 @@ mlxcx_reg_name(mlxcx_register_id_t rid)
return ("PPCNT");
case MLXCX_REG_PPLM:
return ("PPLM");
+ case MLXCX_REG_MTCAP:
+ return ("MTCAP");
+ case MLXCX_REG_MTMP:
+ return ("MTMP");
default:
return ("???");
}
@@ -1737,6 +1741,12 @@ mlxcx_cmd_access_register(mlxcx_t *mlxp, mlxcx_cmd_reg_opmod_t opmod,
case MLXCX_REG_PPLM:
dsize = sizeof (mlxcx_reg_pplm_t);
break;
+ case MLXCX_REG_MTCAP:
+ dsize = sizeof (mlxcx_reg_mtcap_t);
+ break;
+ case MLXCX_REG_MTMP:
+ dsize = sizeof (mlxcx_reg_mtmp_t);
+ break;
default:
dsize = 0;
VERIFY(0);
diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_reg.h b/usr/src/uts/common/io/mlxcx/mlxcx_reg.h
index 1987ae06ea..4b92de92b8 100644
--- a/usr/src/uts/common/io/mlxcx/mlxcx_reg.h
+++ b/usr/src/uts/common/io/mlxcx/mlxcx_reg.h
@@ -2530,6 +2530,30 @@ typedef struct {
uint16be_t mlrd_pplm_fec_override_admin_fdr10;
} mlxcx_reg_pplm_t;
+typedef struct {
+ uint8_t mlrd_mtcap_rsvd[3];
+ uint8_t mlrd_mtcap_sensor_count;
+ uint8_t mlrd_mtcap_rsvd1[4];
+ uint64be_t mlrd_mtcap_sensor_map;
+} mlxcx_reg_mtcap_t;
+
+#define MLXCX_MTMP_NAMELEN 8
+
+typedef struct {
+ uint8_t mlrd_mtmp_rsvd[2];
+ uint16be_t mlrd_mtmp_sensor_index;
+ uint8_t mlrd_mtmp_rsvd1[2];
+ uint16be_t mlrd_mtmp_temperature;
+ bits16_t mlrd_mtmp_max_flags;
+ uint16be_t mlrd_mtmp_max_temperature;
+ bits16_t mlrd_mtmp_tee;
+ uint16be_t mlrd_mtmp_temp_thresh_hi;
+ uint8_t mlrd_mtmp_rsvd2[2];
+ uint16be_t mlrd_mtmp_temp_thresh_lo;
+ uint8_t mlrd_mtmp_rsvd3[4];
+ uint8_t mlrd_mtmp_name[MLXCX_MTMP_NAMELEN];
+} mlxcx_reg_mtmp_t;
+
typedef enum {
MLXCX_REG_PMTU = 0x5003,
MLXCX_REG_PTYS = 0x5004,
@@ -2540,6 +2564,8 @@ typedef enum {
MLXCX_REG_MCIA = 0x9014,
MLXCX_REG_PPCNT = 0x5008,
MLXCX_REG_PPLM = 0x5023,
+ MLXCX_REG_MTCAP = 0x9009,
+ MLXCX_REG_MTMP = 0x900A
} mlxcx_register_id_t;
typedef union {
@@ -2551,6 +2577,8 @@ typedef union {
mlxcx_reg_mcia_t mlrd_mcia;
mlxcx_reg_ppcnt_t mlrd_ppcnt;
mlxcx_reg_pplm_t mlrd_pplm;
+ mlxcx_reg_mtcap_t mlrd_mtcap;
+ mlxcx_reg_mtmp_t mlrd_mtmp;
} mlxcx_register_data_t;
typedef enum {
diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_sensor.c b/usr/src/uts/common/io/mlxcx/mlxcx_sensor.c
new file mode 100644
index 0000000000..6d2c7d0778
--- /dev/null
+++ b/usr/src/uts/common/io/mlxcx/mlxcx_sensor.c
@@ -0,0 +1,126 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2020 Oxide Computer Company
+ */
+
+#include <mlxcx.h>
+#include <sys/sensors.h>
+
+/*
+ * The PRM indicates that the temperature is measured in 1/8th degrees.
+ */
+#define MLXCX_TEMP_GRAN 8
+
+/*
+ * Read a single temperature sensor entry. The ksensor framework guarantees that
+ * it will only call this once for a given sensor at any time, though multiple
+ * sensors can be in parallel.
+ */
+static int
+mlxcx_temperature_read(void *arg, sensor_ioctl_scalar_t *scalar)
+{
+ boolean_t ok;
+ uint16_t tmp;
+ mlxcx_register_data_t data;
+ mlxcx_temp_sensor_t *sensor = arg;
+ mlxcx_t *mlxp = sensor->mlts_mlx;
+
+ bzero(&data, sizeof (data));
+ data.mlrd_mtmp.mlrd_mtmp_sensor_index = to_be16(sensor->mlts_index);
+ ok = mlxcx_cmd_access_register(mlxp, MLXCX_CMD_ACCESS_REGISTER_READ,
+ MLXCX_REG_MTMP, &data);
+ if (!ok) {
+ return (EIO);
+ }
+
+ tmp = from_be16(data.mlrd_mtmp.mlrd_mtmp_temperature);
+ sensor->mlts_value = (int16_t)tmp;
+ tmp = from_be16(data.mlrd_mtmp.mlrd_mtmp_max_temperature);
+ sensor->mlts_max_value = (int16_t)tmp;
+ bcopy(data.mlrd_mtmp.mlrd_mtmp_name, sensor->mlts_name,
+ sizeof (sensor->mlts_name));
+
+ scalar->sis_unit = SENSOR_UNIT_CELSIUS;
+ scalar->sis_gran = MLXCX_TEMP_GRAN;
+ scalar->sis_prec = 0;
+ scalar->sis_value = (int64_t)sensor->mlts_value;
+
+ return (0);
+}
+
+static const ksensor_ops_t mlxcx_temp_ops = {
+ .kso_kind = ksensor_kind_temperature,
+ .kso_scalar = mlxcx_temperature_read
+};
+
+void
+mlxcx_teardown_sensors(mlxcx_t *mlxp)
+{
+ if (mlxp->mlx_temp_nsensors == 0)
+ return;
+ (void) ksensor_remove(mlxp->mlx_dip, KSENSOR_ALL_IDS);
+ kmem_free(mlxp->mlx_temp_sensors, sizeof (mlxcx_temp_sensor_t) *
+ mlxp->mlx_temp_nsensors);
+}
+
+boolean_t
+mlxcx_setup_sensors(mlxcx_t *mlxp)
+{
+ mlxcx_register_data_t data;
+ boolean_t ok;
+
+ mlxp->mlx_temp_nsensors = 0;
+ bzero(&data, sizeof (data));
+ ok = mlxcx_cmd_access_register(mlxp, MLXCX_CMD_ACCESS_REGISTER_READ,
+ MLXCX_REG_MTCAP, &data);
+ if (!ok) {
+ return (B_FALSE);
+ }
+
+ if (data.mlrd_mtcap.mlrd_mtcap_sensor_count == 0) {
+ return (B_TRUE);
+ }
+
+ mlxp->mlx_temp_nsensors = data.mlrd_mtcap.mlrd_mtcap_sensor_count;
+ mlxp->mlx_temp_sensors = kmem_zalloc(sizeof (mlxcx_temp_sensor_t) *
+ mlxp->mlx_temp_nsensors, KM_SLEEP);
+
+ for (uint8_t i = 0; i < mlxp->mlx_temp_nsensors; i++) {
+ char buf[32];
+ int ret;
+
+ if (snprintf(buf, sizeof (buf), "temp%u", i) >= sizeof (buf)) {
+ mlxcx_warn(mlxp, "sensor name %u would overflow "
+ "internal buffer");
+ goto err;
+ }
+
+ mlxp->mlx_temp_sensors[i].mlts_mlx = mlxp;
+ mlxp->mlx_temp_sensors[i].mlts_index = i;
+
+ ret = ksensor_create_scalar_pcidev(mlxp->mlx_dip,
+ SENSOR_KIND_TEMPERATURE, &mlxcx_temp_ops,
+ &mlxp->mlx_temp_sensors[i], buf,
+ &mlxp->mlx_temp_sensors[i].mlts_ksensor);
+ if (ret != 0) {
+ mlxcx_warn(mlxp, "failed to create temp sensor %s: %d",
+ buf, ret);
+ goto err;
+ }
+ }
+
+ return (B_TRUE);
+err:
+ mlxcx_teardown_sensors(mlxp);
+ return (B_FALSE);
+}