source: SVN/rincon/u-boot/cpu/arm920t/at91rm9200/ether.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 7.3 KB
Line 
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#include <miiphy.h>
27
28/* ----- Ethernet Buffer definitions ----- */
29
30typedef struct {
31        unsigned long addr, size;
32} rbf_t;
33
34#define RBF_ADDR      0xfffffffc
35#define RBF_OWNER     (1<<0)
36#define RBF_WRAP      (1<<1)
37#define RBF_BROADCAST (1<<31)
38#define RBF_MULTICAST (1<<30)
39#define RBF_UNICAST   (1<<29)
40#define RBF_EXTERNAL  (1<<28)
41#define RBF_UNKOWN    (1<<27)
42#define RBF_SIZE      0x07ff
43#define RBF_LOCAL4    (1<<26)
44#define RBF_LOCAL3    (1<<25)
45#define RBF_LOCAL2    (1<<24)
46#define RBF_LOCAL1    (1<<23)
47
48#define RBF_FRAMEMAX 64
49#define RBF_FRAMELEN 0x600
50
51#ifdef CONFIG_DRIVER_ETHER
52
53#if defined(CONFIG_CMD_NET)
54
55/* alignment as per Errata #11 (64 bytes) is insufficient! */
56rbf_t rbfdt[RBF_FRAMEMAX] __attribute((aligned(512)));
57rbf_t *rbfp;
58
59unsigned char rbf_framebuf[RBF_FRAMEMAX][RBF_FRAMELEN] __attribute((aligned(4)));
60
61/* structure to interface the PHY */
62AT91S_PhyOps PhyOps;
63
64AT91PS_EMAC p_mac;
65
66/*********** EMAC Phy layer Management functions *************************/
67/*
68 * Name:
69 *      at91rm9200_EmacEnableMDIO
70 * Description:
71 *      Enables the MDIO bit in MAC control register
72 * Arguments:
73 *      p_mac - pointer to struct AT91S_EMAC
74 * Return value:
75 *      none
76 */
77void at91rm9200_EmacEnableMDIO (AT91PS_EMAC p_mac)
78{
79        /* Mac CTRL reg set for MDIO enable */
80        p_mac->EMAC_CTL |= AT91C_EMAC_MPE;      /* Management port enable */
81}
82
83/*
84 * Name:
85 *      at91rm9200_EmacDisableMDIO
86 * Description:
87 *      Disables the MDIO bit in MAC control register
88 * Arguments:
89 *      p_mac - pointer to struct AT91S_EMAC
90 * Return value:
91 *      none
92 */
93void at91rm9200_EmacDisableMDIO (AT91PS_EMAC p_mac)
94{
95        /* Mac CTRL reg set for MDIO disable */
96        p_mac->EMAC_CTL &= ~AT91C_EMAC_MPE;     /* Management port disable */
97}
98
99
100/*
101 * Name:
102 *      at91rm9200_EmacReadPhy
103 * Description:
104 *      Reads data from the PHY register
105 * Arguments:
106 *      dev - pointer to struct net_device
107 *      RegisterAddress - unsigned char
108 *      pInput - pointer to value read from register
109 * Return value:
110 *      TRUE - if data read successfully
111 */
112UCHAR at91rm9200_EmacReadPhy (AT91PS_EMAC p_mac,
113                                     unsigned char RegisterAddress,
114                                     unsigned short *pInput)
115{
116        p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) |
117                          (AT91C_EMAC_RW_R) |
118                          (RegisterAddress << 18) |
119                          (AT91C_EMAC_CODE_802_3);
120
121        udelay (10000);
122
123        *pInput = (unsigned short) p_mac->EMAC_MAN;
124
125        return TRUE;
126}
127
128
129/*
130 * Name:
131 *      at91rm9200_EmacWritePhy
132 * Description:
133 *      Writes data to the PHY register
134 * Arguments:
135 *      dev - pointer to struct net_device
136 *      RegisterAddress - unsigned char
137 *      pOutput - pointer to value to be written in the register
138 * Return value:
139 *      TRUE - if data read successfully
140 */
141UCHAR at91rm9200_EmacWritePhy (AT91PS_EMAC p_mac,
142                                      unsigned char RegisterAddress,
143                                      unsigned short *pOutput)
144{
145        p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) |
146                        AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_W |
147                        (RegisterAddress << 18) | *pOutput;
148
149        udelay (10000);
150
151        return TRUE;
152}
153
154int eth_init (bd_t * bd)
155{
156        int ret;
157        int i;
158
159        p_mac = AT91C_BASE_EMAC;
160
161        /* PIO Disable Register */
162        *AT91C_PIOA_PDR = AT91C_PA16_EMDIO | AT91C_PA15_EMDC | AT91C_PA14_ERXER |
163                          AT91C_PA13_ERX1 | AT91C_PA12_ERX0 | AT91C_PA11_ECRS_ECRSDV |
164                          AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN |
165                          AT91C_PA7_ETXCK_EREFCK;
166
167#ifdef CONFIG_AT91C_USE_RMII
168        *AT91C_PIOB_PDR = AT91C_PB19_ERXCK;
169        *AT91C_PIOB_BSR = AT91C_PB19_ERXCK;
170#else
171        *AT91C_PIOB_PDR = AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV |
172                          AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER |
173                          AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
174
175        /* Select B Register */
176        *AT91C_PIOB_BSR = AT91C_PB19_ERXCK | AT91C_PB18_ECOL |
177                          AT91C_PB17_ERXDV | AT91C_PB16_ERX3 | AT91C_PB15_ERX2 |
178                          AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
179#endif
180
181        *AT91C_PMC_PCER = 1 << AT91C_ID_EMAC;   /* Peripheral Clock Enable Register */
182
183        p_mac->EMAC_CFG |= AT91C_EMAC_CSR;      /* Clear statistics */
184
185        /* Init Ehternet buffers */
186        for (i = 0; i < RBF_FRAMEMAX; i++) {
187                rbfdt[i].addr = (unsigned long)rbf_framebuf[i];
188                rbfdt[i].size = 0;
189        }
190        rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP;
191        rbfp = &rbfdt[0];
192
193        p_mac->EMAC_SA2L = (bd->bi_enetaddr[3] << 24) | (bd->bi_enetaddr[2] << 16)
194                         | (bd->bi_enetaddr[1] <<  8) | (bd->bi_enetaddr[0]);
195        p_mac->EMAC_SA2H = (bd->bi_enetaddr[5] <<  8) | (bd->bi_enetaddr[4]);
196
197        p_mac->EMAC_RBQP = (long) (&rbfdt[0]);
198        p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
199
200        p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC)
201                        & ~AT91C_EMAC_CLK;
202
203#ifdef CONFIG_AT91C_USE_RMII
204        p_mac->EMAC_CFG |= AT91C_EMAC_RMII;
205#endif
206
207#if (AT91C_MASTER_CLOCK > 40000000)
208        /* MDIO clock must not exceed 2.5 MHz, so enable MCK divider */
209        p_mac->EMAC_CFG |= AT91C_EMAC_CLK_HCLK_64;
210#endif
211
212        p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE;
213
214        at91rm9200_GetPhyInterface (& PhyOps);
215
216        if (!PhyOps.IsPhyConnected (p_mac))
217                printf ("PHY not connected!!\n\r");
218
219        /* MII management start from here */
220        if (!(p_mac->EMAC_SR & AT91C_EMAC_LINK)) {
221                if (!(ret = PhyOps.Init (p_mac))) {
222                        printf ("MAC: error during MII initialization\n");
223                        return 0;
224                }
225        } else {
226                printf ("No link\n\r");
227                return 0;
228        }
229
230        return 0;
231}
232
233int eth_send (volatile void *packet, int length)
234{
235        while (!(p_mac->EMAC_TSR & AT91C_EMAC_BNQ));
236        p_mac->EMAC_TAR = (long) packet;
237        p_mac->EMAC_TCR = length;
238        while (p_mac->EMAC_TCR & 0x7ff);
239        p_mac->EMAC_TSR |= AT91C_EMAC_COMP;
240        return 0;
241}
242
243int eth_rx (void)
244{
245        int size;
246
247        if (!(rbfp->addr & RBF_OWNER))
248                return 0;
249
250        size = rbfp->size & RBF_SIZE;
251        NetReceive ((volatile uchar *) (rbfp->addr & RBF_ADDR), size);
252
253        rbfp->addr &= ~RBF_OWNER;
254        if (rbfp->addr & RBF_WRAP)
255                rbfp = &rbfdt[0];
256        else
257                rbfp++;
258
259        p_mac->EMAC_RSR |= AT91C_EMAC_REC;
260
261        return size;
262}
263
264void eth_halt (void)
265{
266};
267
268#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
269int  at91rm9200_miiphy_read(char *devname, unsigned char addr,
270                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
278int  at91rm9200_miiphy_write(char *devname, unsigned char addr,
279                unsigned char reg, unsigned short value)
280{
281        at91rm9200_EmacEnableMDIO (p_mac);
282        at91rm9200_EmacWritePhy (p_mac, reg, &value);
283        at91rm9200_EmacDisableMDIO (p_mac);
284        return 0;
285}
286
287#endif
288
289int at91rm9200_miiphy_initialize(bd_t *bis)
290{
291#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
292        miiphy_register("at91rm9200phy", at91rm9200_miiphy_read, at91rm9200_miiphy_write);
293#endif
294        return 0;
295}
296
297#endif
298
299#endif  /* CONFIG_DRIVER_ETHER */
Note: See TracBrowser for help on using the repository browser.