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