xref: /linux/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c (revision d3757ba4c1421d2ad00d2bf97119005e37ad2902)
13ca8bc6dSDon Skidmore /*******************************************************************************
23ca8bc6dSDon Skidmore 
33ca8bc6dSDon Skidmore   Intel 10 Gigabit PCI Express Linux driver
4434c5e39SDon Skidmore   Copyright(c) 1999 - 2013 Intel Corporation.
53ca8bc6dSDon Skidmore 
63ca8bc6dSDon Skidmore   This program is free software; you can redistribute it and/or modify it
73ca8bc6dSDon Skidmore   under the terms and conditions of the GNU General Public License,
83ca8bc6dSDon Skidmore   version 2, as published by the Free Software Foundation.
93ca8bc6dSDon Skidmore 
103ca8bc6dSDon Skidmore   This program is distributed in the hope it will be useful, but WITHOUT
113ca8bc6dSDon Skidmore   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
123ca8bc6dSDon Skidmore   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
133ca8bc6dSDon Skidmore   more details.
143ca8bc6dSDon Skidmore 
153ca8bc6dSDon Skidmore   You should have received a copy of the GNU General Public License along with
163ca8bc6dSDon Skidmore   this program; if not, write to the Free Software Foundation, Inc.,
173ca8bc6dSDon Skidmore   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
183ca8bc6dSDon Skidmore 
193ca8bc6dSDon Skidmore   The full GNU General Public License is included in this distribution in
203ca8bc6dSDon Skidmore   the file called "COPYING".
213ca8bc6dSDon Skidmore 
223ca8bc6dSDon Skidmore   Contact Information:
23b89aae71SJacob Keller   Linux NICS <linux.nics@intel.com>
243ca8bc6dSDon Skidmore   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
253ca8bc6dSDon Skidmore   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
263ca8bc6dSDon Skidmore 
273ca8bc6dSDon Skidmore *******************************************************************************/
283ca8bc6dSDon Skidmore 
293ca8bc6dSDon Skidmore #include "ixgbe.h"
303ca8bc6dSDon Skidmore #include "ixgbe_common.h"
313ca8bc6dSDon Skidmore #include "ixgbe_type.h"
323ca8bc6dSDon Skidmore 
333ca8bc6dSDon Skidmore #include <linux/module.h>
343ca8bc6dSDon Skidmore #include <linux/types.h>
353ca8bc6dSDon Skidmore #include <linux/sysfs.h>
363ca8bc6dSDon Skidmore #include <linux/kobject.h>
373ca8bc6dSDon Skidmore #include <linux/device.h>
383ca8bc6dSDon Skidmore #include <linux/netdevice.h>
393ca8bc6dSDon Skidmore #include <linux/hwmon.h>
403ca8bc6dSDon Skidmore 
413ca8bc6dSDon Skidmore /* hwmon callback functions */
423ca8bc6dSDon Skidmore static ssize_t ixgbe_hwmon_show_location(struct device *dev,
433ca8bc6dSDon Skidmore 					 struct device_attribute *attr,
443ca8bc6dSDon Skidmore 					 char *buf)
453ca8bc6dSDon Skidmore {
463ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr,
473ca8bc6dSDon Skidmore 						     dev_attr);
483ca8bc6dSDon Skidmore 	return sprintf(buf, "loc%u\n",
493ca8bc6dSDon Skidmore 		       ixgbe_attr->sensor->location);
503ca8bc6dSDon Skidmore }
513ca8bc6dSDon Skidmore 
523ca8bc6dSDon Skidmore static ssize_t ixgbe_hwmon_show_temp(struct device *dev,
533ca8bc6dSDon Skidmore 				     struct device_attribute *attr,
543ca8bc6dSDon Skidmore 				     char *buf)
553ca8bc6dSDon Skidmore {
563ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr,
573ca8bc6dSDon Skidmore 						     dev_attr);
583ca8bc6dSDon Skidmore 	unsigned int value;
593ca8bc6dSDon Skidmore 
603ca8bc6dSDon Skidmore 	/* reset the temp field */
613ca8bc6dSDon Skidmore 	ixgbe_attr->hw->mac.ops.get_thermal_sensor_data(ixgbe_attr->hw);
623ca8bc6dSDon Skidmore 
633ca8bc6dSDon Skidmore 	value = ixgbe_attr->sensor->temp;
643ca8bc6dSDon Skidmore 
653ca8bc6dSDon Skidmore 	/* display millidegree */
663ca8bc6dSDon Skidmore 	value *= 1000;
673ca8bc6dSDon Skidmore 
683ca8bc6dSDon Skidmore 	return sprintf(buf, "%u\n", value);
693ca8bc6dSDon Skidmore }
703ca8bc6dSDon Skidmore 
713ca8bc6dSDon Skidmore static ssize_t ixgbe_hwmon_show_cautionthresh(struct device *dev,
723ca8bc6dSDon Skidmore 				     struct device_attribute *attr,
733ca8bc6dSDon Skidmore 				     char *buf)
743ca8bc6dSDon Skidmore {
753ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr,
763ca8bc6dSDon Skidmore 						     dev_attr);
773ca8bc6dSDon Skidmore 	unsigned int value = ixgbe_attr->sensor->caution_thresh;
783ca8bc6dSDon Skidmore 
793ca8bc6dSDon Skidmore 	/* display millidegree */
803ca8bc6dSDon Skidmore 	value *= 1000;
813ca8bc6dSDon Skidmore 
823ca8bc6dSDon Skidmore 	return sprintf(buf, "%u\n", value);
833ca8bc6dSDon Skidmore }
843ca8bc6dSDon Skidmore 
853ca8bc6dSDon Skidmore static ssize_t ixgbe_hwmon_show_maxopthresh(struct device *dev,
863ca8bc6dSDon Skidmore 				     struct device_attribute *attr,
873ca8bc6dSDon Skidmore 				     char *buf)
883ca8bc6dSDon Skidmore {
893ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr,
903ca8bc6dSDon Skidmore 						     dev_attr);
913ca8bc6dSDon Skidmore 	unsigned int value = ixgbe_attr->sensor->max_op_thresh;
923ca8bc6dSDon Skidmore 
933ca8bc6dSDon Skidmore 	/* display millidegree */
943ca8bc6dSDon Skidmore 	value *= 1000;
953ca8bc6dSDon Skidmore 
963ca8bc6dSDon Skidmore 	return sprintf(buf, "%u\n", value);
973ca8bc6dSDon Skidmore }
983ca8bc6dSDon Skidmore 
9949ce9c2cSBen Hutchings /**
1003ca8bc6dSDon Skidmore  * ixgbe_add_hwmon_attr - Create hwmon attr table for a hwmon sysfs file.
1013ca8bc6dSDon Skidmore  * @adapter: pointer to the adapter structure
1023ca8bc6dSDon Skidmore  * @offset: offset in the eeprom sensor data table
1033ca8bc6dSDon Skidmore  * @type: type of sensor data to display
1043ca8bc6dSDon Skidmore  *
1053ca8bc6dSDon Skidmore  * For each file we want in hwmon's sysfs interface we need a device_attribute
1063ca8bc6dSDon Skidmore  * This is included in our hwmon_attr struct that contains the references to
1073ca8bc6dSDon Skidmore  * the data structures we need to get the data to display.
1083ca8bc6dSDon Skidmore  */
1093ca8bc6dSDon Skidmore static int ixgbe_add_hwmon_attr(struct ixgbe_adapter *adapter,
1103ca8bc6dSDon Skidmore 				unsigned int offset, int type) {
1113ca8bc6dSDon Skidmore 	int rc;
1123ca8bc6dSDon Skidmore 	unsigned int n_attr;
1133ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr;
1143ca8bc6dSDon Skidmore 
11503b77d81SGuenter Roeck 	n_attr = adapter->ixgbe_hwmon_buff->n_hwmon;
11603b77d81SGuenter Roeck 	ixgbe_attr = &adapter->ixgbe_hwmon_buff->hwmon_list[n_attr];
1173ca8bc6dSDon Skidmore 
1183ca8bc6dSDon Skidmore 	switch (type) {
1193ca8bc6dSDon Skidmore 	case IXGBE_HWMON_TYPE_LOC:
1203ca8bc6dSDon Skidmore 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_location;
1213ca8bc6dSDon Skidmore 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name),
12222dd81c5SGuenter Roeck 			 "temp%u_label", offset + 1);
1233ca8bc6dSDon Skidmore 		break;
1243ca8bc6dSDon Skidmore 	case IXGBE_HWMON_TYPE_TEMP:
1253ca8bc6dSDon Skidmore 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_temp;
1263ca8bc6dSDon Skidmore 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name),
12722dd81c5SGuenter Roeck 			 "temp%u_input", offset + 1);
1283ca8bc6dSDon Skidmore 		break;
1293ca8bc6dSDon Skidmore 	case IXGBE_HWMON_TYPE_CAUTION:
1303ca8bc6dSDon Skidmore 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_cautionthresh;
1313ca8bc6dSDon Skidmore 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name),
13222dd81c5SGuenter Roeck 			 "temp%u_max", offset + 1);
1333ca8bc6dSDon Skidmore 		break;
1343ca8bc6dSDon Skidmore 	case IXGBE_HWMON_TYPE_MAX:
1353ca8bc6dSDon Skidmore 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_maxopthresh;
1363ca8bc6dSDon Skidmore 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name),
13722dd81c5SGuenter Roeck 			 "temp%u_crit", offset + 1);
1383ca8bc6dSDon Skidmore 		break;
1393ca8bc6dSDon Skidmore 	default:
1403ca8bc6dSDon Skidmore 		rc = -EPERM;
1413ca8bc6dSDon Skidmore 		return rc;
1423ca8bc6dSDon Skidmore 	}
1433ca8bc6dSDon Skidmore 
1443ca8bc6dSDon Skidmore 	/* These always the same regardless of type */
1453ca8bc6dSDon Skidmore 	ixgbe_attr->sensor =
1463ca8bc6dSDon Skidmore 		&adapter->hw.mac.thermal_sensor_data.sensor[offset];
1473ca8bc6dSDon Skidmore 	ixgbe_attr->hw = &adapter->hw;
1483ca8bc6dSDon Skidmore 	ixgbe_attr->dev_attr.store = NULL;
149*d3757ba4SJoe Perches 	ixgbe_attr->dev_attr.attr.mode = 0444;
1503ca8bc6dSDon Skidmore 	ixgbe_attr->dev_attr.attr.name = ixgbe_attr->name;
15103b77d81SGuenter Roeck 	sysfs_attr_init(&ixgbe_attr->dev_attr.attr);
1523ca8bc6dSDon Skidmore 
15303b77d81SGuenter Roeck 	adapter->ixgbe_hwmon_buff->attrs[n_attr] = &ixgbe_attr->dev_attr.attr;
1543ca8bc6dSDon Skidmore 
15503b77d81SGuenter Roeck 	++adapter->ixgbe_hwmon_buff->n_hwmon;
1563ca8bc6dSDon Skidmore 
15703b77d81SGuenter Roeck 	return 0;
1583ca8bc6dSDon Skidmore }
1593ca8bc6dSDon Skidmore 
1603ca8bc6dSDon Skidmore static void ixgbe_sysfs_del_adapter(struct ixgbe_adapter *adapter)
1613ca8bc6dSDon Skidmore {
1623ca8bc6dSDon Skidmore }
1633ca8bc6dSDon Skidmore 
1643ca8bc6dSDon Skidmore /* called from ixgbe_main.c */
1653ca8bc6dSDon Skidmore void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter)
1663ca8bc6dSDon Skidmore {
1673ca8bc6dSDon Skidmore 	ixgbe_sysfs_del_adapter(adapter);
1683ca8bc6dSDon Skidmore }
1693ca8bc6dSDon Skidmore 
1703ca8bc6dSDon Skidmore /* called from ixgbe_main.c */
1713ca8bc6dSDon Skidmore int ixgbe_sysfs_init(struct ixgbe_adapter *adapter)
1723ca8bc6dSDon Skidmore {
17303b77d81SGuenter Roeck 	struct hwmon_buff *ixgbe_hwmon;
17403b77d81SGuenter Roeck 	struct device *hwmon_dev;
1753ca8bc6dSDon Skidmore 	unsigned int i;
1763ca8bc6dSDon Skidmore 	int rc = 0;
1773ca8bc6dSDon Skidmore 
1783ca8bc6dSDon Skidmore 	/* If this method isn't defined we don't support thermals */
1793ca8bc6dSDon Skidmore 	if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL) {
1801210982bSDon Skidmore 		goto exit;
1813ca8bc6dSDon Skidmore 	}
1823ca8bc6dSDon Skidmore 
1833ca8bc6dSDon Skidmore 	/* Don't create thermal hwmon interface if no sensors present */
1841210982bSDon Skidmore 	if (adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw))
1851210982bSDon Skidmore 		goto exit;
1863ca8bc6dSDon Skidmore 
18703b77d81SGuenter Roeck 	ixgbe_hwmon = devm_kzalloc(&adapter->pdev->dev, sizeof(*ixgbe_hwmon),
1883ca8bc6dSDon Skidmore 				   GFP_KERNEL);
18903b77d81SGuenter Roeck 	if (ixgbe_hwmon == NULL) {
1903ca8bc6dSDon Skidmore 		rc = -ENOMEM;
19103b77d81SGuenter Roeck 		goto exit;
1923ca8bc6dSDon Skidmore 	}
19303b77d81SGuenter Roeck 	adapter->ixgbe_hwmon_buff = ixgbe_hwmon;
1943ca8bc6dSDon Skidmore 
1953ca8bc6dSDon Skidmore 	for (i = 0; i < IXGBE_MAX_SENSORS; i++) {
1963ca8bc6dSDon Skidmore 		/*
1973ca8bc6dSDon Skidmore 		 * Only create hwmon sysfs entries for sensors that have
1983ca8bc6dSDon Skidmore 		 * meaningful data for.
1993ca8bc6dSDon Skidmore 		 */
2003ca8bc6dSDon Skidmore 		if (adapter->hw.mac.thermal_sensor_data.sensor[i].location == 0)
2013ca8bc6dSDon Skidmore 			continue;
2023ca8bc6dSDon Skidmore 
2033ca8bc6dSDon Skidmore 		/* Bail if any hwmon attr struct fails to initialize */
2043ca8bc6dSDon Skidmore 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_CAUTION);
2053ca8bc6dSDon Skidmore 		if (rc)
20603b77d81SGuenter Roeck 			goto exit;
20703b77d81SGuenter Roeck 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_LOC);
20803b77d81SGuenter Roeck 		if (rc)
20903b77d81SGuenter Roeck 			goto exit;
21003b77d81SGuenter Roeck 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_TEMP);
21103b77d81SGuenter Roeck 		if (rc)
21203b77d81SGuenter Roeck 			goto exit;
21303b77d81SGuenter Roeck 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_MAX);
21403b77d81SGuenter Roeck 		if (rc)
21503b77d81SGuenter Roeck 			goto exit;
2163ca8bc6dSDon Skidmore 	}
2173ca8bc6dSDon Skidmore 
21803b77d81SGuenter Roeck 	ixgbe_hwmon->groups[0] = &ixgbe_hwmon->group;
21903b77d81SGuenter Roeck 	ixgbe_hwmon->group.attrs = ixgbe_hwmon->attrs;
2203ca8bc6dSDon Skidmore 
22103b77d81SGuenter Roeck 	hwmon_dev = devm_hwmon_device_register_with_groups(&adapter->pdev->dev,
22203b77d81SGuenter Roeck 							   "ixgbe",
22303b77d81SGuenter Roeck 							   ixgbe_hwmon,
22403b77d81SGuenter Roeck 							   ixgbe_hwmon->groups);
22503b77d81SGuenter Roeck 	if (IS_ERR(hwmon_dev))
22603b77d81SGuenter Roeck 		rc = PTR_ERR(hwmon_dev);
2273ca8bc6dSDon Skidmore exit:
2283ca8bc6dSDon Skidmore 	return rc;
2293ca8bc6dSDon Skidmore }
2303ca8bc6dSDon Skidmore 
231