Skip to content

Commit d85ebad

Browse files
sanmanpradhanmetaPaolo Abeni
authored andcommitted
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: Sanman Pradhan <[email protected]> Reviewed-by: Kalesh AP <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent e60fa8e commit d85ebad

File tree

7 files changed

+126
-0
lines changed

7 files changed

+126
-0
lines changed

drivers/net/ethernet/meta/fbnic/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ fbnic-y := fbnic_devlink.o \
1111
fbnic_ethtool.o \
1212
fbnic_fw.o \
1313
fbnic_hw_stats.o \
14+
fbnic_hwmon.o \
1415
fbnic_irq.o \
1516
fbnic_mac.o \
1617
fbnic_netdev.o \

drivers/net/ethernet/meta/fbnic/fbnic.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
struct fbnic_dev {
2020
struct device *dev;
2121
struct net_device *netdev;
22+
struct device *hwmon;
2223

2324
u32 __iomem *uc_addr0;
2425
u32 __iomem *uc_addr4;
@@ -31,6 +32,7 @@ struct fbnic_dev {
3132

3233
struct fbnic_fw_mbx mbx[FBNIC_IPC_MBX_INDICES];
3334
struct fbnic_fw_cap fw_cap;
35+
struct fbnic_fw_completion *cmpl_data;
3436
/* Lock protecting Tx Mailbox queue to prevent possible races */
3537
spinlock_t fw_tx_lock;
3638

@@ -138,6 +140,9 @@ void fbnic_devlink_unregister(struct fbnic_dev *fbd);
138140
int fbnic_fw_enable_mbx(struct fbnic_dev *fbd);
139141
void fbnic_fw_disable_mbx(struct fbnic_dev *fbd);
140142

143+
void fbnic_hwmon_register(struct fbnic_dev *fbd);
144+
void fbnic_hwmon_unregister(struct fbnic_dev *fbd);
145+
141146
int fbnic_pcs_irq_enable(struct fbnic_dev *fbd);
142147
void fbnic_pcs_irq_disable(struct fbnic_dev *fbd);
143148

drivers/net/ethernet/meta/fbnic/fbnic_fw.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ struct fbnic_fw_cap {
4444
u8 link_fec;
4545
};
4646

47+
struct fbnic_fw_completion {
48+
struct {
49+
s32 millivolts;
50+
s32 millidegrees;
51+
} tsene;
52+
};
53+
4754
void fbnic_mbx_init(struct fbnic_dev *fbd);
4855
void fbnic_mbx_clean(struct fbnic_dev *fbd);
4956
void fbnic_mbx_poll(struct fbnic_dev *fbd);
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) Meta Platforms, Inc. and affiliates. */
3+
4+
#include <linux/hwmon.h>
5+
6+
#include "fbnic.h"
7+
#include "fbnic_mac.h"
8+
9+
static int fbnic_hwmon_sensor_id(enum hwmon_sensor_types type)
10+
{
11+
if (type == hwmon_temp)
12+
return FBNIC_SENSOR_TEMP;
13+
if (type == hwmon_in)
14+
return FBNIC_SENSOR_VOLTAGE;
15+
16+
return -EOPNOTSUPP;
17+
}
18+
19+
static umode_t fbnic_hwmon_is_visible(const void *drvdata,
20+
enum hwmon_sensor_types type,
21+
u32 attr, int channel)
22+
{
23+
if (type == hwmon_temp && attr == hwmon_temp_input)
24+
return 0444;
25+
if (type == hwmon_in && attr == hwmon_in_input)
26+
return 0444;
27+
28+
return 0;
29+
}
30+
31+
static int fbnic_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
32+
u32 attr, int channel, long *val)
33+
{
34+
struct fbnic_dev *fbd = dev_get_drvdata(dev);
35+
const struct fbnic_mac *mac = fbd->mac;
36+
int id;
37+
38+
id = fbnic_hwmon_sensor_id(type);
39+
return id < 0 ? id : mac->get_sensor(fbd, id, val);
40+
}
41+
42+
static const struct hwmon_ops fbnic_hwmon_ops = {
43+
.is_visible = fbnic_hwmon_is_visible,
44+
.read = fbnic_hwmon_read,
45+
};
46+
47+
static const struct hwmon_channel_info *fbnic_hwmon_info[] = {
48+
HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
49+
HWMON_CHANNEL_INFO(in, HWMON_I_INPUT),
50+
NULL
51+
};
52+
53+
static const struct hwmon_chip_info fbnic_chip_info = {
54+
.ops = &fbnic_hwmon_ops,
55+
.info = fbnic_hwmon_info,
56+
};
57+
58+
void fbnic_hwmon_register(struct fbnic_dev *fbd)
59+
{
60+
if (!IS_REACHABLE(CONFIG_HWMON))
61+
return;
62+
63+
fbd->hwmon = hwmon_device_register_with_info(fbd->dev, "fbnic",
64+
fbd, &fbnic_chip_info,
65+
NULL);
66+
if (IS_ERR(fbd->hwmon)) {
67+
dev_notice(fbd->dev,
68+
"Failed to register hwmon device %pe\n",
69+
fbd->hwmon);
70+
fbd->hwmon = NULL;
71+
}
72+
}
73+
74+
void fbnic_hwmon_unregister(struct fbnic_dev *fbd)
75+
{
76+
if (!IS_REACHABLE(CONFIG_HWMON) || !fbd->hwmon)
77+
return;
78+
79+
hwmon_device_unregister(fbd->hwmon);
80+
fbd->hwmon = NULL;
81+
}

