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