From 98626c9b9401986dd035c22ba8e639380ad62f2b Mon Sep 17 00:00:00 2001 From: Kelvin Cao Date: Fri, 1 Dec 2023 17:47:18 -0800 Subject: [PATCH 1/2] lib: Add API switchtec_die_temps for multiple die sensor readings Gen5 introduces a new MRPC for multiple die sensor readings. Add this API to get the individual reading for each die sensor. --- inc/switchtec/switchtec.h | 2 ++ lib/switchtec.c | 58 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/inc/switchtec/switchtec.h b/inc/switchtec/switchtec.h index 30502a19..a8a11b8f 100644 --- a/inc/switchtec/switchtec.h +++ b/inc/switchtec/switchtec.h @@ -408,6 +408,8 @@ int switchtec_log_def_to_file(struct switchtec_dev *dev, enum switchtec_log_def_type type, FILE* file); float switchtec_die_temp(struct switchtec_dev *dev); +int switchtec_die_temps(struct switchtec_dev *dev, int nr_sensor, + float *sensor_readings); int switchtec_calc_lane_id(struct switchtec_dev *dev, int phys_port_id, int lane_id, struct switchtec_status *port); int switchtec_calc_port_lane(struct switchtec_dev *dev, int lane_id, diff --git a/lib/switchtec.c b/lib/switchtec.c index ed8dc7af..2fd407bf 100644 --- a/lib/switchtec.c +++ b/lib/switchtec.c @@ -1825,6 +1825,64 @@ float switchtec_die_temp(struct switchtec_dev *dev) return le32toh(temp) / 100.; } +/** + * @brief Get the die temperature sensor readings of the switchtec device + * @param[in] dev Switchtec device handle + * @param[in] nr_sensor Number of temp sensors to read + * @param[out] sensor_readings Array of sensor readings (in degrees celsius) + * @return The number of sensor readings or a negative value on failure + */ +int switchtec_die_temps(struct switchtec_dev *dev, int nr_sensor, + float *sensor_readings) +{ + int ret; + uint32_t sub_cmd_id; + uint32_t temp; + + if (nr_sensor <= 0 || !sensor_readings) + return 0; + + if (switchtec_is_gen3(dev)) { + sub_cmd_id = MRPC_DIETEMP_SET_MEAS; + ret = switchtec_cmd(dev, MRPC_DIETEMP, &sub_cmd_id, + sizeof(sub_cmd_id), NULL, 0); + if (ret) + return -100.0; + + sub_cmd_id = MRPC_DIETEMP_GET; + ret = switchtec_cmd(dev, MRPC_DIETEMP, &sub_cmd_id, + sizeof(sub_cmd_id), &temp, sizeof(temp)); + if (ret) + return -100.0; + + sensor_readings[0] = le32toh(temp) / 100.; + return 1; + } else if (switchtec_is_gen4(dev)) { + sub_cmd_id = MRPC_DIETEMP_GET_GEN4; + ret = switchtec_cmd(dev, MRPC_DIETEMP, &sub_cmd_id, + sizeof(sub_cmd_id), &temp, sizeof(temp)); + if (ret) + return -100.0; + + sensor_readings[0] = le32toh(temp) / 100.; + return 1; + } else { + sub_cmd_id = MRPC_DIETEMP_GET_GEN5; + uint32_t temps[4]; + int i; + + ret = switchtec_cmd(dev, MRPC_DIETEMP, &sub_cmd_id, + sizeof(sub_cmd_id), temps, sizeof(temps)); + if (ret) + return -100.0; + + for (i = 0; i < nr_sensor && i < 4; i++) + sensor_readings[i] = le32toh(temps[i]) / 100.; + + return i; + } +} + int switchtec_bind_info(struct switchtec_dev *dev, struct switchtec_bind_status_out *status, int phy_port) { From 27dbfd7c484146e3e39391aea3caee286af68819 Mon Sep 17 00:00:00 2001 From: Kelvin Cao Date: Fri, 1 Dec 2023 17:49:48 -0800 Subject: [PATCH 2/2] cli: Add verbose mode for 'temp' command to show individual die temperature sensor readings. --- cli/main.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/cli/main.c b/cli/main.c index 78d3401e..390724ef 100644 --- a/cli/main.c +++ b/cli/main.c @@ -1284,26 +1284,48 @@ static int test(int argc, char **argv) static int temp(int argc, char **argv) { float ret; + int nr_reading; + float temps[4]; static struct { struct switchtec_dev *dev; + int verbose; } cfg = {}; const struct argconfig_options opts[] = { DEVICE_OPTION, + {"verbose", 'v', "", CFG_NONE, &cfg.verbose, no_argument, + "print individual die temperature sensor reading"}, {NULL}}; argconfig_parse(argc, argv, CMD_DESC_TEMP, opts, &cfg, sizeof(cfg)); - ret = switchtec_die_temp(cfg.dev); - if (ret < 0) { - switchtec_perror("die_temp"); - return 1; + if (!cfg.verbose) { + ret = switchtec_die_temp(cfg.dev); + if (ret < 0) { + switchtec_perror("die_temp"); + return 1; + } + + if (have_decent_term()) + printf("%.3g °C\n", ret); + else + printf("%.3g degC\n", ret); + } else { + int i; + nr_reading = switchtec_die_temps(cfg.dev, 4, temps); + if (nr_reading < 0) { + switchtec_perror("die_temp"); + return 1; + } + + for (i = 0; i < nr_reading; i++) { + if (have_decent_term()) + printf("Sensor %d: %.3g °C\n", i, temps[i]); + else + printf("Sensor %d: %.3g degC\n", i, temps[i]); + } } - if (have_decent_term()) - printf("%.3g °C\n", ret); - else - printf("%.3g degC\n", ret); return 0; }