1
2
3
4
5
6
7
8
9
10
11
12#include <common.h>
13#include <net.h>
14#include <malloc.h>
15#include <linux/errno.h>
16#include <linux/immap_qe.h>
17#include <asm/io.h>
18#include "uccf.h"
19#include "uec.h"
20#include "uec_phy.h"
21#include "miiphy.h"
22#include <fsl_qe.h>
23#include <phy.h>
24
25#define ugphy_printk(format, arg...) \
26 printf(format "\n", ## arg)
27
28#define ugphy_dbg(format, arg...) \
29 ugphy_printk(format , ## arg)
30#define ugphy_err(format, arg...) \
31 ugphy_printk(format , ## arg)
32#define ugphy_info(format, arg...) \
33 ugphy_printk(format , ## arg)
34#define ugphy_warn(format, arg...) \
35 ugphy_printk(format , ## arg)
36
37#ifdef UEC_VERBOSE_DEBUG
38#define ugphy_vdbg ugphy_dbg
39#else
40#define ugphy_vdbg(ugeth, fmt, args...) do { } while (0)
41#endif
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74#ifndef CONFIG_FIXED_PHY
75#define CONFIG_FIXED_PHY 0xFFFFFFFF
76#endif
77
78#ifndef CONFIG_SYS_FIXED_PHY_PORTS
79#define CONFIG_SYS_FIXED_PHY_PORTS
80#endif
81
82struct fixed_phy_port {
83 char name[16];
84 unsigned int speed;
85 unsigned int duplex;
86};
87
88static const struct fixed_phy_port fixed_phy_port[] = {
89 CONFIG_SYS_FIXED_PHY_PORTS
90};
91
92
93
94
95
96
97
98
99
100
101
102
103#ifndef CONFIG_SYS_BITBANG_PHY_PORTS
104#define CONFIG_SYS_BITBANG_PHY_PORTS
105#endif
106
107#if defined(CONFIG_BITBANGMII)
108static const char *bitbang_phy_port[] = {
109 CONFIG_SYS_BITBANG_PHY_PORTS
110};
111#endif
112
113static void config_genmii_advert (struct uec_mii_info *mii_info);
114static void genmii_setup_forced (struct uec_mii_info *mii_info);
115static void genmii_restart_aneg (struct uec_mii_info *mii_info);
116static int gbit_config_aneg (struct uec_mii_info *mii_info);
117static int genmii_config_aneg (struct uec_mii_info *mii_info);
118static int genmii_update_link (struct uec_mii_info *mii_info);
119static int genmii_read_status (struct uec_mii_info *mii_info);
120u16 uec_phy_read(struct uec_mii_info *mii_info, u16 regnum);
121void uec_phy_write(struct uec_mii_info *mii_info, u16 regnum, u16 val);
122
123
124
125
126void uec_write_phy_reg (struct eth_device *dev, int mii_id, int regnum, int value)
127{
128 uec_private_t *ugeth = (uec_private_t *) dev->priv;
129 uec_mii_t *ug_regs;
130 enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum;
131 u32 tmp_reg;
132
133
134#if defined(CONFIG_BITBANGMII)
135 u32 i = 0;
136
137 for (i = 0; i < ARRAY_SIZE(bitbang_phy_port); i++) {
138 if (strncmp(dev->name, bitbang_phy_port[i],
139 sizeof(dev->name)) == 0) {
140 (void)bb_miiphy_write(NULL, mii_id, regnum, value);
141 return;
142 }
143 }
144#endif
145
146 ug_regs = ugeth->uec_mii_regs;
147
148
149 out_be32 (&ug_regs->miimcom, 0);
150
151 tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg;
152 out_be32 (&ug_regs->miimadd, tmp_reg);
153
154
155 out_be32 (&ug_regs->miimcon, (u32) value);
156 sync();
157
158
159 while ((in_be32 (&ug_regs->miimind)) & MIIMIND_BUSY);
160}
161
162
163
164
165int uec_read_phy_reg (struct eth_device *dev, int mii_id, int regnum)
166{
167 uec_private_t *ugeth = (uec_private_t *) dev->priv;
168 uec_mii_t *ug_regs;
169 enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum;
170 u32 tmp_reg;
171 u16 value;
172
173
174#if defined(CONFIG_BITBANGMII)
175 u32 i = 0;
176
177 for (i = 0; i < ARRAY_SIZE(bitbang_phy_port); i++) {
178 if (strncmp(dev->name, bitbang_phy_port[i],
179 sizeof(dev->name)) == 0) {
180 (void)bb_miiphy_read(NULL, mii_id, regnum, &value);
181 return (value);
182 }
183 }
184#endif
185
186 ug_regs = ugeth->uec_mii_regs;
187
188
189 tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg;
190 out_be32 (&ug_regs->miimadd, tmp_reg);
191
192
193 out_be32 (&ug_regs->miimcom, 0);
194 sync();
195
196
197 out_be32 (&ug_regs->miimcom, MIIMCOM_READ_CYCLE);
198
199
200 while ((in_be32 (&ug_regs->miimind)) &
201 (MIIMIND_NOT_VALID | MIIMIND_BUSY));
202
203
204 value = (u16) in_be32 (&ug_regs->miimstat);
205 if (value == 0xffff)
206 ugphy_vdbg
207 ("read wrong value : mii_id %d,mii_reg %d, base %08x",
208 mii_id, mii_reg, (u32) & (ug_regs->miimcfg));
209
210 return (value);
211}
212
213void mii_clear_phy_interrupt (struct uec_mii_info *mii_info)
214{
215 if (mii_info->phyinfo->ack_interrupt)
216 mii_info->phyinfo->ack_interrupt (mii_info);
217}
218
219void mii_configure_phy_interrupt (struct uec_mii_info *mii_info,
220 u32 interrupts)
221{
222 mii_info->interrupts = interrupts;
223 if (mii_info->phyinfo->config_intr)
224 mii_info->phyinfo->config_intr (mii_info);
225}
226
227
228
229
230
231static void config_genmii_advert (struct uec_mii_info *mii_info)
232{
233 u32 advertise;
234 u16 adv;
235
236
237 mii_info->advertising &= mii_info->phyinfo->features;
238 advertise = mii_info->advertising;
239
240
241 adv = uec_phy_read(mii_info, MII_ADVERTISE);
242 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
243 if (advertise & ADVERTISED_10baseT_Half)
244 adv |= ADVERTISE_10HALF;
245 if (advertise & ADVERTISED_10baseT_Full)
246 adv |= ADVERTISE_10FULL;
247 if (advertise & ADVERTISED_100baseT_Half)
248 adv |= ADVERTISE_100HALF;
249 if (advertise & ADVERTISED_100baseT_Full)
250 adv |= ADVERTISE_100FULL;
251 uec_phy_write(mii_info, MII_ADVERTISE, adv);
252}
253
254static void genmii_setup_forced (struct uec_mii_info *mii_info)
255{
256 u16 ctrl;
257 u32 features = mii_info->phyinfo->features;
258
259 ctrl = uec_phy_read(mii_info, MII_BMCR);
260
261 ctrl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 |
262 BMCR_SPEED1000 | BMCR_ANENABLE);
263 ctrl |= BMCR_RESET;
264
265 switch (mii_info->speed) {
266 case SPEED_1000:
267 if (features & (SUPPORTED_1000baseT_Half
268 | SUPPORTED_1000baseT_Full)) {
269 ctrl |= BMCR_SPEED1000;
270 break;
271 }
272 mii_info->speed = SPEED_100;
273 case SPEED_100:
274 if (features & (SUPPORTED_100baseT_Half
275 | SUPPORTED_100baseT_Full)) {
276 ctrl |= BMCR_SPEED100;
277 break;
278 }
279 mii_info->speed = SPEED_10;
280 case SPEED_10:
281 if (features & (SUPPORTED_10baseT_Half
282 | SUPPORTED_10baseT_Full))
283 break;
284 default:
285 ugphy_err ("%s: Bad speed!", mii_info->dev->name);
286 break;
287 }
288
289 uec_phy_write(mii_info, MII_BMCR, ctrl);
290}
291
292
293static void genmii_restart_aneg (struct uec_mii_info *mii_info)
294{
295 u16 ctl;
296
297 ctl = uec_phy_read(mii_info, MII_BMCR);
298 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
299 uec_phy_write(mii_info, MII_BMCR, ctl);
300}
301
302static int gbit_config_aneg (struct uec_mii_info *mii_info)
303{
304 u16 adv;
305 u32 advertise;
306
307 if (mii_info->autoneg) {
308
309 config_genmii_advert (mii_info);
310 advertise = mii_info->advertising;
311
312 adv = uec_phy_read(mii_info, MII_CTRL1000);
313 adv &= ~(ADVERTISE_1000FULL |
314 ADVERTISE_1000HALF);
315 if (advertise & SUPPORTED_1000baseT_Half)
316 adv |= ADVERTISE_1000HALF;
317 if (advertise & SUPPORTED_1000baseT_Full)
318 adv |= ADVERTISE_1000FULL;
319 uec_phy_write(mii_info, MII_CTRL1000, adv);
320
321
322 genmii_restart_aneg (mii_info);
323 } else
324 genmii_setup_forced (mii_info);
325
326 return 0;
327}
328
329static int marvell_config_aneg (struct uec_mii_info *mii_info)
330{
331
332
333
334 uec_phy_write(mii_info, MII_BMCR, BMCR_RESET);
335
336 uec_phy_write(mii_info, 0x1d, 0x1f);
337 uec_phy_write(mii_info, 0x1e, 0x200c);
338 uec_phy_write(mii_info, 0x1d, 0x5);
339 uec_phy_write(mii_info, 0x1e, 0);
340 uec_phy_write(mii_info, 0x1e, 0x100);
341
342 gbit_config_aneg (mii_info);
343
344 return 0;
345}
346
347static int genmii_config_aneg (struct uec_mii_info *mii_info)
348{
349 if (mii_info->autoneg) {
350
351
352 if (!genmii_read_status(mii_info) && mii_info->link)
353 if (mii_info->duplex == DUPLEX_FULL &&
354 mii_info->speed == SPEED_100)
355 if (mii_info->advertising &
356 ADVERTISED_100baseT_Full)
357 return 0;
358
359 config_genmii_advert (mii_info);
360 genmii_restart_aneg (mii_info);
361 } else
362 genmii_setup_forced (mii_info);
363
364 return 0;
365}
366
367static int genmii_update_link (struct uec_mii_info *mii_info)
368{
369 u16 status;
370
371
372 uec_phy_read(mii_info, MII_BMSR);
373
374
375
376
377
378 status = uec_phy_read(mii_info, MII_BMSR);
379 if ((status & BMSR_LSTATUS) && (status & BMSR_ANEGCAPABLE)
380 && !(status & BMSR_ANEGCOMPLETE)) {
381 int i = 0;
382
383 while (!(status & BMSR_ANEGCOMPLETE)) {
384
385
386
387 if (i > UGETH_AN_TIMEOUT) {
388 mii_info->link = 0;
389 return 0;
390 }
391
392 i++;
393 udelay(1000);
394 status = uec_phy_read(mii_info, MII_BMSR);
395 }
396 mii_info->link = 1;
397 } else {
398 if (status & BMSR_LSTATUS)
399 mii_info->link = 1;
400 else
401 mii_info->link = 0;
402 }
403
404 return 0;
405}
406
407static int genmii_read_status (struct uec_mii_info *mii_info)
408{
409 u16 status;
410 int err;
411
412
413
414 err = genmii_update_link (mii_info);
415 if (err)
416 return err;
417
418 if (mii_info->autoneg) {
419 status = uec_phy_read(mii_info, MII_STAT1000);
420
421 if (status & (LPA_1000FULL | LPA_1000HALF)) {
422 mii_info->speed = SPEED_1000;
423 if (status & LPA_1000FULL)
424 mii_info->duplex = DUPLEX_FULL;
425 else
426 mii_info->duplex = DUPLEX_HALF;
427 } else {
428 status = uec_phy_read(mii_info, MII_LPA);
429
430 if (status & (LPA_10FULL | LPA_100FULL))
431 mii_info->duplex = DUPLEX_FULL;
432 else
433 mii_info->duplex = DUPLEX_HALF;
434 if (status & (LPA_100FULL | LPA_100HALF))
435 mii_info->speed = SPEED_100;
436 else
437 mii_info->speed = SPEED_10;
438 }
439 mii_info->pause = 0;
440 }
441
442
443
444
445 return 0;
446}
447
448static int bcm_init(struct uec_mii_info *mii_info)
449{
450 struct eth_device *edev = mii_info->dev;
451 uec_private_t *uec = edev->priv;
452
453 gbit_config_aneg(mii_info);
454
455 if ((uec->uec_info->enet_interface_type ==
456 PHY_INTERFACE_MODE_RGMII_RXID) &&
457 (uec->uec_info->speed == SPEED_1000)) {
458 u16 val;
459 int cnt = 50;
460
461
462 do
463 val = uec_phy_read(mii_info, MII_BMSR);
464 while (--cnt && !(val & BMSR_ANEGCOMPLETE));
465
466
467 uec_phy_write(mii_info, 0x18, 0x7 | (7 << 12));
468
469 val = uec_phy_read(mii_info, 0x18);
470
471 val |= (1 << 8);
472 val |= (7 | (7 << 12));
473
474 val |= (1 << 15);
475 uec_phy_write(mii_info, 0x18, val);
476 }
477
478 return 0;
479}
480
481static int uec_marvell_init(struct uec_mii_info *mii_info)
482{
483 struct eth_device *edev = mii_info->dev;
484 uec_private_t *uec = edev->priv;
485 phy_interface_t iface = uec->uec_info->enet_interface_type;
486 int speed = uec->uec_info->speed;
487
488 if ((speed == SPEED_1000) &&
489 (iface == PHY_INTERFACE_MODE_RGMII_ID ||
490 iface == PHY_INTERFACE_MODE_RGMII_RXID ||
491 iface == PHY_INTERFACE_MODE_RGMII_TXID)) {
492 int temp;
493
494 temp = uec_phy_read(mii_info, MII_M1111_PHY_EXT_CR);
495 if (iface == PHY_INTERFACE_MODE_RGMII_ID) {
496 temp |= MII_M1111_RX_DELAY | MII_M1111_TX_DELAY;
497 } else if (iface == PHY_INTERFACE_MODE_RGMII_RXID) {
498 temp &= ~MII_M1111_TX_DELAY;
499 temp |= MII_M1111_RX_DELAY;
500 } else if (iface == PHY_INTERFACE_MODE_RGMII_TXID) {
501 temp &= ~MII_M1111_RX_DELAY;
502 temp |= MII_M1111_TX_DELAY;
503 }
504 uec_phy_write(mii_info, MII_M1111_PHY_EXT_CR, temp);
505
506 temp = uec_phy_read(mii_info, MII_M1111_PHY_EXT_SR);
507 temp &= ~MII_M1111_HWCFG_MODE_MASK;
508 temp |= MII_M1111_HWCFG_MODE_RGMII;
509 uec_phy_write(mii_info, MII_M1111_PHY_EXT_SR, temp);
510
511 uec_phy_write(mii_info, MII_BMCR, BMCR_RESET);
512 }
513
514 return 0;
515}
516
517static int marvell_read_status (struct uec_mii_info *mii_info)
518{
519 u16 status;
520 int err;
521
522
523
524 err = genmii_update_link (mii_info);
525 if (err)
526 return err;
527
528
529
530
531 if (mii_info->autoneg && mii_info->link) {
532 int speed;
533
534 status = uec_phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS);
535
536
537 if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX)
538 mii_info->duplex = DUPLEX_FULL;
539 else
540 mii_info->duplex = DUPLEX_HALF;
541
542
543 speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK;
544 switch (speed) {
545 case MII_M1011_PHY_SPEC_STATUS_1000:
546 mii_info->speed = SPEED_1000;
547 break;
548 case MII_M1011_PHY_SPEC_STATUS_100:
549 mii_info->speed = SPEED_100;
550 break;
551 default:
552 mii_info->speed = SPEED_10;
553 break;
554 }
555 mii_info->pause = 0;
556 }
557
558 return 0;
559}
560
561static int marvell_ack_interrupt (struct uec_mii_info *mii_info)
562{
563
564 uec_phy_read(mii_info, MII_M1011_IEVENT);
565
566 return 0;
567}
568
569static int marvell_config_intr (struct uec_mii_info *mii_info)
570{
571 if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
572 uec_phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
573 else
574 uec_phy_write(mii_info, MII_M1011_IMASK,
575 MII_M1011_IMASK_CLEAR);
576
577 return 0;
578}
579
580static int dm9161_init (struct uec_mii_info *mii_info)
581{
582
583 uec_phy_write(mii_info, MII_BMCR, uec_phy_read(mii_info, MII_BMCR) |
584 BMCR_RESET);
585
586 uec_phy_write(mii_info, MII_BMCR, uec_phy_read(mii_info, MII_BMCR) &
587 ~BMCR_ISOLATE);
588
589 uec_phy_write(mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT);
590
591 config_genmii_advert (mii_info);
592
593 genmii_config_aneg (mii_info);
594
595 return 0;
596}
597
598static int dm9161_config_aneg (struct uec_mii_info *mii_info)
599{
600 return 0;
601}
602
603static int dm9161_read_status (struct uec_mii_info *mii_info)
604{
605 u16 status;
606 int err;
607
608
609 err = genmii_update_link (mii_info);
610 if (err)
611 return err;
612
613
614 if (mii_info->autoneg && mii_info->link) {
615 status = uec_phy_read(mii_info, MII_DM9161_SCSR);
616 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H))
617 mii_info->speed = SPEED_100;
618 else
619 mii_info->speed = SPEED_10;
620
621 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F))
622 mii_info->duplex = DUPLEX_FULL;
623 else
624 mii_info->duplex = DUPLEX_HALF;
625 }
626
627 return 0;
628}
629
630static int dm9161_ack_interrupt (struct uec_mii_info *mii_info)
631{
632
633 uec_phy_read(mii_info, MII_DM9161_INTR);
634
635 return 0;
636}
637
638static int dm9161_config_intr (struct uec_mii_info *mii_info)
639{
640 if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
641 uec_phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_INIT);
642 else
643 uec_phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_STOP);
644
645 return 0;
646}
647
648static void dm9161_close (struct uec_mii_info *mii_info)
649{
650}
651
652static int fixed_phy_aneg (struct uec_mii_info *mii_info)
653{
654 mii_info->autoneg = 0;
655 return 0;
656}
657
658static int fixed_phy_read_status (struct uec_mii_info *mii_info)
659{
660 int i = 0;
661
662 for (i = 0; i < ARRAY_SIZE(fixed_phy_port); i++) {
663 if (strncmp(mii_info->dev->name, fixed_phy_port[i].name,
664 strlen(mii_info->dev->name)) == 0) {
665 mii_info->speed = fixed_phy_port[i].speed;
666 mii_info->duplex = fixed_phy_port[i].duplex;
667 mii_info->link = 1;
668 mii_info->pause = 0;
669 break;
670 }
671 }
672 return 0;
673}
674
675static int smsc_config_aneg (struct uec_mii_info *mii_info)
676{
677 return 0;
678}
679
680static int smsc_read_status (struct uec_mii_info *mii_info)
681{
682 u16 status;
683 int err;
684
685
686
687 err = genmii_update_link (mii_info);
688 if (err)
689 return err;
690
691
692
693
694 if (mii_info->autoneg && mii_info->link) {
695 int val;
696
697 status = uec_phy_read(mii_info, 0x1f);
698 val = (status & 0x1c) >> 2;
699
700 switch (val) {
701 case 1:
702 mii_info->duplex = DUPLEX_HALF;
703 mii_info->speed = SPEED_10;
704 break;
705 case 5:
706 mii_info->duplex = DUPLEX_FULL;
707 mii_info->speed = SPEED_10;
708 break;
709 case 2:
710 mii_info->duplex = DUPLEX_HALF;
711 mii_info->speed = SPEED_100;
712 break;
713 case 6:
714 mii_info->duplex = DUPLEX_FULL;
715 mii_info->speed = SPEED_100;
716 break;
717 }
718 mii_info->pause = 0;
719 }
720
721 return 0;
722}
723
724static struct phy_info phy_info_dm9161 = {
725 .phy_id = 0x0181b880,
726 .phy_id_mask = 0x0ffffff0,
727 .name = "Davicom DM9161E",
728 .init = dm9161_init,
729 .config_aneg = dm9161_config_aneg,
730 .read_status = dm9161_read_status,
731 .close = dm9161_close,
732};
733
734static struct phy_info phy_info_dm9161a = {
735 .phy_id = 0x0181b8a0,
736 .phy_id_mask = 0x0ffffff0,
737 .name = "Davicom DM9161A",
738 .features = MII_BASIC_FEATURES,
739 .init = dm9161_init,
740 .config_aneg = dm9161_config_aneg,
741 .read_status = dm9161_read_status,
742 .ack_interrupt = dm9161_ack_interrupt,
743 .config_intr = dm9161_config_intr,
744 .close = dm9161_close,
745};
746
747static struct phy_info phy_info_marvell = {
748 .phy_id = 0x01410c00,
749 .phy_id_mask = 0xffffff00,
750 .name = "Marvell 88E11x1",
751 .features = MII_GBIT_FEATURES,
752 .init = &uec_marvell_init,
753 .config_aneg = &marvell_config_aneg,
754 .read_status = &marvell_read_status,
755 .ack_interrupt = &marvell_ack_interrupt,
756 .config_intr = &marvell_config_intr,
757};
758
759static struct phy_info phy_info_bcm5481 = {
760 .phy_id = 0x0143bca0,
761 .phy_id_mask = 0xffffff0,
762 .name = "Broadcom 5481",
763 .features = MII_GBIT_FEATURES,
764 .read_status = genmii_read_status,
765 .init = bcm_init,
766};
767
768static struct phy_info phy_info_fixedphy = {
769 .phy_id = CONFIG_FIXED_PHY,
770 .phy_id_mask = CONFIG_FIXED_PHY,
771 .name = "Fixed PHY",
772 .config_aneg = fixed_phy_aneg,
773 .read_status = fixed_phy_read_status,
774};
775
776static struct phy_info phy_info_smsclan8700 = {
777 .phy_id = 0x0007c0c0,
778 .phy_id_mask = 0xfffffff0,
779 .name = "SMSC LAN8700",
780 .features = MII_BASIC_FEATURES,
781 .config_aneg = smsc_config_aneg,
782 .read_status = smsc_read_status,
783};
784
785static struct phy_info phy_info_genmii = {
786 .phy_id = 0x00000000,
787 .phy_id_mask = 0x00000000,
788 .name = "Generic MII",
789 .features = MII_BASIC_FEATURES,
790 .config_aneg = genmii_config_aneg,
791 .read_status = genmii_read_status,
792};
793
794static struct phy_info *phy_info[] = {
795 &phy_info_dm9161,
796 &phy_info_dm9161a,
797 &phy_info_marvell,
798 &phy_info_bcm5481,
799 &phy_info_smsclan8700,
800 &phy_info_fixedphy,
801 &phy_info_genmii,
802 NULL
803};
804
805u16 uec_phy_read(struct uec_mii_info *mii_info, u16 regnum)
806{
807 return mii_info->mdio_read (mii_info->dev, mii_info->mii_id, regnum);
808}
809
810void uec_phy_write(struct uec_mii_info *mii_info, u16 regnum, u16 val)
811{
812 mii_info->mdio_write (mii_info->dev, mii_info->mii_id, regnum, val);
813}
814
815
816
817
818struct phy_info *uec_get_phy_info (struct uec_mii_info *mii_info)
819{
820 u16 phy_reg;
821 u32 phy_ID;
822 int i;
823 struct phy_info *theInfo = NULL;
824
825
826 phy_reg = uec_phy_read(mii_info, MII_PHYSID1);
827 phy_ID = (phy_reg & 0xffff) << 16;
828
829
830 phy_reg = uec_phy_read(mii_info, MII_PHYSID2);
831 phy_ID |= (phy_reg & 0xffff);
832
833
834
835 for (i = 0; phy_info[i]; i++)
836 if (phy_info[i]->phy_id ==
837 (phy_ID & phy_info[i]->phy_id_mask)) {
838 theInfo = phy_info[i];
839 break;
840 }
841
842
843 if (theInfo == NULL) {
844 ugphy_info ("UEC: PHY id %x is not supported!", phy_ID);
845 return NULL;
846 } else {
847 ugphy_info ("UEC: PHY is %s (%x)", theInfo->name, phy_ID);
848 }
849
850 return theInfo;
851}
852
853void marvell_phy_interface_mode(struct eth_device *dev, phy_interface_t type,
854 int speed)
855{
856 uec_private_t *uec = (uec_private_t *) dev->priv;
857 struct uec_mii_info *mii_info;
858 u16 status;
859
860 if (!uec->mii_info) {
861 printf ("%s: the PHY not initialized\n", __FUNCTION__);
862 return;
863 }
864 mii_info = uec->mii_info;
865
866 if (type == PHY_INTERFACE_MODE_RGMII) {
867 if (speed == SPEED_100) {
868 uec_phy_write(mii_info, 0x00, 0x9140);
869 uec_phy_write(mii_info, 0x1d, 0x001f);
870 uec_phy_write(mii_info, 0x1e, 0x200c);
871 uec_phy_write(mii_info, 0x1d, 0x0005);
872 uec_phy_write(mii_info, 0x1e, 0x0000);
873 uec_phy_write(mii_info, 0x1e, 0x0100);
874 uec_phy_write(mii_info, 0x09, 0x0e00);
875 uec_phy_write(mii_info, 0x04, 0x01e1);
876 uec_phy_write(mii_info, 0x00, 0x9140);
877 uec_phy_write(mii_info, 0x00, 0x1000);
878 udelay (100000);
879 uec_phy_write(mii_info, 0x00, 0x2900);
880 uec_phy_write(mii_info, 0x14, 0x0cd2);
881 uec_phy_write(mii_info, 0x00, 0xa100);
882 uec_phy_write(mii_info, 0x09, 0x0000);
883 uec_phy_write(mii_info, 0x1b, 0x800b);
884 uec_phy_write(mii_info, 0x04, 0x05e1);
885 uec_phy_write(mii_info, 0x00, 0xa100);
886 uec_phy_write(mii_info, 0x00, 0x2100);
887 udelay (1000000);
888 } else if (speed == SPEED_10) {
889 uec_phy_write(mii_info, 0x14, 0x8e40);
890 uec_phy_write(mii_info, 0x1b, 0x800b);
891 uec_phy_write(mii_info, 0x14, 0x0c82);
892 uec_phy_write(mii_info, 0x00, 0x8100);
893 udelay (1000000);
894 }
895 }
896
897
898 if (mii_info->autoneg) {
899 status = uec_phy_read(mii_info, MII_BMCR);
900 uec_phy_write(mii_info, MII_BMCR, status | BMCR_ANENABLE);
901 }
902
903}
904
905void change_phy_interface_mode (struct eth_device *dev,
906 phy_interface_t type, int speed)
907{
908#ifdef CONFIG_PHY_MODE_NEED_CHANGE
909 marvell_phy_interface_mode (dev, type, speed);
910#endif
911}
912