Merge branch 'master' of git://git.denx.de/u-boot-arm
[platform/kernel/u-boot.git] / drivers / net / ne2000_base.c
1 /*
2 Ported to U-Boot by Christian Pellegrin <chri@ascensit.com>
3
4 Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
5 eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
6 are GPL, so this is, of course, GPL.
7
8 ==========================================================================
9
10 dev/if_dp83902a.c
11
12 Ethernet device driver for NS DP83902a ethernet controller
13
14 ==========================================================================
15 ####ECOSGPLCOPYRIGHTBEGIN####
16 -------------------------------------------
17 This file is part of eCos, the Embedded Configurable Operating System.
18 Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
19
20 eCos is free software; you can redistribute it and/or modify it under
21 the terms of the GNU General Public License as published by the Free
22 Software Foundation; either version 2 or (at your option) any later version.
23
24 eCos is distributed in the hope that it will be useful, but WITHOUT ANY
25 WARRANTY; without even the implied warranty of MERCHANTABILITY or
26 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
27 for more details.
28
29 You should have received a copy of the GNU General Public License along
30 with eCos; if not, write to the Free Software Foundation, Inc.,
31 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
32
33 As a special exception, if other files instantiate templates or use macros
34 or inline functions from this file, or you compile this file and link it
35 with other works to produce a work based on this file, this file does not
36 by itself cause the resulting work to be covered by the GNU General Public
37 License. However the source code for this file must still be made available
38 in accordance with section (3) of the GNU General Public License.
39
40 This exception does not invalidate any other reasons why a work based on
41 this file might be covered by the GNU General Public License.
42
43 Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
44 at http://sources.redhat.com/ecos/ecos-license/
45 -------------------------------------------
46 ####ECOSGPLCOPYRIGHTEND####
47 ####BSDCOPYRIGHTBEGIN####
48
49 -------------------------------------------
50
51 Portions of this software may have been derived from OpenBSD or other sources,
52 and are covered by the appropriate copyright disclaimers included herein.
53
54 -------------------------------------------
55
56 ####BSDCOPYRIGHTEND####
57 ==========================================================================
58 #####DESCRIPTIONBEGIN####
59
60 Author(s):      gthomas
61 Contributors:   gthomas, jskov, rsandifo
62 Date:           2001-06-13
63 Purpose:
64 Description:
65
66 FIXME:          Will fail if pinged with large packets (1520 bytes)
67 Add promisc config
68 Add SNMP
69
70 ####DESCRIPTIONEND####
71
72 ==========================================================================
73 */
74
75 #include <common.h>
76 #include <command.h>
77 #include <net.h>
78 #include <malloc.h>
79
80 /* forward definition of function used for the uboot interface */
81 void uboot_push_packet_len(int len);
82 void uboot_push_tx_done(int key, int val);
83
84 /* NE2000 base header file */
85 #include "ne2000_base.h"
86
87 #if defined(CONFIG_DRIVER_AX88796L)
88 /* AX88796L support */
89 #include "ax88796.h"
90 #else
91 /* Basic NE2000 chip support */
92 #include "ne2000.h"
93 #endif
94
95 static dp83902a_priv_data_t nic; /* just one instance of the card supported */
96
97 static bool
98 dp83902a_init(void)
99 {
100         dp83902a_priv_data_t *dp = &nic;
101         u8* base;
102 #if defined(NE2000_BASIC_INIT)
103         int i;
104 #endif
105
106         DEBUG_FUNCTION();
107
108         base = dp->base;
109         if (!base)
110                 return false;   /* No device found */
111
112         DEBUG_LINE();
113
114 #if defined(NE2000_BASIC_INIT)
115         /* AX88796L doesn't need */
116         /* Prepare ESA */
117         DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); /* Select page 1 */
118         /* Use the address from the serial EEPROM */
119         for (i = 0; i < 6; i++)
120                 DP_IN(base, DP_P1_PAR0+i, dp->esa[i]);
121         DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0); /* Select page 0 */
122
123         printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
124                 "eeprom",
125                 dp->esa[0],
126                 dp->esa[1],
127                 dp->esa[2],
128                 dp->esa[3],
129                 dp->esa[4],
130                 dp->esa[5] );
131
132 #endif  /* NE2000_BASIC_INIT */
133         return true;
134 }
135
136 static void
137 dp83902a_stop(void)
138 {
139         dp83902a_priv_data_t *dp = &nic;
140         u8 *base = dp->base;
141
142         DEBUG_FUNCTION();
143
144         DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP);    /* Brutal */
145         DP_OUT(base, DP_ISR, 0xFF);             /* Clear any pending interrupts */
146         DP_OUT(base, DP_IMR, 0x00);             /* Disable all interrupts */
147
148         dp->running = false;
149 }
150
151 /*
152  * This function is called to "start up" the interface. It may be called
153  * multiple times, even when the hardware is already running. It will be
154  * called whenever something "hardware oriented" changes and should leave
155  * the hardware ready to send/receive packets.
156  */
157 static void
158 dp83902a_start(u8 * enaddr)
159 {
160         dp83902a_priv_data_t *dp = &nic;
161         u8 *base = dp->base;
162         int i;
163
164         DEBUG_FUNCTION();
165
166         DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */
167         DP_OUT(base, DP_DCR, DP_DCR_INIT);
168         DP_OUT(base, DP_RBCH, 0);               /* Remote byte count */
169         DP_OUT(base, DP_RBCL, 0);
170         DP_OUT(base, DP_RCR, DP_RCR_MON);       /* Accept no packets */
171         DP_OUT(base, DP_TCR, DP_TCR_LOCAL);     /* Transmitter [virtually] off */
172         DP_OUT(base, DP_TPSR, dp->tx_buf1);     /* Transmitter start page */
173         dp->tx1 = dp->tx2 = 0;
174         dp->tx_next = dp->tx_buf1;
175         dp->tx_started = false;
176         dp->running = true;
177         DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */
178         DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); /* Receive ring boundary */
179         DP_OUT(base, DP_PSTOP, dp->rx_buf_end); /* Receive ring end page */
180         dp->rx_next = dp->rx_buf_start - 1;
181         dp->running = true;
182         DP_OUT(base, DP_ISR, 0xFF);             /* Clear any pending interrupts */
183         DP_OUT(base, DP_IMR, DP_IMR_All);       /* Enable all interrupts */
184         DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP);    /* Select page 1 */
185         DP_OUT(base, DP_P1_CURP, dp->rx_buf_start);     /* Current page - next free page for Rx */
186         dp->running = true;
187         for (i = 0; i < ETHER_ADDR_LEN; i++) {
188                 /* FIXME */
189                 /*((vu_short*)( base + ((DP_P1_PAR0 + i) * 2) +
190                  * 0x1400)) = enaddr[i];*/
191                 DP_OUT(base, DP_P1_PAR0+i, enaddr[i]);
192         }
193         /* Enable and start device */
194         DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
195         DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */
196         DP_OUT(base, DP_RCR, DP_RCR_AB); /* Accept broadcast, no errors, no multicast */
197         dp->running = true;
198 }
199
200 /*
201  * This routine is called to start the transmitter. It is split out from the
202  * data handling routine so it may be called either when data becomes first
203  * available or when an Tx interrupt occurs
204  */
205
206 static void
207 dp83902a_start_xmit(int start_page, int len)
208 {
209         dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic;
210         u8 *base = dp->base;
211
212         DEBUG_FUNCTION();
213
214 #if DEBUG & 1
215         printf("Tx pkt %d len %d\n", start_page, len);
216         if (dp->tx_started)
217                 printf("TX already started?!?\n");
218 #endif
219
220         DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE));
221         DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
222         DP_OUT(base, DP_TBCL, len & 0xFF);
223         DP_OUT(base, DP_TBCH, len >> 8);
224         DP_OUT(base, DP_TPSR, start_page);
225         DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
226
227         dp->tx_started = true;
228 }
229
230 /*
231  * This routine is called to send data to the hardware. It is known a-priori
232  * that there is free buffer space (dp->tx_next).
233  */
234 static void
235 dp83902a_send(u8 *data, int total_len, u32 key)
236 {
237         struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
238         u8 *base = dp->base;
239         int len, start_page, pkt_len, i, isr;
240 #if DEBUG & 4
241         int dx;
242 #endif
243
244         DEBUG_FUNCTION();
245
246         len = pkt_len = total_len;
247         if (pkt_len < IEEE_8023_MIN_FRAME)
248                 pkt_len = IEEE_8023_MIN_FRAME;
249
250         start_page = dp->tx_next;
251         if (dp->tx_next == dp->tx_buf1) {
252                 dp->tx1 = start_page;
253                 dp->tx1_len = pkt_len;
254                 dp->tx1_key = key;
255                 dp->tx_next = dp->tx_buf2;
256         } else {
257                 dp->tx2 = start_page;
258                 dp->tx2_len = pkt_len;
259                 dp->tx2_key = key;
260                 dp->tx_next = dp->tx_buf1;
261         }
262
263 #if DEBUG & 5
264         printf("TX prep page %d len %d\n", start_page, pkt_len);
265 #endif
266
267         DP_OUT(base, DP_ISR, DP_ISR_RDC);       /* Clear end of DMA */
268         {
269                 /*
270                  * Dummy read. The manual sez something slightly different,
271                  * but the code is extended a bit to do what Hitachi's monitor
272                  * does (i.e., also read data).
273                  */
274
275                 u16 tmp;
276                 int len = 1;
277
278                 DP_OUT(base, DP_RSAL, 0x100 - len);
279                 DP_OUT(base, DP_RSAH, (start_page - 1) & 0xff);
280                 DP_OUT(base, DP_RBCL, len);
281                 DP_OUT(base, DP_RBCH, 0);
282                 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START);
283                 DP_IN_DATA(dp->data, tmp);
284         }
285
286 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
287         /*
288          * Stall for a bit before continuing to work around random data
289          * corruption problems on some platforms.
290          */
291         CYGACC_CALL_IF_DELAY_US(1);
292 #endif
293
294         /* Send data to device buffer(s) */
295         DP_OUT(base, DP_RSAL, 0);
296         DP_OUT(base, DP_RSAH, start_page);
297         DP_OUT(base, DP_RBCL, pkt_len & 0xFF);
298         DP_OUT(base, DP_RBCH, pkt_len >> 8);
299         DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START);
300
301         /* Put data into buffer */
302 #if DEBUG & 4
303         printf(" sg buf %08lx len %08x\n ", (u32)data, len);
304         dx = 0;
305 #endif
306         while (len > 0) {
307 #if DEBUG & 4
308                 printf(" %02x", *data);
309                 if (0 == (++dx % 16)) printf("\n ");
310 #endif
311
312                 DP_OUT_DATA(dp->data, *data++);
313                 len--;
314         }
315 #if DEBUG & 4
316         printf("\n");
317 #endif
318         if (total_len < pkt_len) {
319 #if DEBUG & 4
320                 printf("  + %d bytes of padding\n", pkt_len - total_len);
321 #endif
322                 /* Padding to 802.3 length was required */
323                 for (i = total_len; i < pkt_len;) {
324                         i++;
325                         DP_OUT_DATA(dp->data, 0);
326                 }
327         }
328
329 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
330         /*
331          * After last data write, delay for a bit before accessing the
332          * device again, or we may get random data corruption in the last
333          * datum (on some platforms).
334          */
335         CYGACC_CALL_IF_DELAY_US(1);
336 #endif
337
338         /* Wait for DMA to complete */
339         do {
340                 DP_IN(base, DP_ISR, isr);
341         } while ((isr & DP_ISR_RDC) == 0);
342
343         /* Then disable DMA */
344         DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
345
346         /* Start transmit if not already going */
347         if (!dp->tx_started) {
348                 if (start_page == dp->tx1) {
349                         dp->tx_int = 1; /* Expecting interrupt from BUF1 */
350                 } else {
351                         dp->tx_int = 2; /* Expecting interrupt from BUF2 */
352                 }
353                 dp83902a_start_xmit(start_page, pkt_len);
354         }
355 }
356
357 /*
358  * This function is called when a packet has been received. It's job is
359  * to prepare to unload the packet from the hardware. Once the length of
360  * the packet is known, the upper layer of the driver can be told. When
361  * the upper layer is ready to unload the packet, the internal function
362  * 'dp83902a_recv' will be called to actually fetch it from the hardware.
363  */
364 static void
365 dp83902a_RxEvent(void)
366 {
367         struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
368         u8 *base = dp->base;
369         u8 rsr;
370         u8 rcv_hdr[4];
371         int i, len, pkt, cur;
372
373         DEBUG_FUNCTION();
374
375         DP_IN(base, DP_RSR, rsr);
376         while (true) {
377                 /* Read incoming packet header */
378                 DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START);
379                 DP_IN(base, DP_P1_CURP, cur);
380                 DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
381                 DP_IN(base, DP_BNDRY, pkt);
382
383                 pkt += 1;
384                 if (pkt == dp->rx_buf_end)
385                         pkt = dp->rx_buf_start;
386
387                 if (pkt == cur) {
388                         break;
389                 }
390                 DP_OUT(base, DP_RBCL, sizeof(rcv_hdr));
391                 DP_OUT(base, DP_RBCH, 0);
392                 DP_OUT(base, DP_RSAL, 0);
393                 DP_OUT(base, DP_RSAH, pkt);
394                 if (dp->rx_next == pkt) {
395                         if (cur == dp->rx_buf_start)
396                                 DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1);
397                         else
398                                 DP_OUT(base, DP_BNDRY, cur - 1); /* Update pointer */
399                         return;
400                 }
401                 dp->rx_next = pkt;
402                 DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
403                 DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
404 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
405                 CYGACC_CALL_IF_DELAY_US(10);
406 #endif
407
408                 /* read header (get data size)*/
409                 for (i = 0; i < sizeof(rcv_hdr);) {
410                         DP_IN_DATA(dp->data, rcv_hdr[i++]);
411                 }
412
413 #if DEBUG & 5
414                 printf("rx hdr %02x %02x %02x %02x\n",
415                         rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]);
416 #endif
417                 len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr);
418
419                 /* data read */
420                 uboot_push_packet_len(len);
421
422                 if (rcv_hdr[1] == dp->rx_buf_start)
423                         DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1);
424                 else
425                         DP_OUT(base, DP_BNDRY, rcv_hdr[1] - 1); /* Update pointer */
426         }
427 }
428
429 /*
430  * This function is called as a result of the "eth_drv_recv()" call above.
431  * It's job is to actually fetch data for a packet from the hardware once
432  * memory buffers have been allocated for the packet. Note that the buffers
433  * may come in pieces, using a scatter-gather list. This allows for more
434  * efficient processing in the upper layers of the stack.
435  */
436 static void
437 dp83902a_recv(u8 *data, int len)
438 {
439         struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
440         u8 *base = dp->base;
441         int i, mlen;
442         u8 saved_char = 0;
443         bool saved;
444 #if DEBUG & 4
445         int dx;
446 #endif
447
448         DEBUG_FUNCTION();
449
450 #if DEBUG & 5
451         printf("Rx packet %d length %d\n", dp->rx_next, len);
452 #endif
453
454         /* Read incoming packet data */
455         DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
456         DP_OUT(base, DP_RBCL, len & 0xFF);
457         DP_OUT(base, DP_RBCH, len >> 8);
458         DP_OUT(base, DP_RSAL, 4);               /* Past header */
459         DP_OUT(base, DP_RSAH, dp->rx_next);
460         DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
461         DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
462 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
463         CYGACC_CALL_IF_DELAY_US(10);
464 #endif
465
466         saved = false;
467         for (i = 0; i < 1; i++) {
468                 if (data) {
469                         mlen = len;
470 #if DEBUG & 4
471                         printf(" sg buf %08lx len %08x \n", (u32) data, mlen);
472                         dx = 0;
473 #endif
474                         while (0 < mlen) {
475                                 /* Saved byte from previous loop? */
476                                 if (saved) {
477                                         *data++ = saved_char;
478                                         mlen--;
479                                         saved = false;
480                                         continue;
481                                 }
482
483                                 {
484                                         u8 tmp;
485                                         DP_IN_DATA(dp->data, tmp);
486 #if DEBUG & 4
487                                         printf(" %02x", tmp);
488                                         if (0 == (++dx % 16)) printf("\n ");
489 #endif
490                                         *data++ = tmp;;
491                                         mlen--;
492                                 }
493                         }
494 #if DEBUG & 4
495                         printf("\n");
496 #endif
497                 }
498         }
499 }
500
501 static void
502 dp83902a_TxEvent(void)
503 {
504         struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
505         u8 *base = dp->base;
506         u8 tsr;
507         u32 key;
508
509         DEBUG_FUNCTION();
510
511         DP_IN(base, DP_TSR, tsr);
512         if (dp->tx_int == 1) {
513                 key = dp->tx1_key;
514                 dp->tx1 = 0;
515         } else {
516                 key = dp->tx2_key;
517                 dp->tx2 = 0;
518         }
519         /* Start next packet if one is ready */
520         dp->tx_started = false;
521         if (dp->tx1) {
522                 dp83902a_start_xmit(dp->tx1, dp->tx1_len);
523                 dp->tx_int = 1;
524         } else if (dp->tx2) {
525                 dp83902a_start_xmit(dp->tx2, dp->tx2_len);
526                 dp->tx_int = 2;
527         } else {
528                 dp->tx_int = 0;
529         }
530         /* Tell higher level we sent this packet */
531         uboot_push_tx_done(key, 0);
532 }
533
534 /*
535  * Read the tally counters to clear them. Called in response to a CNT
536  * interrupt.
537  */
538 static void
539 dp83902a_ClearCounters(void)
540 {
541         struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
542         u8 *base = dp->base;
543         u8 cnt1, cnt2, cnt3;
544
545         DP_IN(base, DP_FER, cnt1);
546         DP_IN(base, DP_CER, cnt2);
547         DP_IN(base, DP_MISSED, cnt3);
548         DP_OUT(base, DP_ISR, DP_ISR_CNT);
549 }
550
551 /*
552  * Deal with an overflow condition. This code follows the procedure set
553  * out in section 7.0 of the datasheet.
554  */
555 static void
556 dp83902a_Overflow(void)
557 {
558         struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic;
559         u8 *base = dp->base;
560         u8 isr;
561
562         /* Issue a stop command and wait 1.6ms for it to complete. */
563         DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA);
564         CYGACC_CALL_IF_DELAY_US(1600);
565
566         /* Clear the remote byte counter registers. */
567         DP_OUT(base, DP_RBCL, 0);
568         DP_OUT(base, DP_RBCH, 0);
569
570         /* Enter loopback mode while we clear the buffer. */
571         DP_OUT(base, DP_TCR, DP_TCR_LOCAL);
572         DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA);
573
574         /*
575          * Read in as many packets as we can and acknowledge any and receive
576          * interrupts. Since the buffer has overflowed, a receive event of
577          * some kind will have occured.
578          */
579         dp83902a_RxEvent();
580         DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE);
581
582         /* Clear the overflow condition and leave loopback mode. */
583         DP_OUT(base, DP_ISR, DP_ISR_OFLW);
584         DP_OUT(base, DP_TCR, DP_TCR_NORMAL);
585
586         /*
587          * If a transmit command was issued, but no transmit event has occured,
588          * restart it here.
589          */
590         DP_IN(base, DP_ISR, isr);
591         if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) {
592                 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
593         }
594 }
595
596 static void
597 dp83902a_poll(void)
598 {
599         struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
600         u8 *base = dp->base;
601         u8 isr;
602
603         DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START);
604         DP_IN(base, DP_ISR, isr);
605         while (0 != isr) {
606                 /*
607                  * The CNT interrupt triggers when the MSB of one of the error
608                  * counters is set. We don't much care about these counters, but
609                  * we should read their values to reset them.
610                  */
611                 if (isr & DP_ISR_CNT) {
612                         dp83902a_ClearCounters();
613                 }
614                 /*
615                  * Check for overflow. It's a special case, since there's a
616                  * particular procedure that must be followed to get back into
617                  * a running state.a
618                  */
619                 if (isr & DP_ISR_OFLW) {
620                         dp83902a_Overflow();
621                 } else {
622                         /*
623                          * Other kinds of interrupts can be acknowledged simply by
624                          * clearing the relevant bits of the ISR. Do that now, then
625                          * handle the interrupts we care about.
626                          */
627                         DP_OUT(base, DP_ISR, isr);      /* Clear set bits */
628                         if (!dp->running) break;        /* Is this necessary? */
629                         /*
630                          * Check for tx_started on TX event since these may happen
631                          * spuriously it seems.
632                          */
633                         if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) {
634                                 dp83902a_TxEvent();
635                         }
636                         if (isr & (DP_ISR_RxP|DP_ISR_RxE)) {
637                                 dp83902a_RxEvent();
638                         }
639                 }
640                 DP_IN(base, DP_ISR, isr);
641         }
642 }
643
644
645 /* U-boot specific routines */
646 static u8 *pbuf = NULL;
647
648 static int pkey = -1;
649 static int initialized = 0;
650
651 void uboot_push_packet_len(int len) {
652         PRINTK("pushed len = %d\n", len);
653         if (len >= 2000) {
654                 printf("NE2000: packet too big\n");
655                 return;
656         }
657         dp83902a_recv(&pbuf[0], len);
658
659         /*Just pass it to the upper layer*/
660         NetReceive(&pbuf[0], len);
661 }
662
663 void uboot_push_tx_done(int key, int val) {
664         PRINTK("pushed key = %d\n", key);
665         pkey = key;
666 }
667
668 int eth_init(bd_t *bd) {
669         int r;
670         u8 dev_addr[6];
671         char ethaddr[20];
672
673         PRINTK("### eth_init\n");
674
675         if (!pbuf) {
676                 pbuf = malloc(2000);
677                 if (!pbuf) {
678                         printf("Cannot allocate rx buffer\n");
679                         return -1;
680                 }
681         }
682
683 #ifdef CONFIG_DRIVER_NE2000_CCR
684         {
685                 vu_char *p = (vu_char *) CONFIG_DRIVER_NE2000_CCR;
686
687                 PRINTK("CCR before is %x\n", *p);
688                 *p = CONFIG_DRIVER_NE2000_VAL;
689                 PRINTK("CCR after is %x\n", *p);
690         }
691 #endif
692
693         nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE;
694
695         r = get_prom(dev_addr, nic.base);
696         if (!r)
697                 return -1;
698
699         sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
700                  dev_addr[0], dev_addr[1],
701                  dev_addr[2], dev_addr[3],
702                  dev_addr[4], dev_addr[5]) ;
703         PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr);
704         setenv ("ethaddr", ethaddr);
705
706         nic.data = nic.base + DP_DATA;
707         nic.tx_buf1 = START_PG;
708         nic.tx_buf2 = START_PG2;
709         nic.rx_buf_start = RX_START;
710         nic.rx_buf_end = RX_END;
711
712         if (dp83902a_init() == false)
713                 return -1;
714
715         dp83902a_start(dev_addr);
716         initialized = 1;
717
718         return 0;
719 }
720
721 void eth_halt() {
722
723         PRINTK("### eth_halt\n");
724         if(initialized)
725                 dp83902a_stop();
726         initialized = 0;
727 }
728
729 int eth_rx() {
730         dp83902a_poll();
731         return 1;
732 }
733
734 int eth_send(volatile void *packet, int length) {
735         int tmo;
736
737         PRINTK("### eth_send\n");
738
739         pkey = -1;
740
741         dp83902a_send((u8 *) packet, length, 666);
742         tmo = get_timer (0) + TOUT * CONFIG_SYS_HZ;
743         while(1) {
744                 dp83902a_poll();
745                 if (pkey != -1) {
746                         PRINTK("Packet sucesfully sent\n");
747                         return 0;
748                 }
749                 if (get_timer (0) >= tmo) {
750                         printf("transmission error (timoeut)\n");
751                         return 0;
752                 }
753
754         }
755         return 0;
756 }