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
;
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("0x%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("0x%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)
212 #ifdef IOV_ET_POWER_SAVE_MODE
213 if (strcmp(av
[optind
], "switch_mode") == 0) {
218 if (ac
== (optind
+ 1)) {
222 } else if (ac
== (optind
+ 2)) {
224 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0);
225 all
= (int)(vecarg
[0] == VECLEN
);
227 if (ac
!= (optind
+ 3))
230 vecarg
[0] = strtoul(av
[optind
+ 1], NULL
, 0);
231 vecarg
[1] = strtoul(av
[optind
+ 2], NULL
, 0);
238 var
.len
= VECLEN
* sizeof(int);
239 var
.cmd
= IOV_ET_POWER_SAVE_MODE
;
242 ifr
.ifr_data
= (caddr_t
) &var
;
243 if (ioctl(s
, SIOCSETGETVAR
, (caddr_t
)&ifr
) < 0)
244 syserr("etcswitchmode");
248 printf("phy power save mode for all phys:"
249 " %d %d %d %d %d \n",
250 vecarg
[0], vecarg
[1], vecarg
[2],
251 vecarg
[3], vecarg
[4]);
253 printf("phy power save mode for phy %d mode %d\n",
254 vecarg
[0], vecarg
[1]);
257 #endif // IOV_ET_POWER_SAVE_MODE
269 fprintf(stderr
, "usage: %s [ [ -a | -i ] interface ] and one of:\n"
274 "\tmsglevel <bitvec> (error=1, trace=2, prhdr=4, prpkt=8)\n"
275 "\tpromisc <0 or 1>\n"
277 "\tspeed <auto, 10half, 10full, 100half, 100full, 1000full>\n"
278 "\tphyrd [<phyaddr>] <reg>\n"
279 "\tphywr [<phyaddr>] <reg> <val>\n"
280 "\trobord <page> <reg>\n"
281 "\trobowr <page> <reg> <val>\n"
282 #ifdef IOV_ET_POWER_SAVE_MODE
283 "\tswitch_mode <phy> <mode> (mode 0, 1, 2, 3)\n"
291 et_find(int s
, struct ifreq
*ifr
)
293 char proc_net_dev
[] = "/proc/net/dev";
295 char buf
[512], *c
, *name
;
297 ifr
->ifr_name
[0] = '\0';
299 /* eat first two lines */
300 if (!(fp
= fopen(proc_net_dev
, "r")) ||
301 !fgets(buf
, sizeof(buf
), fp
) ||
302 !fgets(buf
, sizeof(buf
), fp
))
305 while (fgets(buf
, sizeof(buf
), fp
)) {
309 if (!(name
= strsep(&c
, ":")))
311 strncpy(ifr
->ifr_name
, name
, IFNAMSIZ
);
312 if (et_check(s
, ifr
) == 0)
314 ifr
->ifr_name
[0] = '\0';
321 et_check(int s
, struct ifreq
*ifr
)
323 struct ethtool_drvinfo info
;
325 memset(&info
, 0, sizeof(info
));
326 info
.cmd
= ETHTOOL_GDRVINFO
;
327 ifr
->ifr_data
= (caddr_t
)&info
;
328 if (ioctl(s
, SIOCETHTOOL
, (caddr_t
)ifr
) < 0) {
329 /* print a good diagnostic if not superuser */
331 syserr("siocethtool");
335 if (!strncmp(info
.driver
, "et", 2))
337 else if (!strncmp(info
.driver
, "bcm57", 5))