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