📄 mii-diag.c
字号:
return -1; } } if (msg_level >= 0) { data32[0] = msg_level; if (ioctl(skfd, SIOCSPARAMS, &ifr) < 0) { fprintf(stderr, "SIOCSPARAMS on %s failed: %s\n", ifr.ifr_name, strerror(errno)); return -1; } } if (opt_reset) { printf("Resetting the transceiver...\n"); mdio_write(skfd, phy_id, 0, 0x8000); } /* Note: PHY addresses > 32 are pseudo-MII devices, usually built-in. */ if (phy_id < 64 && nway_advertise > 0) { printf(" Setting the media capability advertisement register of " "PHY #%d to 0x%4.4x.\n", phy_id, nway_advertise | 1); mdio_write(skfd, phy_id, 4, nway_advertise | 1); mdio_write(skfd, phy_id, 0, 0x1000); } if (opt_restart) { printf("Restarting negotiation...\n"); mdio_write(skfd, phy_id, 0, 0x0000); mdio_write(skfd, phy_id, 0, 0x1200); } /* To force 100baseTx-HD do mdio_write(skfd, phy_id, 0, 0x2000); */ if (fixed_speed >= 0) { int reg0_val = 0; if (fixed_speed & 0x0180) /* 100mpbs */ reg0_val |= 0x2000; if ((fixed_speed & 0x0140) && /* A full duplex type and */ ! (fixed_speed & 0x0820)) /* no half duplex types. */ reg0_val |= 0x0100; printf("Setting the speed to \"fixed\", Control register %4.4x.\n", reg0_val); mdio_write(skfd, phy_id, 0, reg0_val); } if (set_BMCR >= 0) { printf("Setting the Basic Mode Control Register to 0x%4.4x.\n", set_BMCR); mdio_write(skfd, phy_id, 0, set_BMCR); } if (opt_watch && opt_status) monitor_status(skfd, phy_id); show_basic_mii(skfd, phy_id);#ifdef LIBMII if (verbose) show_mii_details(skfd, phy_id);#else if (verbose || debug) { int mii_reg, mii_val; printf(" MII PHY #%d transceiver registers:", phy_id); for (mii_reg = 0; mii_reg < 32; mii_reg++) { mii_val = mdio_read(skfd, phy_id, mii_reg); printf("%s %4.4x", (mii_reg % 8) == 0 ? "\n " : "", mii_val); } printf("\n"); }#endif if (opt_watch) monitor_mii(skfd, phy_id); if (opt_status && (mdio_read(skfd, phy_id, 1) & 0x0004) == 0) exit(2); return 0;}int mdio_read(int skfd, int phy_id, int location){ u16 *data = (u16 *)(&ifr.ifr_data); data[0] = phy_id; data[1] = location; if (ioctl(skfd, new_ioctl_nums ? 0x8948 : SIOCDEVPRIVATE+1, &ifr) < 0) { fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name, strerror(errno)); return -1; } return data[3];}void mdio_write(int skfd, int phy_id, int location, int value){ u16 *data = (u16 *)(&ifr.ifr_data); data[0] = phy_id; data[1] = location; data[2] = value; if (ioctl(skfd, new_ioctl_nums ? 0x8949 : SIOCDEVPRIVATE+2, &ifr) < 0) { fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name, strerror(errno)); }}/* Parse the command line argument for advertised capabilities. */static int parse_advertise(const char *capabilities){ const char *mtypes[] = { "100baseT4", "100baseTx", "100baseTx-FD", "100baseTx-HD", "10baseT", "10baseT-FD", "10baseT-HD", 0, }; char *endptr; int cap_map[] = { 0x0200, 0x0180, 0x0100, 0x0080, 0x0060, 0x0040, 0x0020,}; int i; if ( ! capabilities) { fprintf(stderr, "You passed -A 'NULL'. You must provide a media" " list to advertise!\n"); return -1; } if (debug) fprintf(stderr, "Advertise string is '%s'.\n", capabilities); for (i = 0; mtypes[i]; i++) if (strcasecmp(mtypes[i], capabilities) == 0) return cap_map[i]; if ((i = strtol(capabilities, &endptr, 16)) <= 0xffff && endptr[0] == 0) return i; fprintf(stderr, "Invalid media advertisement value '%s'.\n" " Either pass a numeric value or one of the following names:\n", capabilities); for (i = 0; mtypes[i]; i++) fprintf(stderr, " %-14s %3.3x\n", mtypes[i], cap_map[i]); return -1;}/* Trivial versions if we don't link against libmii.c */static const char *media_names[] = { "10baseT", "10baseT-FD", "100baseTx", "100baseTx-FD", "100baseT4", "Flow-control", 0,};/* Various non-good bits in the command register. */static const char *bmcr_bits[] = { " Internal Collision-Test enabled!\n", "", /* 0x0080,0x0100 */ " Restarted auto-negotiation in progress!\n", " Transceiver isolated from the MII!\n", " Transceiver powered down!\n", "", "", " Transceiver in loopback mode!\n", " Transceiver currently being reset!\n",};int show_basic_mii(long ioaddr, int phy_id){ int mii_reg, i; u16 mii_val[32]; u16 bmcr, bmsr, new_bmsr, nway_advert, lkpar; for (mii_reg = 0; mii_reg < 8; mii_reg++) mii_val[mii_reg] = mdio_read(ioaddr, phy_id, mii_reg); if ( ! verbose) { printf("Basic registers of MII PHY #%d: ", phy_id); for (mii_reg = 0; mii_reg < 8; mii_reg++) printf(" %4.4x", mii_val[mii_reg]); printf(".\n"); } if (mii_val[0] == 0xffff || mii_val[1] == 0x0000) { printf(" No MII transceiver present!.\n"); if (! opt_f) { printf(" Use '--force' to view the information anyway.\n"); return -1; } } /* Descriptive rename. */ bmcr = mii_val[0]; bmsr = mii_val[1]; nway_advert = mii_val[4]; lkpar = mii_val[5]; if (lkpar & 0x4000) { int negotiated = nway_advert & lkpar & 0x3e0; int max_capability = 0; /* Scan for the highest negotiated capability, highest priority (100baseTx-FDX) to lowest (10baseT-HDX). */ int media_priority[] = {8, 9, 7, 6, 5}; /* media_names[i-5] */ printf(" The autonegotiated capability is %4.4x.\n", negotiated); for (i = 0; media_priority[i]; i++) if (negotiated & (1 << media_priority[i])) { max_capability = media_priority[i]; break; } if (max_capability) printf("The autonegotiated media type is %s.\n", media_names[max_capability - 5]); else printf("No common media type was autonegotiated!\n" "This is extremely unusual and typically indicates a " "configuration error.\n" "Perhaps the advertised " "capability set was intentionally limited.\n"); } printf(" Basic mode control register 0x%4.4x:", bmcr); if (bmcr & 0x1000) printf(" Auto-negotiation enabled.\n"); else printf(" Auto-negotiation disabled, with\n" " Speed fixed at 10%s mbps, %s-duplex.\n", bmcr & 0x2000 ? "0" : "", bmcr & 0x0100 ? "full":"half"); for (i = 0; i < 9; i++) if (bmcr & (0x0080<<i)) printf(bmcr_bits[i]); new_bmsr = mdio_read(ioaddr, phy_id, 1); if ((bmsr & 0x0016) == 0x0004) printf( " You have link beat, and everything is working OK.\n"); else printf(" Basic mode status register 0x%4.4x ... %4.4x.\n" " Link status: %sestablished.\n", bmsr, new_bmsr, bmsr & 0x0004 ? "" : (new_bmsr & 0x0004) ? "previously broken, but now re" : "not "); if (verbose) { printf(" This transceiver is capable of "); if (bmsr & 0xF800) { for (i = 15; i >= 11; i--) if (bmsr & (1<<i)) printf(" %s", media_names[i-11]); } else printf("<Warning! No media capabilities>"); printf(".\n"); printf(" %s to perform Auto-negotiation, negotiation %scomplete.\n", bmsr & 0x0008 ? "Able" : "Unable", bmsr & 0x0020 ? "" : "not "); } if (bmsr & 0x0010) printf(" Remote fault detected!\n"); if (bmsr & 0x0002) printf(" *** Link Jabber! ***\n"); if (lkpar & 0x4000) { printf(" Your link partner advertised %4.4x:", lkpar); for (i = 5; i >= 0; i--) if (lkpar & (0x20<<i)) printf(" %s", media_names[i]); printf("%s.\n", lkpar & 0x0400 ? ", w/ 802.3X flow control" : ""); } else if (lkpar & 0x00A0) printf(" Your link partner is generating %s link beat (no" " autonegotiation).\n", lkpar & 0x0080 ? "100baseTx" : "10baseT"); else if ( ! (bmcr & 0x1000)) printf(" Link partner information is not exchanged when in" " fixed speed mode.\n"); else if ( ! (new_bmsr & 0x004)) ; /* If no partner, do not report status. */ else if (lkpar == 0x0001 || lkpar == 0x0000) { printf(" Your link partner does not do autonegotiation, and this " "transceiver type\n does not report the sensed link " "speed.\n"); } else printf(" Your link partner is strange, status %4.4x.\n", lkpar); printf(" End of basic transceiver information.\n\n"); return 0;}static void monitor_status(long ioaddr, int phy_id){ unsigned int baseline_1 = 0x55555555; /* Always show initial status. */ while (1) { unsigned int new_1 = mdio_read(ioaddr, phy_id, 1); if (new_1 != baseline_1) { printf("%-12s 0x%4.4x 0x%4.4x\n", new_1 & 0x04 ? (new_1==0xffff ? "unknown" : "up") : new_1 & 0x20 ? "negotiating" : "down", new_1, mdio_read(ioaddr, phy_id, 5)); fflush(stdout); baseline_1 = new_1; } sleep(1); }}/* These functions are not used if we are linked with libmii. */int show_mii_details(long ioaddr, int phy_id) __attribute__((weak));void monitor_mii(long ioaddr, int phy_id) __attribute__((weak));int show_mii_details(long ioaddr, int phy_id){ int mii_reg, mii_val; printf(" MII PHY #%d transceiver registers:", phy_id); for (mii_reg = 0; mii_reg < 32; mii_reg++) { mii_val = mdio_read(skfd, phy_id, mii_reg); printf("%s %4.4x", (mii_reg % 8) == 0 ? "\n " : "", mii_val); } printf("\nThis version of 'mii-diag' has not been linked with " "the libmii.c library.\n" " That library provides extended transceiver status reports.\n"); return 0;}void monitor_mii(long ioaddr, int phy_id){ fprintf(stderr, "\nThis version of 'mii-diag' has not been linked with " "the libmii.c library \n" " required for the media monitor option.\n");}/* * Local variables: * version-control: t * kept-new-versions: 5 * c-indent-level: 4 * c-basic-offset: 4 * tab-width: 4 * compile-command: "gcc -Wall -Wstrict-prototypes -O mii-diag.c -DLIBMII libmii.c -o mii-diag" * simple-compile-command: "gcc mii-diag.c -o mii-diag" * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -