]>
Commit | Line | Data |
---|---|---|
236898d6 MT |
1 | diff -up net-tools-1.60/mii-tool.c.mii-gigabit net-tools-1.60/mii-tool.c |
2 | --- net-tools-1.60/mii-tool.c.mii-gigabit 2010-06-14 15:51:23.000000000 +0200 | |
3 | +++ net-tools-1.60/mii-tool.c 2010-06-14 16:10:34.000000000 +0200 | |
4 | @@ -57,7 +57,7 @@ static char version[] = | |
5 | #define LPA_ABILITY_MASK 0x07e0 | |
6 | ||
7 | /* Table of known MII's */ | |
8 | -static struct { | |
9 | +static const struct { | |
10 | u_short id1, id2; | |
11 | char *name; | |
12 | } mii_id[] = { | |
13 | @@ -76,6 +76,9 @@ static struct { | |
14 | { 0x0181, 0x4410, "Quality QS6612" }, | |
15 | { 0x0282, 0x1c50, "SMSC 83C180" }, | |
16 | { 0x0300, 0xe540, "TDK 78Q2120" }, | |
17 | + { 0x0141, 0x0c20, "Yukon 88E1011" }, | |
18 | + { 0x0141, 0x0cc0, "Yukon-EC 88E1111" }, | |
19 | + { 0x0141, 0x0c90, "Yukon-2 88E1112" }, | |
20 | }; | |
21 | #define NMII (sizeof(mii_id)/sizeof(mii_id[0])) | |
22 | ||
23 | @@ -139,40 +142,47 @@ static void mdio_write(int skfd, int loc | |
24 | ||
25 | const struct { | |
26 | char *name; | |
27 | - u_short value; | |
28 | + u_short value[2]; | |
29 | } media[] = { | |
30 | /* The order through 100baseT4 matches bits in the BMSR */ | |
31 | - { "10baseT-HD", LPA_10HALF }, | |
32 | - { "10baseT-FD", LPA_10FULL }, | |
33 | - { "100baseTx-HD", LPA_100HALF }, | |
34 | - { "100baseTx-FD", LPA_100FULL }, | |
35 | - { "100baseT4", LPA_100BASE4 }, | |
36 | - { "100baseTx", LPA_100FULL | LPA_100HALF }, | |
37 | - { "10baseT", LPA_10FULL | LPA_10HALF }, | |
38 | + { "10baseT-HD", {LPA_10HALF} }, | |
39 | + { "10baseT-FD", {LPA_10FULL} }, | |
40 | + { "100baseTx-HD", {LPA_100HALF} }, | |
41 | + { "100baseTx-FD", {LPA_100FULL} }, | |
42 | + { "100baseT4", {LPA_100BASE4} }, | |
43 | + { "100baseTx", {LPA_100FULL | LPA_100HALF} }, | |
44 | + { "10baseT", {LPA_10FULL | LPA_10HALF} }, | |
45 | + { "1000baseT-HD", {0, ADVERTISE_1000HALF} }, | |
46 | + { "1000baseT-FD", {0, ADVERTISE_1000FULL} }, | |
47 | + { "1000baseT", {0, ADVERTISE_1000HALF|ADVERTISE_1000FULL} }, | |
48 | }; | |
49 | #define NMEDIA (sizeof(media)/sizeof(media[0])) | |
50 | ||
51 | /* Parse an argument list of media types */ | |
52 | -static int parse_media(char *arg) | |
53 | +static int parse_media(char *arg, unsigned *bmcr2) | |
54 | { | |
55 | int mask, i; | |
56 | char *s; | |
57 | mask = strtoul(arg, &s, 16); | |
58 | if ((*arg != '\0') && (*s == '\0')) { | |
59 | - if ((mask & LPA_ABILITY_MASK) && | |
60 | - !(mask & ~LPA_ABILITY_MASK)) | |
61 | - return mask; | |
62 | - goto failed; | |
63 | - } else { | |
64 | - mask = 0; | |
65 | - s = strtok(arg, ", "); | |
66 | - do { | |
67 | - for (i = 0; i < NMEDIA; i++) | |
68 | - if (strcasecmp(media[i].name, s) == 0) break; | |
69 | - if (i == NMEDIA) goto failed; | |
70 | - mask |= media[i].value; | |
71 | - } while ((s = strtok(NULL, ", ")) != NULL); | |
72 | - } | |
73 | + if ((mask & LPA_ABILITY_MASK) && | |
74 | + !(mask & ~LPA_ABILITY_MASK)) { | |
75 | + *bmcr2 = 0; | |
76 | + return mask; | |
77 | + } | |
78 | + goto failed; | |
79 | + } | |
80 | + mask = 0; | |
81 | + *bmcr2 = 0; | |
82 | + s = strtok(arg, ", "); | |
83 | + do { | |
84 | + for (i = 0; i < NMEDIA; i++) | |
85 | + if (s && strcasecmp(media[i].name, s) == 0) break; | |
86 | + if (i == NMEDIA) goto failed; | |
87 | + mask |= media[i].value[0]; | |
88 | + *bmcr2 |= media[i].value[1]; | |
89 | + } while ((s = strtok(NULL, ", ")) != NULL); | |
90 | + | |
91 | return mask; | |
92 | failed: | |
93 | fprintf(stderr, "Invalid media specification '%s'.\n", arg); | |
94 | @@ -181,11 +191,25 @@ failed: | |
95 | ||
96 | /*--------------------------------------------------------------------*/ | |
97 | ||
98 | -static char *media_list(int mask, int best) | |
99 | +static const char *media_list(unsigned mask, unsigned mask2, int best) | |
100 | { | |
101 | static char buf[100]; | |
102 | int i; | |
103 | *buf = '\0'; | |
104 | + | |
105 | + if (mask & BMCR_SPEED1000) { | |
106 | + if (mask2 & ADVERTISE_1000HALF) { | |
107 | + strcat(buf, " "); | |
108 | + strcat(buf, "1000baseT-HD"); | |
109 | + if (best) goto out; | |
110 | + } | |
111 | + if (mask2 & ADVERTISE_1000FULL) { | |
112 | + strcat(buf, " "); | |
113 | + strcat(buf, "1000baseT-FD"); | |
114 | + if (best) goto out; | |
115 | + } | |
116 | + } | |
117 | + | |
118 | mask >>= 5; | |
119 | for (i = 4; i >= 0; i--) { | |
120 | if (mask & (1<<i)) { | |
121 | @@ -194,6 +218,7 @@ static char *media_list(int mask, int be | |
122 | if (best) break; | |
123 | } | |
124 | } | |
125 | +out: | |
126 | if (mask & (1<<5)) | |
127 | strcat(buf, " flow-control"); | |
128 | return buf; | |
129 | @@ -203,11 +228,11 @@ int show_basic_mii(int sock, int phy_id) | |
130 | { | |
131 | char buf[100]; | |
132 | int i, mii_val[32]; | |
133 | - int bmcr, bmsr, advert, lkpar; | |
134 | + unsigned bmcr, bmsr, advert, lkpar, bmcr2, lpa2; | |
135 | /* Some bits in the BMSR are latched, but we can't rely on being | |
136 | the only reader, so only the current values are meaningful */ | |
137 | mdio_read(sock, MII_BMSR); | |
138 | - for (i = 0; i < ((verbose > 1) ? 32 : 8); i++) { | |
139 | + for (i = 0; i < ((verbose > 1) ? 32 : (MII_STAT1000+1)); i++) { | |
140 | if ((i == MII_BMCR) || (i == MII_BMSR) || (i == MII_PHYSID1) || | |
141 | (i == MII_PHYSID2) || (i == MII_ADVERTISE) || (i == MII_LPA) || | |
142 | (i == MII_EXPANSION) || (i == MII_CTRL1000) || (i == MII_STAT1000) || | |
143 | @@ -220,7 +245,7 @@ int show_basic_mii(int sock, int phy_id) | |
144 | else | |
145 | mii_val[i] = 0; | |
146 | } | |
147 | - if (mii_val[MII_BMCR] == 0xffff) { | |
148 | + if (mii_val[MII_BMCR] == 0xffff || mii_val[MII_BMSR] == 0x0000) { | |
149 | fprintf(stderr, " No MII transceiver present!.\n"); | |
150 | return -1; | |
151 | } | |
152 | @@ -228,6 +253,7 @@ int show_basic_mii(int sock, int phy_id) | |
153 | /* Descriptive rename. */ | |
154 | bmcr = mii_val[MII_BMCR]; bmsr = mii_val[MII_BMSR]; | |
155 | advert = mii_val[MII_ADVERTISE]; lkpar = mii_val[MII_LPA]; | |
156 | + bmcr2 = mii_val[MII_CTRL1000]; lpa2 = mii_val[MII_STAT1000]; | |
157 | ||
158 | sprintf(buf, "%s: ", ifr.ifr_name); | |
159 | if (bmcr & BMCR_ANENABLE) { | |
160 | @@ -235,7 +261,7 @@ int show_basic_mii(int sock, int phy_id) | |
161 | if (advert & lkpar) { | |
162 | strcat(buf, (lkpar & LPA_LPACK) ? | |
163 | "negotiated" : "no autonegotiation,"); | |
164 | - strcat(buf, media_list(advert & lkpar, 1)); | |
165 | + strcat(buf, media_list(advert & lkpar, bmcr2 & lpa2>>2, 1)); | |
166 | strcat(buf, ", "); | |
167 | } else { | |
168 | strcat(buf, "autonegotiation failed, "); | |
169 | @@ -245,8 +271,10 @@ int show_basic_mii(int sock, int phy_id) | |
170 | } | |
171 | } else { | |
172 | sprintf(buf+strlen(buf), "%s Mbit, %s duplex, ", | |
173 | - (bmcr & BMCR_SPEED100) ? "100" : "10", | |
174 | - (bmcr & BMCR_FULLDPLX) ? "full" : "half"); | |
175 | + ((bmcr2 & (ADVERTISE_1000HALF | ADVERTISE_1000FULL)) & lpa2 >> 2) | |
176 | + ? "1000" | |
177 | + : (bmcr & BMCR_SPEED100) ? "100" : "10", | |
178 | + (bmcr & BMCR_FULLDPLX) ? "full" : "half"); | |
179 | } | |
180 | strcat(buf, (bmsr & BMSR_LSTATUS) ? "link ok" : "no link"); | |
181 | ||
182 | @@ -307,10 +335,10 @@ int show_basic_mii(int sock, int phy_id) | |
183 | if (bmsr & BMSR_RFAULT) | |
184 | printf("remote fault, "); | |
185 | printf((bmsr & BMSR_LSTATUS) ? "link ok" : "no link"); | |
186 | - printf("\n capabilities:%s", media_list(bmsr >> 6, 0)); | |
187 | - printf("\n advertising: %s", media_list(advert, 0)); | |
188 | + printf("\n capabilities:%s", media_list(bmsr >> 6, bmcr2, 0)); | |
189 | + printf("\n advertising: %s", media_list(advert, lpa2 >> 2, 0)); | |
190 | if (lkpar & LPA_ABILITY_MASK) | |
191 | - printf("\n link partner:%s", media_list(lkpar, 0)); | |
192 | + printf("\n link partner:%s", media_list(lkpar, bmcr2, 0)); | |
193 | printf("\n"); | |
194 | } | |
195 | fflush(stdout); | |
196 | @@ -341,7 +369,7 @@ static int do_one_xcvr(int skfd, char *i | |
197 | printf("resetting the transceiver...\n"); | |
198 | mdio_write(skfd, MII_BMCR, BMCR_RESET); | |
199 | } | |
200 | - if (nway_advertise) { | |
201 | + if (nway_advertise > 0) { | |
202 | mdio_write(skfd, MII_ADVERTISE, nway_advertise | 1); | |
203 | opt_restart = 1; | |
204 | } | |
205 | @@ -400,18 +428,20 @@ usage: %s [-VvRrwl] [-A media,... | -F m | |
206 | -l, --log with -w, write events to syslog\n\ | |
207 | -A, --advertise=media,... advertise only specified media\n\ | |
208 | -F, --force=media force specified media technology\n\ | |
209 | -media: 100baseT4, 100baseTx-FD, 100baseTx-HD, 10baseT-FD, 10baseT-HD,\n\ | |
210 | +media: 1000baseTx-HD, 1000baseTx-FD,\n\ | |
211 | + 100baseT4, 100baseTx-FD, 100baseTx-HD, 10baseT-FD, 10baseT-HD,\n\ | |
212 | (to advertise both HD and FD) 100baseTx, 10baseT\n"; | |
213 | ||
214 | int main(int argc, char **argv) | |
215 | { | |
216 | int i, c, ret, errflag = 0; | |
217 | char s[6]; | |
218 | - | |
219 | + unsigned ctrl1000 = 0; | |
220 | + | |
221 | while ((c = getopt_long(argc, argv, "A:F:p:lrRvVw?", longopts, 0)) != EOF) | |
222 | switch (c) { | |
223 | - case 'A': nway_advertise = parse_media(optarg); break; | |
224 | - case 'F': fixed_speed = parse_media(optarg); break; | |
225 | + case 'A': nway_advertise = parse_media(optarg, &ctrl1000); break; | |
226 | + case 'F': fixed_speed = parse_media(optarg, &ctrl1000); break; | |
227 | case 'p': override_phy = atoi(optarg); break; | |
228 | case 'r': opt_restart++; break; | |
229 | case 'R': opt_reset++; break; | |
230 | @@ -423,6 +453,10 @@ int main(int argc, char **argv) | |
231 | } | |
232 | /* Check for a few inappropriate option combinations */ | |
233 | if (opt_watch) verbose = 0; | |
234 | + | |
235 | + if ((nway_advertise < 0) || (fixed_speed < 0)) | |
236 | + return 2; | |
237 | + | |
238 | if (errflag || (fixed_speed & (fixed_speed-1)) || | |
239 | (fixed_speed && (opt_restart || nway_advertise))) { | |
240 | fprintf(stderr, usage, argv[0]); |