diff options
author | Robert Mustacchi <rm@fingolfin.org> | 2020-07-30 19:11:57 -0700 |
---|---|---|
committer | Robert Mustacchi <rm@fingolfin.org> | 2020-09-14 08:27:50 -0700 |
commit | 1718c31669d146508ea805e88322f5b74d892762 (patch) | |
tree | 7942658359b720bfa4ad60f4456c974a87a6fe0d /usr/src | |
parent | 1045e13a248d94941f864998aa859970ae3a4154 (diff) | |
download | illumos-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.7d | 4 | ||||
-rw-r--r-- | usr/src/uts/common/Makefile.files | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/mlxcx/mlxcx.c | 10 | ||||
-rw-r--r-- | usr/src/uts/common/io/mlxcx/mlxcx.h | 22 | ||||
-rw-r--r-- | usr/src/uts/common/io/mlxcx/mlxcx_cmd.c | 10 | ||||
-rw-r--r-- | usr/src/uts/common/io/mlxcx/mlxcx_reg.h | 28 | ||||
-rw-r--r-- | usr/src/uts/common/io/mlxcx/mlxcx_sensor.c | 126 |
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); +} |