]> git.ipfire.org Git - ipfire-3.x.git/blob - net-tools/mii-diag.c
Merge remote-tracking branch 'ms/u-boot'
[ipfire-3.x.git] / net-tools / mii-diag.c
1 /* Mode: C;
2 * mii-diag.c: Examine and set the MII registers of a network interfaces.
3
4 Usage: mii-diag [-vw] interface.
5
6 This program reads and writes the Media Independent Interface (MII)
7 management registers on network transceivers. The registers control
8 and report network link settings and errors. Examples are link speed,
9 duplex, capabilities advertised to the link partner, status LED
10 indications and link error counters.
11
12 Notes:
13 The compile-command is at the end of this source file.
14 This program works with drivers that implement MII ioctl() calls.
15
16 Written/copyright 1997-2003 by Donald Becker <becker@scyld.com>
17
18 This program is free software; you can redistribute it
19 and/or modify it under the terms of the GNU General Public
20 License as published by the Free Software Foundation.
21
22 The author may be reached as becker@scyld.com, or C/O
23 Scyld Computing Corporation
24 914 Bay Ridge Road, Suite 220
25 Annapolis MD 21403
26
27 References
28 http://scyld.com/expert/mii-status.html
29 http://scyld.com/expert/NWay.html
30 http://www.national.com/pf/DP/DP83840.html
31 */
32
33 static char version[] =
34 "mii-diag.c:v2.11 3/21/2005 Donald Becker (becker@scyld.com)\n"
35 " http://www.scyld.com/diag/index.html\n";
36
37 static const char usage_msg[] =
38 "Usage: %s [--help] [-aDfrRvVw] [-AF <speed+duplex>] [--watch] <interface>.\n";
39 static const char long_usage_msg[] =
40 "Usage: %s [-aDfrRvVw] [-AF <speed+duplex>] [--watch] <interface>.\n\
41 \n\
42 This program configures and monitors the transceiver management registers\n\
43 for network interfaces. It uses the Media Independent Interface (MII)\n\
44 standard with additional Linux-specific controls to communicate with the\n\
45 underlying device driver. The MII registers control and report network\n\
46 link settings and errors. Examples are link speed, duplex, capabilities\n\
47 advertised to the link partner, status LED indications and link error\n\
48 counters.\n\
49 \n\
50 The common usage is\n\
51 mii-diag eth0\n\
52 \n\
53 The default interface is \"eth0\".\n\
54 Frequently used options are\n\
55 -A --advertise <speed|setting>\n\
56 -F --fixed-speed <speed>\n\
57 Speed is one of: 100baseT4, 100baseTx, 100baseTx-FD, 100baseTx-HD,\n\
58 10baseT, 10baseT-FD, 10baseT-HD\n\
59 -s --status Return exit status 2 if there is no link beat.\n\
60 \n\
61 Less frequently used options are\n\
62 -a --all-interfaces Show the status all interfaces\n\
63 (Not recommended with options that change settings.)\n\
64 -D --debug\n\
65 -g --read-parameters Get driver-specific parameters.\n\
66 -G --set-parameters PARMS Set driver-specific parameters.\n\
67 Parameters are comma separated, missing parameters retain\n\
68 their previous values.\n\
69 -M --msg-level LEVEL Set the driver message bit map.\n\
70 -p --phy ADDR Set the PHY (MII address) to report.\n\
71 -r --restart Restart the link autonegotiation.\n\
72 -R --reset Reset the transceiver.\n\
73 -v --verbose Report each action taken.\n\
74 -V --version Emit version information.\n\
75 -w --watch Continuously monitor the transceiver and report changes.\n\
76 \n\
77 This command returns success (zero) if the interface information can be\n\
78 read. If the --status option is passed, a zero return means that the\n\
79 interface has link beat.\n\
80 ";
81
82 #include <unistd.h>
83 #include <stdlib.h>
84 #include <stdio.h>
85 #include <ctype.h>
86 #include <string.h>
87 #include <errno.h>
88 #include <fcntl.h>
89 #include <getopt.h>
90 #include <sys/types.h>
91 #include <sys/socket.h>
92 #include <sys/ioctl.h>
93 #include <net/if.h>
94 #ifdef use_linux_libc5
95 #include <linux/if_arp.h>
96 #include <linux/if_ether.h>
97 #endif
98
99 typedef u_int32_t u32;
100 typedef u_int16_t u16;
101 typedef u_int8_t u8;
102
103 #if defined(SIOCGPARAMS) && SIOCGPARAMS != SIOCDEVPRIVATE+3
104 #error Changed definition for SIOCGPARAMS
105 #else
106 #define SIOCGPARAMS (SIOCDEVPRIVATE+3) /* Read operational parameters. */
107 #define SIOCSPARAMS (SIOCDEVPRIVATE+4) /* Set operational parameters. */
108 #endif
109
110 const char shortopts[] = "aA:C:DfF:gG:hmM:p:rRsvVw?";
111 struct option longopts[] = {
112 /* { name has_arg *flag val } */
113 {"all-interfaces", 0, 0, 'a'}, /* Show all interfaces. */
114 {"advertise", 1, 0, 'A'}, /* Change the capabilities advertised. */
115 {"BMCR", 1, 0, 'C'}, /* Set the control register. */
116 {"debug", 0, 0, 'D'}, /* Increase the debug level. */
117 {"force", 0, 0, 'f'}, /* Force the operation. */
118 {"fixed-speed", 1, 0, 'F'}, /* Fixed speed name. */
119 {"read-parameters", 0, 0, 'g'}, /* Show general settings values. */
120 {"set-parameters", 1, 0, 'G'}, /* Write general settings values. */
121 {"help", 0, 0, 'h'}, /* Print a long usage message. */
122 {"monitor", 0, 0, 'm'}, /* Monitor status register. */
123 {"msg-level", 1, 0, 'M'}, /* Set the driver message level. */
124 {"phy", 1, 0, 'p'}, /* Set the PHY (MII address) to report. */
125 {"restart", 0, 0, 'r'}, /* Restart the link negotiation */
126 {"reset", 0, 0, 'R'}, /* Reset the transceiver. */
127 {"status", 0, 0, 's'}, /* Non-zero exit status w/ no link beat. */
128 {"verbose", 0, 0, 'v'}, /* Report each action taken. */
129 {"version", 0, 0, 'V'}, /* Emit version information. */
130 {"watch", 0, 0, 'w'}, /* Constantly monitor the port. */
131 {"error", 0, 0, '?'}, /* Return the error message. */
132 { 0, 0, 0, 0 }
133 };
134
135 /* Usually in libmii.c, but trivial substitions are below. */
136 extern int show_mii_details(long ioaddr, int phy_id);
137 extern void monitor_mii(long ioaddr, int phy_id);
138 int show_mii_details(long ioaddr, int phy_id) __attribute__((weak));
139 void monitor_mii(long ioaddr, int phy_id) __attribute__((weak));
140
141
142 /* Command-line flags. */
143 unsigned int opt_a = 0, /* Show-all-interfaces flag. */
144 opt_f = 0, /* Force the operation. */
145 opt_g = 0,
146 opt_G = 0,
147 verbose = 0, /* Verbose flag. */
148 debug = 0,
149 opt_version = 0,
150 opt_restart = 0,
151 opt_reset = 0,
152 opt_status = 0,
153 opt_watch = 0;
154 static int msg_level = -1;
155 static int set_BMCR = -1;
156 static int nway_advertise = 0;
157 static int fixed_speed = -1;
158 static int override_phy = -1;
159 char *opt_G_string = NULL;
160
161 /* Internal values. */
162 int new_ioctl_nums;
163 int skfd = -1; /* AF_INET socket for ioctl() calls. */
164 struct ifreq ifr;
165
166 int do_one_xcvr(int skfd);
167 int show_basic_mii(long ioaddr, int phy_id);
168 int mdio_read(int skfd, int phy_id, int location);
169 void mdio_write(int skfd, int phy_id, int location, int value);
170 static int parse_advertise(const char *capabilities);
171 static void monitor_status(long ioaddr, int phy_id);
172
173
174 int
175 main(int argc, char **argv)
176 {
177 int c, errflag = 0;
178 char **spp, *ifname;
179 char *progname = rindex(argv[0], '/') ? rindex(argv[0], '/')+1 : argv[0];
180
181 while ((c = getopt_long(argc, argv, shortopts, longopts, 0)) != EOF)
182 switch (c) {
183 case 'a': opt_a++; break;
184 case 'A': nway_advertise |= parse_advertise(optarg);
185 if (nway_advertise == -1) errflag++;
186 break;
187 case 'C': set_BMCR = strtoul(optarg, NULL, 16); break;
188 case 'D': debug++; break;
189 case 'f': opt_f++; break;
190 case 'F': fixed_speed = parse_advertise(optarg);
191 if (fixed_speed == -1) errflag++;
192 break;
193 case 'g': opt_g++; break;
194 case 'G': opt_G++; opt_G_string = strdup(optarg); break;
195 case 'm': opt_watch++; opt_status++; break;
196 case 'M': msg_level = strtoul(optarg, NULL, 0); break;
197 case 'h': fprintf(stderr, long_usage_msg, progname); return 0;
198 case 'p': override_phy = atoi(optarg); break;
199 case 'r': opt_restart++; break;
200 case 'R': opt_reset++; break;
201 case 's': opt_status++; break;
202 case 'v': verbose++; break;
203 case 'V': opt_version++; break;
204 case 'w': opt_watch++; break;
205 case '?': errflag++; break;
206 }
207 if (errflag) {
208 fprintf(stderr, usage_msg, progname);
209 return 2;
210 }
211
212 if (verbose || opt_version)
213 printf(version);
214
215 /* Open a basic socket. */
216 if ((skfd = socket(AF_INET, SOCK_DGRAM,0)) < 0) {
217 perror("socket");
218 return 1;
219 }
220
221 if (debug)
222 fprintf(stderr, "DEBUG: argc=%d, optind=%d and argv[optind] is %s.\n",
223 argc, optind, argv[optind]);
224
225 /* No remaining args means show all interfaces. */
226 if (optind == argc) {
227 ifname = "eth0";
228 fprintf(stderr, "Using the default interface 'eth0'.\n");
229 } else {
230 /* Copy the interface name. */
231 spp = argv + optind;
232 ifname = *spp++;
233 }
234
235 if (ifname == NULL) {
236 ifname = "eth0";
237 fprintf(stderr, "Using the default interface 'eth0'.\n");
238 }
239
240 /* Verify that the interface supports the ioctl(), and if
241 it is using the new or old SIOCGMIIPHY value (grrr...).
242 */
243 {
244 u16 *data = (u16 *)(&ifr.ifr_data);
245
246 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
247 data[0] = 0;
248
249 if (ioctl(skfd, 0x8947, &ifr) >= 0) {
250 new_ioctl_nums = 1;
251 } else if (ioctl(skfd, SIOCDEVPRIVATE, &ifr) >= 0) {
252 new_ioctl_nums = 0;
253 } else {
254 fprintf(stderr, "SIOCGMIIPHY on %s failed: %s\n", ifname,
255 strerror(errno));
256 (void) close(skfd);
257 return 1;
258 }
259 if (verbose)
260 printf(" Using the %s SIOCGMIIPHY value on PHY %d "
261 "(BMCR 0x%4.4x).\n",
262 new_ioctl_nums ? "new" : "old", data[0], data[3]);
263 }
264
265 do_one_xcvr(skfd);
266
267 (void) close(skfd);
268 return 0;
269 }
270
271 int do_one_xcvr(int skfd)
272 {
273 u16 *data = (u16 *)(&ifr.ifr_data);
274 u32 *data32 = (u32 *)(&ifr.ifr_data);
275 unsigned phy_id = data[0];
276
277 if (override_phy >= 0) {
278 printf("Using the specified MII PHY index %d.\n", override_phy);
279 phy_id = override_phy;
280 }
281
282 if (opt_g || opt_G || msg_level >= 0) {
283 if (ioctl(skfd, SIOCGPARAMS, &ifr) < 0) {
284 fprintf(stderr, "SIOCGPARAMS on %s failed: %s\n", ifr.ifr_name,
285 strerror(errno));
286 return -1;
287 }
288 }
289 if (opt_g) {
290 int i;
291 printf("Driver general parameter settings:");
292 for (i = 0; i*sizeof(u32) < sizeof(ifr.ifr_ifru); i++) {
293 printf(" %d", data32[i]);
294 }
295 printf(".\n");
296 }
297 if (opt_G) {
298 /* Set up to four arbitrary driver parameters from the -G parameter.
299 The format is comma separated integers, with a missing element
300 retaining the previous value.
301 */
302 char *str = opt_G_string;
303 int i;
304 for (i = 0; str && i < 4; i++) {
305 char *endstr;
306 u32 newval = strtol(str, &endstr, 0);
307 if (debug)
308 printf(" parse string '%s' value %d end '%s'.\n",
309 str, newval, endstr);
310 if (str == endstr) {
311 if (endstr[0] == ',') /* No parameter */
312 str = endstr+1;
313 else {
314 fprintf(stderr, "Invalid driver parameter '%s'.\n", str);
315 str = index(str, ',');
316 }
317 } else if (endstr[0] == ',') {
318 data32[i] = newval;
319 str = endstr + 1;
320 } else if (endstr[0] == 0) {
321 data32[i] = newval;
322 break;
323 }
324 }
325 printf("Setting new driver general parameters:");
326 for (i = 0; i*sizeof(u32) < sizeof(ifr.ifr_ifru); i++) {
327 printf(" %d", data32[i]);
328 }
329 printf(".\n");
330 if (ioctl(skfd, SIOCSPARAMS, &ifr) < 0) {
331 fprintf(stderr, "SIOCSPARAMS on %s failed: %s\n", ifr.ifr_name,
332 strerror(errno));
333 return -1;
334 }
335 }
336 if (msg_level >= 0) {
337 data32[0] = msg_level;
338 if (ioctl(skfd, SIOCSPARAMS, &ifr) < 0) {
339 fprintf(stderr, "SIOCSPARAMS on %s failed: %s\n", ifr.ifr_name,
340 strerror(errno));
341 return -1;
342 }
343 }
344
345 if (opt_reset) {
346 printf("Resetting the transceiver...\n");
347 mdio_write(skfd, phy_id, 0, 0x8000);
348 }
349 /* Note: PHY addresses > 32 are pseudo-MII devices, usually built-in. */
350 if (phy_id < 64 && nway_advertise > 0) {
351 printf(" Setting the media capability advertisement register of "
352 "PHY #%d to 0x%4.4x.\n", phy_id, nway_advertise | 1);
353 mdio_write(skfd, phy_id, 4, nway_advertise | 1);
354 mdio_write(skfd, phy_id, 0, 0x1000);
355 }
356
357 if (opt_restart) {
358 printf("Restarting negotiation...\n");
359 mdio_write(skfd, phy_id, 0, 0x0000);
360 mdio_write(skfd, phy_id, 0, 0x1200);
361 }
362 /* To force 100baseTx-HD do mdio_write(skfd, phy_id, 0, 0x2000); */
363 if (fixed_speed >= 0) {
364 int reg0_val = 0;
365 if (fixed_speed & 0x0180) /* 100mpbs */
366 reg0_val |= 0x2000;
367 if ((fixed_speed & 0x0140) && /* A full duplex type and */
368 ! (fixed_speed & 0x0820)) /* no half duplex types. */
369 reg0_val |= 0x0100;
370 printf("Setting the speed to \"fixed\", Control register %4.4x.\n",
371 reg0_val);
372 mdio_write(skfd, phy_id, 0, reg0_val);
373 }
374 if (set_BMCR >= 0) {
375 printf("Setting the Basic Mode Control Register to 0x%4.4x.\n",
376 set_BMCR);
377 mdio_write(skfd, phy_id, 0, set_BMCR);
378 }
379
380 if (opt_watch && opt_status)
381 monitor_status(skfd, phy_id);
382
383 show_basic_mii(skfd, phy_id);
384 #ifdef LIBMII
385 if (verbose)
386 show_mii_details(skfd, phy_id);
387 #else
388 if (verbose || debug) {
389 int mii_reg, mii_val;
390 printf(" MII PHY #%d transceiver registers:", phy_id);
391 for (mii_reg = 0; mii_reg < 32; mii_reg++) {
392 mii_val = mdio_read(skfd, phy_id, mii_reg);
393 printf("%s %4.4x", (mii_reg % 8) == 0 ? "\n " : "",
394 mii_val);
395 }
396 printf("\n");
397 }
398 #endif
399
400 if (opt_watch)
401 monitor_mii(skfd, phy_id);
402 if (opt_status &&
403 (mdio_read(skfd, phy_id, 1) & 0x0004) == 0)
404 exit(2);
405 return 0;
406 }
407
408 int mdio_read(int skfd, int phy_id, int location)
409 {
410 u16 *data = (u16 *)(&ifr.ifr_data);
411
412 data[0] = phy_id;
413 data[1] = location;
414
415 if (ioctl(skfd, new_ioctl_nums ? 0x8948 : SIOCDEVPRIVATE+1, &ifr) < 0) {
416 fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name,
417 strerror(errno));
418 return -1;
419 }
420 return data[3];
421 }
422
423 void mdio_write(int skfd, int phy_id, int location, int value)
424 {
425 u16 *data = (u16 *)(&ifr.ifr_data);
426
427 data[0] = phy_id;
428 data[1] = location;
429 data[2] = value;
430
431 if (ioctl(skfd, new_ioctl_nums ? 0x8949 : SIOCDEVPRIVATE+2, &ifr) < 0) {
432 fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name,
433 strerror(errno));
434 }
435 }
436
437 /* Parse the command line argument for advertised capabilities. */
438 static int parse_advertise(const char *capabilities)
439 {
440 const char *mtypes[] = {
441 "100baseT4", "100baseTx", "100baseTx-FD", "100baseTx-HD",
442 "10baseT", "10baseT-FD", "10baseT-HD", 0,
443 };
444 char *endptr;
445 int cap_map[] = { 0x0200, 0x0180, 0x0100, 0x0080, 0x0060, 0x0040, 0x0020,};
446 int i;
447 if ( ! capabilities) {
448 fprintf(stderr, "You passed -A 'NULL'. You must provide a media"
449 " list to advertise!\n");
450 return -1;
451 }
452 if (debug)
453 fprintf(stderr, "Advertise string is '%s'.\n", capabilities);
454 for (i = 0; mtypes[i]; i++)
455 if (strcasecmp(mtypes[i], capabilities) == 0)
456 return cap_map[i];
457 if ((i = strtol(capabilities, &endptr, 16)) <= 0xffff && endptr[0] == 0)
458 return i;
459 fprintf(stderr, "Invalid media advertisement value '%s'.\n"
460 " Either pass a numeric value or one of the following names:\n",
461 capabilities);
462 for (i = 0; mtypes[i]; i++)
463 fprintf(stderr, " %-14s %3.3x\n", mtypes[i], cap_map[i]);
464 return -1;
465 }
466
467 /* Trivial versions if we don't link against libmii.c */
468 static const char *media_names[] = {
469 "10baseT", "10baseT-FD", "100baseTx", "100baseTx-FD", "100baseT4",
470 "Flow-control", 0,
471 };
472 /* Various non-good bits in the command register. */
473 static const char *bmcr_bits[] = {
474 " Internal Collision-Test enabled!\n", "", /* 0x0080,0x0100 */
475 " Restarted auto-negotiation in progress!\n",
476 " Transceiver isolated from the MII!\n",
477 " Transceiver powered down!\n", "", "",
478 " Transceiver in loopback mode!\n",
479 " Transceiver currently being reset!\n",
480 };
481
482 int show_basic_mii(long ioaddr, int phy_id)
483 {
484 int mii_reg, i;
485 u16 mii_val[32];
486 u16 bmcr, bmsr, new_bmsr, nway_advert, lkpar;
487
488 for (mii_reg = 0; mii_reg < 8; mii_reg++)
489 mii_val[mii_reg] = mdio_read(ioaddr, phy_id, mii_reg);
490 if ( ! verbose) {
491 printf("Basic registers of MII PHY #%d: ", phy_id);
492 for (mii_reg = 0; mii_reg < 8; mii_reg++)
493 printf(" %4.4x", mii_val[mii_reg]);
494 printf(".\n");
495 }
496
497 if (mii_val[0] == 0xffff || mii_val[1] == 0x0000) {
498 printf(" No MII transceiver present!.\n");
499 if (! opt_f) {
500 printf(" Use '--force' to view the information anyway.\n");
501 return -1;
502 }
503 }
504 /* Descriptive rename. */
505 bmcr = mii_val[0];
506 bmsr = mii_val[1];
507 nway_advert = mii_val[4];
508 lkpar = mii_val[5];
509
510 if (lkpar & 0x4000) {
511 int negotiated = nway_advert & lkpar & 0x3e0;
512 int max_capability = 0;
513 /* Scan for the highest negotiated capability, highest priority
514 (100baseTx-FDX) to lowest (10baseT-HDX). */
515 int media_priority[] = {8, 9, 7, 6, 5}; /* media_names[i-5] */
516 printf(" The autonegotiated capability is %4.4x.\n", negotiated);
517 for (i = 0; media_priority[i]; i++)
518 if (negotiated & (1 << media_priority[i])) {
519 max_capability = media_priority[i];
520 break;
521 }
522 if (max_capability)
523 printf("The autonegotiated media type is %s.\n",
524 media_names[max_capability - 5]);
525 else
526 printf("No common media type was autonegotiated!\n"
527 "This is extremely unusual and typically indicates a "
528 "configuration error.\n" "Perhaps the advertised "
529 "capability set was intentionally limited.\n");
530 }
531 printf(" Basic mode control register 0x%4.4x:", bmcr);
532 if (bmcr & 0x1000)
533 printf(" Auto-negotiation enabled.\n");
534 else
535 printf(" Auto-negotiation disabled, with\n"
536 " Speed fixed at 10%s mbps, %s-duplex.\n",
537 bmcr & 0x2000 ? "0" : "",
538 bmcr & 0x0100 ? "full":"half");
539 for (i = 0; i < 9; i++)
540 if (bmcr & (0x0080<<i))
541 printf(bmcr_bits[i]);
542
543 new_bmsr = mdio_read(ioaddr, phy_id, 1);
544 if ((bmsr & 0x0016) == 0x0004)
545 printf( " You have link beat, and everything is working OK.\n");
546 else
547 printf(" Basic mode status register 0x%4.4x ... %4.4x.\n"
548 " Link status: %sestablished.\n",
549 bmsr, new_bmsr,
550 bmsr & 0x0004 ? "" :
551 (new_bmsr & 0x0004) ? "previously broken, but now re" : "not ");
552 if (verbose) {
553 printf(" This transceiver is capable of ");
554 if (bmsr & 0xF800) {
555 for (i = 15; i >= 11; i--)
556 if (bmsr & (1<<i))
557 printf(" %s", media_names[i-11]);
558 } else
559 printf("<Warning! No media capabilities>");
560 printf(".\n");
561 printf(" %s to perform Auto-negotiation, negotiation %scomplete.\n",
562 bmsr & 0x0008 ? "Able" : "Unable",
563 bmsr & 0x0020 ? "" : "not ");
564 }
565
566 if (bmsr & 0x0010)
567 printf(" Remote fault detected!\n");
568 if (bmsr & 0x0002)
569 printf(" *** Link Jabber! ***\n");
570
571 if (lkpar & 0x4000) {
572 printf(" Your link partner advertised %4.4x:",
573 lkpar);
574 for (i = 5; i >= 0; i--)
575 if (lkpar & (0x20<<i))
576 printf(" %s", media_names[i]);
577 printf("%s.\n", lkpar & 0x0400 ? ", w/ 802.3X flow control" : "");
578 } else if (lkpar & 0x00A0)
579 printf(" Your link partner is generating %s link beat (no"
580 " autonegotiation).\n",
581 lkpar & 0x0080 ? "100baseTx" : "10baseT");
582 else if ( ! (bmcr & 0x1000))
583 printf(" Link partner information is not exchanged when in"
584 " fixed speed mode.\n");
585 else if ( ! (new_bmsr & 0x004))
586 ; /* If no partner, do not report status. */
587 else if (lkpar == 0x0001 || lkpar == 0x0000) {
588 printf(" Your link partner does not do autonegotiation, and this "
589 "transceiver type\n does not report the sensed link "
590 "speed.\n");
591 } else
592 printf(" Your link partner is strange, status %4.4x.\n", lkpar);
593
594 printf(" End of basic transceiver information.\n\n");
595 return 0;
596 }
597
598 static void monitor_status(long ioaddr, int phy_id)
599 {
600 unsigned int baseline_1 = 0x55555555; /* Always show initial status. */
601
602 while (1) {
603 unsigned int new_1 = mdio_read(ioaddr, phy_id, 1);
604 if (new_1 != baseline_1) {
605 printf("%-12s 0x%4.4x 0x%4.4x\n",
606 new_1 & 0x04 ? (new_1==0xffff ? "unknown" : "up") :
607 new_1 & 0x20 ? "negotiating" : "down",
608 new_1, mdio_read(ioaddr, phy_id, 5));
609 fflush(stdout);
610 baseline_1 = new_1;
611 }
612 sleep(1);
613 }
614 }
615
616 int show_mii_details(long ioaddr, int phy_id)
617 {
618 int mii_reg, mii_val;
619 printf(" MII PHY #%d transceiver registers:", phy_id);
620 for (mii_reg = 0; mii_reg < 32; mii_reg++) {
621 mii_val = mdio_read(skfd, phy_id, mii_reg);
622 printf("%s %4.4x", (mii_reg % 8) == 0 ? "\n " : "",
623 mii_val);
624 }
625 printf("\nThis version of 'mii-diag' has not been linked with "
626 "the libmii.c library.\n"
627 " That library provides extended transceiver status reports.\n");
628 return 0;
629 }
630
631 void monitor_mii(long ioaddr, int phy_id)
632 {
633 fprintf(stderr, "\nThis version of 'mii-diag' has not been linked with "
634 "the libmii.c library \n"
635 " required for the media monitor option.\n");
636 }
637
638
639 \f
640 /*
641 * Local variables:
642 * version-control: t
643 * kept-new-versions: 5
644 * c-indent-level: 4
645 * c-basic-offset: 4
646 * tab-width: 4
647 * compile-command: "gcc -Wall -Wstrict-prototypes -O mii-diag.c -DLIBMII libmii.c -o mii-diag"
648 * simple-compile-command: "gcc mii-diag.c -o mii-diag"
649 * End:
650 */