1 /*******************************************************************************
3 Intel 10 Gigabit PCI Express Linux driver
4 Copyright(c) 1999 - 2013 Intel Corporation.
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
23 Linux NICS <linux.nics@intel.com>
24 e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
25 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *******************************************************************************/
30 #include "ixgbe_common.h"
31 #include "ixgbe_type.h"
33 #include <linux/module.h>
34 #include <linux/types.h>
35 #include <linux/sysfs.h>
36 #include <linux/kobject.h>
37 #include <linux/device.h>
38 #include <linux/netdevice.h>
39 #include <linux/hwmon.h>
41 /* hwmon callback functions */
42 static ssize_t
ixgbe_hwmon_show_location(struct device
*dev
,
43 struct device_attribute
*attr
,
46 struct hwmon_attr
*ixgbe_attr
= container_of(attr
, struct hwmon_attr
,
48 return sprintf(buf
, "loc%u\n",
49 ixgbe_attr
->sensor
->location
);
52 static ssize_t
ixgbe_hwmon_show_temp(struct device
*dev
,
53 struct device_attribute
*attr
,
56 struct hwmon_attr
*ixgbe_attr
= container_of(attr
, struct hwmon_attr
,
60 /* reset the temp field */
61 ixgbe_attr
->hw
->mac
.ops
.get_thermal_sensor_data(ixgbe_attr
->hw
);
63 value
= ixgbe_attr
->sensor
->temp
;
65 /* display millidegree */
68 return sprintf(buf
, "%u\n", value
);
71 static ssize_t
ixgbe_hwmon_show_cautionthresh(struct device
*dev
,
72 struct device_attribute
*attr
,
75 struct hwmon_attr
*ixgbe_attr
= container_of(attr
, struct hwmon_attr
,
77 unsigned int value
= ixgbe_attr
->sensor
->caution_thresh
;
79 /* display millidegree */
82 return sprintf(buf
, "%u\n", value
);
85 static ssize_t
ixgbe_hwmon_show_maxopthresh(struct device
*dev
,
86 struct device_attribute
*attr
,
89 struct hwmon_attr
*ixgbe_attr
= container_of(attr
, struct hwmon_attr
,
91 unsigned int value
= ixgbe_attr
->sensor
->max_op_thresh
;
93 /* display millidegree */
96 return sprintf(buf
, "%u\n", value
);
100 * ixgbe_add_hwmon_attr - Create hwmon attr table for a hwmon sysfs file.
101 * @adapter: pointer to the adapter structure
102 * @offset: offset in the eeprom sensor data table
103 * @type: type of sensor data to display
105 * For each file we want in hwmon's sysfs interface we need a device_attribute
106 * This is included in our hwmon_attr struct that contains the references to
107 * the data structures we need to get the data to display.
109 static int ixgbe_add_hwmon_attr(struct ixgbe_adapter
*adapter
,
110 unsigned int offset
, int type
) {
113 struct hwmon_attr
*ixgbe_attr
;
115 n_attr
= adapter
->ixgbe_hwmon_buff
->n_hwmon
;
116 ixgbe_attr
= &adapter
->ixgbe_hwmon_buff
->hwmon_list
[n_attr
];
119 case IXGBE_HWMON_TYPE_LOC
:
120 ixgbe_attr
->dev_attr
.show
= ixgbe_hwmon_show_location
;
121 snprintf(ixgbe_attr
->name
, sizeof(ixgbe_attr
->name
),
122 "temp%u_label", offset
+ 1);
124 case IXGBE_HWMON_TYPE_TEMP
:
125 ixgbe_attr
->dev_attr
.show
= ixgbe_hwmon_show_temp
;
126 snprintf(ixgbe_attr
->name
, sizeof(ixgbe_attr
->name
),
127 "temp%u_input", offset
+ 1);
129 case IXGBE_HWMON_TYPE_CAUTION
:
130 ixgbe_attr
->dev_attr
.show
= ixgbe_hwmon_show_cautionthresh
;
131 snprintf(ixgbe_attr
->name
, sizeof(ixgbe_attr
->name
),
132 "temp%u_max", offset
+ 1);
134 case IXGBE_HWMON_TYPE_MAX
:
135 ixgbe_attr
->dev_attr
.show
= ixgbe_hwmon_show_maxopthresh
;
136 snprintf(ixgbe_attr
->name
, sizeof(ixgbe_attr
->name
),
137 "temp%u_crit", offset
+ 1);
144 /* These always the same regardless of type */
146 &adapter
->hw
.mac
.thermal_sensor_data
.sensor
[offset
];
147 ixgbe_attr
->hw
= &adapter
->hw
;
148 ixgbe_attr
->dev_attr
.store
= NULL
;
149 ixgbe_attr
->dev_attr
.attr
.mode
= S_IRUGO
;
150 ixgbe_attr
->dev_attr
.attr
.name
= ixgbe_attr
->name
;
151 sysfs_attr_init(&ixgbe_attr
->dev_attr
.attr
);
153 adapter
->ixgbe_hwmon_buff
->attrs
[n_attr
] = &ixgbe_attr
->dev_attr
.attr
;
155 ++adapter
->ixgbe_hwmon_buff
->n_hwmon
;
160 static void ixgbe_sysfs_del_adapter(struct ixgbe_adapter
*adapter
)
164 /* called from ixgbe_main.c */
165 void ixgbe_sysfs_exit(struct ixgbe_adapter
*adapter
)
167 ixgbe_sysfs_del_adapter(adapter
);
170 /* called from ixgbe_main.c */
171 int ixgbe_sysfs_init(struct ixgbe_adapter
*adapter
)
173 struct hwmon_buff
*ixgbe_hwmon
;
174 struct device
*hwmon_dev
;
178 /* If this method isn't defined we don't support thermals */
179 if (adapter
->hw
.mac
.ops
.init_thermal_sensor_thresh
== NULL
) {
183 /* Don't create thermal hwmon interface if no sensors present */
184 if (adapter
->hw
.mac
.ops
.init_thermal_sensor_thresh(&adapter
->hw
))
187 ixgbe_hwmon
= devm_kzalloc(&adapter
->pdev
->dev
, sizeof(*ixgbe_hwmon
),
189 if (ixgbe_hwmon
== NULL
) {
193 adapter
->ixgbe_hwmon_buff
= ixgbe_hwmon
;
195 for (i
= 0; i
< IXGBE_MAX_SENSORS
; i
++) {
197 * Only create hwmon sysfs entries for sensors that have
198 * meaningful data for.
200 if (adapter
->hw
.mac
.thermal_sensor_data
.sensor
[i
].location
== 0)
203 /* Bail if any hwmon attr struct fails to initialize */
204 rc
= ixgbe_add_hwmon_attr(adapter
, i
, IXGBE_HWMON_TYPE_CAUTION
);
207 rc
= ixgbe_add_hwmon_attr(adapter
, i
, IXGBE_HWMON_TYPE_LOC
);
210 rc
= ixgbe_add_hwmon_attr(adapter
, i
, IXGBE_HWMON_TYPE_TEMP
);
213 rc
= ixgbe_add_hwmon_attr(adapter
, i
, IXGBE_HWMON_TYPE_MAX
);
218 ixgbe_hwmon
->groups
[0] = &ixgbe_hwmon
->group
;
219 ixgbe_hwmon
->group
.attrs
= ixgbe_hwmon
->attrs
;
221 hwmon_dev
= devm_hwmon_device_register_with_groups(&adapter
->pdev
->dev
,
224 ixgbe_hwmon
->groups
);
225 if (IS_ERR(hwmon_dev
))
226 rc
= PTR_ERR(hwmon_dev
);