From 2c3c1048746a4622d8c89a29670120dc8fab93c4 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:49:45 +0200 Subject: Adding upstream version 6.1.76. Signed-off-by: Daniel Baumann --- .../net/ethernet/aquantia/atlantic/aq_drvinfo.c | 158 +++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.c (limited to 'drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.c') diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.c b/drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.c new file mode 100644 index 000000000..d3526cd38 --- /dev/null +++ b/drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Atlantic Network Driver + * + * Copyright (C) 2014-2019 aQuantia Corporation + * Copyright (C) 2019-2020 Marvell International Ltd. + */ + +/* File aq_drvinfo.c: Definition of common code for firmware info in sys.*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "aq_drvinfo.h" +#include "aq_nic.h" + +#if IS_REACHABLE(CONFIG_HWMON) +static const char * const atl_temp_label[] = { + "PHY Temperature", + "MAC Temperature", +}; + +static int aq_hwmon_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *value) +{ + struct aq_nic_s *aq_nic = dev_get_drvdata(dev); + int err = 0; + int temp; + + if (!aq_nic) + return -EIO; + + if (type != hwmon_temp || attr != hwmon_temp_input) + return -EOPNOTSUPP; + + switch (channel) { + case 0: + if (!aq_nic->aq_fw_ops->get_phy_temp) + return -EOPNOTSUPP; + + err = aq_nic->aq_fw_ops->get_phy_temp(aq_nic->aq_hw, &temp); + *value = temp; + break; + case 1: + if (!aq_nic->aq_fw_ops->get_mac_temp && + !aq_nic->aq_hw_ops->hw_get_mac_temp) + return -EOPNOTSUPP; + + if (aq_nic->aq_fw_ops->get_mac_temp) + err = aq_nic->aq_fw_ops->get_mac_temp(aq_nic->aq_hw, &temp); + else + err = aq_nic->aq_hw_ops->hw_get_mac_temp(aq_nic->aq_hw, &temp); + *value = temp; + break; + default: + return -EOPNOTSUPP; + } + + return err; +} + +static int aq_hwmon_read_string(struct device *dev, + enum hwmon_sensor_types type, + u32 attr, int channel, const char **str) +{ + struct aq_nic_s *aq_nic = dev_get_drvdata(dev); + + if (!aq_nic) + return -EIO; + + if (type != hwmon_temp || attr != hwmon_temp_label) + return -EOPNOTSUPP; + + if (channel < ARRAY_SIZE(atl_temp_label)) + *str = atl_temp_label[channel]; + else + return -EOPNOTSUPP; + + return 0; +} + +static umode_t aq_hwmon_is_visible(const void *data, + enum hwmon_sensor_types type, + u32 attr, int channel) +{ + const struct aq_nic_s *nic = data; + + if (type != hwmon_temp) + return 0; + + if (channel == 0 && !nic->aq_fw_ops->get_phy_temp) + return 0; + else if (channel == 1 && !nic->aq_fw_ops->get_mac_temp && + !nic->aq_hw_ops->hw_get_mac_temp) + return 0; + + switch (attr) { + case hwmon_temp_input: + case hwmon_temp_label: + return 0444; + default: + return 0; + } +} + +static const struct hwmon_ops aq_hwmon_ops = { + .is_visible = aq_hwmon_is_visible, + .read = aq_hwmon_read, + .read_string = aq_hwmon_read_string, +}; + +static u32 aq_hwmon_temp_config[] = { + HWMON_T_INPUT | HWMON_T_LABEL, + HWMON_T_INPUT | HWMON_T_LABEL, + 0, +}; + +static const struct hwmon_channel_info aq_hwmon_temp = { + .type = hwmon_temp, + .config = aq_hwmon_temp_config, +}; + +static const struct hwmon_channel_info *aq_hwmon_info[] = { + &aq_hwmon_temp, + NULL, +}; + +static const struct hwmon_chip_info aq_hwmon_chip_info = { + .ops = &aq_hwmon_ops, + .info = aq_hwmon_info, +}; + +int aq_drvinfo_init(struct net_device *ndev) +{ + struct aq_nic_s *aq_nic = netdev_priv(ndev); + struct device *dev = &aq_nic->pdev->dev; + struct device *hwmon_dev; + int err = 0; + + hwmon_dev = devm_hwmon_device_register_with_info(dev, + ndev->name, + aq_nic, + &aq_hwmon_chip_info, + NULL); + + if (IS_ERR(hwmon_dev)) + err = PTR_ERR(hwmon_dev); + + return err; +} + +#else +int aq_drvinfo_init(struct net_device *ndev) { return 0; } +#endif -- cgit v1.2.3