xref: /linux/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c (revision 3eb66e91a25497065c5322b1268cbc3953642227)
1*51dce24bSJeff Kirsher // SPDX-License-Identifier: GPL-2.0
2*51dce24bSJeff Kirsher /* Copyright(c) 1999 - 2018 Intel Corporation. */
33ca8bc6dSDon Skidmore 
43ca8bc6dSDon Skidmore #include "ixgbe.h"
53ca8bc6dSDon Skidmore #include "ixgbe_common.h"
63ca8bc6dSDon Skidmore #include "ixgbe_type.h"
73ca8bc6dSDon Skidmore 
83ca8bc6dSDon Skidmore #include <linux/module.h>
93ca8bc6dSDon Skidmore #include <linux/types.h>
103ca8bc6dSDon Skidmore #include <linux/sysfs.h>
113ca8bc6dSDon Skidmore #include <linux/kobject.h>
123ca8bc6dSDon Skidmore #include <linux/device.h>
133ca8bc6dSDon Skidmore #include <linux/netdevice.h>
143ca8bc6dSDon Skidmore #include <linux/hwmon.h>
153ca8bc6dSDon Skidmore 
163ca8bc6dSDon Skidmore /* hwmon callback functions */
ixgbe_hwmon_show_location(struct device * dev,struct device_attribute * attr,char * buf)173ca8bc6dSDon Skidmore static ssize_t ixgbe_hwmon_show_location(struct device *dev,
183ca8bc6dSDon Skidmore 					 struct device_attribute *attr,
193ca8bc6dSDon Skidmore 					 char *buf)
203ca8bc6dSDon Skidmore {
213ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr,
223ca8bc6dSDon Skidmore 						     dev_attr);
233ca8bc6dSDon Skidmore 	return sprintf(buf, "loc%u\n",
243ca8bc6dSDon Skidmore 		       ixgbe_attr->sensor->location);
253ca8bc6dSDon Skidmore }
263ca8bc6dSDon Skidmore 
ixgbe_hwmon_show_temp(struct device * dev,struct device_attribute * attr,char * buf)273ca8bc6dSDon Skidmore static ssize_t ixgbe_hwmon_show_temp(struct device *dev,
283ca8bc6dSDon Skidmore 				     struct device_attribute *attr,
293ca8bc6dSDon Skidmore 				     char *buf)
303ca8bc6dSDon Skidmore {
313ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr,
323ca8bc6dSDon Skidmore 						     dev_attr);
333ca8bc6dSDon Skidmore 	unsigned int value;
343ca8bc6dSDon Skidmore 
353ca8bc6dSDon Skidmore 	/* reset the temp field */
363ca8bc6dSDon Skidmore 	ixgbe_attr->hw->mac.ops.get_thermal_sensor_data(ixgbe_attr->hw);
373ca8bc6dSDon Skidmore 
383ca8bc6dSDon Skidmore 	value = ixgbe_attr->sensor->temp;
393ca8bc6dSDon Skidmore 
403ca8bc6dSDon Skidmore 	/* display millidegree */
413ca8bc6dSDon Skidmore 	value *= 1000;
423ca8bc6dSDon Skidmore 
433ca8bc6dSDon Skidmore 	return sprintf(buf, "%u\n", value);
443ca8bc6dSDon Skidmore }
453ca8bc6dSDon Skidmore 
ixgbe_hwmon_show_cautionthresh(struct device * dev,struct device_attribute * attr,char * buf)463ca8bc6dSDon Skidmore static ssize_t ixgbe_hwmon_show_cautionthresh(struct device *dev,
473ca8bc6dSDon Skidmore 				     struct device_attribute *attr,
483ca8bc6dSDon Skidmore 				     char *buf)
493ca8bc6dSDon Skidmore {
503ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr,
513ca8bc6dSDon Skidmore 						     dev_attr);
523ca8bc6dSDon Skidmore 	unsigned int value = ixgbe_attr->sensor->caution_thresh;
533ca8bc6dSDon Skidmore 
543ca8bc6dSDon Skidmore 	/* display millidegree */
553ca8bc6dSDon Skidmore 	value *= 1000;
563ca8bc6dSDon Skidmore 
573ca8bc6dSDon Skidmore 	return sprintf(buf, "%u\n", value);
583ca8bc6dSDon Skidmore }
593ca8bc6dSDon Skidmore 
ixgbe_hwmon_show_maxopthresh(struct device * dev,struct device_attribute * attr,char * buf)603ca8bc6dSDon Skidmore static ssize_t ixgbe_hwmon_show_maxopthresh(struct device *dev,
613ca8bc6dSDon Skidmore 				     struct device_attribute *attr,
623ca8bc6dSDon Skidmore 				     char *buf)
633ca8bc6dSDon Skidmore {
643ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr,
653ca8bc6dSDon Skidmore 						     dev_attr);
663ca8bc6dSDon Skidmore 	unsigned int value = ixgbe_attr->sensor->max_op_thresh;
673ca8bc6dSDon Skidmore 
683ca8bc6dSDon Skidmore 	/* display millidegree */
693ca8bc6dSDon Skidmore 	value *= 1000;
703ca8bc6dSDon Skidmore 
713ca8bc6dSDon Skidmore 	return sprintf(buf, "%u\n", value);
723ca8bc6dSDon Skidmore }
733ca8bc6dSDon Skidmore 
7449ce9c2cSBen Hutchings /**
753ca8bc6dSDon Skidmore  * ixgbe_add_hwmon_attr - Create hwmon attr table for a hwmon sysfs file.
763ca8bc6dSDon Skidmore  * @adapter: pointer to the adapter structure
773ca8bc6dSDon Skidmore  * @offset: offset in the eeprom sensor data table
783ca8bc6dSDon Skidmore  * @type: type of sensor data to display
793ca8bc6dSDon Skidmore  *
803ca8bc6dSDon Skidmore  * For each file we want in hwmon's sysfs interface we need a device_attribute
813ca8bc6dSDon Skidmore  * This is included in our hwmon_attr struct that contains the references to
823ca8bc6dSDon Skidmore  * the data structures we need to get the data to display.
833ca8bc6dSDon Skidmore  */
ixgbe_add_hwmon_attr(struct ixgbe_adapter * adapter,unsigned int offset,int type)843ca8bc6dSDon Skidmore static int ixgbe_add_hwmon_attr(struct ixgbe_adapter *adapter,
853ca8bc6dSDon Skidmore 				unsigned int offset, int type) {
863ca8bc6dSDon Skidmore 	int rc;
873ca8bc6dSDon Skidmore 	unsigned int n_attr;
883ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr;
893ca8bc6dSDon Skidmore 
9003b77d81SGuenter Roeck 	n_attr = adapter->ixgbe_hwmon_buff->n_hwmon;
9103b77d81SGuenter Roeck 	ixgbe_attr = &adapter->ixgbe_hwmon_buff->hwmon_list[n_attr];
923ca8bc6dSDon Skidmore 
933ca8bc6dSDon Skidmore 	switch (type) {
943ca8bc6dSDon Skidmore 	case IXGBE_HWMON_TYPE_LOC:
953ca8bc6dSDon Skidmore 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_location;
963ca8bc6dSDon Skidmore 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name),
9722dd81c5SGuenter Roeck 			 "temp%u_label", offset + 1);
983ca8bc6dSDon Skidmore 		break;
993ca8bc6dSDon Skidmore 	case IXGBE_HWMON_TYPE_TEMP:
1003ca8bc6dSDon Skidmore 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_temp;
1013ca8bc6dSDon Skidmore 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name),
10222dd81c5SGuenter Roeck 			 "temp%u_input", offset + 1);
1033ca8bc6dSDon Skidmore 		break;
1043ca8bc6dSDon Skidmore 	case IXGBE_HWMON_TYPE_CAUTION:
1053ca8bc6dSDon Skidmore 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_cautionthresh;
1063ca8bc6dSDon Skidmore 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name),
10722dd81c5SGuenter Roeck 			 "temp%u_max", offset + 1);
1083ca8bc6dSDon Skidmore 		break;
1093ca8bc6dSDon Skidmore 	case IXGBE_HWMON_TYPE_MAX:
1103ca8bc6dSDon Skidmore 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_maxopthresh;
1113ca8bc6dSDon Skidmore 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name),
11222dd81c5SGuenter Roeck 			 "temp%u_crit", offset + 1);
1133ca8bc6dSDon Skidmore 		break;
1143ca8bc6dSDon Skidmore 	default:
1153ca8bc6dSDon Skidmore 		rc = -EPERM;
1163ca8bc6dSDon Skidmore 		return rc;
1173ca8bc6dSDon Skidmore 	}
1183ca8bc6dSDon Skidmore 
1193ca8bc6dSDon Skidmore 	/* These always the same regardless of type */
1203ca8bc6dSDon Skidmore 	ixgbe_attr->sensor =
1213ca8bc6dSDon Skidmore 		&adapter->hw.mac.thermal_sensor_data.sensor[offset];
1223ca8bc6dSDon Skidmore 	ixgbe_attr->hw = &adapter->hw;
1233ca8bc6dSDon Skidmore 	ixgbe_attr->dev_attr.store = NULL;
124d3757ba4SJoe Perches 	ixgbe_attr->dev_attr.attr.mode = 0444;
1253ca8bc6dSDon Skidmore 	ixgbe_attr->dev_attr.attr.name = ixgbe_attr->name;
12603b77d81SGuenter Roeck 	sysfs_attr_init(&ixgbe_attr->dev_attr.attr);
1273ca8bc6dSDon Skidmore 
12803b77d81SGuenter Roeck 	adapter->ixgbe_hwmon_buff->attrs[n_attr] = &ixgbe_attr->dev_attr.attr;
1293ca8bc6dSDon Skidmore 
13003b77d81SGuenter Roeck 	++adapter->ixgbe_hwmon_buff->n_hwmon;
1313ca8bc6dSDon Skidmore 
13203b77d81SGuenter Roeck 	return 0;
1333ca8bc6dSDon Skidmore }
1343ca8bc6dSDon Skidmore 
ixgbe_sysfs_del_adapter(struct ixgbe_adapter * adapter)1353ca8bc6dSDon Skidmore static void ixgbe_sysfs_del_adapter(struct ixgbe_adapter *adapter)
1363ca8bc6dSDon Skidmore {
1373ca8bc6dSDon Skidmore }
1383ca8bc6dSDon Skidmore 
1393ca8bc6dSDon Skidmore /* called from ixgbe_main.c */
ixgbe_sysfs_exit(struct ixgbe_adapter * adapter)1403ca8bc6dSDon Skidmore void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter)
1413ca8bc6dSDon Skidmore {
1423ca8bc6dSDon Skidmore 	ixgbe_sysfs_del_adapter(adapter);
1433ca8bc6dSDon Skidmore }
1443ca8bc6dSDon Skidmore 
1453ca8bc6dSDon Skidmore /* called from ixgbe_main.c */
ixgbe_sysfs_init(struct ixgbe_adapter * adapter)1463ca8bc6dSDon Skidmore int ixgbe_sysfs_init(struct ixgbe_adapter *adapter)
1473ca8bc6dSDon Skidmore {
14803b77d81SGuenter Roeck 	struct hwmon_buff *ixgbe_hwmon;
14903b77d81SGuenter Roeck 	struct device *hwmon_dev;
1503ca8bc6dSDon Skidmore 	unsigned int i;
1513ca8bc6dSDon Skidmore 	int rc = 0;
1523ca8bc6dSDon Skidmore 
1533ca8bc6dSDon Skidmore 	/* If this method isn't defined we don't support thermals */
1543ca8bc6dSDon Skidmore 	if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL) {
1551210982bSDon Skidmore 		goto exit;
1563ca8bc6dSDon Skidmore 	}
1573ca8bc6dSDon Skidmore 
1583ca8bc6dSDon Skidmore 	/* Don't create thermal hwmon interface if no sensors present */
1591210982bSDon Skidmore 	if (adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw))
1601210982bSDon Skidmore 		goto exit;
1613ca8bc6dSDon Skidmore 
16203b77d81SGuenter Roeck 	ixgbe_hwmon = devm_kzalloc(&adapter->pdev->dev, sizeof(*ixgbe_hwmon),
1633ca8bc6dSDon Skidmore 				   GFP_KERNEL);
16403b77d81SGuenter Roeck 	if (ixgbe_hwmon == NULL) {
1653ca8bc6dSDon Skidmore 		rc = -ENOMEM;
16603b77d81SGuenter Roeck 		goto exit;
1673ca8bc6dSDon Skidmore 	}
16803b77d81SGuenter Roeck 	adapter->ixgbe_hwmon_buff = ixgbe_hwmon;
1693ca8bc6dSDon Skidmore 
1703ca8bc6dSDon Skidmore 	for (i = 0; i < IXGBE_MAX_SENSORS; i++) {
1713ca8bc6dSDon Skidmore 		/*
1723ca8bc6dSDon Skidmore 		 * Only create hwmon sysfs entries for sensors that have
1733ca8bc6dSDon Skidmore 		 * meaningful data for.
1743ca8bc6dSDon Skidmore 		 */
1753ca8bc6dSDon Skidmore 		if (adapter->hw.mac.thermal_sensor_data.sensor[i].location == 0)
1763ca8bc6dSDon Skidmore 			continue;
1773ca8bc6dSDon Skidmore 
1783ca8bc6dSDon Skidmore 		/* Bail if any hwmon attr struct fails to initialize */
1793ca8bc6dSDon Skidmore 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_CAUTION);
1803ca8bc6dSDon Skidmore 		if (rc)
18103b77d81SGuenter Roeck 			goto exit;
18203b77d81SGuenter Roeck 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_LOC);
18303b77d81SGuenter Roeck 		if (rc)
18403b77d81SGuenter Roeck 			goto exit;
18503b77d81SGuenter Roeck 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_TEMP);
18603b77d81SGuenter Roeck 		if (rc)
18703b77d81SGuenter Roeck 			goto exit;
18803b77d81SGuenter Roeck 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_MAX);
18903b77d81SGuenter Roeck 		if (rc)
19003b77d81SGuenter Roeck 			goto exit;
1913ca8bc6dSDon Skidmore 	}
1923ca8bc6dSDon Skidmore 
19303b77d81SGuenter Roeck 	ixgbe_hwmon->groups[0] = &ixgbe_hwmon->group;
19403b77d81SGuenter Roeck 	ixgbe_hwmon->group.attrs = ixgbe_hwmon->attrs;
1953ca8bc6dSDon Skidmore 
19603b77d81SGuenter Roeck 	hwmon_dev = devm_hwmon_device_register_with_groups(&adapter->pdev->dev,
19703b77d81SGuenter Roeck 							   "ixgbe",
19803b77d81SGuenter Roeck 							   ixgbe_hwmon,
19903b77d81SGuenter Roeck 							   ixgbe_hwmon->groups);
20003b77d81SGuenter Roeck 	if (IS_ERR(hwmon_dev))
20103b77d81SGuenter Roeck 		rc = PTR_ERR(hwmon_dev);
2023ca8bc6dSDon Skidmore exit:
2033ca8bc6dSDon Skidmore 	return rc;
2043ca8bc6dSDon Skidmore }
2053ca8bc6dSDon Skidmore 
206