1 | BOOL_32 EMAC_Init(void)
|
2 | {
|
3 | /* Initialize the EMAC ethernet controller. */
|
4 | UNS_32 regv,tout,id1,id2;
|
5 |
|
6 | /* Power Up the EMAC controller. */
|
7 | SC->PCONP |= 0x40000000;
|
8 |
|
9 | /* Enable P1 Ethernet Pins. */
|
10 | PINCON->PINSEL2 = 0x50150105;
|
11 | PINCON->PINSEL3 = (PINCON->PINSEL3 & ~0x0000000F) | 0x00000005;
|
12 |
|
13 | /* Reset all EMAC internal modules. */
|
14 | EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX |
|
15 | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES;
|
16 | EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES;
|
17 |
|
18 | /* A short delay after reset. */
|
19 | for (tout = 100; tout; tout--);
|
20 |
|
21 | /* Initialize MAC control registers. */
|
22 | EMAC->MAC1 = MAC1_PASS_ALL;
|
23 | EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
|
24 | EMAC->MAXF = ETH_MAX_FLEN;
|
25 | EMAC->CLRT = CLRT_DEF;
|
26 | EMAC->IPGR = IPGR_DEF;
|
27 |
|
28 | /* Enable Reduced MII interface. */
|
29 | EMAC->MCFG = MCFG_CLK_DIV20 | MCFG_RES_MII;
|
30 | for (tout = 100; tout; tout--);
|
31 | EMAC->MCFG = MCFG_CLK_DIV20;
|
32 |
|
33 | /* Enable Reduced MII interface. */
|
34 | EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM | CR_PASS_RX_FILT;
|
35 |
|
36 | /* Reset Reduced MII Logic. */
|
37 | EMAC->SUPP = SUPP_RES_RMII | SUPP_SPEED;
|
38 | for (tout = 100; tout; tout--);
|
39 | EMAC->SUPP = SUPP_SPEED;
|
40 |
|
41 | /* Put the PHY in reset mode */
|
42 | write_PHY (PHY_REG_BMCR, 0x8000);
|
43 | for (tout = 1000; tout; tout--);
|
44 |
|
45 | /* Wait for hardware reset to end. */
|
46 | for (tout = 0; tout < 0x100000; tout++) {
|
47 | regv = read_PHY (PHY_REG_BMCR);
|
48 |
|
49 | if (!(regv & 0x8000))
|
50 | {
|
51 | /* Reset complete */
|
52 | break;
|
53 | }
|
54 | }
|
55 | if (tout >= 0x100000)
|
56 | return FALSE; /* reset failed */
|
57 |
|
58 | /* Check if this is a DP83848C PHY. */
|
59 | id1 = read_PHY (PHY_REG_IDR1);
|
60 | id2 = read_PHY (PHY_REG_IDR2);
|
61 |
|
62 | if (((id1 << 16) | (id2 & 0xFFF0)) != DP83848C_ID)
|
63 | return FALSE;
|
64 |
|
65 | /* Use autonegotiation about the link speed. */
|
66 | write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG);
|
67 | /* Wait to complete Auto_Negotiation. */
|
68 | for (tout = 0; tout < 0x100000; tout++) {
|
69 | regv = read_PHY (PHY_REG_BMSR);
|
70 | if (regv & 0x0020) {
|
71 | /* Autonegotiation Complete. */
|
72 | break;
|
73 | }
|
74 | }
|
75 | if (tout >= 0x100000)
|
76 | return FALSE; // auto_neg failed
|
77 |
|
78 | /* Check the link status. */
|
79 | for (tout = 0; tout < 0x10000; tout++) {
|
80 | regv = read_PHY (PHY_REG_STS);
|
81 | if (regv & 0x0001)
|
82 | {
|
83 | /* Link is on. */
|
84 | break;
|
85 | }
|
86 | }
|
87 | if (tout >= 0x10000)
|
88 | return FALSE;
|
89 |
|
90 | /* Configure Full/Half Duplex mode. */
|
91 | if (regv & 0x0004)
|
92 | {
|
93 | /* Full duplex is enabled. */
|
94 | EMAC->MAC2 |= MAC2_FULL_DUP;
|
95 | EMAC->Command |= CR_FULL_DUP;
|
96 | EMAC->IPGT = IPGT_FULL_DUP;
|
97 | }
|
98 | else {
|
99 | /* Half duplex mode. */
|
100 | EMAC->IPGT = IPGT_HALF_DUP;
|
101 | }
|
102 |
|
103 | /* Configure 100MBit/10MBit mode. */
|
104 | if (regv & 0x0002) {
|
105 | /* 10MBit mode. */
|
106 | EMAC->SUPP = 0;
|
107 | }
|
108 | else {
|
109 | /* 100MBit mode. */
|
110 | EMAC->SUPP = SUPP_SPEED;
|
111 | }
|
112 | /* Set the Ethernet MAC Address registers */
|
113 | EMAC->SA0 = (MYMAC_6 << 8) | MYMAC_5;
|
114 | EMAC->SA1 = (MYMAC_4 << 8) | MYMAC_3;
|
115 | EMAC->SA2 = (MYMAC_2 << 8) | MYMAC_1;
|
116 |
|
117 | /* Initialize Tx and Rx DMA Descriptors */
|
118 | rx_descr_init ();
|
119 | tx_descr_init ();
|
120 |
|
121 | /* Receive Broadcast and Perfect Match Packets */
|
122 | EMAC->RxFilterCtrl = RFC_BCAST_EN | RFC_PERFECT_EN;
|
123 |
|
124 | /* Enable receive and transmit mode of MAC Ethernet core */
|
125 | EMAC->Command |= (CR_RX_EN | CR_TX_EN);
|
126 | EMAC->MAC1 |= MAC1_REC_EN;
|
127 |
|
128 | return TRUE;
|
129 | }
|