summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Popelka <jpopelka@redhat.com>2012-01-05 14:53:49 +0100
committerJiri Popelka <jpopelka@redhat.com>2012-01-05 14:53:49 +0100
commitfaf31f80deba7c27040f925a4ad194d76197cd1c (patch)
tree9b9276851a1bd6624bf2e5dfd7e4a7e4b4d87110
parent6ccabd574062869c3b1101e64b4e85c86a85ec15 (diff)
downloadnet-tools-faf31f80deba7c27040f925a4ad194d76197cd1c.tar.gz
net-tools-faf31f80deba7c27040f925a4ad194d76197cd1c.tar.bz2
net-tools-faf31f80deba7c27040f925a4ad194d76197cd1c.zip
mii-tool: use <linux/mii.h> instead of "mii.h" and fix RHBZ #491358
Using mii-tool with e1000e driver results in: SIOCGMIIREG on eth0 failed: Input/output error Problem is in show_basic_mii() where the loop for (i = 0; i < ((verbose > 1) ? 32 : MII_BASIC_MAX); i++) mii_val[i] = mdio_read(sock, i); checks all MII registers from 0x00 to 0x07 (or to 0x1F in verbose mode). But there's no register with 0x07 value. For more details see: https://bugzilla.redhat.com/show_bug.cgi?id=491358#c1 Solution is to check only defined MII registers. Also the "mii.h" is actually a duplicate of <linux/mii.h>.
-rw-r--r--include/mii.h103
-rw-r--r--mii-tool.c132
2 files changed, 81 insertions, 154 deletions
diff --git a/include/mii.h b/include/mii.h
deleted file mode 100644
index 8a26226..0000000
--- a/include/mii.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * mii.h 1.4 2000/04/25 22:06:15
- *
- * Media Independent Interface support: register layout and ioctl's
- *
- * Copyright (C) 2000 David A. Hinds -- dhinds@pcmcia.sourceforge.org
- */
-
-#ifndef _NETTOOL_MII_H
-#define _NETTOOLS_MII_H
-
-#include <linux/sockios.h>
-
-/* network interface ioctl's for MII commands */
-#ifndef SIOCGMIIPHY
-#warning "SIOCGMIIPHY is not defined by your kernel source"
-#define SIOCGMIIPHY (SIOCDEVPRIVATE) /* Read from current PHY */
-#define SIOCGMIIREG (SIOCDEVPRIVATE+1) /* Read any PHY register */
-#define SIOCSMIIREG (SIOCDEVPRIVATE+2) /* Write any PHY register */
-#define SIOCGPARAMS (SIOCDEVPRIVATE+3) /* Read operational parameters */
-#define SIOCSPARAMS (SIOCDEVPRIVATE+4) /* Set operational parameters */
-#endif
-
-#include <linux/types.h>
-
-/* This data structure is used for all the MII ioctl's */
-struct mii_data {
- __u16 phy_id;
- __u16 reg_num;
- __u16 val_in;
- __u16 val_out;
-};
-
-/* Basic Mode Control Register */
-#define MII_BMCR 0x00
-#define MII_BMCR_RESET 0x8000
-#define MII_BMCR_LOOPBACK 0x4000
-#define MII_BMCR_100MBIT 0x2000
-#define MII_BMCR_AN_ENA 0x1000
-#define MII_BMCR_ISOLATE 0x0400
-#define MII_BMCR_RESTART 0x0200
-#define MII_BMCR_DUPLEX 0x0100
-#define MII_BMCR_COLTEST 0x0080
-#define MII_BMCR_SPEED1000 0x0040
-
-/* Basic Mode Status Register */
-#define MII_BMSR 0x01
-#define MII_BMSR_CAP_MASK 0xf800
-#define MII_BMSR_100BASET4 0x8000
-#define MII_BMSR_100BASETX_FD 0x4000
-#define MII_BMSR_100BASETX_HD 0x2000
-#define MII_BMSR_10BASET_FD 0x1000
-#define MII_BMSR_10BASET_HD 0x0800
-#define MII_BMSR_NO_PREAMBLE 0x0040
-#define MII_BMSR_AN_COMPLETE 0x0020
-#define MII_BMSR_REMOTE_FAULT 0x0010
-#define MII_BMSR_AN_ABLE 0x0008
-#define MII_BMSR_LINK_VALID 0x0004
-#define MII_BMSR_JABBER 0x0002
-#define MII_BMSR_EXT_CAP 0x0001
-
-#define MII_PHY_ID1 0x02
-#define MII_PHY_ID2 0x03
-
-/* Auto-Negotiation Advertisement Register */
-#define MII_ANAR 0x04
-/* Auto-Negotiation Link Partner Ability Register */
-#define MII_ANLPAR 0x05
-#define MII_AN_NEXT_PAGE 0x8000
-#define MII_AN_ACK 0x4000
-#define MII_AN_REMOTE_FAULT 0x2000
-#define MII_AN_ABILITY_MASK 0x07e0
-#define MII_AN_FLOW_CONTROL 0x0400
-#define MII_AN_100BASET4 0x0200
-#define MII_AN_100BASETX_FD 0x0100
-#define MII_AN_100BASETX_HD 0x0080
-#define MII_AN_10BASET_FD 0x0040
-#define MII_AN_10BASET_HD 0x0020
-#define MII_AN_PROT_MASK 0x001f
-#define MII_AN_PROT_802_3 0x0001
-
-/* Auto-Negotiation Expansion Register */
-#define MII_ANER 0x06
-#define MII_ANER_MULT_FAULT 0x0010
-#define MII_ANER_LP_NP_ABLE 0x0008
-#define MII_ANER_NP_ABLE 0x0004
-#define MII_ANER_PAGE_RX 0x0002
-#define MII_ANER_LP_AN_ABLE 0x0001
-
-#define MII_CTRL1000 0x09
-#define MII_BMCR2_1000FULL 0x0200
-#define MII_BMCR2_1000HALF 0x0100
-
-#define MII_STAT1000 0x0a
-#define MII_LPA2_1000LOCALOK 0x2000
-#define MII_LPA2_1000REMRXOK 0x1000
-#define MII_LPA2_1000FULL 0x0800
-#define MII_LPA2_1000HALF 0x0400
-
-/* Last register we need for show_basic_mii() */
-#define MII_BASIC_MAX (MII_STAT1000+1)
-
-#endif /* _NETTOOLS_MII_H */
diff --git a/mii-tool.c b/mii-tool.c
index 1d57526..13e6cc3 100644
--- a/mii-tool.c
+++ b/mii-tool.c
@@ -51,10 +51,12 @@ static char Version[] = "$Id: mii-tool.c,v 1.9 2006/09/27 20:59:18 ecki Exp $\n(
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#endif
-#include "mii.h"
+#include <linux/mii.h>
+#include <linux/sockios.h>
#include "version.h"
#define MAX_ETH 8 /* Maximum # of interfaces */
+#define LPA_ABILITY_MASK 0x07e0
/* Table of known MII's */
static const struct {
@@ -117,7 +119,7 @@ static struct ifreq ifr;
static int mdio_read(int skfd, int location)
{
- struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;
+ struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr.ifr_data;
mii->reg_num = location;
if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) {
fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name,
@@ -129,7 +131,7 @@ static int mdio_read(int skfd, int location)
static void mdio_write(int skfd, int location, int value)
{
- struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;
+ struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr.ifr_data;
mii->reg_num = location;
mii->val_in = value;
if (ioctl(skfd, SIOCSMIIREG, &ifr) < 0) {
@@ -145,17 +147,17 @@ const struct {
u_short value[2];
} media[] = {
/* The order through 100baseT4 matches bits in the BMSR */
- { "10baseT-HD", {MII_AN_10BASET_HD} },
- { "10baseT-FD", {MII_AN_10BASET_FD} },
- { "100baseTx-HD", {MII_AN_100BASETX_HD} },
- { "100baseTx-FD", {MII_AN_100BASETX_FD} },
- { "100baseT4", {MII_AN_100BASET4} },
- { "100baseTx", {MII_AN_100BASETX_FD | MII_AN_100BASETX_HD} },
- { "10baseT", {MII_AN_10BASET_FD | MII_AN_10BASET_HD} },
-
- { "1000baseT-HD", {0, MII_BMCR2_1000HALF} },
- { "1000baseT-FD", {0, MII_BMCR2_1000FULL} },
- { "1000baseT", {0, MII_BMCR2_1000HALF|MII_BMCR2_1000FULL} },
+ { "10baseT-HD", {LPA_10HALF} },
+ { "10baseT-FD", {LPA_10FULL} },
+ { "100baseTx-HD", {LPA_100HALF} },
+ { "100baseTx-FD", {LPA_100FULL} },
+ { "100baseT4", {LPA_100BASE4} },
+ { "100baseTx", {LPA_100FULL | LPA_100HALF} },
+ { "10baseT", {LPA_10FULL | LPA_10HALF} },
+
+ { "1000baseT-HD", {0, ADVERTISE_1000HALF} },
+ { "1000baseT-FD", {0, ADVERTISE_1000FULL} },
+ { "1000baseT", {0, ADVERTISE_1000HALF|ADVERTISE_1000FULL} },
};
#define NMEDIA (sizeof(media)/sizeof(media[0]))
@@ -166,8 +168,8 @@ static int parse_media(char *arg, unsigned *bmcr2)
char *s;
mask = strtoul(arg, &s, 16);
if ((*arg != '\0') && (*s == '\0')) {
- if ((mask & MII_AN_ABILITY_MASK) &&
- !(mask & ~MII_AN_ABILITY_MASK)) {
+ if ((mask & LPA_ABILITY_MASK) &&
+ !(mask & ~LPA_ABILITY_MASK)) {
*bmcr2 = 0;
return mask;
}
@@ -198,18 +200,19 @@ static const char *media_list(unsigned mask, unsigned mask2, int best)
int i;
*buf = '\0';
- if (mask & MII_BMCR_SPEED1000) {
- if (mask2 & MII_BMCR2_1000HALF) {
+ if (mask & BMCR_SPEED1000) {
+ if (mask2 & ADVERTISE_1000HALF) {
strcat(buf, " ");
strcat(buf, "1000baseT-HD");
if (best) goto out;
}
- if (mask2 & MII_BMCR2_1000FULL) {
+ if (mask2 & ADVERTISE_1000FULL) {
strcat(buf, " ");
strcat(buf, "1000baseT-FD");
if (best) goto out;
}
}
+
mask >>= 5;
for (i = 4; i >= 0; i--) {
if (mask & (1<<i)) {
@@ -233,8 +236,35 @@ int show_basic_mii(int sock, int phy_id)
/* Some bits in the BMSR are latched, but we can't rely on being
the only reader, so only the current values are meaningful */
mdio_read(sock, MII_BMSR);
- for (i = 0; i < ((verbose > 1) ? 32 : MII_BASIC_MAX); i++)
- mii_val[i] = mdio_read(sock, i);
+ for (i = 0; i < ((verbose > 1) ? 32 : (MII_STAT1000+1)); i++)
+ switch (i & 0x1F) {
+ case MII_BMCR:
+ case MII_BMSR:
+ case MII_PHYSID1:
+ case MII_PHYSID2:
+ case MII_ADVERTISE:
+ case MII_LPA:
+ case MII_EXPANSION:
+ case MII_CTRL1000:
+ case MII_STAT1000:
+ case MII_ESTATUS:
+ case MII_DCOUNTER:
+ case MII_FCSCOUNTER:
+ case MII_NWAYTEST:
+ case MII_RERRCOUNTER:
+ case MII_SREVISION:
+ case MII_RESV1:
+ case MII_LBRERROR:
+ case MII_PHYADDR:
+ case MII_RESV2:
+ case MII_TPISTATUS:
+ case MII_NCONFIG:
+ mii_val[i] = mdio_read(sock, i);
+ break;
+ default:
+ mii_val[i] = 0;
+ break;
+ }
if (mii_val[MII_BMCR] == 0xffff || mii_val[MII_BMSR] == 0x0000) {
fprintf(stderr, " No MII transceiver present!.\n");
@@ -243,31 +273,31 @@ int show_basic_mii(int sock, int phy_id)
/* Descriptive rename. */
bmcr = mii_val[MII_BMCR]; bmsr = mii_val[MII_BMSR];
- advert = mii_val[MII_ANAR]; lkpar = mii_val[MII_ANLPAR];
+ advert = mii_val[MII_ADVERTISE]; lkpar = mii_val[MII_LPA];
bmcr2 = mii_val[MII_CTRL1000]; lpa2 = mii_val[MII_STAT1000];
sprintf(buf, "%s: ", ifr.ifr_name);
- if (bmcr & MII_BMCR_AN_ENA) {
- if (bmsr & MII_BMSR_AN_COMPLETE) {
+ if (bmcr & BMCR_ANENABLE) {
+ if (bmsr & BMSR_ANEGCOMPLETE) {
if (advert & lkpar) {
- strcat(buf, (lkpar & MII_AN_ACK) ?
+ strcat(buf, (lkpar & LPA_LPACK) ?
"negotiated" : "no autonegotiation,");
strcat(buf, media_list(advert & lkpar, bmcr2 & lpa2>>2, 1));
strcat(buf, ", ");
} else {
strcat(buf, "autonegotiation failed, ");
}
- } else if (bmcr & MII_BMCR_RESTART) {
+ } else if (bmcr & BMCR_ANRESTART) {
strcat(buf, "autonegotiation restarted, ");
}
} else {
sprintf(buf+strlen(buf), "%s Mbit, %s duplex, ",
- ((bmcr2 & (MII_BMCR2_1000HALF | MII_BMCR2_1000FULL)) & lpa2 >> 2)
+ ((bmcr2 & (ADVERTISE_1000HALF | ADVERTISE_1000FULL)) & lpa2 >> 2)
? "1000"
- : (bmcr & MII_BMCR_100MBIT) ? "100" : "10",
- (bmcr & MII_BMCR_DUPLEX) ? "full" : "half");
+ : (bmcr & BMCR_SPEED100) ? "100" : "10",
+ (bmcr & BMCR_FULLDPLX) ? "full" : "half");
}
- strcat(buf, (bmsr & MII_BMSR_LINK_VALID) ? "link ok" : "no link");
+ strcat(buf, (bmsr & BMSR_LSTATUS) ? "link ok" : "no link");
if (opt_watch) {
if (opt_log) {
@@ -303,32 +333,32 @@ int show_basic_mii(int sock, int phy_id)
((mii_val[2]<<6)|(mii_val[3]>>10))&0xff,
(mii_val[3]>>4)&0x3f, mii_val[3]&0x0f);
printf(" basic mode: ");
- if (bmcr & MII_BMCR_RESET)
+ if (bmcr & BMCR_RESET)
printf("software reset, ");
- if (bmcr & MII_BMCR_LOOPBACK)
+ if (bmcr & BMCR_LOOPBACK)
printf("loopback, ");
- if (bmcr & MII_BMCR_ISOLATE)
+ if (bmcr & BMCR_ISOLATE)
printf("isolate, ");
- if (bmcr & MII_BMCR_COLTEST)
+ if (bmcr & BMCR_CTST)
printf("collision test, ");
- if (bmcr & MII_BMCR_AN_ENA) {
+ if (bmcr & BMCR_ANENABLE) {
printf("autonegotiation enabled\n");
} else {
printf("%s Mbit, %s duplex\n",
- (bmcr & MII_BMCR_100MBIT) ? "100" : "10",
- (bmcr & MII_BMCR_DUPLEX) ? "full" : "half");
+ (bmcr & BMCR_SPEED100) ? "100" : "10",
+ (bmcr & BMCR_FULLDPLX) ? "full" : "half");
}
printf(" basic status: ");
- if (bmsr & MII_BMSR_AN_COMPLETE)
+ if (bmsr & BMSR_ANEGCOMPLETE)
printf("autonegotiation complete, ");
- else if (bmcr & MII_BMCR_RESTART)
+ else if (bmcr & BMCR_ANRESTART)
printf("autonegotiation restarted, ");
- if (bmsr & MII_BMSR_REMOTE_FAULT)
+ if (bmsr & BMSR_RFAULT)
printf("remote fault, ");
- printf((bmsr & MII_BMSR_LINK_VALID) ? "link ok" : "no link");
+ printf((bmsr & BMSR_LSTATUS) ? "link ok" : "no link");
printf("\n capabilities:%s", media_list(bmsr >> 6, bmcr2, 0));
printf("\n advertising: %s", media_list(advert, bmcr2, 0));
- if (lkpar & MII_AN_ABILITY_MASK)
+ if (lkpar & LPA_ABILITY_MASK)
printf("\n link partner:%s", media_list(lkpar, lpa2 >> 2, 0));
printf("\n");
}
@@ -340,7 +370,7 @@ int show_basic_mii(int sock, int phy_id)
static int do_one_xcvr(int skfd, char *ifname, int maybe)
{
- struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;
+ struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr.ifr_data;
/* Get the vitals from the interface. */
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
@@ -358,23 +388,23 @@ static int do_one_xcvr(int skfd, char *ifname, int maybe)
if (opt_reset) {
printf("resetting the transceiver...\n");
- mdio_write(skfd, MII_BMCR, MII_BMCR_RESET);
+ mdio_write(skfd, MII_BMCR, BMCR_RESET);
}
if (nway_advertise > 0) {
- mdio_write(skfd, MII_ANAR, nway_advertise | 1);
+ mdio_write(skfd, MII_ADVERTISE, nway_advertise | 1);
opt_restart = 1;
}
if (opt_restart) {
printf("restarting autonegotiation...\n");
mdio_write(skfd, MII_BMCR, 0x0000);
- mdio_write(skfd, MII_BMCR, MII_BMCR_AN_ENA|MII_BMCR_RESTART);
+ mdio_write(skfd, MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART);
}
if (fixed_speed) {
int bmcr = 0;
- if (fixed_speed & (MII_AN_100BASETX_FD|MII_AN_100BASETX_HD))
- bmcr |= MII_BMCR_100MBIT;
- if (fixed_speed & (MII_AN_100BASETX_FD|MII_AN_10BASET_FD))
- bmcr |= MII_BMCR_DUPLEX;
+ if (fixed_speed & (LPA_100FULL|LPA_100HALF))
+ bmcr |= BMCR_SPEED100;
+ if (fixed_speed & (LPA_100FULL|LPA_10FULL))
+ bmcr |= BMCR_FULLDPLX;
mdio_write(skfd, MII_BMCR, bmcr);
}
@@ -388,7 +418,7 @@ static int do_one_xcvr(int skfd, char *ifname, int maybe)
static void watch_one_xcvr(int skfd, char *ifname, int index)
{
- struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;
+ struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr.ifr_data;
static int status[MAX_ETH] = { 0, /* ... */ };
int now;