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.13.18.1 2010-07-01 23:24:02 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
;
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)
212 } else if (strcmp(av
[optind
], "clear_dump") == 0) {
213 if ((ac
> (optind
+ 2)))
217 var
.cmd
= IOV_ET_CLEAR_DUMP
;
219 ifr
.ifr_data
= (caddr_t
) &var
;
220 if (ioctl(s
, SIOCSETGETVAR
, (caddr_t
)&ifr
) < 0)
221 syserr("etccleardump");
223 if (strcmp(av
[optind
], "switch_mode") == 0) {
227 if (ac
== (optind
+ 1)) {
231 } else if (ac
== (optind
+ 2)) {
233 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0);
234 all
= (int)(vecarg
[0] == VECLEN
);
236 if (ac
!= (optind
+ 3))
239 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0);
240 vecarg
[1] = strtoul(av
[optind
+ 2], NULL
, 0);
247 var
.len
= VECLEN
* sizeof(int);
248 var
.cmd
= IOV_ET_POWER_SAVE_MODE
;
251 ifr
.ifr_data
= (caddr_t
) &var
;
252 if (ioctl(s
, SIOCSETGETVAR
, (caddr_t
)&ifr
) < 0)
253 syserr("etcswitchmode");
257 printf("phy power save mode for all phys:"
258 " %d %d %d %d %d \n",
259 vecarg
[0], vecarg
[1], vecarg
[2],
260 vecarg
[3], vecarg
[4]);
262 printf("phy power save mode for phy %d mode %d\n",
263 vecarg
[0], vecarg
[1]);
276 fprintf(stderr
, "usage: %s [ [ -a | -i ] interface ] and one of:\n"
282 "\tmsglevel <bitvec> (error=1, trace=2, prhdr=4, prpkt=8)\n"
283 "\tpromisc <0 or 1>\n"
285 "\tspeed <auto, 10half, 10full, 100half, 100full, 1000full>\n"
286 "\tphyrd [<phyaddr>] <reg>\n"
287 "\tphywr [<phyaddr>] <reg> <val>\n"
288 "\trobord <page> <reg>\n"
289 "\trobowr <page> <reg> <val>\n"
290 "\tswitch_mode <phy> <mode> (mode 0, 1, 2, 3)\n"
297 et_find(int s
, struct ifreq
*ifr
)
299 char proc_net_dev
[] = "/proc/net/dev";
301 char buf
[512], *c
, *name
;
303 ifr
->ifr_name
[0] = '\0';
305 /* eat first two lines */
306 if (!(fp
= fopen(proc_net_dev
, "r")) ||
307 !fgets(buf
, sizeof(buf
), fp
) ||
308 !fgets(buf
, sizeof(buf
), fp
))
311 while (fgets(buf
, sizeof(buf
), fp
)) {
315 if (!(name
= strsep(&c
, ":")))
317 strncpy(ifr
->ifr_name
, name
, IFNAMSIZ
);
318 if (et_check(s
, ifr
) == 0)
320 ifr
->ifr_name
[0] = '\0';
327 et_check(int s
, struct ifreq
*ifr
)
329 struct ethtool_drvinfo info
;
331 memset(&info
, 0, sizeof(info
));
332 info
.cmd
= ETHTOOL_GDRVINFO
;
333 ifr
->ifr_data
= (caddr_t
)&info
;
334 if (ioctl(s
, SIOCETHTOOL
, (caddr_t
)ifr
) < 0) {
335 /* print a good diagnostic if not superuser */
337 syserr("siocethtool");
341 if (!strncmp(info
.driver
, "et", 2))
343 else if (!strncmp(info
.driver
, "bcm57", 5))