xref: /openbmc/u-boot/drivers/net/ne2000.c (revision 0cf4fd3c)
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 /*
86  * Debugging details
87  *
88  * Set to perms of:
89  * 0 disables all debug output
90  * 1 for process debug output
91  * 2 for added data IO output: get_reg, put_reg
92  * 4 for packet allocation/free output
93  * 8 for only startup status, so we can tell we're installed OK
94  */
95 #if 0
96 #define DEBUG 0xf
97 #else
98 #define DEBUG 0
99 #endif
100 
101 #if DEBUG & 1
102 #define DEBUG_FUNCTION() do { printf("%s\n", __FUNCTION__); } while (0)
103 #define DEBUG_LINE() do { printf("%d\n", __LINE__); } while (0)
104 #define PRINTK(args...) printf(args)
105 #else
106 #define DEBUG_FUNCTION() do {} while(0)
107 #define DEBUG_LINE() do {} while(0)
108 #define PRINTK(args...)
109 #endif
110 
111 /* NE2000 base header file */
112 #include "ne2000_base.h"
113 
114 #if defined(CONFIG_DRIVER_AX88796L)
115 /* AX88796L support */
116 #include "ax88796.h"
117 #else
118 /* Basic NE2000 chip support */
119 #include "ne2000.h"
120 #endif
121 
122 static dp83902a_priv_data_t nic; /* just one instance of the card supported */
123 
124 static bool
125 dp83902a_init(void)
126 {
127 	dp83902a_priv_data_t *dp = &nic;
128 	u8* base;
129 #if defined(NE2000_BASIC_INIT)
130 	int i;
131 #endif
132 
133 	DEBUG_FUNCTION();
134 
135 	base = dp->base;
136 	if (!base)
137 		return false;	/* No device found */
138 
139 	DEBUG_LINE();
140 
141 #if defined(NE2000_BASIC_INIT)
142 	/* AX88796L doesn't need */
143 	/* Prepare ESA */
144 	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1);	/* Select page 1 */
145 	/* Use the address from the serial EEPROM */
146 	for (i = 0; i < 6; i++)
147 		DP_IN(base, DP_P1_PAR0+i, dp->esa[i]);
148 	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0);	/* Select page 0 */
149 
150 	printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
151 		"eeprom",
152 		dp->esa[0],
153 		dp->esa[1],
154 		dp->esa[2],
155 		dp->esa[3],
156 		dp->esa[4],
157 		dp->esa[5] );
158 
159 #endif	/* NE2000_BASIC_INIT */
160 	return true;
161 }
162 
163 static void
164 dp83902a_stop(void)
165 {
166 	dp83902a_priv_data_t *dp = &nic;
167 	u8 *base = dp->base;
168 
169 	DEBUG_FUNCTION();
170 
171 	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP);	/* Brutal */
172 	DP_OUT(base, DP_ISR, 0xFF);		/* Clear any pending interrupts */
173 	DP_OUT(base, DP_IMR, 0x00);		/* Disable all interrupts */
174 
175 	dp->running = false;
176 }
177 
178 /*
179  * This function is called to "start up" the interface. It may be called
180  * multiple times, even when the hardware is already running. It will be
181  * called whenever something "hardware oriented" changes and should leave
182  * the hardware ready to send/receive packets.
183  */
184 static void
185 dp83902a_start(u8 * enaddr)
186 {
187 	dp83902a_priv_data_t *dp = &nic;
188 	u8 *base = dp->base;
189 	int i;
190 
191 	DEBUG_FUNCTION();
192 
193 	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */
194 	DP_OUT(base, DP_DCR, DP_DCR_INIT);
195 	DP_OUT(base, DP_RBCH, 0);		/* Remote byte count */
196 	DP_OUT(base, DP_RBCL, 0);
197 	DP_OUT(base, DP_RCR, DP_RCR_MON);	/* Accept no packets */
198 	DP_OUT(base, DP_TCR, DP_TCR_LOCAL);	/* Transmitter [virtually] off */
199 	DP_OUT(base, DP_TPSR, dp->tx_buf1);	/* Transmitter start page */
200 	dp->tx1 = dp->tx2 = 0;
201 	dp->tx_next = dp->tx_buf1;
202 	dp->tx_started = false;
203 	dp->running = true;
204 	DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */
205 	DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); /* Receive ring boundary */
206 	DP_OUT(base, DP_PSTOP, dp->rx_buf_end);	/* Receive ring end page */
207 	dp->rx_next = dp->rx_buf_start - 1;
208 	dp->running = true;
209 	DP_OUT(base, DP_ISR, 0xFF);		/* Clear any pending interrupts */
210 	DP_OUT(base, DP_IMR, DP_IMR_All);	/* Enable all interrupts */
211 	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP);	/* Select page 1 */
212 	DP_OUT(base, DP_P1_CURP, dp->rx_buf_start);	/* Current page - next free page for Rx */
213 	dp->running = true;
214 	for (i = 0; i < ETHER_ADDR_LEN; i++) {
215 		/* FIXME */
216 		/*((vu_short*)( base + ((DP_P1_PAR0 + i) * 2) +
217 		 * 0x1400)) = enaddr[i];*/
218 		DP_OUT(base, DP_P1_PAR0+i, enaddr[i]);
219 	}
220 	/* Enable and start device */
221 	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
222 	DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */
223 	DP_OUT(base, DP_RCR, DP_RCR_AB); /* Accept broadcast, no errors, no multicast */
224 	dp->running = true;
225 }
226 
227 /*
228  * This routine is called to start the transmitter. It is split out from the
229  * data handling routine so it may be called either when data becomes first
230  * available or when an Tx interrupt occurs
231  */
232 
233 static void
234 dp83902a_start_xmit(int start_page, int len)
235 {
236 	dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic;
237 	u8 *base = dp->base;
238 
239 	DEBUG_FUNCTION();
240 
241 #if DEBUG & 1
242 	printf("Tx pkt %d len %d\n", start_page, len);
243 	if (dp->tx_started)
244 		printf("TX already started?!?\n");
245 #endif
246 
247 	DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE));
248 	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
249 	DP_OUT(base, DP_TBCL, len & 0xFF);
250 	DP_OUT(base, DP_TBCH, len >> 8);
251 	DP_OUT(base, DP_TPSR, start_page);
252 	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
253 
254 	dp->tx_started = true;
255 }
256 
257 /*
258  * This routine is called to send data to the hardware. It is known a-priori
259  * that there is free buffer space (dp->tx_next).
260  */
261 static void
262 dp83902a_send(u8 *data, int total_len, u32 key)
263 {
264 	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
265 	u8 *base = dp->base;
266 	int len, start_page, pkt_len, i, isr;
267 #if DEBUG & 4
268 	int dx;
269 #endif
270 
271 	DEBUG_FUNCTION();
272 
273 	len = pkt_len = total_len;
274 	if (pkt_len < IEEE_8023_MIN_FRAME)
275 		pkt_len = IEEE_8023_MIN_FRAME;
276 
277 	start_page = dp->tx_next;
278 	if (dp->tx_next == dp->tx_buf1) {
279 		dp->tx1 = start_page;
280 		dp->tx1_len = pkt_len;
281 		dp->tx1_key = key;
282 		dp->tx_next = dp->tx_buf2;
283 	} else {
284 		dp->tx2 = start_page;
285 		dp->tx2_len = pkt_len;
286 		dp->tx2_key = key;
287 		dp->tx_next = dp->tx_buf1;
288 	}
289 
290 #if DEBUG & 5
291 	printf("TX prep page %d len %d\n", start_page, pkt_len);
292 #endif
293 
294 	DP_OUT(base, DP_ISR, DP_ISR_RDC);	/* Clear end of DMA */
295 	{
296 		/*
297 		 * Dummy read. The manual sez something slightly different,
298 		 * but the code is extended a bit to do what Hitachi's monitor
299 		 * does (i.e., also read data).
300 		 */
301 
302 		u16 tmp;
303 		int len = 1;
304 
305 		DP_OUT(base, DP_RSAL, 0x100 - len);
306 		DP_OUT(base, DP_RSAH, (start_page - 1) & 0xff);
307 		DP_OUT(base, DP_RBCL, len);
308 		DP_OUT(base, DP_RBCH, 0);
309 		DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START);
310 		DP_IN_DATA(dp->data, tmp);
311 	}
312 
313 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
314 	/*
315 	 * Stall for a bit before continuing to work around random data
316 	 * corruption problems on some platforms.
317 	 */
318 	CYGACC_CALL_IF_DELAY_US(1);
319 #endif
320 
321 	/* Send data to device buffer(s) */
322 	DP_OUT(base, DP_RSAL, 0);
323 	DP_OUT(base, DP_RSAH, start_page);
324 	DP_OUT(base, DP_RBCL, pkt_len & 0xFF);
325 	DP_OUT(base, DP_RBCH, pkt_len >> 8);
326 	DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START);
327 
328 	/* Put data into buffer */
329 #if DEBUG & 4
330 	printf(" sg buf %08lx len %08x\n ", (u32)data, len);
331 	dx = 0;
332 #endif
333 	while (len > 0) {
334 #if DEBUG & 4
335 		printf(" %02x", *data);
336 		if (0 == (++dx % 16)) printf("\n ");
337 #endif
338 
339 		DP_OUT_DATA(dp->data, *data++);
340 		len--;
341 	}
342 #if DEBUG & 4
343 	printf("\n");
344 #endif
345 	if (total_len < pkt_len) {
346 #if DEBUG & 4
347 		printf("  + %d bytes of padding\n", pkt_len - total_len);
348 #endif
349 		/* Padding to 802.3 length was required */
350 		for (i = total_len; i < pkt_len;) {
351 			i++;
352 			DP_OUT_DATA(dp->data, 0);
353 		}
354 	}
355 
356 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
357 	/*
358 	 * After last data write, delay for a bit before accessing the
359 	 * device again, or we may get random data corruption in the last
360 	 * datum (on some platforms).
361 	 */
362 	CYGACC_CALL_IF_DELAY_US(1);
363 #endif
364 
365 	/* Wait for DMA to complete */
366 	do {
367 		DP_IN(base, DP_ISR, isr);
368 	} while ((isr & DP_ISR_RDC) == 0);
369 
370 	/* Then disable DMA */
371 	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
372 
373 	/* Start transmit if not already going */
374 	if (!dp->tx_started) {
375 		if (start_page == dp->tx1) {
376 			dp->tx_int = 1; /* Expecting interrupt from BUF1 */
377 		} else {
378 			dp->tx_int = 2; /* Expecting interrupt from BUF2 */
379 		}
380 		dp83902a_start_xmit(start_page, pkt_len);
381 	}
382 }
383 
384 /*
385  * This function is called when a packet has been received. It's job is
386  * to prepare to unload the packet from the hardware. Once the length of
387  * the packet is known, the upper layer of the driver can be told. When
388  * the upper layer is ready to unload the packet, the internal function
389  * 'dp83902a_recv' will be called to actually fetch it from the hardware.
390  */
391 static void
392 dp83902a_RxEvent(void)
393 {
394 	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
395 	u8 *base = dp->base;
396 	u8 rsr;
397 	u8 rcv_hdr[4];
398 	int i, len, pkt, cur;
399 
400 	DEBUG_FUNCTION();
401 
402 	DP_IN(base, DP_RSR, rsr);
403 	while (true) {
404 		/* Read incoming packet header */
405 		DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START);
406 		DP_IN(base, DP_P1_CURP, cur);
407 		DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
408 		DP_IN(base, DP_BNDRY, pkt);
409 
410 		pkt += 1;
411 		if (pkt == dp->rx_buf_end)
412 			pkt = dp->rx_buf_start;
413 
414 		if (pkt == cur) {
415 			break;
416 		}
417 		DP_OUT(base, DP_RBCL, sizeof(rcv_hdr));
418 		DP_OUT(base, DP_RBCH, 0);
419 		DP_OUT(base, DP_RSAL, 0);
420 		DP_OUT(base, DP_RSAH, pkt);
421 		if (dp->rx_next == pkt) {
422 			if (cur == dp->rx_buf_start)
423 				DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1);
424 			else
425 				DP_OUT(base, DP_BNDRY, cur - 1); /* Update pointer */
426 			return;
427 		}
428 		dp->rx_next = pkt;
429 		DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
430 		DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
431 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
432 		CYGACC_CALL_IF_DELAY_US(10);
433 #endif
434 
435 		/* read header (get data size)*/
436 		for (i = 0; i < sizeof(rcv_hdr);) {
437 			DP_IN_DATA(dp->data, rcv_hdr[i++]);
438 		}
439 
440 #if DEBUG & 5
441 		printf("rx hdr %02x %02x %02x %02x\n",
442 			rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]);
443 #endif
444 		len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr);
445 
446 		/* data read */
447 		uboot_push_packet_len(len);
448 
449 		if (rcv_hdr[1] == dp->rx_buf_start)
450 			DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1);
451 		else
452 			DP_OUT(base, DP_BNDRY, rcv_hdr[1] - 1); /* Update pointer */
453 	}
454 }
455 
456 /*
457  * This function is called as a result of the "eth_drv_recv()" call above.
458  * It's job is to actually fetch data for a packet from the hardware once
459  * memory buffers have been allocated for the packet. Note that the buffers
460  * may come in pieces, using a scatter-gather list. This allows for more
461  * efficient processing in the upper layers of the stack.
462  */
463 static void
464 dp83902a_recv(u8 *data, int len)
465 {
466 	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
467 	u8 *base = dp->base;
468 	int i, mlen;
469 	u8 saved_char = 0;
470 	bool saved;
471 #if DEBUG & 4
472 	int dx;
473 #endif
474 
475 	DEBUG_FUNCTION();
476 
477 #if DEBUG & 5
478 	printf("Rx packet %d length %d\n", dp->rx_next, len);
479 #endif
480 
481 	/* Read incoming packet data */
482 	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
483 	DP_OUT(base, DP_RBCL, len & 0xFF);
484 	DP_OUT(base, DP_RBCH, len >> 8);
485 	DP_OUT(base, DP_RSAL, 4);		/* Past header */
486 	DP_OUT(base, DP_RSAH, dp->rx_next);
487 	DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
488 	DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
489 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
490 	CYGACC_CALL_IF_DELAY_US(10);
491 #endif
492 
493 	saved = false;
494 	for (i = 0; i < 1; i++) {
495 		if (data) {
496 			mlen = len;
497 #if DEBUG & 4
498 			printf(" sg buf %08lx len %08x \n", (u32) data, mlen);
499 			dx = 0;
500 #endif
501 			while (0 < mlen) {
502 				/* Saved byte from previous loop? */
503 				if (saved) {
504 					*data++ = saved_char;
505 					mlen--;
506 					saved = false;
507 					continue;
508 				}
509 
510 				{
511 					u8 tmp;
512 					DP_IN_DATA(dp->data, tmp);
513 #if DEBUG & 4
514 					printf(" %02x", tmp);
515 					if (0 == (++dx % 16)) printf("\n ");
516 #endif
517 					*data++ = tmp;;
518 					mlen--;
519 				}
520 			}
521 #if DEBUG & 4
522 			printf("\n");
523 #endif
524 		}
525 	}
526 }
527 
528 static void
529 dp83902a_TxEvent(void)
530 {
531 	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
532 	u8 *base = dp->base;
533 	u8 tsr;
534 	u32 key;
535 
536 	DEBUG_FUNCTION();
537 
538 	DP_IN(base, DP_TSR, tsr);
539 	if (dp->tx_int == 1) {
540 		key = dp->tx1_key;
541 		dp->tx1 = 0;
542 	} else {
543 		key = dp->tx2_key;
544 		dp->tx2 = 0;
545 	}
546 	/* Start next packet if one is ready */
547 	dp->tx_started = false;
548 	if (dp->tx1) {
549 		dp83902a_start_xmit(dp->tx1, dp->tx1_len);
550 		dp->tx_int = 1;
551 	} else if (dp->tx2) {
552 		dp83902a_start_xmit(dp->tx2, dp->tx2_len);
553 		dp->tx_int = 2;
554 	} else {
555 		dp->tx_int = 0;
556 	}
557 	/* Tell higher level we sent this packet */
558 	uboot_push_tx_done(key, 0);
559 }
560 
561 /*
562  * Read the tally counters to clear them. Called in response to a CNT
563  * interrupt.
564  */
565 static void
566 dp83902a_ClearCounters(void)
567 {
568 	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
569 	u8 *base = dp->base;
570 	u8 cnt1, cnt2, cnt3;
571 
572 	DP_IN(base, DP_FER, cnt1);
573 	DP_IN(base, DP_CER, cnt2);
574 	DP_IN(base, DP_MISSED, cnt3);
575 	DP_OUT(base, DP_ISR, DP_ISR_CNT);
576 }
577 
578 /*
579  * Deal with an overflow condition. This code follows the procedure set
580  * out in section 7.0 of the datasheet.
581  */
582 static void
583 dp83902a_Overflow(void)
584 {
585 	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic;
586 	u8 *base = dp->base;
587 	u8 isr;
588 
589 	/* Issue a stop command and wait 1.6ms for it to complete. */
590 	DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA);
591 	CYGACC_CALL_IF_DELAY_US(1600);
592 
593 	/* Clear the remote byte counter registers. */
594 	DP_OUT(base, DP_RBCL, 0);
595 	DP_OUT(base, DP_RBCH, 0);
596 
597 	/* Enter loopback mode while we clear the buffer. */
598 	DP_OUT(base, DP_TCR, DP_TCR_LOCAL);
599 	DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA);
600 
601 	/*
602 	 * Read in as many packets as we can and acknowledge any and receive
603 	 * interrupts. Since the buffer has overflowed, a receive event of
604 	 * some kind will have occured.
605 	 */
606 	dp83902a_RxEvent();
607 	DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE);
608 
609 	/* Clear the overflow condition and leave loopback mode. */
610 	DP_OUT(base, DP_ISR, DP_ISR_OFLW);
611 	DP_OUT(base, DP_TCR, DP_TCR_NORMAL);
612 
613 	/*
614 	 * If a transmit command was issued, but no transmit event has occured,
615 	 * restart it here.
616 	 */
617 	DP_IN(base, DP_ISR, isr);
618 	if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) {
619 		DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
620 	}
621 }
622 
623 static void
624 dp83902a_poll(void)
625 {
626 	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
627 	u8 *base = dp->base;
628 	u8 isr;
629 
630 	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START);
631 	DP_IN(base, DP_ISR, isr);
632 	while (0 != isr) {
633 		/*
634 		 * The CNT interrupt triggers when the MSB of one of the error
635 		 * counters is set. We don't much care about these counters, but
636 		 * we should read their values to reset them.
637 		 */
638 		if (isr & DP_ISR_CNT) {
639 			dp83902a_ClearCounters();
640 		}
641 		/*
642 		 * Check for overflow. It's a special case, since there's a
643 		 * particular procedure that must be followed to get back into
644 		 * a running state.a
645 		 */
646 		if (isr & DP_ISR_OFLW) {
647 			dp83902a_Overflow();
648 		} else {
649 			/*
650 			 * Other kinds of interrupts can be acknowledged simply by
651 			 * clearing the relevant bits of the ISR. Do that now, then
652 			 * handle the interrupts we care about.
653 			 */
654 			DP_OUT(base, DP_ISR, isr);	/* Clear set bits */
655 			if (!dp->running) break;	/* Is this necessary? */
656 			/*
657 			 * Check for tx_started on TX event since these may happen
658 			 * spuriously it seems.
659 			 */
660 			if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) {
661 				dp83902a_TxEvent();
662 			}
663 			if (isr & (DP_ISR_RxP|DP_ISR_RxE)) {
664 				dp83902a_RxEvent();
665 			}
666 		}
667 		DP_IN(base, DP_ISR, isr);
668 	}
669 }
670 
671 /* find prom (taken from pc_net_cs.c from Linux) */
672 
673 #include "8390.h"
674 /*
675 typedef struct hw_info_t {
676 	u_int	offset;
677 	u_char	a0, a1, a2;
678 	u_int	flags;
679 } hw_info_t;
680 */
681 #define DELAY_OUTPUT	0x01
682 #define HAS_MISC_REG	0x02
683 #define USE_BIG_BUF	0x04
684 #define HAS_IBM_MISC	0x08
685 #define IS_DL10019	0x10
686 #define IS_DL10022	0x20
687 #define HAS_MII		0x40
688 #define USE_SHMEM	0x80	/* autodetected */
689 
690 #define AM79C9XX_HOME_PHY	0x00006B90	/* HomePNA PHY */
691 #define AM79C9XX_ETH_PHY	0x00006B70	/* 10baseT PHY */
692 #define MII_PHYID_REV_MASK	0xfffffff0
693 #define MII_PHYID_REG1		0x02
694 #define MII_PHYID_REG2		0x03
695 
696 static hw_info_t hw_info[] = {
697 	{ /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT },
698 	{ /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 },
699 	{ /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 },
700 	{ /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94,
701 			DELAY_OUTPUT | HAS_IBM_MISC },
702 	{ /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 },
703 	{ /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 },
704 	{ /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 },
705 	{ /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 },
706 	{ /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 },
707 	{ /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 },
708 	{ /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48,
709 			HAS_MISC_REG | HAS_IBM_MISC },
710 	{ /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 },
711 	{ /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 },
712 	{ /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a,
713 			HAS_MISC_REG | HAS_IBM_MISC },
714 	{ /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac,
715 			HAS_MISC_REG | HAS_IBM_MISC },
716 	{ /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29,
717 			HAS_MISC_REG | HAS_IBM_MISC },
718 	{ /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a,
719 			HAS_MISC_REG | HAS_IBM_MISC },
720 	{ /* IBM FME */ 0x0374, 0x00, 0x04, 0xac,
721 			HAS_MISC_REG | HAS_IBM_MISC },
722 	{ /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87,
723 			HAS_MISC_REG | HAS_IBM_MISC },
724 	{ /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17,
725 			HAS_MISC_REG | HAS_IBM_MISC },
726 	{ /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8,
727 			HAS_MISC_REG | HAS_IBM_MISC },
728 	{ /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0,
729 			HAS_MISC_REG | HAS_IBM_MISC },
730 	{ /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0,
731 			HAS_MISC_REG | HAS_IBM_MISC },
732 	{ /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 },
733 	{ /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 },
734 	{ /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0,
735 			HAS_MISC_REG | HAS_IBM_MISC },
736 	{ /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f,
737 			HAS_MISC_REG | HAS_IBM_MISC },
738 	{ /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 },
739 	{ /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 },
740 	{ /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 },
741 	{ /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 },
742 	{ /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65,
743 			HAS_MISC_REG | HAS_IBM_MISC },
744 	{ /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45,
745 			HAS_MISC_REG | HAS_IBM_MISC },
746 	{ /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 },
747 	{ /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 },
748 	{ /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 },
749 	{ /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b,
750 			DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF },
751 	{ /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 },
752 	{ /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 },
753 	{ /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 },
754 	{ /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 },
755 	{ /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 },
756 	{ /* Qemu */ 0x0, 0x52, 0x54, 0x00, 0 }
757 };
758 
759 #define NR_INFO		(sizeof(hw_info)/sizeof(hw_info_t))
760 
761 #define PCNET_CMD	0x00
762 #define PCNET_DATAPORT	0x10	/* NatSemi-defined port window offset. */
763 #define PCNET_RESET	0x1f	/* Issue a read to reset, a write to clear. */
764 #define PCNET_MISC	0x18	/* For IBM CCAE and Socket EA cards */
765 
766 static void pcnet_reset_8390(void)
767 {
768 	int i, r;
769 
770 	PRINTK("nic base is %lx\n", nic.base);
771 
772 	n2k_outb(E8390_NODMA + E8390_PAGE0+E8390_STOP, E8390_CMD);
773 	PRINTK("cmd (at %lx) is %x\n", nic.base + E8390_CMD, n2k_inb(E8390_CMD));
774 	n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD);
775 	PRINTK("cmd (at %lx) is %x\n", nic.base + E8390_CMD, n2k_inb(E8390_CMD));
776 	n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
777 	PRINTK("cmd (at %lx) is %x\n", nic.base + E8390_CMD, n2k_inb(E8390_CMD));
778 	n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
779 
780 	n2k_outb(n2k_inb(PCNET_RESET), PCNET_RESET);
781 
782 	for (i = 0; i < 100; i++) {
783 		if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0)
784 			break;
785 		PRINTK("got %x in reset\n", r);
786 		udelay(100);
787 	}
788 	n2k_outb(ENISR_RESET, EN0_ISR); /* Ack intr. */
789 
790 	if (i == 100)
791 		printf("pcnet_reset_8390() did not complete.\n");
792 } /* pcnet_reset_8390 */
793 
794 int get_prom(u8* mac_addr) __attribute__ ((weak, alias ("__get_prom")));
795 int __get_prom(u8* mac_addr)
796 {
797 	u8 prom[32];
798 	int i, j;
799 	struct {
800 		u_char value, offset;
801 	} program_seq[] = {
802 		{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
803 		{0x48, EN0_DCFG},		/* Set byte-wide (0x48) access. */
804 		{0x00, EN0_RCNTLO},		/* Clear the count regs. */
805 		{0x00, EN0_RCNTHI},
806 		{0x00, EN0_IMR},		/* Mask completion irq. */
807 		{0xFF, EN0_ISR},
808 		{E8390_RXOFF, EN0_RXCR},	/* 0x20 Set to monitor */
809 		{E8390_TXOFF, EN0_TXCR},	/* 0x02 and loopback mode. */
810 		{32, EN0_RCNTLO},
811 		{0x00, EN0_RCNTHI},
812 		{0x00, EN0_RSARLO},		/* DMA starting at 0x0000. */
813 		{0x00, EN0_RSARHI},
814 		{E8390_RREAD+E8390_START, E8390_CMD},
815 	};
816 
817 	PRINTK ("trying to get MAC via prom reading\n");
818 
819 	pcnet_reset_8390 ();
820 
821 	mdelay (10);
822 
823 	for (i = 0; i < sizeof (program_seq) / sizeof (program_seq[0]); i++)
824 		n2k_outb (program_seq[i].value, program_seq[i].offset);
825 
826 	PRINTK ("PROM:");
827 	for (i = 0; i < 32; i++) {
828 		prom[i] = n2k_inb (PCNET_DATAPORT);
829 		PRINTK (" %02x", prom[i]);
830 	}
831 	PRINTK ("\n");
832 	for (i = 0; i < NR_INFO; i++) {
833 		if ((prom[0] == hw_info[i].a0) &&
834 			(prom[2] == hw_info[i].a1) &&
835 			(prom[4] == hw_info[i].a2)) {
836 			PRINTK ("matched board %d\n", i);
837 			break;
838 		}
839 	}
840 	if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) {
841 		PRINTK ("on exit i is %d/%ld\n", i, NR_INFO);
842 		PRINTK ("MAC address is ");
843 		for (j = 0; j < 6; j++) {
844 			mac_addr[j] = prom[j << 1];
845 			PRINTK ("%02x:", mac_addr[i]);
846 		}
847 		PRINTK ("\n");
848 		return (i < NR_INFO) ? i : 0;
849 	}
850 	return 0;
851 }
852 
853 /* U-boot specific routines */
854 static u8 *pbuf = NULL;
855 
856 static int pkey = -1;
857 static int initialized = 0;
858 
859 void uboot_push_packet_len(int len) {
860 	PRINTK("pushed len = %d\n", len);
861 	if (len >= 2000) {
862 		printf("NE2000: packet too big\n");
863 		return;
864 	}
865 	dp83902a_recv(&pbuf[0], len);
866 
867 	/*Just pass it to the upper layer*/
868 	NetReceive(&pbuf[0], len);
869 }
870 
871 void uboot_push_tx_done(int key, int val) {
872 	PRINTK("pushed key = %d\n", key);
873 	pkey = key;
874 }
875 
876 int eth_init(bd_t *bd) {
877 	int r;
878 	u8 dev_addr[6];
879 	char ethaddr[20];
880 
881 	PRINTK("### eth_init\n");
882 
883 	if (!pbuf) {
884 		pbuf = malloc(2000);
885 		if (!pbuf) {
886 			printf("Cannot allocate rx buffer\n");
887 			return -1;
888 		}
889 	}
890 
891 #ifdef CONFIG_DRIVER_NE2000_CCR
892 	{
893 		vu_char *p = (vu_char *) CONFIG_DRIVER_NE2000_CCR;
894 
895 		PRINTK("CCR before is %x\n", *p);
896 		*p = CONFIG_DRIVER_NE2000_VAL;
897 		PRINTK("CCR after is %x\n", *p);
898 	}
899 #endif
900 
901 	nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE;
902 
903 	r = get_prom(dev_addr);
904 	if (!r)
905 		return -1;
906 
907 	sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
908 		 dev_addr[0], dev_addr[1],
909 		 dev_addr[2], dev_addr[3],
910 		 dev_addr[4], dev_addr[5]) ;
911 	PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr);
912 	setenv ("ethaddr", ethaddr);
913 
914 	nic.data = nic.base + DP_DATA;
915 	nic.tx_buf1 = START_PG;
916 	nic.tx_buf2 = START_PG2;
917 	nic.rx_buf_start = RX_START;
918 	nic.rx_buf_end = RX_END;
919 
920 	if (dp83902a_init() == false)
921 		return -1;
922 
923 	dp83902a_start(dev_addr);
924 	initialized = 1;
925 
926 	return 0;
927 }
928 
929 void eth_halt() {
930 
931 	PRINTK("### eth_halt\n");
932 	if(initialized)
933 		dp83902a_stop();
934 	initialized = 0;
935 }
936 
937 int eth_rx() {
938 	dp83902a_poll();
939 	return 1;
940 }
941 
942 int eth_send(volatile void *packet, int length) {
943 	int tmo;
944 
945 	PRINTK("### eth_send\n");
946 
947 	pkey = -1;
948 
949 	dp83902a_send((u8 *) packet, length, 666);
950 	tmo = get_timer (0) + TOUT * CFG_HZ;
951 	while(1) {
952 		dp83902a_poll();
953 		if (pkey != -1) {
954 			PRINTK("Packet sucesfully sent\n");
955 			return 0;
956 		}
957 		if (get_timer (0) >= tmo) {
958 			printf("transmission error (timoeut)\n");
959 			return 0;
960 		}
961 
962 	}
963 	return 0;
964 }
965