Commit 88063073 authored by Sanman Pradhan's avatar Sanman Pradhan Committed by Jakub Kicinski
Browse files

eth: fbnic: Add hardware monitoring support via HWMON interface



This patch adds support for hardware monitoring to the fbnic driver,
allowing for temperature and voltage sensor data to be exposed to
userspace via the HWMON interface. The driver registers a HWMON device
and provides callbacks for reading sensor data, enabling system
admins to monitor the health and operating conditions of fbnic.

Signed-off-by: default avatarSanman Pradhan <sanman.p211993@gmail.com>
Reviewed-by: default avatarMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Link: https://patch.msgid.link/20250114000705.2081288-4-sanman.p211993@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 89e6f190
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ fbnic-y := fbnic_csr.o \
	   fbnic_ethtool.o \
	   fbnic_fw.o \
	   fbnic_hw_stats.o \
	   fbnic_hwmon.o \
	   fbnic_irq.o \
	   fbnic_mac.o \
	   fbnic_netdev.o \
+4 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ struct fbnic_dev {
	struct device *dev;
	struct net_device *netdev;
	struct dentry *dbg_fbd;
	struct device *hwmon;

	u32 __iomem *uc_addr0;
	u32 __iomem *uc_addr4;
@@ -150,6 +151,9 @@ void fbnic_devlink_unregister(struct fbnic_dev *fbd);
int fbnic_fw_enable_mbx(struct fbnic_dev *fbd);
void fbnic_fw_disable_mbx(struct fbnic_dev *fbd);

void fbnic_hwmon_register(struct fbnic_dev *fbd);
void fbnic_hwmon_unregister(struct fbnic_dev *fbd);

int fbnic_pcs_irq_enable(struct fbnic_dev *fbd);
void fbnic_pcs_irq_disable(struct fbnic_dev *fbd);

+81 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) Meta Platforms, Inc. and affiliates. */

#include <linux/hwmon.h>

#include "fbnic.h"
#include "fbnic_mac.h"

static int fbnic_hwmon_sensor_id(enum hwmon_sensor_types type)
{
	if (type == hwmon_temp)
		return FBNIC_SENSOR_TEMP;
	if (type == hwmon_in)
		return FBNIC_SENSOR_VOLTAGE;

	return -EOPNOTSUPP;
}

static umode_t fbnic_hwmon_is_visible(const void *drvdata,
				      enum hwmon_sensor_types type,
				      u32 attr, int channel)
{
	if (type == hwmon_temp && attr == hwmon_temp_input)
		return 0444;
	if (type == hwmon_in && attr == hwmon_in_input)
		return 0444;

	return 0;
}

static int fbnic_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
			    u32 attr, int channel, long *val)
{
	struct fbnic_dev *fbd = dev_get_drvdata(dev);
	const struct fbnic_mac *mac = fbd->mac;
	int id;

	id = fbnic_hwmon_sensor_id(type);
	return id < 0 ? id : mac->get_sensor(fbd, id, val);
}

static const struct hwmon_ops fbnic_hwmon_ops = {
	.is_visible = fbnic_hwmon_is_visible,
	.read = fbnic_hwmon_read,
};

static const struct hwmon_channel_info *fbnic_hwmon_info[] = {
	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
	HWMON_CHANNEL_INFO(in, HWMON_I_INPUT),
	NULL
};

static const struct hwmon_chip_info fbnic_chip_info = {
	.ops = &fbnic_hwmon_ops,
	.info = fbnic_hwmon_info,
};

void fbnic_hwmon_register(struct fbnic_dev *fbd)
{
	if (!IS_REACHABLE(CONFIG_HWMON))
		return;

	fbd->hwmon = hwmon_device_register_with_info(fbd->dev, "fbnic",
						     fbd, &fbnic_chip_info,
						     NULL);
	if (IS_ERR(fbd->hwmon)) {
		dev_notice(fbd->dev,
			   "Failed to register hwmon device %pe\n",
			   fbd->hwmon);
		fbd->hwmon = NULL;
	}
}

void fbnic_hwmon_unregister(struct fbnic_dev *fbd)
{
	if (!IS_REACHABLE(CONFIG_HWMON) || !fbd->hwmon)
		return;

	hwmon_device_unregister(fbd->hwmon);
	fbd->hwmon = NULL;
}
+3 −0
Original line number Diff line number Diff line
@@ -296,6 +296,8 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
	/* Capture snapshot of hardware stats so netdev can calculate delta */
	fbnic_reset_hw_stats(fbd);

	fbnic_hwmon_register(fbd);

	if (!fbd->dsn) {
		dev_warn(&pdev->dev, "Reading serial number failed\n");
		goto init_failure_mode;
@@ -358,6 +360,7 @@ static void fbnic_remove(struct pci_dev *pdev)
		fbnic_netdev_free(fbd);
	}

	fbnic_hwmon_unregister(fbd);
	fbnic_dbg_fbd_exit(fbd);
	fbnic_devlink_unregister(fbd);
	fbnic_fw_disable_mbx(fbd);