uboot/drivers/net/ne2000_base.c
<<
>>
Prefs
   1/*
   2Ported to U-Boot by Christian Pellegrin <chri@ascensit.com>
   3
   4Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
   5eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
   6are GPL, so this is, of course, GPL.
   7
   8==========================================================================
   9
  10dev/if_dp83902a.c
  11
  12Ethernet device driver for NS DP83902a ethernet controller
  13
  14==========================================================================
  15####ECOSGPLCOPYRIGHTBEGIN####
  16-------------------------------------------
  17This file is part of eCos, the Embedded Configurable Operating System.
  18Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
  19
  20eCos is free software; you can redistribute it and/or modify it under
  21the terms of the GNU General Public License as published by the Free
  22Software Foundation; either version 2 or (at your option) any later version.
  23
  24eCos is distributed in the hope that it will be useful, but WITHOUT ANY
  25WARRANTY; without even the implied warranty of MERCHANTABILITY or
  26FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  27for more details.
  28
  29You should have received a copy of the GNU General Public License along
  30with eCos; if not, write to the Free Software Foundation, Inc.,
  3159 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  32
  33As a special exception, if other files instantiate templates or use macros
  34or inline functions from this file, or you compile this file and link it
  35with other works to produce a work based on this file, this file does not
  36by itself cause the resulting work to be covered by the GNU General Public
  37License. However the source code for this file must still be made available
  38in accordance with section (3) of the GNU General Public License.
  39
  40This exception does not invalidate any other reasons why a work based on
  41this file might be covered by the GNU General Public License.
  42
  43Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
  44at http://sources.redhat.com/ecos/ecos-license/
  45-------------------------------------------
  46####ECOSGPLCOPYRIGHTEND####
  47####BSDCOPYRIGHTBEGIN####
  48
  49-------------------------------------------
  50
  51Portions of this software may have been derived from OpenBSD or other sources,
  52and are covered by the appropriate copyright disclaimers included herein.
  53
  54-------------------------------------------
  55
  56####BSDCOPYRIGHTEND####
  57==========================================================================
  58#####DESCRIPTIONBEGIN####
  59
  60Author(s):      gthomas
  61Contributors:   gthomas, jskov, rsandifo
  62Date:           2001-06-13
  63Purpose:
  64Description:
  65
  66FIXME:          Will fail if pinged with large packets (1520 bytes)
  67Add promisc config
  68Add 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 */
  82void uboot_push_packet_len(int len);
  83void 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
  96static dp83902a_priv_data_t nic; /* just one instance of the card supported */
  97
  98static bool
  99dp83902a_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
 137static void
 138dp83902a_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 */
 158static void
 159dp83902a_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
 207static void
 208dp83902a_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 */
 235static void
 236dp83902a_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 */
 365static void
 366dp83902a_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 */
 437static void
 438dp83902a_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
 502static void
 503dp83902a_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 */
 539static void
 540dp83902a_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 */
 556static void
 557dp83902a_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
 597static void
 598dp83902a_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 */
 647static u8 *pbuf = NULL;
 648
 649static int pkey = -1;
 650static int initialized = 0;
 651
 652void 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
 664void uboot_push_tx_done(int key, int val) {
 665        PRINTK("pushed key = %d\n", key);
 666        pkey = key;
 667}
 668
 669int 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
 722void eth_halt() {
 723
 724        PRINTK("### eth_halt\n");
 725        if(initialized)
 726                dp83902a_stop();
 727        initialized = 0;
 728}
 729
 730int eth_rx() {
 731        dp83902a_poll();
 732        return 1;
 733}
 734
 735int 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