drivers/net/ethernet/meta/fbnic/fbnic_mac.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,27 @@ fbnic_mac_get_eth_mac_stats(struct fbnic_dev *fbd, bool reset,
686686
MAC_STAT_TX_BROADCAST);
687687
}
688688

689+
static int fbnic_mac_get_sensor_asic(struct fbnic_dev *fbd, int id, long *val)
690+
{
691+
struct fbnic_fw_completion fw_cmpl;
692+
s32 *sensor;
693+
694+
switch (id) {
695+
case FBNIC_SENSOR_TEMP:
696+
sensor = &fw_cmpl.tsene.millidegrees;
697+
break;
698+
case FBNIC_SENSOR_VOLTAGE:
699+
sensor = &fw_cmpl.tsene.millivolts;
700+
break;
701+
default:
702+
return -EINVAL;
703+
}
704+
705+
*val = *sensor;
706+
707+
return 0;
708+
}
709+
689710
static const struct fbnic_mac fbnic_mac_asic = {
690711
.init_regs = fbnic_mac_init_regs,
691712
.pcs_enable = fbnic_pcs_enable_asic,
@@ -695,6 +716,7 @@ static const struct fbnic_mac fbnic_mac_asic = {
695716
.get_eth_mac_stats = fbnic_mac_get_eth_mac_stats,
696717
.link_down = fbnic_mac_link_down_asic,
697718
.link_up = fbnic_mac_link_up_asic,
719+
.get_sensor = fbnic_mac_get_sensor_asic,
698720
};
699721

700722
/**

drivers/net/ethernet/meta/fbnic/fbnic_mac.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ enum {
4747
#define FBNIC_LINK_MODE_PAM4 (FBNIC_LINK_50R1)
4848
#define FBNIC_LINK_MODE_MASK (FBNIC_LINK_AUTO - 1)
4949

50+
enum fbnic_sensor_id {
51+
FBNIC_SENSOR_TEMP, /* Temp in millidegrees Centigrade */
52+
FBNIC_SENSOR_VOLTAGE, /* Voltage in millivolts */
53+
};
54+
5055
/* This structure defines the interface hooks for the MAC. The MAC hooks
5156
* will be configured as a const struct provided with a set of function
5257
* pointers.
@@ -83,6 +88,8 @@ struct fbnic_mac {
8388

8489
void (*link_down)(struct fbnic_dev *fbd);
8590
void (*link_up)(struct fbnic_dev *fbd, bool tx_pause, bool rx_pause);
91+
92+
int (*get_sensor)(struct fbnic_dev *fbd, int id, long *val);
8693
};
8794

8895
int fbnic_mac_init(struct fbnic_dev *fbd);

drivers/net/ethernet/meta/fbnic/fbnic_pci.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
289289

290290
fbnic_devlink_register(fbd);
291291

292+
fbnic_hwmon_register(fbd);
293+
292294
if (!fbd->dsn) {
293295
dev_warn(&pdev->dev, "Reading serial number failed\n");
294296
goto init_failure_mode;
@@ -352,6 +354,7 @@ static void fbnic_remove(struct pci_dev *pdev)
352354
fbnic_netdev_free(fbd);
353355
}
354356

357+
fbnic_hwmon_unregister(fbd);
355358
fbnic_devlink_unregister(fbd);
356359
fbnic_fw_disable_mbx(fbd);
357360
fbnic_free_irqs(fbd);

0 commit comments

Comments
 (0)