2 Ported to U-Boot by Christian Pellegrin <chri@ascensit.com>
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.
8 ==========================================================================
12 Ethernet device driver for NS DP83902a ethernet controller
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.
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.
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
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.
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.
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.
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####
49 -------------------------------------------
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.
54 -------------------------------------------
56 ####BSDCOPYRIGHTEND####
57 ==========================================================================
58 #####DESCRIPTIONBEGIN####
61 Contributors: gthomas, jskov, rsandifo
66 FIXME: Will fail if pinged with large packets (1520 bytes)
70 ####DESCRIPTIONEND####
72 ==========================================================================
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);
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
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)
106 #define DEBUG_FUNCTION() do {} while(0)
107 #define DEBUG_LINE() do {} while(0)
108 #define PRINTK(args...)
111 /* NE2000 base header file */
112 #include "ne2000_base.h"
114 #if defined(CONFIG_DRIVER_AX88796L)
115 /* AX88796L support */
118 /* Basic NE2000 chip support */
122 static dp83902a_priv_data_t nic; /* just one instance of the card supported */
127 dp83902a_priv_data_t *dp = &nic;
129 #if defined(NE2000_BASIC_INIT)
137 return false; /* No device found */
141 #if defined(NE2000_BASIC_INIT)
142 /* AX88796L doesn't need */
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 */
150 printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
159 #endif /* NE2000_BASIC_INIT */
166 dp83902a_priv_data_t *dp = &nic;
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 */
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.
185 dp83902a_start(u8 * enaddr)
187 dp83902a_priv_data_t *dp = &nic;
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;
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;
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 */
214 for (i = 0; i < ETHER_ADDR_LEN; i++) {
216 /*((vu_short*)( base + ((DP_P1_PAR0 + i) * 2) +
217 * 0x1400)) = enaddr[i];*/
218 DP_OUT(base, DP_P1_PAR0+i, enaddr[i]);
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 */
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
234 dp83902a_start_xmit(int start_page, int len)
236 dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic;
242 printf("Tx pkt %d len %d\n", start_page, len);
244 printf("TX already started?!?\n");
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);
254 dp->tx_started = true;
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).
262 dp83902a_send(u8 *data, int total_len, u32 key)
264 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
266 int len, start_page, pkt_len, i, isr;
273 len = pkt_len = total_len;
274 if (pkt_len < IEEE_8023_MIN_FRAME)
275 pkt_len = IEEE_8023_MIN_FRAME;
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;
282 dp->tx_next = dp->tx_buf2;
284 dp->tx2 = start_page;
285 dp->tx2_len = pkt_len;
287 dp->tx_next = dp->tx_buf1;
291 printf("TX prep page %d len %d\n", start_page, pkt_len);
294 DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
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).
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);
313 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
315 * Stall for a bit before continuing to work around random data
316 * corruption problems on some platforms.
318 CYGACC_CALL_IF_DELAY_US(1);
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);
328 /* Put data into buffer */
330 printf(" sg buf %08lx len %08x\n ", (u32)data, len);
335 printf(" %02x", *data);
336 if (0 == (++dx % 16)) printf("\n ");
339 DP_OUT_DATA(dp->data, *data++);
345 if (total_len < pkt_len) {
347 printf(" + %d bytes of padding\n", pkt_len - total_len);
349 /* Padding to 802.3 length was required */
350 for (i = total_len; i < pkt_len;) {
352 DP_OUT_DATA(dp->data, 0);
356 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
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).
362 CYGACC_CALL_IF_DELAY_US(1);
365 /* Wait for DMA to complete */
367 DP_IN(base, DP_ISR, isr);
368 } while ((isr & DP_ISR_RDC) == 0);
370 /* Then disable DMA */
371 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
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 */
378 dp->tx_int = 2; /* Expecting interrupt from BUF2 */
380 dp83902a_start_xmit(start_page, pkt_len);
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.
392 dp83902a_RxEvent(void)
394 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
398 int i, len, pkt, cur;
402 DP_IN(base, DP_RSR, rsr);
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);
411 if (pkt == dp->rx_buf_end)
412 pkt = dp->rx_buf_start;
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);
425 DP_OUT(base, DP_BNDRY, cur - 1); /* Update pointer */
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);
435 /* read header (get data size)*/
436 for (i = 0; i < sizeof(rcv_hdr);) {
437 DP_IN_DATA(dp->data, rcv_hdr[i++]);
441 printf("rx hdr %02x %02x %02x %02x\n",
442 rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]);
444 len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr);
447 uboot_push_packet_len(len);
449 if (rcv_hdr[1] == dp->rx_buf_start)
450 DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1);
452 DP_OUT(base, DP_BNDRY, rcv_hdr[1] - 1); /* Update pointer */
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.
464 dp83902a_recv(u8 *data, int len)
466 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
478 printf("Rx packet %d length %d\n", dp->rx_next, len);
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);
494 for (i = 0; i < 1; i++) {
498 printf(" sg buf %08lx len %08x \n", (u32) data, mlen);
502 /* Saved byte from previous loop? */
504 *data++ = saved_char;
512 DP_IN_DATA(dp->data, tmp);
514 printf(" %02x", tmp);
515 if (0 == (++dx % 16)) printf("\n ");
529 dp83902a_TxEvent(void)
531 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
538 DP_IN(base, DP_TSR, tsr);
539 if (dp->tx_int == 1) {
546 /* Start next packet if one is ready */
547 dp->tx_started = false;
549 dp83902a_start_xmit(dp->tx1, dp->tx1_len);
551 } else if (dp->tx2) {
552 dp83902a_start_xmit(dp->tx2, dp->tx2_len);
557 /* Tell higher level we sent this packet */
558 uboot_push_tx_done(key, 0);
562 * Read the tally counters to clear them. Called in response to a CNT
566 dp83902a_ClearCounters(void)
568 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
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);
579 * Deal with an overflow condition. This code follows the procedure set
580 * out in section 7.0 of the datasheet.
583 dp83902a_Overflow(void)
585 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic;
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);
593 /* Clear the remote byte counter registers. */
594 DP_OUT(base, DP_RBCL, 0);
595 DP_OUT(base, DP_RBCH, 0);
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);
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.
607 DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE);
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);
614 * If a transmit command was issued, but no transmit event has occured,
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);
626 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
630 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START);
631 DP_IN(base, DP_ISR, isr);
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.
638 if (isr & DP_ISR_CNT) {
639 dp83902a_ClearCounters();
642 * Check for overflow. It's a special case, since there's a
643 * particular procedure that must be followed to get back into
646 if (isr & DP_ISR_OFLW) {
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.
654 DP_OUT(base, DP_ISR, isr); /* Clear set bits */
655 if (!dp->running) break; /* Is this necessary? */
657 * Check for tx_started on TX event since these may happen
658 * spuriously it seems.
660 if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) {
663 if (isr & (DP_ISR_RxP|DP_ISR_RxE)) {
667 DP_IN(base, DP_ISR, isr);
671 /* find prom (taken from pc_net_cs.c from Linux) */
675 typedef struct hw_info_t {
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
688 #define USE_SHMEM 0x80 /* autodetected */
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
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 }
759 #define NR_INFO (sizeof(hw_info)/sizeof(hw_info_t))
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 */
766 static void pcnet_reset_8390(void)
770 PRINTK("nic base is %lx\n", nic.base);
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);
780 n2k_outb(n2k_inb(PCNET_RESET), PCNET_RESET);
782 for (i = 0; i < 100; i++) {
783 if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0)
785 PRINTK("got %x in reset\n", r);
788 n2k_outb(ENISR_RESET, EN0_ISR); /* Ack intr. */
791 printf("pcnet_reset_8390() did not complete.\n");
792 } /* pcnet_reset_8390 */
794 int get_prom(u8* mac_addr) __attribute__ ((weak, alias ("__get_prom")));
795 int __get_prom(u8* mac_addr)
800 u_char value, offset;
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. */
806 {0x00, EN0_IMR}, /* Mask completion irq. */
808 {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
809 {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
812 {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
814 {E8390_RREAD+E8390_START, E8390_CMD},
817 PRINTK ("trying to get MAC via prom reading\n");
823 for (i = 0; i < sizeof (program_seq) / sizeof (program_seq[0]); i++)
824 n2k_outb (program_seq[i].value, program_seq[i].offset);
827 for (i = 0; i < 32; i++) {
828 prom[i] = n2k_inb (PCNET_DATAPORT);
829 PRINTK (" %02x", prom[i]);
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);
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]);
848 return (i < NR_INFO) ? i : 0;
853 /* U-boot specific routines */
854 static u8 *pbuf = NULL;
856 static int pkey = -1;
857 static int initialized = 0;
859 void uboot_push_packet_len(int len) {
860 PRINTK("pushed len = %d\n", len);
862 printf("NE2000: packet too big\n");
865 dp83902a_recv(&pbuf[0], len);
867 /*Just pass it to the upper layer*/
868 NetReceive(&pbuf[0], len);
871 void uboot_push_tx_done(int key, int val) {
872 PRINTK("pushed key = %d\n", key);
876 int eth_init(bd_t *bd) {
881 PRINTK("### eth_init\n");
886 printf("Cannot allocate rx buffer\n");
891 #ifdef CONFIG_DRIVER_NE2000_CCR
893 vu_char *p = (vu_char *) CONFIG_DRIVER_NE2000_CCR;
895 PRINTK("CCR before is %x\n", *p);
896 *p = CONFIG_DRIVER_NE2000_VAL;
897 PRINTK("CCR after is %x\n", *p);
901 nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE;
903 r = get_prom(dev_addr);
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);
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;
920 if (dp83902a_init() == false)
923 dp83902a_start(dev_addr);
931 PRINTK("### eth_halt\n");
942 int eth_send(volatile void *packet, int length) {
945 PRINTK("### eth_send\n");
949 dp83902a_send((u8 *) packet, length, 666);
950 tmo = get_timer (0) + TOUT * CFG_HZ;
954 PRINTK("Packet sucesfully sent\n");
957 if (get_timer (0) >= tmo) {
958 printf("transmission error (timoeut)\n");