xref: /linux/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c (revision 03b77d8180378632e76f1157d9a685ca4c79d0cf)
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:
233ca8bc6dSDon Skidmore   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
243ca8bc6dSDon Skidmore   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
253ca8bc6dSDon Skidmore 
263ca8bc6dSDon Skidmore *******************************************************************************/
273ca8bc6dSDon Skidmore 
283ca8bc6dSDon Skidmore #include "ixgbe.h"
293ca8bc6dSDon Skidmore #include "ixgbe_common.h"
303ca8bc6dSDon Skidmore #include "ixgbe_type.h"
313ca8bc6dSDon Skidmore 
323ca8bc6dSDon Skidmore #include <linux/module.h>
333ca8bc6dSDon Skidmore #include <linux/types.h>
343ca8bc6dSDon Skidmore #include <linux/sysfs.h>
353ca8bc6dSDon Skidmore #include <linux/kobject.h>
363ca8bc6dSDon Skidmore #include <linux/device.h>
373ca8bc6dSDon Skidmore #include <linux/netdevice.h>
383ca8bc6dSDon Skidmore #include <linux/hwmon.h>
393ca8bc6dSDon Skidmore 
403ca8bc6dSDon Skidmore /* hwmon callback functions */
413ca8bc6dSDon Skidmore static ssize_t ixgbe_hwmon_show_location(struct device *dev,
423ca8bc6dSDon Skidmore 					 struct device_attribute *attr,
433ca8bc6dSDon Skidmore 					 char *buf)
443ca8bc6dSDon Skidmore {
453ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr,
463ca8bc6dSDon Skidmore 						     dev_attr);
473ca8bc6dSDon Skidmore 	return sprintf(buf, "loc%u\n",
483ca8bc6dSDon Skidmore 		       ixgbe_attr->sensor->location);
493ca8bc6dSDon Skidmore }
503ca8bc6dSDon Skidmore 
513ca8bc6dSDon Skidmore static ssize_t ixgbe_hwmon_show_temp(struct device *dev,
523ca8bc6dSDon Skidmore 				     struct device_attribute *attr,
533ca8bc6dSDon Skidmore 				     char *buf)
543ca8bc6dSDon Skidmore {
553ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr,
563ca8bc6dSDon Skidmore 						     dev_attr);
573ca8bc6dSDon Skidmore 	unsigned int value;
583ca8bc6dSDon Skidmore 
593ca8bc6dSDon Skidmore 	/* reset the temp field */
603ca8bc6dSDon Skidmore 	ixgbe_attr->hw->mac.ops.get_thermal_sensor_data(ixgbe_attr->hw);
613ca8bc6dSDon Skidmore 
623ca8bc6dSDon Skidmore 	value = ixgbe_attr->sensor->temp;
633ca8bc6dSDon Skidmore 
643ca8bc6dSDon Skidmore 	/* display millidegree */
653ca8bc6dSDon Skidmore 	value *= 1000;
663ca8bc6dSDon Skidmore 
673ca8bc6dSDon Skidmore 	return sprintf(buf, "%u\n", value);
683ca8bc6dSDon Skidmore }
693ca8bc6dSDon Skidmore 
703ca8bc6dSDon Skidmore static ssize_t ixgbe_hwmon_show_cautionthresh(struct device *dev,
713ca8bc6dSDon Skidmore 				     struct device_attribute *attr,
723ca8bc6dSDon Skidmore 				     char *buf)
733ca8bc6dSDon Skidmore {
743ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr,
753ca8bc6dSDon Skidmore 						     dev_attr);
763ca8bc6dSDon Skidmore 	unsigned int value = ixgbe_attr->sensor->caution_thresh;
773ca8bc6dSDon Skidmore 
783ca8bc6dSDon Skidmore 	/* display millidegree */
793ca8bc6dSDon Skidmore 	value *= 1000;
803ca8bc6dSDon Skidmore 
813ca8bc6dSDon Skidmore 	return sprintf(buf, "%u\n", value);
823ca8bc6dSDon Skidmore }
833ca8bc6dSDon Skidmore 
843ca8bc6dSDon Skidmore static ssize_t ixgbe_hwmon_show_maxopthresh(struct device *dev,
853ca8bc6dSDon Skidmore 				     struct device_attribute *attr,
863ca8bc6dSDon Skidmore 				     char *buf)
873ca8bc6dSDon Skidmore {
883ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr,
893ca8bc6dSDon Skidmore 						     dev_attr);
903ca8bc6dSDon Skidmore 	unsigned int value = ixgbe_attr->sensor->max_op_thresh;
913ca8bc6dSDon Skidmore 
923ca8bc6dSDon Skidmore 	/* display millidegree */
933ca8bc6dSDon Skidmore 	value *= 1000;
943ca8bc6dSDon Skidmore 
953ca8bc6dSDon Skidmore 	return sprintf(buf, "%u\n", value);
963ca8bc6dSDon Skidmore }
973ca8bc6dSDon Skidmore 
9849ce9c2cSBen Hutchings /**
993ca8bc6dSDon Skidmore  * ixgbe_add_hwmon_attr - Create hwmon attr table for a hwmon sysfs file.
1003ca8bc6dSDon Skidmore  * @adapter: pointer to the adapter structure
1013ca8bc6dSDon Skidmore  * @offset: offset in the eeprom sensor data table
1023ca8bc6dSDon Skidmore  * @type: type of sensor data to display
1033ca8bc6dSDon Skidmore  *
1043ca8bc6dSDon Skidmore  * For each file we want in hwmon's sysfs interface we need a device_attribute
1053ca8bc6dSDon Skidmore  * This is included in our hwmon_attr struct that contains the references to
1063ca8bc6dSDon Skidmore  * the data structures we need to get the data to display.
1073ca8bc6dSDon Skidmore  */
1083ca8bc6dSDon Skidmore static int ixgbe_add_hwmon_attr(struct ixgbe_adapter *adapter,
1093ca8bc6dSDon Skidmore 				unsigned int offset, int type) {
1103ca8bc6dSDon Skidmore 	int rc;
1113ca8bc6dSDon Skidmore 	unsigned int n_attr;
1123ca8bc6dSDon Skidmore 	struct hwmon_attr *ixgbe_attr;
1133ca8bc6dSDon Skidmore 
114*03b77d81SGuenter Roeck 	n_attr = adapter->ixgbe_hwmon_buff->n_hwmon;
115*03b77d81SGuenter Roeck 	ixgbe_attr = &adapter->ixgbe_hwmon_buff->hwmon_list[n_attr];
1163ca8bc6dSDon Skidmore 
1173ca8bc6dSDon Skidmore 	switch (type) {
1183ca8bc6dSDon Skidmore 	case IXGBE_HWMON_TYPE_LOC:
1193ca8bc6dSDon Skidmore 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_location;
1203ca8bc6dSDon Skidmore 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name),
1213ca8bc6dSDon Skidmore 			 "temp%u_label", offset);
1223ca8bc6dSDon Skidmore 		break;
1233ca8bc6dSDon Skidmore 	case IXGBE_HWMON_TYPE_TEMP:
1243ca8bc6dSDon Skidmore 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_temp;
1253ca8bc6dSDon Skidmore 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name),
1263ca8bc6dSDon Skidmore 			 "temp%u_input", offset);
1273ca8bc6dSDon Skidmore 		break;
1283ca8bc6dSDon Skidmore 	case IXGBE_HWMON_TYPE_CAUTION:
1293ca8bc6dSDon Skidmore 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_cautionthresh;
1303ca8bc6dSDon Skidmore 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name),
1313ca8bc6dSDon Skidmore 			 "temp%u_max", offset);
1323ca8bc6dSDon Skidmore 		break;
1333ca8bc6dSDon Skidmore 	case IXGBE_HWMON_TYPE_MAX:
1343ca8bc6dSDon Skidmore 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_maxopthresh;
1353ca8bc6dSDon Skidmore 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name),
1363ca8bc6dSDon Skidmore 			 "temp%u_crit", offset);
1373ca8bc6dSDon Skidmore 		break;
1383ca8bc6dSDon Skidmore 	default:
1393ca8bc6dSDon Skidmore 		rc = -EPERM;
1403ca8bc6dSDon Skidmore 		return rc;
1413ca8bc6dSDon Skidmore 	}
1423ca8bc6dSDon Skidmore 
1433ca8bc6dSDon Skidmore 	/* These always the same regardless of type */
1443ca8bc6dSDon Skidmore 	ixgbe_attr->sensor =
1453ca8bc6dSDon Skidmore 		&adapter->hw.mac.thermal_sensor_data.sensor[offset];
1463ca8bc6dSDon Skidmore 	ixgbe_attr->hw = &adapter->hw;
1473ca8bc6dSDon Skidmore 	ixgbe_attr->dev_attr.store = NULL;
1483ca8bc6dSDon Skidmore 	ixgbe_attr->dev_attr.attr.mode = S_IRUGO;
1493ca8bc6dSDon Skidmore 	ixgbe_attr->dev_attr.attr.name = ixgbe_attr->name;
150*03b77d81SGuenter Roeck 	sysfs_attr_init(&ixgbe_attr->dev_attr.attr);
1513ca8bc6dSDon Skidmore 
152*03b77d81SGuenter Roeck 	adapter->ixgbe_hwmon_buff->attrs[n_attr] = &ixgbe_attr->dev_attr.attr;
1533ca8bc6dSDon Skidmore 
154*03b77d81SGuenter Roeck 	++adapter->ixgbe_hwmon_buff->n_hwmon;
1553ca8bc6dSDon Skidmore 
156*03b77d81SGuenter Roeck 	return 0;
1573ca8bc6dSDon Skidmore }
1583ca8bc6dSDon Skidmore 
1593ca8bc6dSDon Skidmore static void ixgbe_sysfs_del_adapter(struct ixgbe_adapter *adapter)
1603ca8bc6dSDon Skidmore {
1613ca8bc6dSDon Skidmore }
1623ca8bc6dSDon Skidmore 
1633ca8bc6dSDon Skidmore /* called from ixgbe_main.c */
1643ca8bc6dSDon Skidmore void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter)
1653ca8bc6dSDon Skidmore {
1663ca8bc6dSDon Skidmore 	ixgbe_sysfs_del_adapter(adapter);
1673ca8bc6dSDon Skidmore }
1683ca8bc6dSDon Skidmore 
1693ca8bc6dSDon Skidmore /* called from ixgbe_main.c */
1703ca8bc6dSDon Skidmore int ixgbe_sysfs_init(struct ixgbe_adapter *adapter)
1713ca8bc6dSDon Skidmore {
172*03b77d81SGuenter Roeck 	struct hwmon_buff *ixgbe_hwmon;
173*03b77d81SGuenter Roeck 	struct device *hwmon_dev;
1743ca8bc6dSDon Skidmore 	unsigned int i;
1753ca8bc6dSDon Skidmore 	int rc = 0;
1763ca8bc6dSDon Skidmore 
1773ca8bc6dSDon Skidmore 	/* If this method isn't defined we don't support thermals */
1783ca8bc6dSDon Skidmore 	if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL) {
1791210982bSDon Skidmore 		goto exit;
1803ca8bc6dSDon Skidmore 	}
1813ca8bc6dSDon Skidmore 
1823ca8bc6dSDon Skidmore 	/* Don't create thermal hwmon interface if no sensors present */
1831210982bSDon Skidmore 	if (adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw))
1841210982bSDon Skidmore 		goto exit;
1853ca8bc6dSDon Skidmore 
186*03b77d81SGuenter Roeck 	ixgbe_hwmon = devm_kzalloc(&adapter->pdev->dev, sizeof(*ixgbe_hwmon),
1873ca8bc6dSDon Skidmore 				   GFP_KERNEL);
188*03b77d81SGuenter Roeck 	if (ixgbe_hwmon == NULL) {
1893ca8bc6dSDon Skidmore 		rc = -ENOMEM;
190*03b77d81SGuenter Roeck 		goto exit;
1913ca8bc6dSDon Skidmore 	}
192*03b77d81SGuenter Roeck 	adapter->ixgbe_hwmon_buff = ixgbe_hwmon;
1933ca8bc6dSDon Skidmore 
1943ca8bc6dSDon Skidmore 	for (i = 0; i < IXGBE_MAX_SENSORS; i++) {
1953ca8bc6dSDon Skidmore 		/*
1963ca8bc6dSDon Skidmore 		 * Only create hwmon sysfs entries for sensors that have
1973ca8bc6dSDon Skidmore 		 * meaningful data for.
1983ca8bc6dSDon Skidmore 		 */
1993ca8bc6dSDon Skidmore 		if (adapter->hw.mac.thermal_sensor_data.sensor[i].location == 0)
2003ca8bc6dSDon Skidmore 			continue;
2013ca8bc6dSDon Skidmore 
2023ca8bc6dSDon Skidmore 		/* Bail if any hwmon attr struct fails to initialize */
2033ca8bc6dSDon Skidmore 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_CAUTION);
2043ca8bc6dSDon Skidmore 		if (rc)
205*03b77d81SGuenter Roeck 			goto exit;
206*03b77d81SGuenter Roeck 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_LOC);
207*03b77d81SGuenter Roeck 		if (rc)
208*03b77d81SGuenter Roeck 			goto exit;
209*03b77d81SGuenter Roeck 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_TEMP);
210*03b77d81SGuenter Roeck 		if (rc)
211*03b77d81SGuenter Roeck 			goto exit;
212*03b77d81SGuenter Roeck 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_MAX);
213*03b77d81SGuenter Roeck 		if (rc)
214*03b77d81SGuenter Roeck 			goto exit;
2153ca8bc6dSDon Skidmore 	}
2163ca8bc6dSDon Skidmore 
217*03b77d81SGuenter Roeck 	ixgbe_hwmon->groups[0] = &ixgbe_hwmon->group;
218*03b77d81SGuenter Roeck 	ixgbe_hwmon->group.attrs = ixgbe_hwmon->attrs;
2193ca8bc6dSDon Skidmore 
220*03b77d81SGuenter Roeck 	hwmon_dev = devm_hwmon_device_register_with_groups(&adapter->pdev->dev,
221*03b77d81SGuenter Roeck 							   "ixgbe",
222*03b77d81SGuenter Roeck 							   ixgbe_hwmon,
223*03b77d81SGuenter Roeck 							   ixgbe_hwmon->groups);
224*03b77d81SGuenter Roeck 	if (IS_ERR(hwmon_dev))
225*03b77d81SGuenter Roeck 		rc = PTR_ERR(hwmon_dev);
2263ca8bc6dSDon Skidmore exit:
2273ca8bc6dSDon Skidmore 	return rc;
2283ca8bc6dSDon Skidmore }
2293ca8bc6dSDon Skidmore 
230