88f2b379f37bbb5f73907d5631b56ed7763c78d7
[oweals/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 /**
98  * This function reads the MAC address from the serial EEPROM,
99  * used if PROM read fails. Does nothing for ax88796 chips (sh boards)
100  */
101 static bool
102 dp83902a_init(unsigned char *enetaddr)
103 {
104         dp83902a_priv_data_t *dp = &nic;
105         u8* base;
106 #if defined(NE2000_BASIC_INIT)
107         int i;
108 #endif
109
110         DEBUG_FUNCTION();
111
112         base = dp->base;
113         if (!base)
114                 return false;   /* No device found */
115
116         DEBUG_LINE();
117
118 #if defined(NE2000_BASIC_INIT)
119         /* AX88796L doesn't need */
120         /* Prepare ESA */
121         DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); /* Select page 1 */
122         /* Use the address from the serial EEPROM */
123         for (i = 0; i < 6; i++)
124                 DP_IN(base, DP_P1_PAR0+i, dp->esa[i]);
125         DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0); /* Select page 0 */
126
127         printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
128                 "eeprom",
129                 dp->esa[0],
130                 dp->esa[1],
131                 dp->esa[2],
132                 dp->esa[3],
133                 dp->esa[4],
134                 dp->esa[5] );
135
136         memcpy(enetaddr, dp->esa, 6); /* Use MAC from serial EEPROM */
137 #endif  /* NE2000_BASIC_INIT */
138         return true;
139 }
140
141 static void
142 dp83902a_stop(void)
143 {
144         dp83902a_priv_data_t *dp = &nic;
145         u8 *base = dp->base;
146
147         DEBUG_FUNCTION();
148
149         DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP);    /* Brutal */
150         DP_OUT(base, DP_ISR, 0xFF);             /* Clear any pending interrupts */
151         DP_OUT(base, DP_IMR, 0x00);             /* Disable all interrupts */
152
153         dp->running = false;
154 }
155
156 /*
157  * This function is called to "start up" the interface. It may be called
158  * multiple times, even when the hardware is already running. It will be
159  * called whenever something "hardware oriented" changes and should leave
160  * the hardware ready to send/receive packets.
161  */
162 static void
163 dp83902a_start(u8 * enaddr)
164 {
165         dp83902a_priv_data_t *dp = &nic;
166         u8 *base = dp->base;
167         int i;
168
169         debug("The MAC is %pM\n", enaddr);
170
171         DEBUG_FUNCTION();
172
173         DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */
174         DP_OUT(base, DP_DCR, DP_DCR_INIT);
175         DP_OUT(base, DP_RBCH, 0);               /* Remote byte count */
176         DP_OUT(base, DP_RBCL, 0);
177         DP_OUT(base, DP_RCR, DP_RCR_MON);       /* Accept no packets */
178         DP_OUT(base, DP_TCR, DP_TCR_LOCAL);     /* Transmitter [virtually] off */
179         DP_OUT(base, DP_TPSR, dp->tx_buf1);     /* Transmitter start page */
180         dp->tx1 = dp->tx2 = 0;
181         dp->tx_next = dp->tx_buf1;
182         dp->tx_started = false;
183         dp->running = true;
184         DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */
185         DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); /* Receive ring boundary */
186         DP_OUT(base, DP_PSTOP, dp->rx_buf_end); /* Receive ring end page */
187         dp->rx_next = dp->rx_buf_start - 1;
188         dp->running = true;
189         DP_OUT(base, DP_ISR, 0xFF);             /* Clear any pending interrupts */
190         DP_OUT(base, DP_IMR, DP_IMR_All);       /* Enable all interrupts */
191         DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP);    /* Select page 1 */
192         DP_OUT(base, DP_P1_CURP, dp->rx_buf_start);     /* Current page - next free page for Rx */
193         dp->running = true;
194         for (i = 0; i < ETHER_ADDR_LEN; i++) {
195                 /* FIXME */
196                 /*((vu_short*)( base + ((DP_P1_PAR0 + i) * 2) +
197                  * 0x1400)) = enaddr[i];*/
198                 DP_OUT(base, DP_P1_PAR0+i, enaddr[i]);
199         }
200         /* Enable and start device */
201         DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
202         DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */
203         DP_OUT(base, DP_RCR, DP_RCR_AB); /* Accept broadcast, no errors, no multicast */
204         dp->running = true;
205 }
206
207 /*
208  * This routine is called to start the transmitter. It is split out from the
209  * data handling routine so it may be called either when data becomes first
210  * available or when an Tx interrupt occurs
211  */
212
213 static void
214 dp83902a_start_xmit(int start_page, int len)
215 {
216         dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic;
217         u8 *base = dp->base;
218
219         DEBUG_FUNCTION();
220
221 #if DEBUG & 1
222         printf("Tx pkt %d len %d\n", start_page, len);
223         if (dp->tx_started)
224                 printf("TX already started?!?\n");
225 #endif
226
227         DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE));
228         DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
229         DP_OUT(base, DP_TBCL, len & 0xFF);
230         DP_OUT(base, DP_TBCH, len >> 8);
231         DP_OUT(base, DP_TPSR, start_page);
232         DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
233
234         dp->tx_started = true;
235 }
236
237 /*
238  * This routine is called to send data to the hardware. It is known a-priori
239  * that there is free buffer space (dp->tx_next).
240  */
241 static void
242 dp83902a_send(u8 *data, int total_len, u32 key)
243 {
244         struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
245         u8 *base = dp->base;
246         int len, start_page, pkt_len, i, isr;
247 #if DEBUG & 4
248         int dx;
249 #endif
250
251         DEBUG_FUNCTION();
252
253         len = pkt_len = total_len;
254         if (pkt_len < IEEE_8023_MIN_FRAME)
255                 pkt_len = IEEE_8023_MIN_FRAME;
256
257         start_page = dp->tx_next;
258         if (dp->tx_next == dp->tx_buf1) {
259                 dp->tx1 = start_page;
260                 dp->tx1_len = pkt_len;
261                 dp->tx1_key = key;
262                 dp->tx_next = dp->tx_buf2;
263         } else {
264                 dp->tx2 = start_page;
265                 dp->tx2_len = pkt_len;
266                 dp->tx2_key = key;
267                 dp->tx_next = dp->tx_buf1;
268         }
269
270 #if DEBUG & 5
271         printf("TX prep page %d len %d\n", start_page, pkt_len);
272 #endif
273
274         DP_OUT(base, DP_ISR, DP_ISR_RDC);       /* Clear end of DMA */
275         {
276                 /*
277                  * Dummy read. The manual sez something slightly different,
278                  * but the code is extended a bit to do what Hitachi's monitor
279                  * does (i.e., also read data).
280                  */
281
282                 u16 tmp;
283                 int len = 1;
284
285                 DP_OUT(base, DP_RSAL, 0x100 - len);
286                 DP_OUT(base, DP_RSAH, (start_page - 1) & 0xff);
287                 DP_OUT(base, DP_RBCL, len);
288                 DP_OUT(base, DP_RBCH, 0);
289                 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START);
290                 DP_IN_DATA(dp->data, tmp);
291         }
292
293 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
294         /*
295          * Stall for a bit before continuing to work around random data
296          * corruption problems on some platforms.
297          */
298         CYGACC_CALL_IF_DELAY_US(1);
299 #endif
300
301         /* Send data to device buffer(s) */
302         DP_OUT(base, DP_RSAL, 0);
303         DP_OUT(base, DP_RSAH, start_page);
304         DP_OUT(base, DP_RBCL, pkt_len & 0xFF);
305         DP_OUT(base, DP_RBCH, pkt_len >> 8);
306         DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START);
307
308         /* Put data into buffer */
309 #if DEBUG & 4
310         printf(" sg buf %08lx len %08x\n ", (u32)data, len);
311         dx = 0;
312 #endif
313         while (len > 0) {
314 #if DEBUG & 4
315                 printf(" %02x", *data);
316                 if (0 == (++dx % 16)) printf("\n ");
317 #endif
318
319                 DP_OUT_DATA(dp->data, *data++);
320                 len--;
321         }
322 #if DEBUG & 4
323         printf("\n");
324 #endif
325         if (total_len < pkt_len) {
326 #if DEBUG & 4
327                 printf("  + %d bytes of padding\n", pkt_len - total_len);
328 #endif
329                 /* Padding to 802.3 length was required */
330                 for (i = total_len; i < pkt_len;) {
331                         i++;
332                         DP_OUT_DATA(dp->data, 0);
333                 }
334         }
335
336 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
337         /*
338          * After last data write, delay for a bit before accessing the
339          * device again, or we may get random data corruption in the last
340          * datum (on some platforms).
341          */
342         CYGACC_CALL_IF_DELAY_US(1);
343 #endif
344
345         /* Wait for DMA to complete */
346         do {
347                 DP_IN(base, DP_ISR, isr);
348         } while ((isr & DP_ISR_RDC) == 0);
349
350         /* Then disable DMA */
351         DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
352
353         /* Start transmit if not already going */
354         if (!dp->tx_started) {
355                 if (start_page == dp->tx1) {
356                         dp->tx_int = 1; /* Expecting interrupt from BUF1 */
357                 } else {
358                         dp->tx_int = 2; /* Expecting interrupt from BUF2 */
359                 }
360                 dp83902a_start_xmit(start_page, pkt_len);
361         }
362 }
363
364 /*
365  * This function is called when a packet has been received. It's job is
366  * to prepare to unload the packet from the hardware. Once the length of
367  * the packet is known, the upper layer of the driver can be told. When
368  * the upper layer is ready to unload the packet, the internal function
369  * 'dp83902a_recv' will be called to actually fetch it from the hardware.
370  */
371 static void
372 dp83902a_RxEvent(void)
373 {
374         struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
375         u8 *base = dp->base;
376         u8 rsr;
377         u8 rcv_hdr[4];
378         int i, len, pkt, cur;
379
380         DEBUG_FUNCTION();
381
382         DP_IN(base, DP_RSR, rsr);
383         while (true) {
384                 /* Read incoming packet header */
385                 DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START);
386                 DP_IN(base, DP_P1_CURP, cur);
387                 DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
388                 DP_IN(base, DP_BNDRY, pkt);
389
390                 pkt += 1;
391                 if (pkt == dp->rx_buf_end)
392                         pkt = dp->rx_buf_start;
393
394                 if (pkt == cur) {
395                         break;
396                 }
397                 DP_OUT(base, DP_RBCL, sizeof(rcv_hdr));
398                 DP_OUT(base, DP_RBCH, 0);
399                 DP_OUT(base, DP_RSAL, 0);
400                 DP_OUT(base, DP_RSAH, pkt);
401                 if (dp->rx_next == pkt) {
402                         if (cur == dp->rx_buf_start)
403                                 DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1);
404                         else
405                                 DP_OUT(base, DP_BNDRY, cur - 1); /* Update pointer */
406                         return;
407                 }
408                 dp->rx_next = pkt;
409                 DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
410                 DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
411 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
412                 CYGACC_CALL_IF_DELAY_US(10);
413 #endif
414
415                 /* read header (get data size)*/
416                 for (i = 0; i < sizeof(rcv_hdr);) {
417                         DP_IN_DATA(dp->data, rcv_hdr[i++]);
418                 }
419
420 #if DEBUG & 5
421                 printf("rx hdr %02x %02x %02x %02x\n",
422                         rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]);
423 #endif
424                 len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr);
425
426                 /* data read */
427                 uboot_push_packet_len(len);
428
429                 if (rcv_hdr[1] == dp->rx_buf_start)
430                         DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1);
431                 else
432                         DP_OUT(base, DP_BNDRY, rcv_hdr[1] - 1); /* Update pointer */
433         }
434 }
435
436 /*
437  * This function is called as a result of the "eth_drv_recv()" call above.
438  * It's job is to actually fetch data for a packet from the hardware once
439  * memory buffers have been allocated for the packet. Note that the buffers
440  * may come in pieces, using a scatter-gather list. This allows for more
441  * efficient processing in the upper layers of the stack.
442  */
443 static void
444 dp83902a_recv(u8 *data, int len)
445 {
446         struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
447         u8 *base = dp->base;
448         int i, mlen;
449         u8 saved_char = 0;
450         bool saved;
451 #if DEBUG & 4
452         int dx;
453 #endif
454
455         DEBUG_FUNCTION();
456
457 #if DEBUG & 5
458         printf("Rx packet %d length %d\n", dp->rx_next, len);
459 #endif
460
461         /* Read incoming packet data */
462         DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
463         DP_OUT(base, DP_RBCL, len & 0xFF);
464         DP_OUT(base, DP_RBCH, len >> 8);
465         DP_OUT(base, DP_RSAL, 4);               /* Past header */
466         DP_OUT(base, DP_RSAH, dp->rx_next);
467         DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
468         DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
469 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
470         CYGACC_CALL_IF_DELAY_US(10);
471 #endif
472
473         saved = false;
474         for (i = 0; i < 1; i++) {
475                 if (data) {
476                         mlen = len;
477 #if DEBUG & 4
478                         printf(" sg buf %08lx len %08x \n", (u32) data, mlen);
479                         dx = 0;
480 #endif
481                         while (0 < mlen) {
482                                 /* Saved byte from previous loop? */
483                                 if (saved) {
484                                         *data++ = saved_char;
485                                         mlen--;
486                                         saved = false;
487                                         continue;
488                                 }
489
490                                 {
491                                         u8 tmp;
492                                         DP_IN_DATA(dp->data, tmp);
493 #if DEBUG & 4
494                                         printf(" %02x", tmp);
495                                         if (0 == (++dx % 16)) printf("\n ");
496 #endif
497                                         *data++ = tmp;;
498                                         mlen--;
499                                 }
500                         }
501 #if DEBUG & 4
502                         printf("\n");
503 #endif
504                 }
505         }
506 }
507
508 static void
509 dp83902a_TxEvent(void)
510 {
511         struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
512         u8 *base = dp->base;
513         u8 tsr;
514         u32 key;
515
516         DEBUG_FUNCTION();
517
518         DP_IN(base, DP_TSR, tsr);
519         if (dp->tx_int == 1) {
520                 key = dp->tx1_key;
521                 dp->tx1 = 0;
522         } else {
523                 key = dp->tx2_key;
524                 dp->tx2 = 0;
525         }
526         /* Start next packet if one is ready */
527         dp->tx_started = false;
528         if (dp->tx1) {
529                 dp83902a_start_xmit(dp->tx1, dp->tx1_len);
530                 dp->tx_int = 1;
531         } else if (dp->tx2) {
532                 dp83902a_start_xmit(dp->tx2, dp->tx2_len);
533                 dp->tx_int = 2;
534         } else {
535                 dp->tx_int = 0;
536         }
537         /* Tell higher level we sent this packet */
538         uboot_push_tx_done(key, 0);
539 }
540
541 /*
542  * Read the tally counters to clear them. Called in response to a CNT
543  * interrupt.
544  */
545 static void
546 dp83902a_ClearCounters(void)
547 {
548         struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
549         u8 *base = dp->base;
550         u8 cnt1, cnt2, cnt3;
551
552         DP_IN(base, DP_FER, cnt1);
553         DP_IN(base, DP_CER, cnt2);
554         DP_IN(base, DP_MISSED, cnt3);
555         DP_OUT(base, DP_ISR, DP_ISR_CNT);
556 }
557
558 /*
559  * Deal with an overflow condition. This code follows the procedure set
560  * out in section 7.0 of the datasheet.
561  */
562 static void
563 dp83902a_Overflow(void)
564 {
565         struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic;
566         u8 *base = dp->base;
567         u8 isr;
568
569         /* Issue a stop command and wait 1.6ms for it to complete. */
570         DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA);
571         CYGACC_CALL_IF_DELAY_US(1600);
572
573         /* Clear the remote byte counter registers. */
574         DP_OUT(base, DP_RBCL, 0);
575         DP_OUT(base, DP_RBCH, 0);
576
577         /* Enter loopback mode while we clear the buffer. */
578         DP_OUT(base, DP_TCR, DP_TCR_LOCAL);
579         DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA);
580
581         /*
582          * Read in as many packets as we can and acknowledge any and receive
583          * interrupts. Since the buffer has overflowed, a receive event of
584          * some kind will have occured.
585          */
586         dp83902a_RxEvent();
587         DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE);
588
589         /* Clear the overflow condition and leave loopback mode. */
590         DP_OUT(base, DP_ISR, DP_ISR_OFLW);
591         DP_OUT(base, DP_TCR, DP_TCR_NORMAL);
592
593         /*
594          * If a transmit command was issued, but no transmit event has occured,
595          * restart it here.
596          */
597         DP_IN(base, DP_ISR, isr);
598         if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) {
599                 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
600         }
601 }
602
603 static void
604 dp83902a_poll(void)
605 {
606         struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
607         u8 *base = dp->base;
608         u8 isr;
609
610         DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START);
611         DP_IN(base, DP_ISR, isr);
612         while (0 != isr) {
613                 /*
614                  * The CNT interrupt triggers when the MSB of one of the error
615                  * counters is set. We don't much care about these counters, but
616                  * we should read their values to reset them.
617                  */
618                 if (isr & DP_ISR_CNT) {
619                         dp83902a_ClearCounters();
620                 }
621                 /*
622                  * Check for overflow. It's a special case, since there's a
623                  * particular procedure that must be followed to get back into
624                  * a running state.a
625                  */
626                 if (isr & DP_ISR_OFLW) {
627                         dp83902a_Overflow();
628                 } else {
629                         /*
630                          * Other kinds of interrupts can be acknowledged simply by
631                          * clearing the relevant bits of the ISR. Do that now, then
632                          * handle the interrupts we care about.
633                          */
634                         DP_OUT(base, DP_ISR, isr);      /* Clear set bits */
635                         if (!dp->running) break;        /* Is this necessary? */
636                         /*
637                          * Check for tx_started on TX event since these may happen
638                          * spuriously it seems.
639                          */
640                         if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) {
641                                 dp83902a_TxEvent();
642                         }
643                         if (isr & (DP_ISR_RxP|DP_ISR_RxE)) {
644                                 dp83902a_RxEvent();
645                         }
646                 }
647                 DP_IN(base, DP_ISR, isr);
648         }
649 }
650
651
652 /* U-boot specific routines */
653 static u8 *pbuf = NULL;
654
655 static int pkey = -1;
656 static int initialized = 0;
657
658 void uboot_push_packet_len(int len) {
659         PRINTK("pushed len = %d\n", len);
660         if (len >= 2000) {
661                 printf("NE2000: packet too big\n");
662                 return;
663         }
664         dp83902a_recv(&pbuf[0], len);
665
666         /*Just pass it to the upper layer*/
667         NetReceive(&pbuf[0], len);
668 }
669
670 void uboot_push_tx_done(int key, int val) {
671         PRINTK("pushed key = %d\n", key);
672         pkey = key;
673 }
674
675 /**
676  * Setup the driver and init MAC address according to doc/README.enetaddr
677  * Called by ne2k_register() before registering the driver @eth layer
678  *
679  * @param struct ethdevice of this instance of the driver for dev->enetaddr
680  * @return 0 on success, -1 on error (causing caller to print error msg)
681  */
682 static int ne2k_setup_driver(struct eth_device *dev)
683 {
684         PRINTK("### ne2k_setup_driver\n");
685
686         if (!pbuf) {
687                 pbuf = malloc(2000);
688                 if (!pbuf) {
689                         printf("Cannot allocate rx buffer\n");
690                         return -1;
691                 }
692         }
693
694 #ifdef CONFIG_DRIVER_NE2000_CCR
695         {
696                 vu_char *p = (vu_char *) CONFIG_DRIVER_NE2000_CCR;
697
698                 PRINTK("CCR before is %x\n", *p);
699                 *p = CONFIG_DRIVER_NE2000_VAL;
700                 PRINTK("CCR after is %x\n", *p);
701         }
702 #endif
703
704         nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE;
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         /*
713          * According to doc/README.enetaddr, drivers shall give priority
714          * to the MAC address value in the environment, so we do not read
715          * it from the prom or eeprom if it is specified in the environment.
716          */
717         if (!eth_getenv_enetaddr("ethaddr", dev->enetaddr)) {
718                 /* If the MAC address is not in the environment, get it: */
719                 if (!get_prom(dev->enetaddr, nic.base)) /* get MAC from prom */
720                         dp83902a_init(dev->enetaddr);   /* fallback: seeprom */
721                 /* And write it into the environment otherwise eth_write_hwaddr
722                  * returns -1 due to eth_getenv_enetaddr_by_index() failing,
723                  * and this causes "Warning: failed to set MAC address", and
724                  * cmd_bdinfo has no ethaddr value which it can show: */
725                 eth_setenv_enetaddr("ethaddr", dev->enetaddr);
726         }
727         return 0;
728 }
729
730 static int ne2k_init(struct eth_device *dev, bd_t *bd)
731 {
732         dp83902a_start(dev->enetaddr);
733         initialized = 1;
734         return 0;
735 }
736
737 static void ne2k_halt(struct eth_device *dev)
738 {
739         debug("### ne2k_halt\n");
740         if(initialized)
741                 dp83902a_stop();
742         initialized = 0;
743 }
744
745 static int ne2k_recv(struct eth_device *dev)
746 {
747         dp83902a_poll();
748         return 1;
749 }
750
751 static int ne2k_send(struct eth_device *dev, volatile void *packet, int length)
752 {
753         int tmo;
754
755         debug("### ne2k_send\n");
756
757         pkey = -1;
758
759         dp83902a_send((u8 *) packet, length, 666);
760         tmo = get_timer (0) + TOUT * CONFIG_SYS_HZ;
761         while(1) {
762                 dp83902a_poll();
763                 if (pkey != -1) {
764                         PRINTK("Packet sucesfully sent\n");
765                         return 0;
766                 }
767                 if (get_timer (0) >= tmo) {
768                         printf("transmission error (timoeut)\n");
769                         return 0;
770                 }
771
772         }
773         return 0;
774 }
775
776 /**
777  * Setup the driver for use and register it with the eth layer
778  * @return 0 on success, -1 on error (causing caller to print error msg)
779  */
780 int ne2k_register(void)
781 {
782         struct eth_device *dev;
783
784         dev = calloc(sizeof(*dev), 1);
785         if (dev == NULL)
786                 return -1;
787
788         if (ne2k_setup_driver(dev))
789                 return -1;
790
791         dev->init = ne2k_init;
792         dev->halt = ne2k_halt;
793         dev->send = ne2k_send;
794         dev->recv = ne2k_recv;
795
796         sprintf(dev->name, "NE2000");
797
798         return eth_register(dev);
799 }