xref: /openbmc/u-boot/drivers/net/ne2000_base.c (revision 6d0f6bcf)
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 }
758