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