* Patch by Bernhard Kuhn, 28 Nov 2003:
[platform/kernel/u-boot.git] / cpu / coldfire / fec.c
1 /*
2  * (C) Copyright 2000
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
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 <common.h>
25 #include <commproc.h>
26 #include <net.h>
27 #include <command.h>
28
29
30
31 /**************************************************************
32  *
33  * FEC Ethernet Initialization Routine
34  *
35  *************************************************************/
36
37 #define FEC_ECNTRL_ETHER_EN     0x00000002
38 #define FEC_ECNTRL_RESET        0x00000001
39
40 #define FEC_RCNTRL_BC_REJ       0x00000010
41 #define FEC_RCNTRL_PROM         0x00000008
42 #define FEC_RCNTRL_MII_MODE     0x00000004
43 #define FEC_RCNTRL_DRT          0x00000002
44 #define FEC_RCNTRL_LOOP         0x00000001
45
46 #define FEC_TCNTRL_FDEN         0x00000004
47 #define FEC_TCNTRL_HBC          0x00000002
48 #define FEC_TCNTRL_GTS          0x00000001
49
50 #define FEC_RESET_DELAY         50000
51
52
53
54 /* Ethernet Transmit and Receive Buffers */
55 #define DBUF_LENGTH  1520
56
57 #define TX_BUF_CNT 2
58
59 #define TOUT_LOOP 100
60
61 #define PKT_MAXBUF_SIZE         1518
62 #define PKT_MINBUF_SIZE         64
63 #define PKT_MAXBLR_SIZE         1520
64
65
66
67 #ifdef CONFIG_M5272
68 #define FEC_ADDR 0x10000840
69 #endif
70 #ifdef CONFIG_M5282
71 #define FEC_ADDR 0x40001000
72 #endif
73
74 #undef  ET_DEBUG
75
76 #if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(FEC_ENET)
77
78
79
80 static char txbuf[DBUF_LENGTH];
81
82 static uint rxIdx;      /* index of the current RX buffer */
83 static uint txIdx;      /* index of the current TX buffer */
84
85 /*
86   * FEC Ethernet Tx and Rx buffer descriptors allocated at the
87   *  immr->udata_bd address on Dual-Port RAM
88   * Provide for Double Buffering
89   */
90
91 typedef volatile struct CommonBufferDescriptor {
92     cbd_t rxbd[PKTBUFSRX];              /* Rx BD */
93     cbd_t txbd[TX_BUF_CNT];             /* Tx BD */
94 } RTXBD;
95
96 static RTXBD *rtx = 0x380000;
97
98
99 int eth_send(volatile void *packet, int length)
100 {
101         int j, rc;
102         volatile fec_t *fecp = FEC_ADDR;
103
104         /* section 16.9.23.3
105          * Wait for ready
106          */
107         j = 0;
108         while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) {
109                 udelay(1);
110                 j++;
111         }
112         if (j>=TOUT_LOOP) {
113                 printf("TX not ready\n");
114         }
115
116         rtx->txbd[txIdx].cbd_bufaddr = (uint)packet;
117         rtx->txbd[txIdx].cbd_datlen  = length;
118         rtx->txbd[txIdx].cbd_sc |= BD_ENET_TX_READY | BD_ENET_TX_LAST;
119
120         /* Activate transmit Buffer Descriptor polling */
121         fecp->fec_x_des_active = 0x01000000;    /* Descriptor polling active    */
122
123         j = 0;
124         while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) {
125                 udelay(1);
126                 j++;
127         }
128         if (j>=TOUT_LOOP) {
129                 printf("TX timeout\n");
130         }
131 #ifdef ET_DEBUG
132         printf("%s[%d] %s: cycles: %d    status: %x  retry cnt: %d\n",
133         __FILE__,__LINE__,__FUNCTION__,j,rtx->txbd[txIdx].cbd_sc,
134         (rtx->txbd[txIdx].cbd_sc & 0x003C)>>2);
135 #endif
136         /* return only status bits */;
137         rc = (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_STATS);
138
139         txIdx = (txIdx + 1) % TX_BUF_CNT;
140
141         return rc;
142 }
143
144 int eth_rx(void)
145 {
146         int length;
147         volatile fec_t *fecp = FEC_ADDR;
148
149    for (;;)
150    {     
151         /* section 16.9.23.2 */
152         if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
153                 length = -1;
154                 break;     /* nothing received - leave for() loop */
155         }
156
157         length = rtx->rxbd[rxIdx].cbd_datlen;
158
159         if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) {
160 #ifdef ET_DEBUG
161                 printf("%s[%d] err: %x\n",
162                 __FUNCTION__,__LINE__,rtx->rxbd[rxIdx].cbd_sc);
163 #endif
164         } else {
165                 /* Pass the packet up to the protocol layers. */
166                 NetReceive(NetRxPackets[rxIdx], length - 4);
167         }
168
169         /* Give the buffer back to the FEC. */
170         rtx->rxbd[rxIdx].cbd_datlen = 0;
171
172         /* wrap around buffer index when necessary */
173         if ((rxIdx + 1) >= PKTBUFSRX) {
174            rtx->rxbd[PKTBUFSRX - 1].cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
175            rxIdx = 0;
176         } else {
177            rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
178            rxIdx++;
179         }
180         
181         /* Try to fill Buffer Descriptors */
182         fecp->fec_r_des_active = 0x01000000;    /* Descriptor polling active    */
183    }
184
185    return length;
186 }
187
188
189 int eth_init (bd_t * bd)
190 {
191
192         int i;
193         volatile fec_t *fecp = FEC_ADDR;
194         
195         /* Whack a reset.
196          * A delay is required between a reset of the FEC block and
197          * initialization of other FEC registers because the reset takes
198          * some time to complete. If you don't delay, subsequent writes
199          * to FEC registers might get killed by the reset routine which is
200          * still in progress.
201          */
202
203         fecp->fec_ecntrl = FEC_ECNTRL_RESET;
204         for (i = 0;
205              (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
206              ++i) {
207                 udelay (1);
208         }
209         if (i == FEC_RESET_DELAY) {
210                 printf ("FEC_RESET_DELAY timeout\n");
211                 return 0;
212         }
213
214         /* We use strictly polling mode only
215          */
216         fecp->fec_imask = 0;
217         
218         /* Clear any pending interrupt */
219         fecp->fec_ievent = 0xffffffff;
220         
221         /* Set station address   */
222 #define ea bd->bi_enetaddr
223         fecp->fec_addr_low   =  (ea[0] << 24) | (ea[1] << 16) |
224                                 (ea[2] <<  8) | (ea[3]        ) ;
225         fecp->fec_addr_high  =  (ea[4] << 24) | (ea[5] << 16  ) ;
226 #undef ea
227
228         /* Clear multicast address hash table
229          */
230         fecp->fec_hash_table_high = 0;
231         fecp->fec_hash_table_low  = 0;
232
233         /* Set maximum receive buffer size.
234          */
235         fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
236
237         /*
238          * Setup Buffers and Buffer Desriptors
239          */
240         rxIdx = 0;
241         txIdx = 0;
242
243         /*
244          * Setup Receiver Buffer Descriptors (13.14.24.18)
245          * Settings:
246          *     Empty, Wrap
247          */
248         for (i = 0; i < PKTBUFSRX; i++) {
249                 rtx->rxbd[i].cbd_sc      = BD_ENET_RX_EMPTY;
250                 rtx->rxbd[i].cbd_datlen  = 0;   /* Reset */
251                 rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
252         }
253         rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
254
255         /*
256          * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
257          * Settings:
258          *    Last, Tx CRC
259          */
260         for (i = 0; i < TX_BUF_CNT; i++) {
261                 rtx->txbd[i].cbd_sc      = BD_ENET_TX_LAST | BD_ENET_TX_TC;
262                 rtx->txbd[i].cbd_datlen  = 0;   /* Reset */
263                 rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]);
264         }
265         rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
266
267         /* Set receive and transmit descriptor base
268          */
269         fecp->fec_r_des_start = (unsigned int) (&rtx->rxbd[0]);
270         fecp->fec_x_des_start = (unsigned int) (&rtx->txbd[0]);
271
272         /* Enable MII mode
273          */
274
275         /* Half duplex mode */
276         fecp->fec_r_cntrl = (PKT_MAXBUF_SIZE<<16) | FEC_RCNTRL_MII_MODE;
277         fecp->fec_r_cntrl = (PKT_MAXBUF_SIZE<<16) | FEC_RCNTRL_MII_MODE;
278         fecp->fec_x_cntrl = 0;
279
280         fecp->fec_mii_speed = 0;
281
282         /* Now enable the transmit and receive processing
283          */
284         fecp->fec_ecntrl = FEC_ECNTRL_ETHER_EN;
285
286         /* And last, try to fill Rx Buffer Descriptors */
287         fecp->fec_r_des_active = 0x01000000;    /* Descriptor polling active    */
288
289         return 1;
290 }
291
292
293
294 void eth_halt(void)
295 {
296         volatile fec_t *fecp = FEC_ADDR;
297         fecp->fec_ecntrl = 0;
298 }
299
300 #endif