xref: /openbmc/u-boot/drivers/net/ne2000_base.c (revision 2482e3c8)
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 }
757