]>
Commit | Line | Data |
---|---|---|
2abbe075 WD |
1 | /* |
2 | * (C) Copyright 2003 | |
3 | * Author : Hamid Ikdoumi (Atmel) | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | */ | |
23 | ||
24 | #include <at91rm9200_net.h> | |
25 | #include <net.h> | |
26 | ||
27 | /* ----- Ethernet Buffer definitions ----- */ | |
28 | ||
29 | typedef struct { | |
30 | unsigned long addr, size; | |
31 | } rbf_t; | |
32 | ||
33 | #define RBF_ADDR 0xfffffffc | |
34 | #define RBF_OWNER (1<<0) | |
35 | #define RBF_WRAP (1<<1) | |
36 | #define RBF_BROADCAST (1<<31) | |
37 | #define RBF_MULTICAST (1<<30) | |
38 | #define RBF_UNICAST (1<<29) | |
39 | #define RBF_EXTERNAL (1<<28) | |
40 | #define RBF_UNKOWN (1<<27) | |
41 | #define RBF_SIZE 0x07ff | |
42 | #define RBF_LOCAL4 (1<<26) | |
43 | #define RBF_LOCAL3 (1<<25) | |
44 | #define RBF_LOCAL2 (1<<24) | |
45 | #define RBF_LOCAL1 (1<<23) | |
46 | ||
47 | /* Emac Buffers in last 512KBytes of SDRAM*/ | |
48 | /* Be careful, buffer size is limited to 512KBytes !!! */ | |
49 | #define RBF_FRAMEMAX 100 | |
50 | /*#define RBF_FRAMEMEM 0x200000 */ | |
51 | #define RBF_FRAMEMEM 0x21F80000 | |
52 | #define RBF_FRAMELEN 0x600 | |
53 | ||
54 | #define RBF_FRAMEBTD RBF_FRAMEMEM | |
55 | #define RBF_FRAMEBUF (RBF_FRAMEMEM + RBF_FRAMEMAX*sizeof(rbf_t)) | |
56 | ||
57 | ||
58 | #ifdef CONFIG_DRIVER_ETHER | |
59 | ||
60 | #if (CONFIG_COMMANDS & CFG_CMD_NET) | |
61 | ||
62 | /* structure to interface the PHY */ | |
429168ea | 63 | AT91S_PhyOps PhyOps; |
2abbe075 WD |
64 | |
65 | AT91PS_EMAC p_mac; | |
66 | ||
2abbe075 WD |
67 | /*********** EMAC Phy layer Management functions *************************/ |
68 | /* | |
8bde7f77 | 69 | * Name: |
2abbe075 | 70 | * at91rm9200_EmacEnableMDIO |
8bde7f77 | 71 | * Description: |
2abbe075 | 72 | * Enables the MDIO bit in MAC control register |
8bde7f77 | 73 | * Arguments: |
2abbe075 | 74 | * p_mac - pointer to struct AT91S_EMAC |
8bde7f77 | 75 | * Return value: |
2abbe075 WD |
76 | * none |
77 | */ | |
429168ea | 78 | void at91rm9200_EmacEnableMDIO (AT91PS_EMAC p_mac) |
2abbe075 WD |
79 | { |
80 | /* Mac CTRL reg set for MDIO enable */ | |
81 | p_mac->EMAC_CTL |= AT91C_EMAC_MPE; /* Management port enable */ | |
82 | } | |
83 | ||
84 | /* | |
8bde7f77 | 85 | * Name: |
2abbe075 | 86 | * at91rm9200_EmacDisableMDIO |
8bde7f77 | 87 | * Description: |
2abbe075 | 88 | * Disables the MDIO bit in MAC control register |
8bde7f77 | 89 | * Arguments: |
2abbe075 | 90 | * p_mac - pointer to struct AT91S_EMAC |
8bde7f77 | 91 | * Return value: |
2abbe075 WD |
92 | * none |
93 | */ | |
429168ea | 94 | void at91rm9200_EmacDisableMDIO (AT91PS_EMAC p_mac) |
2abbe075 WD |
95 | { |
96 | /* Mac CTRL reg set for MDIO disable */ | |
97 | p_mac->EMAC_CTL &= ~AT91C_EMAC_MPE; /* Management port disable */ | |
98 | } | |
99 | ||
100 | ||
101 | /* | |
8bde7f77 | 102 | * Name: |
2abbe075 | 103 | * at91rm9200_EmacReadPhy |
8bde7f77 | 104 | * Description: |
2abbe075 | 105 | * Reads data from the PHY register |
8bde7f77 | 106 | * Arguments: |
2abbe075 WD |
107 | * dev - pointer to struct net_device |
108 | * RegisterAddress - unsigned char | |
8bde7f77 WD |
109 | * pInput - pointer to value read from register |
110 | * Return value: | |
2abbe075 WD |
111 | * TRUE - if data read successfully |
112 | */ | |
429168ea | 113 | UCHAR at91rm9200_EmacReadPhy (AT91PS_EMAC p_mac, |
2abbe075 WD |
114 | unsigned char RegisterAddress, |
115 | unsigned short *pInput) | |
116 | { | |
117 | p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) | | |
074cff0d WD |
118 | (AT91C_EMAC_RW_R) | |
119 | (RegisterAddress << 18) | | |
120 | (AT91C_EMAC_CODE_802_3); | |
2abbe075 WD |
121 | |
122 | udelay (10000); | |
123 | ||
124 | *pInput = (unsigned short) p_mac->EMAC_MAN; | |
125 | ||
126 | return TRUE; | |
127 | } | |
128 | ||
129 | ||
130 | /* | |
8bde7f77 | 131 | * Name: |
2abbe075 | 132 | * at91rm9200_EmacWritePhy |
8bde7f77 | 133 | * Description: |
2abbe075 | 134 | * Writes data to the PHY register |
8bde7f77 | 135 | * Arguments: |
2abbe075 WD |
136 | * dev - pointer to struct net_device |
137 | * RegisterAddress - unsigned char | |
8bde7f77 WD |
138 | * pOutput - pointer to value to be written in the register |
139 | * Return value: | |
2abbe075 WD |
140 | * TRUE - if data read successfully |
141 | */ | |
429168ea | 142 | UCHAR at91rm9200_EmacWritePhy (AT91PS_EMAC p_mac, |
a3ad8e26 WD |
143 | unsigned char RegisterAddress, |
144 | unsigned short *pOutput) | |
2abbe075 WD |
145 | { |
146 | p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) | | |
147 | AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_W | | |
a3ad8e26 | 148 | (RegisterAddress << 18) | *pOutput; |
2abbe075 WD |
149 | |
150 | udelay (10000); | |
151 | ||
152 | return TRUE; | |
153 | } | |
154 | ||
2abbe075 WD |
155 | |
156 | rbf_t *rbfdt; | |
157 | rbf_t *rbfp; | |
158 | ||
159 | int eth_init (bd_t * bd) | |
160 | { | |
161 | int ret; | |
162 | int i; | |
163 | ||
164 | p_mac = AT91C_BASE_EMAC; | |
165 | ||
0b8fa03b WD |
166 | /* PIO Disable Register */ |
167 | *AT91C_PIOA_PDR = AT91C_PA16_EMDIO | AT91C_PA15_EMDC | AT91C_PA14_ERXER | | |
168 | AT91C_PA13_ERX1 | AT91C_PA12_ERX0 | AT91C_PA11_ECRS_ECRSDV | | |
169 | AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN | | |
170 | AT91C_PA7_ETXCK_EREFCK; | |
2abbe075 | 171 | |
ea287deb WD |
172 | #ifdef CONFIG_AT91C_USE_RMII |
173 | *AT91C_PIOB_PDR = AT91C_PB19_ERXCK; | |
174 | *AT91C_PIOB_BSR = AT91C_PB19_ERXCK; | |
175 | #else | |
176 | *AT91C_PIOB_PDR = AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | | |
0b8fa03b WD |
177 | AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER | |
178 | AT91C_PB13_ETX3 | AT91C_PB12_ETX2; | |
2abbe075 | 179 | |
0b8fa03b | 180 | /* Select B Register */ |
ea287deb | 181 | *AT91C_PIOB_BSR = AT91C_PB19_ERXCK | AT91C_PB18_ECOL | |
0b8fa03b WD |
182 | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | |
183 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2; | |
9d5028c2 | 184 | #endif |
2abbe075 WD |
185 | |
186 | *AT91C_PMC_PCER = 1 << AT91C_ID_EMAC; /* Peripheral Clock Enable Register */ | |
187 | ||
188 | p_mac->EMAC_CFG |= AT91C_EMAC_CSR; /* Clear statistics */ | |
189 | ||
190 | /* Init Ehternet buffers */ | |
191 | rbfdt = (rbf_t *) RBF_FRAMEBTD; | |
192 | for (i = 0; i < RBF_FRAMEMAX; i++) { | |
193 | rbfdt[i].addr = RBF_FRAMEBUF + RBF_FRAMELEN * i; | |
194 | rbfdt[i].size = 0; | |
195 | } | |
196 | rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP; | |
197 | rbfp = &rbfdt[0]; | |
198 | ||
0b8fa03b WD |
199 | p_mac->EMAC_SA2L = (bd->bi_enetaddr[3] << 24) | (bd->bi_enetaddr[2] << 16) |
200 | | (bd->bi_enetaddr[1] << 8) | (bd->bi_enetaddr[0]); | |
201 | p_mac->EMAC_SA2H = (bd->bi_enetaddr[5] << 8) | (bd->bi_enetaddr[4]); | |
202 | ||
203 | p_mac->EMAC_RBQP = (long) (&rbfdt[0]); | |
204 | p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA); | |
205 | ||
206 | p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC) | |
207 | & ~AT91C_EMAC_CLK; | |
208 | ||
209 | #ifdef CONFIG_AT91C_USE_RMII | |
210 | p_mac->EMAC_CFG |= AT91C_EMAC_RMII; | |
211 | #endif | |
212 | ||
213 | p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE; | |
214 | ||
429168ea | 215 | at91rm92000_GetPhyInterface (& PhyOps); |
2abbe075 | 216 | |
429168ea | 217 | if (!PhyOps.IsPhyConnected (p_mac)) |
2abbe075 WD |
218 | printf ("PHY not connected!!\n\r"); |
219 | ||
220 | /* MII management start from here */ | |
221 | if (!(p_mac->EMAC_SR & AT91C_EMAC_LINK)) { | |
429168ea | 222 | if (!(ret = PhyOps.Init (p_mac))) { |
2abbe075 WD |
223 | printf ("MAC: error during MII initialization\n"); |
224 | return 0; | |
225 | } | |
226 | } else { | |
227 | printf ("No link\n\r"); | |
228 | return 0; | |
229 | } | |
230 | ||
2abbe075 WD |
231 | return 0; |
232 | } | |
233 | ||
234 | int eth_send (volatile void *packet, int length) | |
235 | { | |
236 | while (!(p_mac->EMAC_TSR & AT91C_EMAC_BNQ)); | |
237 | p_mac->EMAC_TAR = (long) packet; | |
238 | p_mac->EMAC_TCR = length; | |
239 | while (p_mac->EMAC_TCR & 0x7ff); | |
240 | p_mac->EMAC_TSR |= AT91C_EMAC_COMP; | |
241 | return 0; | |
242 | } | |
243 | ||
244 | int eth_rx (void) | |
245 | { | |
246 | int size; | |
247 | ||
248 | if (!(rbfp->addr & RBF_OWNER)) | |
249 | return 0; | |
250 | ||
251 | size = rbfp->size & RBF_SIZE; | |
252 | NetReceive ((volatile uchar *) (rbfp->addr & RBF_ADDR), size); | |
253 | ||
254 | rbfp->addr &= ~RBF_OWNER; | |
255 | if (rbfp->addr & RBF_WRAP) | |
256 | rbfp = &rbfdt[0]; | |
257 | else | |
258 | rbfp++; | |
259 | ||
260 | p_mac->EMAC_RSR |= AT91C_EMAC_REC; | |
261 | ||
262 | return size; | |
263 | } | |
264 | ||
265 | void eth_halt (void) | |
266 | { | |
267 | }; | |
074cff0d WD |
268 | |
269 | #if (CONFIG_COMMANDS & CFG_CMD_MII) | |
270 | int miiphy_read(unsigned char addr, unsigned char reg, unsigned short * value) | |
271 | { | |
272 | at91rm9200_EmacEnableMDIO (p_mac); | |
273 | at91rm9200_EmacReadPhy (p_mac, reg, value); | |
274 | at91rm9200_EmacDisableMDIO (p_mac); | |
275 | return 0; | |
276 | } | |
277 | ||
278 | int miiphy_write(unsigned char addr, unsigned char reg, unsigned short value) | |
279 | { | |
280 | at91rm9200_EmacEnableMDIO (p_mac); | |
281 | at91rm9200_EmacWritePhy (p_mac, reg, &value); | |
282 | at91rm9200_EmacDisableMDIO (p_mac); | |
283 | return 0; | |
284 | } | |
285 | #endif /* CONFIG_COMMANDS & CFG_CMD_MII */ | |
286 | ||
2abbe075 | 287 | #endif /* CONFIG_COMMANDS & CFG_CMD_NET */ |
074cff0d | 288 | |
2abbe075 | 289 | #endif /* CONFIG_DRIVER_ETHER */ |