]>
Commit | Line | Data |
---|---|---|
dd7d41f0 WD |
1 | /* |
2 | * (C) Copyright 2001 | |
3 | * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | */ | |
23 | ||
24 | /* | |
25 | * MII Utilities | |
26 | */ | |
27 | ||
28 | #include <common.h> | |
29 | #include <command.h> | |
dd7d41f0 | 30 | |
c76fe474 | 31 | #if defined(CONFIG_CMD_MII) |
e35745bb WD |
32 | #include <miiphy.h> |
33 | ||
2471111d | 34 | #ifdef CONFIG_TERSE_MII |
dd7d41f0 WD |
35 | /* |
36 | * Display values from last command. | |
37 | */ | |
38 | uint last_op; | |
39 | uint last_addr; | |
40 | uint last_data; | |
41 | uint last_reg; | |
42 | ||
43 | /* | |
63ff004c | 44 | * MII device/info/read/write |
dd7d41f0 WD |
45 | * |
46 | * Syntax: | |
63ff004c MB |
47 | * mii device {devname} |
48 | * mii info {addr} | |
49 | * mii read {addr} {reg} | |
50 | * mii write {addr} {reg} {data} | |
dd7d41f0 | 51 | */ |
dd7d41f0 WD |
52 | int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
53 | { | |
54 | char op; | |
55 | unsigned char addr, reg; | |
56 | unsigned short data; | |
57 | int rcode = 0; | |
63ff004c | 58 | char *devname; |
dd7d41f0 | 59 | |
311d8027 WD |
60 | if (argc < 2) { |
61 | printf ("Usage:\n%s\n", cmdtp->usage); | |
62 | return 1; | |
63 | } | |
64 | ||
bf9e3b38 | 65 | #if defined(CONFIG_8xx) || defined(CONFIG_MCF52x2) |
dd7d41f0 WD |
66 | mii_init (); |
67 | #endif | |
68 | ||
69 | /* | |
70 | * We use the last specified parameters, unless new ones are | |
71 | * entered. | |
72 | */ | |
73 | op = last_op; | |
74 | addr = last_addr; | |
75 | data = last_data; | |
76 | reg = last_reg; | |
77 | ||
78 | if ((flag & CMD_FLAG_REPEAT) == 0) { | |
79 | op = argv[1][0]; | |
80 | if (argc >= 3) | |
81 | addr = simple_strtoul (argv[2], NULL, 16); | |
82 | if (argc >= 4) | |
83 | reg = simple_strtoul (argv[3], NULL, 16); | |
84 | if (argc >= 5) | |
85 | data = simple_strtoul (argv[4], NULL, 16); | |
86 | } | |
87 | ||
63ff004c MB |
88 | /* use current device */ |
89 | devname = miiphy_get_current_dev(); | |
90 | ||
dd7d41f0 | 91 | /* |
63ff004c | 92 | * check device/read/write/list. |
dd7d41f0 WD |
93 | */ |
94 | if (op == 'i') { | |
8bf3b005 | 95 | unsigned char j, start, end; |
dd7d41f0 WD |
96 | unsigned int oui; |
97 | unsigned char model; | |
98 | unsigned char rev; | |
99 | ||
100 | /* | |
101 | * Look for any and all PHYs. Valid addresses are 0..31. | |
102 | */ | |
8bf3b005 | 103 | if (argc >= 3) { |
63ff004c | 104 | start = addr; end = addr + 1; |
8bf3b005 | 105 | } else { |
63ff004c | 106 | start = 0; end = 31; |
8bf3b005 WD |
107 | } |
108 | ||
109 | for (j = start; j < end; j++) { | |
63ff004c | 110 | if (miiphy_info (devname, j, &oui, &model, &rev) == 0) { |
dd7d41f0 WD |
111 | printf ("PHY 0x%02X: " |
112 | "OUI = 0x%04X, " | |
113 | "Model = 0x%02X, " | |
114 | "Rev = 0x%02X, " | |
115 | "%3dbaseT, %s\n", | |
116 | j, oui, model, rev, | |
63ff004c MB |
117 | miiphy_speed (devname, j), |
118 | (miiphy_duplex (devname, j) == FULL) | |
119 | ? "FDX" : "HDX"); | |
dd7d41f0 WD |
120 | } |
121 | } | |
122 | } else if (op == 'r') { | |
63ff004c | 123 | if (miiphy_read (devname, addr, reg, &data) != 0) { |
4b9206ed | 124 | puts ("Error reading from the PHY\n"); |
dd7d41f0 | 125 | rcode = 1; |
63ff004c MB |
126 | } else { |
127 | printf ("%04X\n", data & 0x0000FFFF); | |
dd7d41f0 | 128 | } |
dd7d41f0 | 129 | } else if (op == 'w') { |
63ff004c | 130 | if (miiphy_write (devname, addr, reg, data) != 0) { |
4b9206ed | 131 | puts ("Error writing to the PHY\n"); |
dd7d41f0 WD |
132 | rcode = 1; |
133 | } | |
63ff004c MB |
134 | } else if (op == 'd') { |
135 | if (argc == 2) | |
136 | miiphy_listdev (); | |
137 | else | |
138 | miiphy_set_current_dev (argv[2]); | |
dd7d41f0 WD |
139 | } else { |
140 | printf ("Usage:\n%s\n", cmdtp->usage); | |
141 | return 1; | |
142 | } | |
143 | ||
144 | /* | |
145 | * Save the parameters for repeats. | |
146 | */ | |
147 | last_op = op; | |
148 | last_addr = addr; | |
149 | last_data = data; | |
80885a9d | 150 | last_reg = reg; |
dd7d41f0 WD |
151 | |
152 | return rcode; | |
153 | } | |
154 | ||
8bde7f77 WD |
155 | /***************************************************/ |
156 | ||
0d498393 WD |
157 | U_BOOT_CMD( |
158 | mii, 5, 1, do_mii, | |
8bde7f77 | 159 | "mii - MII utility commands\n", |
63ff004c MB |
160 | "device - list available devices\n" |
161 | "mii device <devname> - set current device\n" | |
162 | "mii info <addr> - display MII PHY info\n" | |
163 | "mii read <addr> <reg> - read MII PHY <addr> register <reg>\n" | |
164 | "mii write <addr> <reg> <data> - write MII PHY <addr> register <reg>\n" | |
8bde7f77 | 165 | ); |
e35745bb WD |
166 | |
167 | #else /* ! CONFIG_TERSE_MII ================================================= */ | |
168 | ||
2471111d WD |
169 | typedef struct _MII_reg_desc_t { |
170 | ushort regno; | |
171 | char * name; | |
172 | } MII_reg_desc_t; | |
173 | ||
174 | MII_reg_desc_t reg_0_5_desc_tbl[] = { | |
175 | { 0, "PHY control register" }, | |
176 | { 1, "PHY status register" }, | |
177 | { 2, "PHY ID 1 register" }, | |
178 | { 3, "PHY ID 2 register" }, | |
179 | { 4, "Autonegotiation advertisement register" }, | |
180 | { 5, "Autonegotiation partner abilities register" }, | |
181 | }; | |
182 | ||
183 | typedef struct _MII_field_desc_t { | |
184 | ushort hi; | |
185 | ushort lo; | |
186 | ushort mask; | |
187 | char * name; | |
188 | } MII_field_desc_t; | |
189 | ||
190 | MII_field_desc_t reg_0_desc_tbl[] = { | |
191 | { 15, 15, 0x01, "reset" }, | |
192 | { 14, 14, 0x01, "loopback" }, | |
193 | { 13, 6, 0x81, "speed selection" }, /* special */ | |
194 | { 12, 12, 0x01, "A/N enable" }, | |
195 | { 11, 11, 0x01, "power-down" }, | |
196 | { 10, 10, 0x01, "isolate" }, | |
197 | { 9, 9, 0x01, "restart A/N" }, | |
198 | { 8, 8, 0x01, "duplex" }, /* special */ | |
199 | { 7, 7, 0x01, "collision test enable" }, | |
200 | { 5, 0, 0x3f, "(reserved)" } | |
201 | }; | |
202 | ||
203 | MII_field_desc_t reg_1_desc_tbl[] = { | |
204 | { 15, 15, 0x01, "100BASE-T4 able" }, | |
205 | { 14, 14, 0x01, "100BASE-X full duplex able" }, | |
206 | { 13, 13, 0x01, "100BASE-X half duplex able" }, | |
207 | { 12, 12, 0x01, "10 Mbps full duplex able" }, | |
208 | { 11, 11, 0x01, "10 Mbps half duplex able" }, | |
209 | { 10, 10, 0x01, "100BASE-T2 full duplex able" }, | |
210 | { 9, 9, 0x01, "100BASE-T2 half duplex able" }, | |
211 | { 8, 8, 0x01, "extended status" }, | |
212 | { 7, 7, 0x01, "(reserved)" }, | |
213 | { 6, 6, 0x01, "MF preamble suppression" }, | |
214 | { 5, 5, 0x01, "A/N complete" }, | |
215 | { 4, 4, 0x01, "remote fault" }, | |
216 | { 3, 3, 0x01, "A/N able" }, | |
217 | { 2, 2, 0x01, "link status" }, | |
218 | { 1, 1, 0x01, "jabber detect" }, | |
219 | { 0, 0, 0x01, "extended capabilities" }, | |
220 | }; | |
221 | ||
222 | MII_field_desc_t reg_2_desc_tbl[] = { | |
223 | { 15, 0, 0xffff, "OUI portion" }, | |
224 | }; | |
225 | ||
226 | MII_field_desc_t reg_3_desc_tbl[] = { | |
227 | { 15, 10, 0x3f, "OUI portion" }, | |
228 | { 9, 4, 0x3f, "manufacturer part number" }, | |
229 | { 3, 0, 0x0f, "manufacturer rev. number" }, | |
230 | }; | |
231 | ||
232 | MII_field_desc_t reg_4_desc_tbl[] = { | |
233 | { 15, 15, 0x01, "next page able" }, | |
234 | { 14, 14, 0x01, "reserved" }, | |
235 | { 13, 13, 0x01, "remote fault" }, | |
236 | { 12, 12, 0x01, "reserved" }, | |
237 | { 11, 11, 0x01, "asymmetric pause" }, | |
238 | { 10, 10, 0x01, "pause enable" }, | |
239 | { 9, 9, 0x01, "100BASE-T4 able" }, | |
240 | { 8, 8, 0x01, "100BASE-TX full duplex able" }, | |
241 | { 7, 7, 0x01, "100BASE-TX able" }, | |
242 | { 6, 6, 0x01, "10BASE-T full duplex able" }, | |
243 | { 5, 5, 0x01, "10BASE-T able" }, | |
244 | { 4, 0, 0x1f, "xxx to do" }, | |
245 | }; | |
246 | ||
247 | MII_field_desc_t reg_5_desc_tbl[] = { | |
248 | { 15, 15, 0x01, "next page able" }, | |
249 | { 14, 14, 0x01, "acknowledge" }, | |
250 | { 13, 13, 0x01, "remote fault" }, | |
251 | { 12, 12, 0x01, "(reserved)" }, | |
252 | { 11, 11, 0x01, "asymmetric pause able" }, | |
253 | { 10, 10, 0x01, "pause able" }, | |
254 | { 9, 9, 0x01, "100BASE-T4 able" }, | |
255 | { 8, 8, 0x01, "100BASE-X full duplex able" }, | |
256 | { 7, 7, 0x01, "100BASE-TX able" }, | |
257 | { 6, 6, 0x01, "10BASE-T full duplex able" }, | |
258 | { 5, 5, 0x01, "10BASE-T able" }, | |
259 | { 4, 0, 0x1f, "xxx to do" }, | |
260 | }; | |
261 | ||
262 | #define DESC0LEN (sizeof(reg_0_desc_tbl)/sizeof(reg_0_desc_tbl[0])) | |
263 | #define DESC1LEN (sizeof(reg_1_desc_tbl)/sizeof(reg_1_desc_tbl[0])) | |
264 | #define DESC2LEN (sizeof(reg_2_desc_tbl)/sizeof(reg_2_desc_tbl[0])) | |
265 | #define DESC3LEN (sizeof(reg_3_desc_tbl)/sizeof(reg_3_desc_tbl[0])) | |
266 | #define DESC4LEN (sizeof(reg_4_desc_tbl)/sizeof(reg_4_desc_tbl[0])) | |
267 | #define DESC5LEN (sizeof(reg_5_desc_tbl)/sizeof(reg_5_desc_tbl[0])) | |
268 | ||
269 | typedef struct _MII_field_desc_and_len_t { | |
270 | MII_field_desc_t * pdesc; | |
271 | ushort len; | |
272 | } MII_field_desc_and_len_t; | |
273 | ||
274 | MII_field_desc_and_len_t desc_and_len_tbl[] = { | |
275 | { reg_0_desc_tbl, DESC0LEN }, | |
276 | { reg_1_desc_tbl, DESC1LEN }, | |
277 | { reg_2_desc_tbl, DESC2LEN }, | |
278 | { reg_3_desc_tbl, DESC3LEN }, | |
279 | { reg_4_desc_tbl, DESC4LEN }, | |
280 | { reg_5_desc_tbl, DESC5LEN }, | |
281 | }; | |
282 | ||
283 | static void dump_reg( | |
284 | ushort regval, | |
285 | MII_reg_desc_t * prd, | |
286 | MII_field_desc_and_len_t * pdl); | |
287 | ||
288 | static int special_field( | |
289 | ushort regno, | |
290 | MII_field_desc_t * pdesc, | |
291 | ushort regval); | |
292 | ||
293 | void MII_dump_0_to_5( | |
294 | ushort regvals[6], | |
295 | uchar reglo, | |
296 | uchar reghi) | |
297 | { | |
298 | ulong i; | |
299 | ||
300 | for (i = 0; i < 6; i++) { | |
301 | if ((reglo <= i) && (i <= reghi)) | |
302 | dump_reg(regvals[i], ®_0_5_desc_tbl[i], | |
303 | &desc_and_len_tbl[i]); | |
304 | } | |
305 | } | |
306 | ||
307 | static void dump_reg( | |
308 | ushort regval, | |
309 | MII_reg_desc_t * prd, | |
310 | MII_field_desc_and_len_t * pdl) | |
311 | { | |
312 | ulong i; | |
313 | ushort mask_in_place; | |
314 | MII_field_desc_t * pdesc; | |
315 | ||
316 | printf("%u. (%04hx) -- %s --\n", | |
317 | prd->regno, regval, prd->name); | |
318 | ||
319 | for (i = 0; i < pdl->len; i++) { | |
320 | pdesc = &pdl->pdesc[i]; | |
321 | ||
322 | mask_in_place = pdesc->mask << pdesc->lo; | |
323 | ||
324 | printf(" (%04hx:%04hx) %u.", | |
325 | mask_in_place, | |
326 | regval & mask_in_place, | |
327 | prd->regno); | |
328 | ||
329 | if (special_field(prd->regno, pdesc, regval)) { | |
330 | } | |
331 | else { | |
332 | if (pdesc->hi == pdesc->lo) | |
333 | printf("%2u ", pdesc->lo); | |
334 | else | |
335 | printf("%2u-%2u", pdesc->hi, pdesc->lo); | |
336 | printf(" = %5u %s", | |
337 | (regval & mask_in_place) >> pdesc->lo, | |
338 | pdesc->name); | |
339 | } | |
340 | printf("\n"); | |
341 | ||
342 | } | |
343 | printf("\n"); | |
344 | } | |
345 | ||
346 | /* Special fields: | |
347 | ** 0.6,13 | |
348 | ** 0.8 | |
349 | ** 2.15-0 | |
350 | ** 3.15-0 | |
351 | ** 4.4-0 | |
352 | ** 5.4-0 | |
353 | */ | |
354 | ||
355 | static int special_field( | |
356 | ushort regno, | |
357 | MII_field_desc_t * pdesc, | |
358 | ushort regval) | |
359 | { | |
360 | if ((regno == 0) && (pdesc->lo == 6)) { | |
b9711de1 | 361 | ushort speed_bits = regval & PHY_BMCR_SPEED_MASK; |
2471111d WD |
362 | printf("%2u,%2u = b%u%u speed selection = %s Mbps", |
363 | 6, 13, | |
364 | (regval >> 6) & 1, | |
365 | (regval >> 13) & 1, | |
b9711de1 WD |
366 | speed_bits == PHY_BMCR_1000_MBPS ? "1000" : |
367 | speed_bits == PHY_BMCR_100_MBPS ? "100" : | |
368 | speed_bits == PHY_BMCR_10_MBPS ? "10" : | |
2471111d WD |
369 | "???"); |
370 | return 1; | |
371 | } | |
372 | ||
373 | else if ((regno == 0) && (pdesc->lo == 8)) { | |
374 | printf("%2u = %5u duplex = %s", | |
375 | pdesc->lo, | |
376 | (regval >> pdesc->lo) & 1, | |
377 | ((regval >> pdesc->lo) & 1) ? "full" : "half"); | |
378 | return 1; | |
379 | } | |
380 | ||
381 | else if ((regno == 4) && (pdesc->lo == 0)) { | |
382 | ushort sel_bits = (regval >> pdesc->lo) & pdesc->mask; | |
383 | printf("%2u-%2u = %5u selector = %s", | |
384 | pdesc->hi, pdesc->lo, sel_bits, | |
b9711de1 | 385 | sel_bits == PHY_ANLPAR_PSB_802_3 ? |
2471111d | 386 | "IEEE 802.3" : |
b9711de1 | 387 | sel_bits == PHY_ANLPAR_PSB_802_9 ? |
2471111d WD |
388 | "IEEE 802.9 ISLAN-16T" : |
389 | "???"); | |
390 | return 1; | |
391 | } | |
392 | ||
393 | else if ((regno == 5) && (pdesc->lo == 0)) { | |
394 | ushort sel_bits = (regval >> pdesc->lo) & pdesc->mask; | |
395 | printf("%2u-%2u = %u selector = %s", | |
396 | pdesc->hi, pdesc->lo, sel_bits, | |
b9711de1 | 397 | sel_bits == PHY_ANLPAR_PSB_802_3 ? |
2471111d | 398 | "IEEE 802.3" : |
b9711de1 | 399 | sel_bits == PHY_ANLPAR_PSB_802_9 ? |
2471111d WD |
400 | "IEEE 802.9 ISLAN-16T" : |
401 | "???"); | |
402 | return 1; | |
403 | } | |
404 | ||
405 | return 0; | |
406 | } | |
407 | ||
63ff004c | 408 | char last_op[2]; |
2471111d WD |
409 | uint last_data; |
410 | uint last_addr_lo; | |
411 | uint last_addr_hi; | |
412 | uint last_reg_lo; | |
413 | uint last_reg_hi; | |
414 | ||
415 | static void extract_range( | |
416 | char * input, | |
417 | unsigned char * plo, | |
418 | unsigned char * phi) | |
419 | { | |
420 | char * end; | |
421 | *plo = simple_strtoul(input, &end, 16); | |
422 | if (*end == '-') { | |
423 | end++; | |
424 | *phi = simple_strtoul(end, NULL, 16); | |
425 | } | |
426 | else { | |
427 | *phi = *plo; | |
428 | } | |
429 | } | |
430 | ||
5cf91d6b | 431 | /* ---------------------------------------------------------------- */ |
2471111d WD |
432 | int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
433 | { | |
63ff004c | 434 | char op[2]; |
2471111d | 435 | unsigned char addrlo, addrhi, reglo, reghi; |
2b792afc | 436 | unsigned char addr, reg; |
2471111d WD |
437 | unsigned short data; |
438 | int rcode = 0; | |
63ff004c | 439 | char *devname; |
2471111d WD |
440 | |
441 | #ifdef CONFIG_8xx | |
442 | mii_init (); | |
443 | #endif | |
444 | ||
445 | /* | |
446 | * We use the last specified parameters, unless new ones are | |
447 | * entered. | |
448 | */ | |
63ff004c MB |
449 | op[0] = last_op[0]; |
450 | op[1] = last_op[1]; | |
2471111d WD |
451 | addrlo = last_addr_lo; |
452 | addrhi = last_addr_hi; | |
453 | reglo = last_reg_lo; | |
454 | reghi = last_reg_hi; | |
455 | data = last_data; | |
456 | ||
457 | if ((flag & CMD_FLAG_REPEAT) == 0) { | |
63ff004c MB |
458 | op[0] = argv[1][0]; |
459 | if (strlen(argv[1]) > 1) | |
460 | op[1] = argv[1][1]; | |
461 | else | |
462 | op[1] = '\0'; | |
463 | ||
2471111d WD |
464 | if (argc >= 3) |
465 | extract_range(argv[2], &addrlo, &addrhi); | |
466 | if (argc >= 4) | |
467 | extract_range(argv[3], ®lo, ®hi); | |
468 | if (argc >= 5) | |
469 | data = simple_strtoul (argv[4], NULL, 16); | |
470 | } | |
471 | ||
63ff004c MB |
472 | /* use current device */ |
473 | devname = miiphy_get_current_dev(); | |
474 | ||
2471111d WD |
475 | /* |
476 | * check info/read/write. | |
477 | */ | |
63ff004c | 478 | if (op[0] == 'i') { |
2471111d WD |
479 | unsigned char j, start, end; |
480 | unsigned int oui; | |
481 | unsigned char model; | |
482 | unsigned char rev; | |
483 | ||
484 | /* | |
485 | * Look for any and all PHYs. Valid addresses are 0..31. | |
486 | */ | |
487 | if (argc >= 3) { | |
2b792afc | 488 | start = addrlo; end = addrhi; |
2471111d | 489 | } else { |
2b792afc | 490 | start = 0; end = 31; |
2471111d WD |
491 | } |
492 | ||
2b792afc | 493 | for (j = start; j <= end; j++) { |
63ff004c | 494 | if (miiphy_info (devname, j, &oui, &model, &rev) == 0) { |
2471111d WD |
495 | printf("PHY 0x%02X: " |
496 | "OUI = 0x%04X, " | |
497 | "Model = 0x%02X, " | |
498 | "Rev = 0x%02X, " | |
499 | "%3dbaseT, %s\n", | |
500 | j, oui, model, rev, | |
63ff004c MB |
501 | miiphy_speed (devname, j), |
502 | (miiphy_duplex (devname, j) == FULL) | |
503 | ? "FDX" : "HDX"); | |
2471111d WD |
504 | } |
505 | } | |
63ff004c | 506 | } else if (op[0] == 'r') { |
2471111d WD |
507 | for (addr = addrlo; addr <= addrhi; addr++) { |
508 | for (reg = reglo; reg <= reghi; reg++) { | |
509 | data = 0xffff; | |
63ff004c | 510 | if (miiphy_read (devname, addr, reg, &data) != 0) { |
2471111d WD |
511 | printf( |
512 | "Error reading from the PHY addr=%02x reg=%02x\n", | |
513 | addr, reg); | |
514 | rcode = 1; | |
2b792afc | 515 | } else { |
2471111d WD |
516 | if ((addrlo != addrhi) || (reglo != reghi)) |
517 | printf("addr=%02x reg=%02x data=", | |
518 | (uint)addr, (uint)reg); | |
519 | printf("%04X\n", data & 0x0000FFFF); | |
520 | } | |
521 | } | |
522 | if ((addrlo != addrhi) && (reglo != reghi)) | |
523 | printf("\n"); | |
524 | } | |
63ff004c | 525 | } else if (op[0] == 'w') { |
2471111d WD |
526 | for (addr = addrlo; addr <= addrhi; addr++) { |
527 | for (reg = reglo; reg <= reghi; reg++) { | |
63ff004c | 528 | if (miiphy_write (devname, addr, reg, data) != 0) { |
2471111d WD |
529 | printf("Error writing to the PHY addr=%02x reg=%02x\n", |
530 | addr, reg); | |
531 | rcode = 1; | |
532 | } | |
533 | } | |
534 | } | |
63ff004c | 535 | } else if (strncmp(op, "du", 2) == 0) { |
2471111d WD |
536 | ushort regs[6]; |
537 | int ok = 1; | |
538 | if ((reglo > 5) || (reghi > 5)) { | |
539 | printf( | |
540 | "The MII dump command only formats the " | |
541 | "standard MII registers, 0-5.\n"); | |
542 | return 1; | |
543 | } | |
544 | for (addr = addrlo; addr <= addrhi; addr++) { | |
63ff004c MB |
545 | for (reg = reglo; reg < reghi + 1; reg++) { |
546 | if (miiphy_read(devname, addr, reg, ®s[reg]) != 0) { | |
2471111d WD |
547 | ok = 0; |
548 | printf( | |
549 | "Error reading from the PHY addr=%02x reg=%02x\n", | |
550 | addr, reg); | |
551 | rcode = 1; | |
552 | } | |
553 | } | |
554 | if (ok) | |
555 | MII_dump_0_to_5(regs, reglo, reghi); | |
556 | printf("\n"); | |
557 | } | |
63ff004c MB |
558 | } else if (strncmp(op, "de", 2) == 0) { |
559 | if (argc == 2) | |
560 | miiphy_listdev (); | |
561 | else | |
562 | miiphy_set_current_dev (argv[2]); | |
2471111d WD |
563 | } else { |
564 | printf("Usage:\n%s\n", cmdtp->usage); | |
565 | return 1; | |
566 | } | |
567 | ||
568 | /* | |
569 | * Save the parameters for repeats. | |
570 | */ | |
63ff004c MB |
571 | last_op[0] = op[0]; |
572 | last_op[1] = op[1]; | |
2471111d WD |
573 | last_addr_lo = addrlo; |
574 | last_addr_hi = addrhi; | |
575 | last_reg_lo = reglo; | |
576 | last_reg_hi = reghi; | |
577 | last_data = data; | |
578 | ||
579 | return rcode; | |
580 | } | |
581 | ||
582 | /***************************************************/ | |
583 | ||
584 | U_BOOT_CMD( | |
585 | mii, 5, 1, do_mii, | |
586 | "mii - MII utility commands\n", | |
63ff004c MB |
587 | "device - list available devices\n" |
588 | "mii device <devname> - set current device\n" | |
589 | "mii info <addr> - display MII PHY info\n" | |
590 | "mii read <addr> <reg> - read MII PHY <addr> register <reg>\n" | |
591 | "mii write <addr> <reg> <data> - write MII PHY <addr> register <reg>\n" | |
592 | "mii dump <addr> <reg> - pretty-print <addr> <reg> (0-5 only)\n" | |
2471111d WD |
593 | "Addr and/or reg may be ranges, e.g. 2-7.\n" |
594 | ); | |
595 | ||
596 | #endif /* CONFIG_TERSE_MII */ | |
8bde7f77 | 597 | |
90253178 | 598 | #endif |