1 /*
2  * Copyright 2007, Intel Corporation
3  *
4  * This file is part of PowerTOP
5  *
6  * This program file is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that 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
13  * for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program in a file named COPYING; if not, write to the
17  * Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301 USA
20  *
21  * Authors:
22  * 	Arjan van de Ven <arjan@linux.intel.com>
23  */
24 
25 #include <unistd.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdint.h>
30 #include <sys/types.h>
31 #include <dirent.h>
32 #include <linux/types.h>
33 #include <net/if.h>
34 #include <linux/sockios.h>
35 #include <sys/ioctl.h>
36 
37 /* work around a bug in debian -- it exposes kernel internal types to userspace */
38 #define u64 __u64
39 #define u32 __u32
40 #define u16 __u16
41 #define u8 __u8
42 #include <linux/ethtool.h>
43 #undef u64
44 #undef u32
45 #undef u16
46 #undef u8
47 
48 
49 
50 #include "powertop.h"
51 
activate_WOL_suggestion(void)52 void activate_WOL_suggestion(void)
53 {
54 	int sock;
55 	struct ifreq ifr;
56 	struct ethtool_wolinfo wol;
57 	int ret;
58 
59 	memset(&ifr, 0, sizeof(struct ifreq));
60 
61 	sock = socket(AF_INET, SOCK_DGRAM, 0);
62 	if (sock<0)
63 		return;
64 
65 	strcpy(ifr.ifr_name, "eth0");
66 
67 	/* Check if the interface is up */
68 	ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
69 	if (ret<0) {
70 		close(sock);
71 		return;
72 	}
73 
74 	if (ifr.ifr_flags & (IFF_UP | IFF_RUNNING)) {
75 		close(sock);
76 		return;
77 	}
78 
79 	memset(&wol, 0, sizeof(wol));
80 
81 	wol.cmd = ETHTOOL_GWOL;
82 	ifr.ifr_data = (caddr_t)&wol;
83         ioctl(sock, SIOCETHTOOL, &ifr);
84 	wol.cmd = ETHTOOL_SWOL;
85 	wol.wolopts = 0;
86         ioctl(sock, SIOCETHTOOL, &ifr);
87 
88 	close(sock);
89 }
90 
91 
92 
suggest_WOL_off(void)93 void suggest_WOL_off(void)
94 {
95 	int sock;
96 	struct ifreq ifr;
97 	struct ethtool_wolinfo wol;
98 	int ret;
99 
100 	memset(&ifr, 0, sizeof(struct ifreq));
101 
102 	sock = socket(AF_INET, SOCK_DGRAM, 0);
103 	if (sock<0)
104 		return;
105 
106 	strcpy(ifr.ifr_name, "eth0");
107 
108 	/* Check if the interface is up */
109 	ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
110 	if (ret<0) {
111 		close(sock);
112 		return;
113 	}
114 
115 	if (ifr.ifr_flags & (IFF_UP | IFF_RUNNING)) {
116 		close(sock);
117 		return;
118 	}
119 
120 	memset(&wol, 0, sizeof(wol));
121 
122 	wol.cmd = ETHTOOL_GWOL;
123 	ifr.ifr_data = (caddr_t)&wol;
124         ioctl(sock, SIOCETHTOOL, &ifr);
125 
126 	if (wol.wolopts) {
127 		add_suggestion(_(
128 			"Disable Ethernet Wake-On-Lan with the following command:\n"
129 			"  ethtool -s eth0 wol d \n"
130 			"Wake-on-Lan keeps the phy active, this costs power."), 5,
131 			'W', _(" W - disable Wake-On-Lan "), activate_WOL_suggestion);
132 
133 
134 	}
135 
136 	close(sock);
137 }
138 
139