00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 static char version[] =
00034 "mii-diag.c:v2.11 3/21/2005 Donald Becker (becker@scyld.com)\n"
00035 " http://www.scyld.com/diag/index.html\n";
00036
00037 static const char usage_msg[] =
00038 "Usage: %s [--help] [-aDfrRvVw] [-AF <speed+duplex>] [--watch] <interface>.\n";
00039 static const char long_usage_msg[] =
00040 "Usage: %s [-aDfrRvVw] [-AF <speed+duplex>] [--watch] <interface>.\n"
00041 "\n"
00042 " This program configures and monitors the transceiver management registers\n"
00043 " for network interfaces. It uses the Media Independent Interface (MII)\n"
00044 " standard with additional Linux-specific controls to communicate with the\n"
00045 " underlying device driver. The MII registers control and report network\n"
00046 " link settings and errors. Examples are link speed, duplex, capabilities\n"
00047 " advertised to the link partner, status LED indications and link error\n"
00048 " counters.\n"
00049 "\n"
00050 " The common usage is\n"
00051 " mii-diag eth0\n"
00052 "\n"
00053 " The default interface is \"eth0\".\n"
00054 " Frequently used options are\n"
00055 " -A --advertise <speed|setting>\n"
00056 " -F --fixed-speed <speed>\n"
00057 " Speed is one of: 100baseT4, 100baseTx, 100baseTx-FD, 100baseTx-HD,\n"
00058 " 10baseT, 10baseT-FD, 10baseT-HD\n"
00059 " -s --status Return exit status 2 if there is no link beat.\n"
00060 "\n"
00061 " Less frequently used options are\n"
00062 " -a --all-interfaces Show the status all interfaces\n"
00063 " (Not recommended with options that change settings.)\n"
00064 " -D --debug\n"
00065 " -g --read-parameters Get driver-specific parameters.\n"
00066 " -G --set-parameters PARMS Set driver-specific parameters.\n"
00067 " Parameters are comma separated, missing elements retain existing value.\n"
00068 " -M --msg-level LEVEL Set the driver message bit map.\n"
00069 " -p --phy ADDR Set the PHY (MII address) to report.\n"
00070 " -r --restart Restart the link autonegotiation.\n"
00071 " -R --reset Reset the transceiver.\n"
00072 " -v --verbose Report each action taken.\n"
00073 " -V --version Emit version information.\n"
00074 " -w --watch Continuously monitor the transceiver and report changes.\n"
00075 " MII register manipulation options are\n"
00076 " -x --mii-addr ADDR MII register decimal address (to read, if VALUE not present). Must be in the range from '0' to '31' .\n"
00077 " -y --mii-value VALUE write new value to MII register, hex format. Must be used together with ADDR option.\n"
00078 "\n"
00079 " This command returns success (zero) if the interface information can be\n"
00080 " read. If the --status option is passed, a zero return means that the\n"
00081 " interface has link beat.\n";
00082
00083 #include <unistd.h>
00084 #include <stdlib.h>
00085 #include <stdio.h>
00086 #include <ctype.h>
00087 #include <string.h>
00088 #include <errno.h>
00089 #include <fcntl.h>
00090 #include <getopt.h>
00091 #include <sys/types.h>
00092 #include <sys/socket.h>
00093 #include <sys/ioctl.h>
00094 #include <net/if.h>
00095 #ifdef use_linux_libc5
00096 #include <linux/if_arp.h>
00097 #include <linux/if_ether.h>
00098 #endif
00099
00100 typedef u_int32_t u32;
00101 typedef u_int16_t u16;
00102 typedef u_int8_t u8;
00103
00104 #if defined(SIOCGPARAMS) && SIOCGPARAMS != SIOCDEVPRIVATE+3
00105 #error Changed definition for SIOCGPARAMS
00106 #else
00107 #define SIOCGPARAMS (SIOCDEVPRIVATE+3)
00108 #define SIOCSPARAMS (SIOCDEVPRIVATE+4)
00109 #endif
00110
00111 const char shortopts[] = "aA:C:x:y:DfF:gG:hmM:p:rRsvVw?";
00112 struct option longopts[] = {
00113
00114 {"all-interfaces", 0, 0, 'a'},
00115 {"advertise", 1, 0, 'A'},
00116 {"BMCR", 1, 0, 'C'},
00117 {"debug", 0, 0, 'D'},
00118 {"force", 0, 0, 'f'},
00119 {"fixed-speed", 1, 0, 'F'},
00120 {"read-parameters", 0, 0, 'g'},
00121 {"set-parameters", 1, 0, 'G'},
00122 {"mii-addr", 1, 0, 'x'},
00123 {"mii-value", 1, 0, 'y'},
00124 {"help", 0, 0, 'h'},
00125 {"monitor", 0, 0, 'm'},
00126 {"msg-level", 1, 0, 'M'},
00127 {"phy", 1, 0, 'p'},
00128 {"restart", 0, 0, 'r'},
00129 {"reset", 0, 0, 'R'},
00130 {"status", 0, 0, 's'},
00131 {"verbose", 0, 0, 'v'},
00132 {"version", 0, 0, 'V'},
00133 {"watch", 0, 0, 'w'},
00134 {"error", 0, 0, '?'},
00135 { 0, 0, 0, 0 }
00136 };
00137
00138
00139 extern int show_mii_details(long ioaddr, int phy_id);
00140 extern void monitor_mii(long ioaddr, int phy_id);
00141 int show_mii_details(long ioaddr, int phy_id) __attribute__((weak));
00142 void monitor_mii(long ioaddr, int phy_id) __attribute__((weak));
00143
00144
00145
00146 unsigned int opt_a = 0,
00147 opt_f = 0,
00148 opt_g = 0,
00149 opt_G = 0,
00150 verbose = 0,
00151 debug = 0,
00152 opt_version = 0,
00153 opt_restart = 0,
00154 opt_reset = 0,
00155 opt_status = 0,
00156 opt_watch = 0;
00157 static int msg_level = -1;
00158 static int set_BMCR = -1;
00159 static int nway_advertise = 0;
00160 static int fixed_speed = -1;
00161 static int override_phy = -1;
00162 char *opt_G_string = NULL;
00163
00164 #define MII_ACTION_NONE 0
00165 #define MII_ACTION_READ 1
00166 #define MII_ACTION_WRITE 2
00167 static int mii_action = MII_ACTION_NONE;
00168 unsigned mii_addr = 0xFFFF;
00169 unsigned mii_value = 0;
00170 int silent = 0;
00171
00172
00173 int new_ioctl_nums;
00174 int skfd = -1;
00175 struct ifreq ifr;
00176
00177 int do_one_xcvr(int skfd);
00178 int show_basic_mii(long ioaddr, int phy_id);
00179 int mdio_read(int skfd, int phy_id, int location);
00180 void mdio_write(int skfd, int phy_id, int location, int value);
00181 static int parse_advertise(const char *capabilities);
00182 static void monitor_status(long ioaddr, int phy_id);
00183
00184
00185 int
00186 main(int argc, char **argv)
00187 {
00188 int c, errflag = 0;
00189 char **spp, *ifname;
00190 char *progname = rindex(argv[0], '/') ? rindex(argv[0], '/')+1 : argv[0];
00191
00192 while ((c = getopt_long(argc, argv, shortopts, longopts, 0)) != EOF)
00193 switch (c) {
00194 case 'a': opt_a++; break;
00195 case 'A': nway_advertise |= parse_advertise(optarg);
00196 if (nway_advertise == -1) errflag++;
00197 break;
00198 case 'C': set_BMCR = strtoul(optarg, NULL, 16); break;
00199 case 'x': {
00200 mii_addr = strtoul(optarg, NULL, 10);
00201 if(mii_action == MII_ACTION_NONE)
00202 mii_action = MII_ACTION_READ;
00203 break;
00204 }
00205 case 'y': {
00206 printf("y\n");
00207 mii_value = strtoul(optarg, NULL, 16);
00208 mii_action = MII_ACTION_WRITE;
00209 break;
00210 }
00211 case 'D': debug++; break;
00212 case 'f': opt_f++; break;
00213 case 'F': fixed_speed = parse_advertise(optarg);
00214 if (fixed_speed == -1) errflag++;
00215 break;
00216 case 'g': opt_g++; break;
00217 case 'G': opt_G++; opt_G_string = strdup(optarg); break;
00218 case 'm': opt_watch++; opt_status++; break;
00219 case 'M': msg_level = strtoul(optarg, NULL, 0); break;
00220 case 'h': fprintf(stderr, long_usage_msg, progname); return 0;
00221 case 'p': override_phy = atoi(optarg); break;
00222 case 'r': opt_restart++; break;
00223 case 'R': opt_reset++; break;
00224 case 's': opt_status++; break;
00225 case 'v': verbose++; break;
00226 case 'V': opt_version++; break;
00227 case 'w': opt_watch++; break;
00228 case '?': errflag++; break;
00229 }
00230 if (errflag) {
00231 fprintf(stderr, usage_msg, progname);
00232 return 2;
00233 }
00234
00235 if (verbose || opt_version)
00236 printf(version);
00237
00238
00239 if ((skfd = socket(AF_INET, SOCK_DGRAM,0)) < 0) {
00240 perror("socket");
00241 return 1;
00242 }
00243
00244 if (debug)
00245 fprintf(stderr, "DEBUG: argc=%d, optind=%d and argv[optind] is %s.\n",
00246 argc, optind, argv[optind]);
00247
00248
00249 if (optind == argc) {
00250 ifname = "eth0";
00251 fprintf(stderr, "Using the default interface 'eth0'.\n");
00252 } else {
00253
00254 spp = argv + optind;
00255 ifname = *spp++;
00256 }
00257
00258 if (ifname == NULL) {
00259 ifname = "eth0";
00260 fprintf(stderr, "Using the default interface 'eth0'.\n");
00261 }
00262
00263
00264
00265
00266 {
00267 u16 *data = (u16 *)(&ifr.ifr_data);
00268
00269 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
00270 data[0] = 0;
00271
00272 if (ioctl(skfd, 0x8947, &ifr) >= 0) {
00273 new_ioctl_nums = 1;
00274 } else if (ioctl(skfd, SIOCDEVPRIVATE, &ifr) >= 0) {
00275 new_ioctl_nums = 0;
00276 } else {
00277 fprintf(stderr, "SIOCGMIIPHY on %s failed: %s\n", ifname,
00278 strerror(errno));
00279 (void) close(skfd);
00280 return 1;
00281 }
00282 if (verbose)
00283 printf(" Using the %s SIOCGMIIPHY value on PHY %d "
00284 "(BMCR 0x%4.4x).\n",
00285 new_ioctl_nums ? "new" : "old", data[0], data[3]);
00286 }
00287
00288 do_one_xcvr(skfd);
00289
00290 (void) close(skfd);
00291 return 0;
00292 }
00293
00294 int do_one_xcvr(int skfd)
00295 {
00296 u16 *data = (u16 *)(&ifr.ifr_data);
00297 u32 *data32 = (u32 *)(&ifr.ifr_data);
00298 unsigned phy_id = data[0];
00299
00300 if (override_phy >= 0) {
00301 printf("Using the specified MII PHY index %d.\n", override_phy);
00302 phy_id = override_phy;
00303 }
00304
00305 if (opt_g || opt_G || msg_level >= 0) {
00306 if (ioctl(skfd, SIOCGPARAMS, &ifr) < 0) {
00307 fprintf(stderr, "SIOCGPARAMS on %s failed: %s\n", ifr.ifr_name,
00308 strerror(errno));
00309 return -1;
00310 }
00311 }
00312 if (opt_g) {
00313 int i;
00314 printf("Driver general parameter settings:");
00315 for (i = 0; i*sizeof(u32) < sizeof(ifr.ifr_ifru); i++) {
00316 printf(" %d", data32[i]);
00317 }
00318 printf(".\n");
00319 }
00320 if (opt_G) {
00321
00322
00323
00324
00325 char *str = opt_G_string;
00326 int i;
00327 for (i = 0; str && i < 4; i++) {
00328 char *endstr;
00329 u32 newval = strtol(str, &endstr, 0);
00330 if (debug)
00331 printf(" parse string '%s' value %d end '%s'.\n",
00332 str, newval, endstr);
00333 if (str == endstr) {
00334 if (endstr[0] == ',')
00335 str = endstr+1;
00336 else {
00337 fprintf(stderr, "Invalid driver parameter '%s'.\n", str);
00338 str = index(str, ',');
00339 }
00340 } else if (endstr[0] == ',') {
00341 data32[i] = newval;
00342 str = endstr + 1;
00343 } else if (endstr[0] == 0) {
00344 data32[i] = newval;
00345 break;
00346 }
00347 }
00348 printf("Setting new driver general parameters:");
00349 for (i = 0; i*sizeof(u32) < sizeof(ifr.ifr_ifru); i++) {
00350 printf(" %d", data32[i]);
00351 }
00352 printf(".\n");
00353 if (ioctl(skfd, SIOCSPARAMS, &ifr) < 0) {
00354 fprintf(stderr, "SIOCSPARAMS on %s failed: %s\n", ifr.ifr_name,
00355 strerror(errno));
00356 return -1;
00357 }
00358 }
00359 if (msg_level >= 0) {
00360 data32[0] = msg_level;
00361 if (ioctl(skfd, SIOCSPARAMS, &ifr) < 0) {
00362 fprintf(stderr, "SIOCSPARAMS on %s failed: %s\n", ifr.ifr_name,
00363 strerror(errno));
00364 return -1;
00365 }
00366 }
00367
00368 if (opt_reset) {
00369 printf("Resetting the transceiver...\n");
00370 mdio_write(skfd, phy_id, 0, 0x8000);
00371 }
00372
00373 if (phy_id < 64 && nway_advertise > 0) {
00374 printf(" Setting the media capability advertisement register of "
00375 "PHY #%d to 0x%4.4x.\n", phy_id, nway_advertise | 1);
00376 mdio_write(skfd, phy_id, 4, nway_advertise | 1);
00377 mdio_write(skfd, phy_id, 0, 0x1000);
00378 }
00379
00380 if (opt_restart) {
00381 printf("Restarting negotiation...\n");
00382 mdio_write(skfd, phy_id, 0, 0x0000);
00383 mdio_write(skfd, phy_id, 0, 0x1200);
00384 }
00385
00386 if (fixed_speed >= 0) {
00387 int reg0_val = 0;
00388 if (fixed_speed & 0x0180)
00389 reg0_val |= 0x2000;
00390 if ((fixed_speed & 0x0140) &&
00391 ! (fixed_speed & 0x0820))
00392 reg0_val |= 0x0100;
00393 printf("Setting the speed to \"fixed\", Control register %4.4x.\n",
00394 reg0_val);
00395 mdio_write(skfd, phy_id, 0, reg0_val);
00396 }
00397 if (mii_action != MII_ACTION_NONE) {
00398 if (mii_addr > 31) {
00399 fprintf(stderr, "MII register address must be in 0-31 diapason\n");
00400 } else {
00401 silent = 1;
00402 if (mii_action == MII_ACTION_WRITE) {
00403 mdio_write(skfd, phy_id, mii_addr, mii_value);
00404 fprintf(stderr, "write to register MR%d value 0x%04X\n", mii_addr, mii_value);
00405 }
00406 if (mii_action == MII_ACTION_READ) {
00407 unsigned long v = mdio_read(skfd, phy_id, mii_addr);
00408 printf("0x%04X\n", v);
00409 fprintf(stderr, "read from register MR%d value 0x%04X\n", mii_addr, v);
00410 }
00411 }
00412 }
00413 if (set_BMCR >= 0) {
00414 printf("Setting the Basic Mode Control Register to 0x%4.4x.\n",
00415 set_BMCR);
00416 mdio_write(skfd, phy_id, 0, set_BMCR);
00417 }
00418
00419 if (opt_watch && opt_status)
00420 monitor_status(skfd, phy_id);
00421
00422 show_basic_mii(skfd, phy_id);
00423 #ifdef LIBMII
00424 if (verbose)
00425 show_mii_details(skfd, phy_id);
00426 #else
00427 if (verbose || debug) {
00428 int mii_reg, mii_val;
00429 printf(" MII PHY #%d transceiver registers:", phy_id);
00430 for (mii_reg = 0; mii_reg < 32; mii_reg++) {
00431 mii_val = mdio_read(skfd, phy_id, mii_reg);
00432 printf("%s %4.4x", (mii_reg % 8) == 0 ? "\n " : "",
00433 mii_val);
00434 }
00435 printf("\n");
00436 }
00437 #endif
00438
00439 if (opt_watch)
00440 monitor_mii(skfd, phy_id);
00441 if (opt_status &&
00442 (mdio_read(skfd, phy_id, 1) & 0x0004) == 0)
00443 exit(2);
00444 return 0;
00445 }
00446
00447 int mdio_read(int skfd, int phy_id, int location)
00448 {
00449 u16 *data = (u16 *)(&ifr.ifr_data);
00450
00451 data[0] = phy_id;
00452 data[1] = location;
00453
00454 if (ioctl(skfd, new_ioctl_nums ? 0x8948 : SIOCDEVPRIVATE+1, &ifr) < 0) {
00455 fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name,
00456 strerror(errno));
00457 return -1;
00458 }
00459 return data[3];
00460 }
00461
00462 void mdio_write(int skfd, int phy_id, int location, int value)
00463 {
00464 u16 *data = (u16 *)(&ifr.ifr_data);
00465
00466 data[0] = phy_id;
00467 data[1] = location;
00468 data[2] = value;
00469
00470 if (ioctl(skfd, new_ioctl_nums ? 0x8949 : SIOCDEVPRIVATE+2, &ifr) < 0) {
00471 fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name,
00472 strerror(errno));
00473 }
00474 }
00475
00476
00477 static int parse_advertise(const char *capabilities)
00478 {
00479 const char *mtypes[] = {
00480 "100baseT4", "100baseTx", "100baseTx-FD", "100baseTx-HD",
00481 "10baseT", "10baseT-FD", "10baseT-HD", 0,
00482 };
00483 char *endptr;
00484 int cap_map[] = { 0x0200, 0x0180, 0x0100, 0x0080, 0x0060, 0x0040, 0x0020,};
00485 int i;
00486 if ( ! capabilities) {
00487 fprintf(stderr, "You passed -A 'NULL'. You must provide a media"
00488 " list to advertise!\n");
00489 return -1;
00490 }
00491 if (debug)
00492 fprintf(stderr, "Advertise string is '%s'.\n", capabilities);
00493 for (i = 0; mtypes[i]; i++)
00494 if (strcasecmp(mtypes[i], capabilities) == 0)
00495 return cap_map[i];
00496 if ((i = strtol(capabilities, &endptr, 16)) <= 0xffff && endptr[0] == 0)
00497 return i;
00498 fprintf(stderr, "Invalid media advertisement value '%s'.\n"
00499 " Either pass a numeric value or one of the following names:\n",
00500 capabilities);
00501 for (i = 0; mtypes[i]; i++)
00502 fprintf(stderr, " %-14s %3.3x\n", mtypes[i], cap_map[i]);
00503 return -1;
00504 }
00505
00506
00507 static const char *media_names[] = {
00508 "10baseT", "10baseT-FD", "100baseTx", "100baseTx-FD", "100baseT4",
00509 "Flow-control", 0,
00510 };
00511
00512 static const char *bmcr_bits[] = {
00513 " Internal Collision-Test enabled!\n", "",
00514 " Restarted auto-negotiation in progress!\n",
00515 " Transceiver isolated from the MII!\n",
00516 " Transceiver powered down!\n", "", "",
00517 " Transceiver in loopback mode!\n",
00518 " Transceiver currently being reset!\n",
00519 };
00520
00521 int show_basic_mii(long ioaddr, int phy_id)
00522 {
00523 int mii_reg, i;
00524 u16 mii_val[32];
00525 u16 bmcr, bmsr, new_bmsr, nway_advert, lkpar;
00526
00527 if(silent)
00528 return 0;
00529 for (mii_reg = 0; mii_reg < 8; mii_reg++)
00530 mii_val[mii_reg] = mdio_read(ioaddr, phy_id, mii_reg);
00531 if ( ! verbose) {
00532 printf("Basic registers of MII PHY #%d: ", phy_id);
00533 for (mii_reg = 0; mii_reg < 8; mii_reg++)
00534 printf(" %4.4x", mii_val[mii_reg]);
00535 printf(".\n");
00536 }
00537
00538 if (mii_val[0] == 0xffff || mii_val[1] == 0x0000) {
00539 printf(" No MII transceiver present!.\n");
00540 if (! opt_f) {
00541 printf(" Use '--force' to view the information anyway.\n");
00542 return -1;
00543 }
00544 }
00545
00546 bmcr = mii_val[0];
00547 bmsr = mii_val[1];
00548 nway_advert = mii_val[4];
00549 lkpar = mii_val[5];
00550
00551 if (lkpar & 0x4000) {
00552 int negotiated = nway_advert & lkpar & 0x3e0;
00553 int max_capability = 0;
00554
00555
00556 int media_priority[] = {8, 9, 7, 6, 5};
00557 printf(" The autonegotiated capability is %4.4x.\n", negotiated);
00558 for (i = 0; media_priority[i]; i++)
00559 if (negotiated & (1 << media_priority[i])) {
00560 max_capability = media_priority[i];
00561 break;
00562 }
00563 if (max_capability)
00564 printf("The autonegotiated media type is %s.\n",
00565 media_names[max_capability - 5]);
00566 else
00567 printf("No common media type was autonegotiated!\n"
00568 "This is extremely unusual and typically indicates a "
00569 "configuration error.\n" "Perhaps the advertised "
00570 "capability set was intentionally limited.\n");
00571 }
00572 printf(" Basic mode control register 0x%4.4x:", bmcr);
00573 if (bmcr & 0x1000)
00574 printf(" Auto-negotiation enabled.\n");
00575 else
00576 printf(" Auto-negotiation disabled, with\n"
00577 " Speed fixed at 10%s mbps, %s-duplex.\n",
00578 bmcr & 0x2000 ? "0" : "",
00579 bmcr & 0x0100 ? "full":"half");
00580 for (i = 0; i < 9; i++)
00581 if (bmcr & (0x0080<<i))
00582 printf(bmcr_bits[i]);
00583
00584 new_bmsr = mdio_read(ioaddr, phy_id, 1);
00585 if ((bmsr & 0x0016) == 0x0004)
00586 printf( " You have link beat, and everything is working OK.\n");
00587 else
00588 printf(" Basic mode status register 0x%4.4x ... %4.4x.\n"
00589 " Link status: %sestablished.\n",
00590 bmsr, new_bmsr,
00591 bmsr & 0x0004 ? "" :
00592 (new_bmsr & 0x0004) ? "previously broken, but now re" : "not ");
00593 if (verbose) {
00594 printf(" This transceiver is capable of ");
00595 if (bmsr & 0xF800) {
00596 for (i = 15; i >= 11; i--)
00597 if (bmsr & (1<<i))
00598 printf(" %s", media_names[i-11]);
00599 } else
00600 printf("<Warning! No media capabilities>");
00601 printf(".\n");
00602 printf(" %s to perform Auto-negotiation, negotiation %scomplete.\n",
00603 bmsr & 0x0008 ? "Able" : "Unable",
00604 bmsr & 0x0020 ? "" : "not ");
00605 }
00606
00607 if (bmsr & 0x0010)
00608 printf(" Remote fault detected!\n");
00609 if (bmsr & 0x0002)
00610 printf(" *** Link Jabber! ***\n");
00611
00612 if (lkpar & 0x4000) {
00613 printf(" Your link partner advertised %4.4x:",
00614 lkpar);
00615 for (i = 5; i >= 0; i--)
00616 if (lkpar & (0x20<<i))
00617 printf(" %s", media_names[i]);
00618 printf("%s.\n", lkpar & 0x0400 ? ", w/ 802.3X flow control" : "");
00619 } else if (lkpar & 0x00A0)
00620 printf(" Your link partner is generating %s link beat (no"
00621 " autonegotiation).\n",
00622 lkpar & 0x0080 ? "100baseTx" : "10baseT");
00623 else if ( ! (bmcr & 0x1000))
00624 printf(" Link partner information is not exchanged when in"
00625 " fixed speed mode.\n");
00626 else if ( ! (new_bmsr & 0x004))
00627 ;
00628 else if (lkpar == 0x0001 || lkpar == 0x0000) {
00629 printf(" Your link partner does not do autonegotiation, and this "
00630 "transceiver type\n does not report the sensed link "
00631 "speed.\n");
00632 } else
00633 printf(" Your link partner is strange, status %4.4x.\n", lkpar);
00634
00635 printf(" End of basic transceiver information.\n\n");
00636 return 0;
00637 }
00638
00639 static void monitor_status(long ioaddr, int phy_id)
00640 {
00641 unsigned int baseline_1 = 0x55555555;
00642
00643 while (1) {
00644 unsigned int new_1 = mdio_read(ioaddr, phy_id, 1);
00645 if (new_1 != baseline_1) {
00646 printf("%-12s 0x%4.4x 0x%4.4x\n",
00647 new_1 & 0x04 ? (new_1==0xffff ? "unknown" : "up") :
00648 new_1 & 0x20 ? "negotiating" : "down",
00649 new_1, mdio_read(ioaddr, phy_id, 5));
00650 fflush(stdout);
00651 baseline_1 = new_1;
00652 }
00653 sleep(1);
00654 }
00655 }
00656
00657 int show_mii_details(long ioaddr, int phy_id)
00658 {
00659 int mii_reg, mii_val;
00660 printf(" MII PHY #%d transceiver registers:", phy_id);
00661 for (mii_reg = 0; mii_reg < 32; mii_reg++) {
00662 mii_val = mdio_read(skfd, phy_id, mii_reg);
00663 printf("%s %4.4x", (mii_reg % 8) == 0 ? "\n " : "",
00664 mii_val);
00665 }
00666 printf("\nThis version of 'mii-diag' has not been linked with "
00667 "the libmii.c library.\n"
00668 " That library provides extended transceiver status reports.\n");
00669 return 0;
00670 }
00671
00672 void monitor_mii(long ioaddr, int phy_id)
00673 {
00674 fprintf(stderr, "\nThis version of 'mii-diag' has not been linked with "
00675 "the libmii.c library \n"
00676 " required for the media monitor option.\n");
00677 }
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691