From: Arun Kumar Prakash Add the admin queue commands the device uses to describe and report its sensors: IONIC_CMD_HWMON_GETCAPS returns a buffer enumerating the sensor types, their channel counts and per-channel attribute capabilities, and IONIC_CMD_HWMON_GETATTR reads a single attribute of a single channel. The capability buffer has a variable layout that depends on the number of sensor types the firmware supports, so it cannot be expressed as a C struct and its format is documented in a comment instead. The sensor types, attribute IDs and capability buffer layout go in a new public header, include/linux/ionic/ionic_hwmon.h, because the hwmon driver that parses the buffer lives outside the ionic directory. Signed-off-by: Arun Kumar Prakash Signed-off-by: Eric Joyner Reviewed-by: Brett Creeley Co-developed-by: Nikhil P. Rao Signed-off-by: Nikhil P. Rao --- MAINTAINERS | 1 + drivers/net/ethernet/pensando/ionic/ionic_dev.h | 8 ++ drivers/net/ethernet/pensando/ionic/ionic_if.h | 104 +++++++++++++++++ drivers/net/ethernet/pensando/ionic/ionic_main.c | 4 + include/linux/ionic/ionic_hwmon.h | 138 +++++++++++++++++++++++ 5 files changed, 255 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 09713dc4c6a7..220b26c73b37 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -21804,6 +21804,7 @@ L: netdev@vger.kernel.org S: Maintained F: Documentation/networking/device_drivers/ethernet/pensando/ionic.rst F: drivers/net/ethernet/pensando/ +F: include/linux/ionic/ PER-CPU MEMORY ALLOCATOR M: Dennis Zhou diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h index db90e39a1442..869adb0a0e0c 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "ionic_if.h" #include "ionic_regs.h" @@ -116,6 +117,13 @@ static_assert(sizeof(ionic_rx_filter_del_comp) == 16); static_assert(sizeof(struct ionic_rdma_reset_cmd) == 64); static_assert(sizeof(struct ionic_rdma_queue_cmd) == 64); +/* HWMON commands */ +static_assert(sizeof(struct ionic_hwmon_getattr_cmd) == 64); +static_assert(sizeof(struct ionic_hwmon_getattr_comp) == 16); +static_assert(sizeof(struct ionic_hwmon_getcaps_cmd) == 64); +static_assert(sizeof(struct ionic_hwmon_getcaps_comp) == 16); +static_assert(sizeof(struct ionic_hwmon_chan_caps) == 164); + /* Events */ static_assert(sizeof(struct ionic_notifyq_cmd) == 4); static_assert(sizeof(union ionic_notifyq_comp) == 64); diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h b/drivers/net/ethernet/pensando/ionic/ionic_if.h index e911fad545d6..271731a35d9f 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_if.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h @@ -60,6 +60,10 @@ enum ionic_cmd_opcode { /* CMB command */ IONIC_CMD_DISCOVER_CMB = 80, + /* Hardware monitoring commands */ + IONIC_CMD_HWMON_GETATTR = 110, + IONIC_CMD_HWMON_GETCAPS = 111, + /* QoS commands */ IONIC_CMD_QOS_CLASS_IDENTIFY = 240, IONIC_CMD_QOS_CLASS_INIT = 241, @@ -274,11 +278,13 @@ union ionic_drv_identity { * enum ionic_dev_capability - Device capabilities * @IONIC_DEV_CAP_VF_CTRL: Device supports VF ctrl operations * @IONIC_DEV_CAP_DISC_CMB: Device supports CMB discovery operations + * @IONIC_DEV_CAP_HWMON: Device supports hardware monitoring * @IONIC_DEV_CAP_EXTRA_STATS: Device supports extra stats schema */ enum ionic_dev_capability { IONIC_DEV_CAP_VF_CTRL = BIT(0), IONIC_DEV_CAP_DISC_CMB = BIT(1), + IONIC_DEV_CAP_HWMON = BIT(3), IONIC_DEV_CAP_EXTRA_STATS = BIT(4), }; @@ -2526,6 +2532,100 @@ struct ionic_qos_clear_stats_cmd { typedef struct ionic_admin_comp ionic_qos_reset_comp; +/** + * struct ionic_hwmon_getattr_cmd - Hardware monitoring get attribute command + * @opcode: Command opcode (IONIC_CMD_HWMON_GETATTR) + * @rsvd: reserved byte(s) + * @lif_index: LIF index + * @sensor_type: Sensor type from enum ionic_hwmon_sensor_type + * @channel: Channel index within the sensor type + * @attr: Attribute ID from sensor-specific attribute enum + * @rsvd2: reserved byte(s) + * + * A *_ATTR_LABEL attribute ID must never be sent in this command. The label is + * already reported in ionic_hwmon_chan_caps.label; the attr_caps LABEL bit only + * signals that a label is present. + */ +struct ionic_hwmon_getattr_cmd { + u8 opcode; + u8 rsvd; + __le16 lif_index; + u8 sensor_type; + u8 channel; + u8 attr; + u8 rsvd2[57]; +}; + +/** + * struct ionic_hwmon_getattr_comp - Hardware monitor get attribute completion + * @status: Status of the command (enum ionic_status_code) + * @rsvd: reserved byte(s) + * @comp_index: Index in the descriptor ring for which this is the completion + * @attr_value: Attribute value + * @rsvd2: reserved byte(s) + * @color: Color bit + * + * attr_value depends on the (sensor_type, attr) pair being read: + * + * temperature INPUT, CRIT millidegrees Celsius, signed 32-bit + * temperature CRIT_ALARM 0 or 1 + * voltage INPUT millivolts + * power INPUT, MAX milliwatts + */ +struct ionic_hwmon_getattr_comp { + u8 status; + u8 rsvd; + __le16 comp_index; + __le32 attr_value; + u8 rsvd2[7]; + u8 color; +}; + +/** + * struct ionic_hwmon_getcaps_cmd - Hardware monitoring get capabilities command + * @opcode: Command opcode (IONIC_CMD_HWMON_GETCAPS) + * @ver: Highest capability buffer layout version supported by + * the driver + * @lif_index: LIF index + * @resp_buf_len: Length of response buffer + * @resp_dma_addr: DMA address for response data + * @rsvd2: reserved byte(s) + * + * The device writes the capability buffer in the highest layout version it + * supports that does not exceed @ver, and reports that version in the + * completion. IONIC_HWMON_CAPS_VERSION_0 is the layout documented in + * include/linux/ionic/ionic_hwmon.h. + */ +struct ionic_hwmon_getcaps_cmd { + u8 opcode; + u8 ver; + __le16 lif_index; + __le32 resp_buf_len; + __le64 resp_dma_addr; + u8 rsvd2[48]; +}; + +/** + * struct ionic_hwmon_getcaps_comp - Hardware monitoring get caps completion + * @status: Status of the command (enum ionic_status_code) + * @rsvd: reserved byte(s) + * @comp_index: Index in the descriptor ring for which this is the completion + * @ver: Layout version of the capability buffer written by the device + * @rsvd2: reserved byte(s) + * @color: Color bit + * + * Devices that predate @ver leave it zero, which is + * IONIC_HWMON_CAPS_VERSION_0. + */ +struct ionic_hwmon_getcaps_comp { + u8 status; + u8 rsvd; + __le16 comp_index; + u8 ver; + u8 rsvd2[10]; + u8 color; +}; + /** * struct ionic_fw_download_cmd - Firmware download command * @opcode: opcode @@ -3306,6 +3406,8 @@ union ionic_adminq_cmd { struct ionic_rx_filter_del_cmd rx_filter_del; struct ionic_rdma_reset_cmd rdma_reset; struct ionic_rdma_queue_cmd rdma_queue; + struct ionic_hwmon_getattr_cmd hwmon_getattr; + struct ionic_hwmon_getcaps_cmd hwmon_getcaps; struct ionic_fw_download_cmd fw_download; struct ionic_fw_control_cmd fw_control; }; @@ -3319,6 +3421,8 @@ union ionic_adminq_comp { struct ionic_lif_getattr_comp lif_getattr; struct ionic_admin_comp lif_setphc; struct ionic_rx_filter_add_comp rx_filter_add; + struct ionic_hwmon_getattr_comp hwmon_getattr; + struct ionic_hwmon_getcaps_comp hwmon_getcaps; struct ionic_fw_control_comp fw_control; }; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c index 38b47b959a11..9955ab77d86d 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_main.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c @@ -185,6 +185,10 @@ static const char *ionic_opcode_to_str(enum ionic_cmd_opcode opcode) return "IONIC_CMD_VF_GETATTR"; case IONIC_CMD_VF_SETATTR: return "IONIC_CMD_VF_SETATTR"; + case IONIC_CMD_HWMON_GETATTR: + return "IONIC_CMD_HWMON_GETATTR"; + case IONIC_CMD_HWMON_GETCAPS: + return "IONIC_CMD_HWMON_GETCAPS"; default: return "DEVCMD_UNKNOWN"; } diff --git a/include/linux/ionic/ionic_hwmon.h b/include/linux/ionic/ionic_hwmon.h new file mode 100644 index 000000000000..62667e3d7135 --- /dev/null +++ b/include/linux/ionic/ionic_hwmon.h @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) OR BSD-2-Clause */ +/* Copyright(c) 2026 Advanced Micro Devices, Inc */ + +#ifndef _LINUX_IONIC_HWMON_H_ +#define _LINUX_IONIC_HWMON_H_ + +#include + +#define IONIC_HWMON_CAPS_BUF_SIZE 4096 +#define IONIC_HWMON_CAPS_VERSION_0 0 + +/** + * enum ionic_hwmon_sensor_type - Hardware monitoring sensor types + * @IONIC_HWMON_TYPE_TEMP: Temperature sensors + * @IONIC_HWMON_TYPE_VOLTAGE: Voltage sensors + * @IONIC_HWMON_TYPE_POWER: Power sensors + * @IONIC_HWMON_TYPE_CHIP: Chip wide attributes + * @IONIC_HWMON_TYPE_CURRENT: Current sensors + * @IONIC_HWMON_TYPE_ENERGY: Energy sensors + * @IONIC_HWMON_TYPE_HUMIDITY: Humidity sensors + * @IONIC_HWMON_TYPE_FAN: Fan speed sensors + * @IONIC_HWMON_TYPE_PWM: PWM controllers + * @IONIC_HWMON_TYPE_INTRUSION: Intrusion detection + * @IONIC_HWMON_TYPE_MAX: Number of sensor types defined by this interface + * + * These values do not necessarily match enum hwmon_sensor_types. + */ +enum ionic_hwmon_sensor_type { + IONIC_HWMON_TYPE_TEMP = 0, + IONIC_HWMON_TYPE_VOLTAGE = 1, + IONIC_HWMON_TYPE_POWER = 2, + IONIC_HWMON_TYPE_CHIP = 3, + IONIC_HWMON_TYPE_CURRENT = 4, + IONIC_HWMON_TYPE_ENERGY = 5, + IONIC_HWMON_TYPE_HUMIDITY = 6, + IONIC_HWMON_TYPE_FAN = 7, + IONIC_HWMON_TYPE_PWM = 8, + IONIC_HWMON_TYPE_INTRUSION = 9, + IONIC_HWMON_TYPE_MAX = 10, +}; + +/** + * enum ionic_hwmon_temp_attr - Temperature sensor attributes + * @IONIC_HWMON_TEMP_ATTR_INPUT: Temperature input reading + * @IONIC_HWMON_TEMP_ATTR_LABEL: Temperature sensor label + * @IONIC_HWMON_TEMP_ATTR_CRIT: Critical temperature threshold + * @IONIC_HWMON_TEMP_ATTR_CRIT_ALARM: Critical temperature alarm status + */ +enum ionic_hwmon_temp_attr { + IONIC_HWMON_TEMP_ATTR_INPUT = 0, + IONIC_HWMON_TEMP_ATTR_LABEL = 1, + IONIC_HWMON_TEMP_ATTR_CRIT = 2, + IONIC_HWMON_TEMP_ATTR_CRIT_ALARM = 3, +}; + +/** + * enum ionic_hwmon_voltage_attr - Voltage sensor attributes + * @IONIC_HWMON_VOLTAGE_ATTR_INPUT: Voltage input reading + * @IONIC_HWMON_VOLTAGE_ATTR_LABEL: Voltage sensor label + */ +enum ionic_hwmon_voltage_attr { + IONIC_HWMON_VOLTAGE_ATTR_INPUT = 0, + IONIC_HWMON_VOLTAGE_ATTR_LABEL = 1, +}; + +/** + * enum ionic_hwmon_power_attr - Power sensor attributes + * @IONIC_HWMON_POWER_ATTR_INPUT: Power input reading + * @IONIC_HWMON_POWER_ATTR_LABEL: Power sensor label + * @IONIC_HWMON_POWER_ATTR_MAX: Maximum power threshold + */ +enum ionic_hwmon_power_attr { + IONIC_HWMON_POWER_ATTR_INPUT = 0, + IONIC_HWMON_POWER_ATTR_LABEL = 1, + IONIC_HWMON_POWER_ATTR_MAX = 2, +}; + +/** + * struct ionic_hwmon_chan_caps - Per-channel capability descriptor + * @attr_caps: Attribute bitmask where bit N indicates attribute N is supported + * (use sensor-type-specific attribute enums: + * ionic_hwmon_temp_attr, ionic_hwmon_voltage_attr, + * ionic_hwmon_power_attr) + * @mode: Permissions for attribute N, as a single octal rwx digit + * (4 = readable). Zero hides the attribute. Values above 7 + * are not a mode and hide the attribute too. + * @label: NUL-terminated channel label string + * + * Every channel reports at least one attribute that its sensor type defines. + * Firmware that adds attributes keeps reporting one that older drivers + * recognise, and uses @mode to control what is visible. + * + * The structure needs to be packed since the size of n_channels in the + * capability buffer layout documented below is variable, so the channels + * array is not guaranteed to start on a 4 byte boundary. + */ +struct ionic_hwmon_chan_caps { + __le32 attr_caps; + __le32 mode[32]; + char label[32]; +} __packed; + +#define IONIC_HWMON_MODE_MASK 0x7 +#define IONIC_HWMON_MODE_READ 4 + +/* + * Hardware monitoring capabilities buffer layout + * + * The buffer is a struct ionic_hwmon_caps_hdr followed by the channel + * descriptors, so where the descriptors start depends on num_types: + * + * struct ionic_hwmon_caps_buf { + * __le16 num_types; + * __le16 n_channels[num_types]; + * struct ionic_hwmon_chan_caps channels[total_channels]; + * }; + * + * total_channels is the sum of n_channels, and the channels of each sensor + * type are contiguous, in n_channels order. A driver reads at most + * IONIC_HWMON_TYPE_MAX entries of n_channels and ignores the channels of + * any further types, which follow the ones it knows. + * + * num_types and n_channels come from the device, and the completion does not + * report how much was written, so a parser checks every offset against the + * resp_buf_len sent in IONIC_CMD_HWMON_GETCAPS. + */ + +/** + * struct ionic_hwmon_caps_hdr - Start of the capabilities buffer + * @num_types: Number of sensor types described by firmware + * @n_channels: Channel count for each sensor type, num_types entries + */ +struct ionic_hwmon_caps_hdr { + __le16 num_types; + __le16 n_channels[]; +}; + +#endif /* _LINUX_IONIC_HWMON_H_ */ -- 2.43.0