From: "Nikhil P. Rao" <nikhil.rao@amd.com>
To: Brett Creeley <brett.creeley@amd.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
"Eric Dumazet" <edumazet@kernel.org>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Guenter Roeck <linux@roeck-us.net>,
Jonathan Corbet <corbet@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>,
Randy Dunlap <rdunlap@infradead.org>, Kees Cook <kees@kernel.org>,
"Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: <netdev@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<linux-hwmon@vger.kernel.org>, <linux-doc@vger.kernel.org>,
<linux-hardening@vger.kernel.org>,
Abhijit Gangurde <abhijit.gangurde@amd.com>,
"Nikhil P. Rao" <nikhil.rao@amd.com>
Subject: [PATCH net-next 3/4] ionic: add an auxiliary device for hardware monitoring
Date: Tue, 3 Nov 2026 18:14:48 +0000 [thread overview]
Message-ID: <20261103-pr46-b4-v1-3-850ab7fbec19@amd.com> (raw)
In-Reply-To: <20261103-pr46-b4-v1-0-850ab7fbec19@amd.com>
When the firmware sets IONIC_DEV_CAP_HWMON, create an "hwmon" auxiliary
device so the adapter's sensors can be exposed by a driver in
drivers/hwmon/ rather than by the Ethernet driver.
The GETCAPS response buffer belongs to ionic for the life of the device,
not to the hwmon driver, so a command abandoned on timeout or unbind can
only write into that buffer, never into freed memory.
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
Signed-off-by: Nikhil P. Rao <nikhil.rao@amd.com>
---
drivers/net/ethernet/pensando/ionic/ionic.h | 2 +
drivers/net/ethernet/pensando/ionic/ionic_aux.c | 109 ++++++++++++++++++++++++
drivers/net/ethernet/pensando/ionic/ionic_lif.h | 1 +
include/linux/ionic/ionic_hwmon.h | 40 +++++++++
4 files changed, 152 insertions(+)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic.h b/drivers/net/ethernet/pensando/ionic/ionic.h
index 555a77db1b1e..814d70b8623b 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic.h
@@ -64,6 +64,8 @@ struct ionic {
int num_vfs;
struct timer_list watchdog_timer;
int watchdog_period;
+ void *hwmon_caps_buf;
+ dma_addr_t hwmon_caps_pa;
};
int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_aux.c b/drivers/net/ethernet/pensando/ionic/ionic_aux.c
index 370a7eff3e28..521f3bd9aee1 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_aux.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_aux.c
@@ -2,6 +2,8 @@
/* Copyright (C) 2018-2025, Advanced Micro Devices, Inc. */
#include <linux/kernel.h>
+#include <linux/ionic/ionic_hwmon.h>
+
#include "ionic.h"
#include "ionic_lif.h"
#include "ionic_aux.h"
@@ -17,11 +19,39 @@ static bool ionic_rdma_supported(struct ionic *ionic)
return le64_to_cpu(ionic->ident.lif.capabilities) & IONIC_LIF_CAP_RDMA;
}
+static bool ionic_hwmon_supported(struct ionic *ionic)
+{
+ return le64_to_cpu(ionic->ident.dev.capabilities) & IONIC_DEV_CAP_HWMON;
+}
+
+static int ionic_hwmon_prepare(struct ionic *ionic)
+{
+ void *buf;
+
+ if (ionic->hwmon_caps_buf)
+ return 0;
+
+ buf = dmam_alloc_coherent(ionic->dev, IONIC_HWMON_CAPS_BUF_SIZE,
+ &ionic->hwmon_caps_pa, GFP_KERNEL);
+ if (!buf) {
+ dev_warn(ionic->dev, "Failed to allocate hwmon buffer\n");
+ return -ENOMEM;
+ }
+
+ ionic->hwmon_caps_buf = buf;
+ return 0;
+}
+
static const struct ionic_aux_type_info ionic_aux_types[IONIC_AUX_MAX] = {
[IONIC_AUX_RDMA] = {
.name = "rdma",
.supported = ionic_rdma_supported,
},
+ [IONIC_AUX_HWMON] = {
+ .name = "hwmon",
+ .supported = ionic_hwmon_supported,
+ .prepare = ionic_hwmon_prepare,
+ },
};
static void ionic_auxbus_release(struct device *dev)
@@ -117,6 +147,85 @@ void ionic_auxbus_unregister(struct ionic_lif *lif)
mutex_unlock(&lif->adev_lock);
}
+static struct ionic_lif *ionic_hwmon_lif(struct auxiliary_device *adev)
+{
+ return container_of(adev, struct ionic_aux_dev, adev)->lif;
+}
+
+int ionic_hwmon_get_caps(struct auxiliary_device *adev, u8 max_ver,
+ const void **buf, size_t *len, u8 *ver)
+{
+ struct ionic_lif *lif = ionic_hwmon_lif(adev);
+ struct ionic *ionic = lif->ionic;
+ struct ionic_admin_ctx ctx = {
+ .work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
+ .comp.comp.status = IONIC_RC_EIO,
+ .cmd.hwmon_getcaps = {
+ .opcode = IONIC_CMD_HWMON_GETCAPS,
+ .ver = max_ver,
+ .lif_index = cpu_to_le16(lif->index),
+ .resp_buf_len = cpu_to_le32(IONIC_HWMON_CAPS_BUF_SIZE),
+ .resp_dma_addr = cpu_to_le64(ionic->hwmon_caps_pa),
+ },
+ };
+ int err;
+
+ if (!ionic->hwmon_caps_buf)
+ return -ENODEV;
+
+ memset(ionic->hwmon_caps_buf, 0, IONIC_HWMON_CAPS_BUF_SIZE);
+
+ err = ionic_adminq_post_wait_nomsg(lif, &ctx);
+ if (err)
+ return err;
+
+ if (ctx.comp.comp.status)
+ return ionic_error_to_errno(ctx.comp.comp.status);
+
+ *buf = ionic->hwmon_caps_buf;
+ *len = IONIC_HWMON_CAPS_BUF_SIZE;
+ *ver = ctx.comp.hwmon_getcaps.ver;
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(ionic_hwmon_get_caps, "NET_IONIC");
+
+int ionic_hwmon_get_attr(struct auxiliary_device *adev, u8 type, u8 channel,
+ u8 attr, u32 *val)
+{
+ struct ionic_lif *lif = ionic_hwmon_lif(adev);
+ struct ionic_admin_ctx ctx = {
+ .work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
+ .comp.comp.status = IONIC_RC_EIO,
+ .cmd.hwmon_getattr = {
+ .opcode = IONIC_CMD_HWMON_GETATTR,
+ .lif_index = cpu_to_le16(lif->index),
+ .sensor_type = type,
+ .channel = channel,
+ .attr = attr,
+ },
+ };
+ int err;
+
+ err = ionic_adminq_post_wait_nomsg(lif, &ctx);
+ if (err)
+ return err;
+
+ if (ctx.comp.comp.status)
+ return ionic_error_to_errno(ctx.comp.comp.status);
+
+ *val = le32_to_cpu(ctx.comp.hwmon_getattr.attr_value);
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(ionic_hwmon_get_attr, "NET_IONIC");
+
+struct device *ionic_hwmon_dev(struct auxiliary_device *adev)
+{
+ return ionic_hwmon_lif(adev)->ionic->dev;
+}
+EXPORT_SYMBOL_NS_GPL(ionic_hwmon_dev, "NET_IONIC");
+
void ionic_request_rdma_reset(struct ionic_lif *lif)
{
struct ionic *ionic = lif->ionic;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
index d04503b19c51..95bcfcded562 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
@@ -182,6 +182,7 @@ struct ionic_phc;
enum ionic_aux_type {
IONIC_AUX_RDMA,
+ IONIC_AUX_HWMON,
IONIC_AUX_MAX,
};
diff --git a/include/linux/ionic/ionic_hwmon.h b/include/linux/ionic/ionic_hwmon.h
index 62667e3d7135..bc82f2903386 100644
--- a/include/linux/ionic/ionic_hwmon.h
+++ b/include/linux/ionic/ionic_hwmon.h
@@ -135,4 +135,44 @@ struct ionic_hwmon_caps_hdr {
__le16 n_channels[];
};
+struct auxiliary_device;
+struct device;
+
+/**
+ * ionic_hwmon_get_caps - Read the sensor capabilities from the device
+ * @adev: ionic "hwmon" auxiliary device
+ * @max_ver: highest capabilities buffer layout version the caller parses
+ * @buf: set to the capabilities buffer
+ * @len: set to the length of @buf
+ * @ver: set to the layout version of @buf, as reported by the device
+ *
+ * The buffer belongs to ionic and is overwritten by the next call.
+ *
+ * Return: zero or negative error status
+ */
+int ionic_hwmon_get_caps(struct auxiliary_device *adev, u8 max_ver,
+ const void **buf, size_t *len, u8 *ver);
+
+/**
+ * ionic_hwmon_get_attr - Read one sensor attribute from the device
+ * @adev: ionic "hwmon" auxiliary device
+ * @type: sensor type from enum ionic_hwmon_sensor_type
+ * @channel: channel index within @type
+ * @attr: attribute ID from the attribute enum for @type
+ * @val: set to the attribute value, in the units documented for
+ * struct ionic_hwmon_getattr_comp
+ *
+ * Return: zero or negative error status
+ */
+int ionic_hwmon_get_attr(struct auxiliary_device *adev, u8 type, u8 channel,
+ u8 attr, u32 *val);
+
+/**
+ * ionic_hwmon_dev - Device to parent the hwmon device to
+ * @adev: ionic "hwmon" auxiliary device
+ *
+ * Return: the PCI function's device
+ */
+struct device *ionic_hwmon_dev(struct auxiliary_device *adev);
+
#endif /* _LINUX_IONIC_HWMON_H_ */
--
2.43.0
next prev parent reply other threads:[~2026-11-03 18:15 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 18:14 [PATCH net-next 0/4] ionic: report on-board sensors through an hwmon auxiliary driver Nikhil P. Rao
2026-11-03 18:14 ` [PATCH net-next 1/4] ionic: register auxiliary devices from a table of device types Nikhil P. Rao
2026-11-03 18:14 ` [PATCH net-next 2/4] ionic: add device interface definitions for hardware monitoring Nikhil P. Rao
2026-11-03 18:14 ` Nikhil P. Rao [this message]
2026-11-03 18:14 ` [PATCH net-next 4/4] hwmon: add AMD Pensando ionic sensor driver Nikhil P. Rao
2026-11-03 20:50 ` Guenter Roeck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261103-pr46-b4-v1-3-850ab7fbec19@amd.com \
--to=nikhil.rao@amd.com \
--cc=abhijit.gangurde@amd.com \
--cc=andrew+netdev@lunn.ch \
--cc=brett.creeley@amd.com \
--cc=corbet@lwn.net \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=gustavoars@kernel.org \
--cc=kees@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=rdunlap@infradead.org \
--cc=skhan@linuxfoundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®