1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#include <at91rm9200_net.h>
30#include <net.h>
31#include <bcm5221.h>
32
33#ifdef CONFIG_DRIVER_ETHER
34
35#if defined(CONFIG_CMD_NET)
36
37
38
39
40
41
42
43
44
45
46
47
48unsigned int bcm5221_IsPhyConnected (AT91PS_EMAC p_mac)
49{
50 unsigned short Id1, Id2;
51
52 at91rm9200_EmacEnableMDIO (p_mac);
53 at91rm9200_EmacReadPhy (p_mac, BCM5221_PHYID1, &Id1);
54 at91rm9200_EmacReadPhy (p_mac, BCM5221_PHYID2, &Id2);
55 at91rm9200_EmacDisableMDIO (p_mac);
56
57 if ((Id1 == (BCM5221_PHYID1_OUI >> 6)) &&
58 ((Id2 >> 10) == (BCM5221_PHYID1_OUI & BCM5221_LSB_MASK)))
59 return TRUE;
60
61 return FALSE;
62}
63
64
65
66
67
68
69
70
71
72
73
74
75
76unsigned char bcm5221_GetLinkSpeed (AT91PS_EMAC p_mac)
77{
78 unsigned short stat1, stat2;
79
80 if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMSR, &stat1))
81 return FALSE;
82
83 if (!(stat1 & BCM5221_LINK_STATUS))
84 return FALSE;
85
86 if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_ACSR, &stat2))
87 return FALSE;
88
89 if ((stat1 & BCM5221_100BASE_TX_FD) && (stat2 & BCM5221_100) && (stat2 & BCM5221_FDX)) {
90
91 p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
92 return TRUE;
93 }
94
95 if ((stat1 & BCM5221_10BASE_T_FD) && !(stat2 & BCM5221_100) && (stat2 & BCM5221_FDX)) {
96
97 p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
98 ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
99 | AT91C_EMAC_FD;
100 return TRUE;
101 }
102
103 if ((stat1 & BCM5221_100BASE_TX_HD) && (stat2 & BCM5221_100) && !(stat2 & BCM5221_FDX)) {
104
105 p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
106 ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
107 | AT91C_EMAC_SPD;
108 return TRUE;
109 }
110
111 if ((stat1 & BCM5221_10BASE_T_HD) && !(stat2 & BCM5221_100) && !(stat2 & BCM5221_FDX)) {
112
113 p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
114 return TRUE;
115 }
116 return FALSE;
117}
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132unsigned char bcm5221_InitPhy (AT91PS_EMAC p_mac)
133{
134 unsigned char ret = TRUE;
135 unsigned short IntValue;
136
137 at91rm9200_EmacEnableMDIO (p_mac);
138
139 if (!bcm5221_GetLinkSpeed (p_mac)) {
140
141 ret = bcm5221_GetLinkSpeed (p_mac);
142 }
143
144
145 at91rm9200_EmacReadPhy (p_mac, BCM5221_INTR, &IntValue);
146
147 IntValue &= ~(BCM5221_FDX_LED | BCM5221_INTR_ENABLE);
148
149 IntValue |= (BCM5221_FDX_MASK | BCM5221_SPD_MASK |
150 BCM5221_LINK_MASK | BCM5221_INTR_MASK);
151 at91rm9200_EmacWritePhy (p_mac, BCM5221_INTR, &IntValue);
152 at91rm9200_EmacDisableMDIO (p_mac);
153
154 return (ret);
155}
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170unsigned char bcm5221_AutoNegotiate (AT91PS_EMAC p_mac, int *status)
171{
172 unsigned short value;
173 unsigned short PhyAnar;
174 unsigned short PhyAnalpar;
175
176
177 if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMCR, &value))
178 return FALSE;
179 value &= ~BCM5221_AUTONEG;
180 value |= BCM5221_ISOLATE;
181 if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value))
182 return FALSE;
183
184
185
186 PhyAnar = BCM5221_TX_FDX | BCM5221_TX_HDX |
187 BCM5221_10_FDX | BCM5221_10_HDX | BCM5221_AN_IEEE_802_3;
188 if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_ANAR, &PhyAnar))
189 return FALSE;
190
191
192 if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMCR, &value))
193 return FALSE;
194
195 value |= BCM5221_SPEED_SELECT | BCM5221_AUTONEG | BCM5221_DUPLEX_MODE;
196 if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value))
197 return FALSE;
198
199 value |= BCM5221_RESTART_AUTONEG;
200 value &= ~BCM5221_ISOLATE;
201 if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value))
202 return FALSE;
203
204
205 udelay (10000);
206 at91rm9200_EmacReadPhy (p_mac, BCM5221_BMSR, &value);
207 if (!(value & BCM5221_AUTONEG_COMP))
208 return FALSE;
209
210
211 if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_ANLPAR, &PhyAnalpar))
212 return FALSE;
213
214 if ((PhyAnar & BCM5221_TX_FDX) && (PhyAnalpar & BCM5221_TX_FDX)) {
215
216 p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
217 return TRUE;
218 }
219
220 if ((PhyAnar & BCM5221_10_FDX) && (PhyAnalpar & BCM5221_10_FDX)) {
221
222 p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
223 ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
224 | AT91C_EMAC_FD;
225 return TRUE;
226 }
227 return FALSE;
228}
229
230#endif
231
232#endif
233