2 * et driver ioctl swiss army knife command.
4 * Copyright (C) 2010, 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>
31 #include <linux/types.h>
33 typedef u_int64_t u64
;
34 typedef u_int32_t u32
;
35 typedef u_int16_t u16
;
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
;
67 if (av
[1][0] == '-') {
68 if ((av
[1][1] != 'a') && (av
[1][1] != 'i'))
76 if ((s
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0)
80 strncpy(ifr
.ifr_name
, interface
, sizeof (ifr
.ifr_name
));
85 fprintf(stderr
, "et interface not found\n");
89 if (strcmp(av
[optind
], "up") == 0) {
90 if (ioctl(s
, SIOCSETCUP
, (caddr_t
)&ifr
) < 0)
92 } else if (strcmp(av
[optind
], "down") == 0) {
93 if (ioctl(s
, SIOCSETCDOWN
, (caddr_t
)&ifr
) < 0)
95 } else if (strcmp(av
[optind
], "loop") == 0) {
96 if (optind
>= (ac
-1))
98 arg
= atoi(av
[optind
+ 1]);
99 ifr
.ifr_data
= (caddr_t
) &arg
;
100 if (ioctl(s
, SIOCSETCLOOP
, (caddr_t
)&ifr
) < 0)
102 } else if (strcmp(av
[optind
], "dump") == 0) {
104 if (ioctl(s
, SIOCGETCDUMP
, (caddr_t
)&ifr
) < 0)
107 } else if (strcmp(av
[optind
], "msglevel") == 0) {
108 if (optind
>= (ac
-1))
110 arg
= strtol(av
[optind
+ 1], &endptr
, 0);
111 ifr
.ifr_data
= (caddr_t
) &arg
;
112 if (ioctl(s
, SIOCSETCSETMSGLEVEL
, (caddr_t
)&ifr
) < 0)
113 syserr("etcsetmsglevel");
114 } else if (strcmp(av
[optind
], "promisc") == 0) {
115 if (optind
>= (ac
-1))
117 arg
= atoi(av
[optind
+ 1]);
118 ifr
.ifr_data
= (caddr_t
) &arg
;
119 if (ioctl(s
, SIOCSETCPROMISC
, (caddr_t
)&ifr
) < 0)
120 syserr("etcpromisc");
121 } else if (strcmp(av
[optind
], "qos") == 0) {
122 if (optind
>= (ac
-1))
124 arg
= atoi(av
[optind
+ 1]);
125 ifr
.ifr_data
= (caddr_t
) &arg
;
126 if (ioctl(s
, SIOCSETCQOS
, (caddr_t
)&ifr
) < 0)
128 } else if (strcmp(av
[optind
], "speed") == 0) {
129 if (optind
>= (ac
-1))
131 if (strcmp(av
[optind
+1], "auto") == 0)
133 else if (strcmp(av
[optind
+1], "10half") == 0)
135 else if (strcmp(av
[optind
+1], "10full") == 0)
137 else if (strcmp(av
[optind
+1], "100half") == 0)
139 else if (strcmp(av
[optind
+1], "100full") == 0)
141 else if (strcmp(av
[optind
+1], "1000full") == 0)
146 ifr
.ifr_data
= (caddr_t
) &arg
;
147 if (ioctl(s
, SIOCSETCSPEED
, (caddr_t
)&ifr
) < 0)
150 else if (strcmp(av
[optind
], "phyrd") == 0) {
153 if ((ac
< (optind
+ 2)) || (ac
> (optind
+ 3))) {
155 } else if (ac
== (optind
+ 3)) {
156 /* PHY address provided */
157 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0) << 16;;
158 vecarg
[0] |= strtoul(av
[optind
+ 2], NULL
, 0) & 0xffff;
159 cmd
= SIOCGETCPHYRD2
;
161 /* "My" PHY address implied */
162 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0);
165 ifr
.ifr_data
= (caddr_t
) vecarg
;
166 if (ioctl(s
, cmd
, (caddr_t
)&ifr
) < 0)
169 printf("000x%04x\n", vecarg
[1]);
170 } else if (strcmp(av
[optind
], "phywr") == 0) {
173 if ((ac
< (optind
+ 3)) || (ac
> (optind
+ 4))) {
175 } else if (ac
== (optind
+ 4)) {
176 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0) << 16;;
177 vecarg
[0] |= strtoul(av
[optind
+ 2], NULL
, 0) & 0xffff;
178 vecarg
[1] = strtoul(av
[optind
+ 3], NULL
, 0);
179 cmd
= SIOCSETCPHYWR2
;
181 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0);
182 vecarg
[1] = strtoul(av
[optind
+ 2], NULL
, 0);
185 ifr
.ifr_data
= (caddr_t
) vecarg
;
186 if (ioctl(s
, cmd
, (caddr_t
)&ifr
) < 0)
188 } else if (strcmp(av
[optind
], "robord") == 0) {
189 if (ac
!= (optind
+ 3))
192 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0) << 16;;
193 vecarg
[0] |= strtoul(av
[optind
+ 2], NULL
, 0) & 0xffff;
195 ifr
.ifr_data
= (caddr_t
) vecarg
;
196 if (ioctl(s
, SIOCGETCROBORD
, (caddr_t
)&ifr
) < 0)
199 printf("000x%04x\n", vecarg
[1]);
200 } else if (strcmp(av
[optind
], "robowr") == 0) {
201 if (ac
!= (optind
+ 4))
204 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0) << 16;;
205 vecarg
[0] |= strtoul(av
[optind
+ 2], NULL
, 0) & 0xffff;
206 vecarg
[1] = strtoul(av
[optind
+ 3], NULL
, 0);
208 ifr
.ifr_data
= (caddr_t
) vecarg
;
209 if (ioctl(s
, SIOCSETCROBOWR
, (caddr_t
)&ifr
) < 0)
211 #ifdef IOV_ET_CLEAR_DUMP
212 } else if (strcmp(av
[optind
], "clear_dump") == 0) {
215 if ((ac
> (optind
+ 2)))
219 var
.cmd
= IOV_ET_CLEAR_DUMP
;
221 ifr
.ifr_data
= (caddr_t
) &var
;
222 if (ioctl(s
, SIOCSETGETVAR
, (caddr_t
)&ifr
) < 0)
223 syserr("etccleardump");
226 #ifdef IOV_ET_POWER_SAVE_MODE
227 if (strcmp(av
[optind
], "switch_mode") == 0) {
232 if (ac
== (optind
+ 1)) {
236 } else if (ac
== (optind
+ 2)) {
238 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0);
239 all
= (int)(vecarg
[0] == VECLEN
);
241 if (ac
!= (optind
+ 3))
244 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0);
245 vecarg
[1] = strtoul(av
[optind
+ 2], NULL
, 0);
252 var
.len
= VECLEN
* sizeof(int);
253 var
.cmd
= IOV_ET_POWER_SAVE_MODE
;
256 ifr
.ifr_data
= (caddr_t
) &var
;
257 if (ioctl(s
, SIOCSETGETVAR
, (caddr_t
)&ifr
) < 0)
258 syserr("etcswitchmode");
262 printf("phy power save mode for all phys:"
263 " %d %d %d %d %d \n",
264 vecarg
[0], vecarg
[1], vecarg
[2],
265 vecarg
[3], vecarg
[4]);
267 printf("phy power save mode for phy %d mode %d\n",
268 vecarg
[0], vecarg
[1]);
271 #endif // IOV_ET_POWER_SAVE_MODE
283 fprintf(stderr
, "usage: %s [ [ -a | -i ] interface ] and one of:\n"
289 "\tmsglevel <bitvec> (error=1, trace=2, prhdr=4, prpkt=8)\n"
290 "\tpromisc <0 or 1>\n"
292 "\tspeed <auto, 10half, 10full, 100half, 100full, 1000full>\n"
293 "\tphyrd [<phyaddr>] <reg>\n"
294 "\tphywr [<phyaddr>] <reg> <val>\n"
295 "\trobord <page> <reg>\n"
296 "\trobowr <page> <reg> <val>\n"
297 #ifdef IOV_ET_POWER_SAVE_MODE
298 "\tswitch_mode <phy> <mode> (mode 0, 1, 2, 3)\n"
306 et_find(int s
, struct ifreq
*ifr
)
308 char proc_net_dev
[] = "/proc/net/dev";
310 char buf
[512], *c
, *name
;
312 ifr
->ifr_name
[0] = '\0';
314 /* eat first two lines */
315 if (!(fp
= fopen(proc_net_dev
, "r")) ||
316 !fgets(buf
, sizeof(buf
), fp
) ||
317 !fgets(buf
, sizeof(buf
), fp
))
320 while (fgets(buf
, sizeof(buf
), fp
)) {
324 if (!(name
= strsep(&c
, ":")))
326 strncpy(ifr
->ifr_name
, name
, IFNAMSIZ
);
327 if (et_check(s
, ifr
) == 0)
329 ifr
->ifr_name
[0] = '\0';
336 et_check(int s
, struct ifreq
*ifr
)
338 struct ethtool_drvinfo info
;
340 memset(&info
, 0, sizeof(info
));
341 info
.cmd
= ETHTOOL_GDRVINFO
;
342 ifr
->ifr_data
= (caddr_t
)&info
;
343 if (ioctl(s
, SIOCETHTOOL
, (caddr_t
)ifr
) < 0) {
344 /* print a good diagnostic if not superuser */
346 syserr("siocethtool");
350 if (!strncmp(info
.driver
, "et", 2))
352 else if (!strncmp(info
.driver
, "bcm57", 5))