2 * et driver ioctl swiss army knife command.
4 * Copyright (C) 2009, Broadcom Corporation
7 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
8 * the contents of this file may not be disclosed to third parties, copied
9 * or duplicated in any form, in whole or in part, without the prior
10 * written permission of Broadcom Corporation.
12 * $Id: et.c,v 1.9.130.4 2009/07/17 03:09:33 Exp $
17 #include <sys/param.h>
18 #include <sys/ioctl.h>
19 #include <sys/socket.h>
20 #include <sys/sysctl.h>
23 #include <netinet/in.h>
30 #include <proto/ethernet.h>
32 typedef u_int64_t u64
;
33 typedef u_int32_t u32
;
34 typedef u_int16_t u16
;
36 #include <linux/types.h>
37 #include <linux/sockios.h>
38 #include <linux/ethtool.h>
40 static void usage(char *av0
);
41 static void syserr(char *s
);
42 static void et_find(int s
, struct ifreq
*ifr
);
43 static int et_check(int s
, struct ifreq
*ifr
);
52 main(int ac
, char *av
[])
54 char *interface
= NULL
;
68 if (av
[1][0] == '-') {
69 if ((av
[1][1] != 'a') && (av
[1][1] != 'i'))
77 if ((s
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0)
81 strncpy(ifr
.ifr_name
, interface
, sizeof (ifr
.ifr_name
));
86 fprintf(stderr
, "et interface not found\n");
90 if (strcmp(av
[optind
], "up") == 0) {
91 if (ioctl(s
, SIOCSETCUP
, (caddr_t
)&ifr
) < 0)
93 } else if (strcmp(av
[optind
], "down") == 0) {
94 if (ioctl(s
, SIOCSETCDOWN
, (caddr_t
)&ifr
) < 0)
96 } else if (strcmp(av
[optind
], "loop") == 0) {
97 if (optind
>= (ac
-1))
99 arg
= atoi(av
[optind
+ 1]);
100 ifr
.ifr_data
= (caddr_t
) &arg
;
101 if (ioctl(s
, SIOCSETCLOOP
, (caddr_t
)&ifr
) < 0)
103 } else if (strcmp(av
[optind
], "dump") == 0) {
105 if (ioctl(s
, SIOCGETCDUMP
, (caddr_t
)&ifr
) < 0)
108 } else if (strcmp(av
[optind
], "msglevel") == 0) {
109 if (optind
>= (ac
-1))
111 arg
= strtol(av
[optind
+ 1], &endptr
, 0);
112 ifr
.ifr_data
= (caddr_t
) &arg
;
113 if (ioctl(s
, SIOCSETCSETMSGLEVEL
, (caddr_t
)&ifr
) < 0)
114 syserr("etcsetmsglevel");
115 } else if (strcmp(av
[optind
], "promisc") == 0) {
116 if (optind
>= (ac
-1))
118 arg
= atoi(av
[optind
+ 1]);
119 ifr
.ifr_data
= (caddr_t
) &arg
;
120 if (ioctl(s
, SIOCSETCPROMISC
, (caddr_t
)&ifr
) < 0)
121 syserr("etcpromisc");
122 } else if (strcmp(av
[optind
], "qos") == 0) {
123 if (optind
>= (ac
-1))
125 arg
= atoi(av
[optind
+ 1]);
126 ifr
.ifr_data
= (caddr_t
) &arg
;
127 if (ioctl(s
, SIOCSETCQOS
, (caddr_t
)&ifr
) < 0)
129 } else if (strcmp(av
[optind
], "speed") == 0) {
130 if (optind
>= (ac
-1))
132 if (strcmp(av
[optind
+1], "auto") == 0)
134 else if (strcmp(av
[optind
+1], "10half") == 0)
136 else if (strcmp(av
[optind
+1], "10full") == 0)
138 else if (strcmp(av
[optind
+1], "100half") == 0)
140 else if (strcmp(av
[optind
+1], "100full") == 0)
142 else if (strcmp(av
[optind
+1], "1000full") == 0)
147 ifr
.ifr_data
= (caddr_t
) &arg
;
148 if (ioctl(s
, SIOCSETCSPEED
, (caddr_t
)&ifr
) < 0)
151 else if (strcmp(av
[optind
], "phyrd") == 0) {
154 if ((ac
< (optind
+ 2)) || (ac
> (optind
+ 3))) {
156 } else if (ac
== (optind
+ 3)) {
157 /* PHY address provided */
158 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0) << 16;;
159 vecarg
[0] |= strtoul(av
[optind
+ 2], NULL
, 0) & 0xffff;
160 cmd
= SIOCGETCPHYRD2
;
162 /* "My" PHY address implied */
163 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0);
166 ifr
.ifr_data
= (caddr_t
) vecarg
;
167 if (ioctl(s
, cmd
, (caddr_t
)&ifr
) < 0)
170 printf("0x%04x\n", vecarg
[1]);
171 } else if (strcmp(av
[optind
], "phywr") == 0) {
174 if ((ac
< (optind
+ 3)) || (ac
> (optind
+ 4))) {
176 } else if (ac
== (optind
+ 4)) {
177 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0) << 16;;
178 vecarg
[0] |= strtoul(av
[optind
+ 2], NULL
, 0) & 0xffff;
179 vecarg
[1] = strtoul(av
[optind
+ 3], NULL
, 0);
180 cmd
= SIOCSETCPHYWR2
;
182 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0);
183 vecarg
[1] = strtoul(av
[optind
+ 2], NULL
, 0);
186 ifr
.ifr_data
= (caddr_t
) vecarg
;
187 if (ioctl(s
, cmd
, (caddr_t
)&ifr
) < 0)
189 } else if (strcmp(av
[optind
], "robord") == 0) {
190 if (ac
!= (optind
+ 3))
193 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0) << 16;;
194 vecarg
[0] |= strtoul(av
[optind
+ 2], NULL
, 0) & 0xffff;
196 ifr
.ifr_data
= (caddr_t
) vecarg
;
197 if (ioctl(s
, SIOCGETCROBORD
, (caddr_t
)&ifr
) < 0)
200 printf("0x%04x\n", vecarg
[1]);
201 } else if (strcmp(av
[optind
], "robowr") == 0) {
202 if (ac
!= (optind
+ 4))
205 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0) << 16;;
206 vecarg
[0] |= strtoul(av
[optind
+ 2], NULL
, 0) & 0xffff;
207 vecarg
[1] = strtoul(av
[optind
+ 3], NULL
, 0);
209 ifr
.ifr_data
= (caddr_t
) vecarg
;
210 if (ioctl(s
, SIOCSETCROBOWR
, (caddr_t
)&ifr
) < 0)
213 if (strcmp(av
[optind
], "switch_mode") == 0) {
217 if (ac
== (optind
+ 1)) {
221 } else if (ac
== (optind
+ 2)) {
223 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0);
224 all
= (int)(vecarg
[0] == VECLEN
);
226 if (ac
!= (optind
+ 3))
229 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0);
230 vecarg
[1] = strtoul(av
[optind
+ 2], NULL
, 0);
237 var
.len
= VECLEN
* sizeof(int);
238 var
.cmd
= IOV_ET_POWER_SAVE_MODE
;
241 ifr
.ifr_data
= (caddr_t
) &var
;
242 if (ioctl(s
, SIOCSETGETVAR
, (caddr_t
)&ifr
) < 0)
243 syserr("etcswitchmode");
247 printf("phy power save mode for all phys:"
248 " %d %d %d %d %d \n",
249 vecarg
[0], vecarg
[1], vecarg
[2],
250 vecarg
[3], vecarg
[4]);
252 printf("phy power save mode for phy %d mode %d\n",
253 vecarg
[0], vecarg
[1]);
266 fprintf(stderr
, "usage: %s [ [ -a | -i ] interface ] and one of:\n"
271 "\tmsglevel <bitvec> (error=1, trace=2, prhdr=4, prpkt=8)\n"
272 "\tpromisc <0 or 1>\n"
274 "\tspeed <auto, 10half, 10full, 100half, 100full, 1000full>\n"
275 "\tphyrd [<phyaddr>] <reg>\n"
276 "\tphywr [<phyaddr>] <reg> <val>\n"
277 "\trobord <page> <reg>\n"
278 "\trobowr <page> <reg> <val>\n"
279 "\tswitch_mode <phy> <mode> (mode 0, 1, 2, 3)\n"
286 et_find(int s
, struct ifreq
*ifr
)
288 char proc_net_dev
[] = "/proc/net/dev";
290 char buf
[512], *c
, *name
;
292 ifr
->ifr_name
[0] = '\0';
294 /* eat first two lines */
295 if (!(fp
= fopen(proc_net_dev
, "r")) ||
296 !fgets(buf
, sizeof(buf
), fp
) ||
297 !fgets(buf
, sizeof(buf
), fp
))
300 while (fgets(buf
, sizeof(buf
), fp
)) {
304 if (!(name
= strsep(&c
, ":")))
306 strncpy(ifr
->ifr_name
, name
, IFNAMSIZ
);
307 if (et_check(s
, ifr
) == 0)
309 ifr
->ifr_name
[0] = '\0';
316 et_check(int s
, struct ifreq
*ifr
)
318 struct ethtool_drvinfo info
;
320 memset(&info
, 0, sizeof(info
));
321 info
.cmd
= ETHTOOL_GDRVINFO
;
322 ifr
->ifr_data
= (caddr_t
)&info
;
323 if (ioctl(s
, SIOCETHTOOL
, (caddr_t
)ifr
) < 0) {
324 /* print a good diagnostic if not superuser */
326 syserr("siocethtool");
330 if (!strncmp(info
.driver
, "et", 2))
332 else if (!strncmp(info
.driver
, "bcm57", 5))