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#include <linux/compiler.h>
  80
  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
  98/**
  99 * This function reads the MAC address from the serial EEPROM,
 100 * used if PROM read fails. Does nothing for ax88796 chips (sh boards)
 101 */
 102static bool
 103dp83902a_init(unsigned char *enetaddr)
 104{
 105        dp83902a_priv_data_t *dp = &nic;
 106        u8* base;
 107#if defined(NE2000_BASIC_INIT)
 108        int i;
 109#endif
 110
 111        DEBUG_FUNCTION();
 112
 113        base = dp->base;
 114        if (!base)
 115                return false;   /* No device found */
 116
 117        DEBUG_LINE();
 118
 119#if defined(NE2000_BASIC_INIT)
 120        /* AX88796L doesn't need */
 121        /* Prepare ESA */
 122        DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); /* Select page 1 */
 123        /* Use the address from the serial EEPROM */
 124        for (i = 0; i < 6; i++)
 125                DP_IN(base, DP_P1_PAR0+i, dp->esa[i]);
 126        DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0); /* Select page 0 */
 127
 128        printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
 129                "eeprom",
 130                dp->esa[0],
 131                dp->esa[1],
 132                dp->esa[2],
 133                dp->esa[3],
 134                dp->esa[4],
 135                dp->esa[5] );
 136
 137        memcpy(enetaddr, dp->esa, 6); /* Use MAC from serial EEPROM */
 138#endif  /* NE2000_BASIC_INIT */
 139        return true;
 140}
 141
 142static void
 143dp83902a_stop(void)
 144{
 145        dp83902a_priv_data_t *dp = &nic;
 146        u8 *base = dp->base;
 147
 148        DEBUG_FUNCTION();
 149
 150        DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP);    /* Brutal */
 151        DP_OUT(base, DP_ISR, 0xFF);             /* Clear any pending interrupts */
 152        DP_OUT(base, DP_IMR, 0x00);             /* Disable all interrupts */
 153
 154        dp->running = false;
 155}
 156
 157/*
 158 * This function is called to "start up" the interface. It may be called
 159 * multiple times, even when the hardware is already running. It will be
 160 * called whenever something "hardware oriented" changes and should leave
 161 * the hardware ready to send/receive packets.
 162 */
 163static void
 164dp83902a_start(u8 * enaddr)
 165{
 166        dp83902a_priv_data_t *dp = &nic;
 167        u8 *base = dp->base;
 168        int i;
 169
 170        debug("The MAC is %pM\n", enaddr);
 171
 172        DEBUG_FUNCTION();
 173
 174        DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */
 175        DP_OUT(base, DP_DCR, DP_DCR_INIT);
 176        DP_OUT(base, DP_RBCH, 0);               /* Remote byte count */
 177        DP_OUT(base, DP_RBCL, 0);
 178        DP_OUT(base, DP_RCR, DP_RCR_MON);       /* Accept no packets */
 179        DP_OUT(base, DP_TCR, DP_TCR_LOCAL);     /* Transmitter [virtually] off */
 180        DP_OUT(base, DP_TPSR, dp->tx_buf1);     /* Transmitter start page */
 181        dp->tx1 = dp->tx2 = 0;
 182        dp->tx_next = dp->tx_buf1;
 183        dp->tx_started = false;
 184        dp->running = true;
 185        DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */
 186        DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); /* Receive ring boundary */
 187        DP_OUT(base, DP_PSTOP, dp->rx_buf_end); /* Receive ring end page */
 188        dp->rx_next = dp->rx_buf_start - 1;
 189        dp->running = true;
 190        DP_OUT(base, DP_ISR, 0xFF);             /* Clear any pending interrupts */
 191        DP_OUT(base, DP_IMR, DP_IMR_All);       /* Enable all interrupts */
 192        DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP);    /* Select page 1 */
 193        DP_OUT(base, DP_P1_CURP, dp->rx_buf_start);     /* Current page - next free page for Rx */
 194        dp->running = true;
 195        for (i = 0; i < ETHER_ADDR_LEN; i++) {
 196                /* FIXME */
 197                /*((vu_short*)( base + ((DP_P1_PAR0 + i) * 2) +
 198                 * 0x1400)) = enaddr[i];*/
 199                DP_OUT(base, DP_P1_PAR0+i, enaddr[i]);
 200        }
 201        /* Enable and start device */
 202        DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
 203        DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */
 204        DP_OUT(base, DP_RCR, DP_RCR_AB); /* Accept broadcast, no errors, no multicast */
 205        dp->running = true;
 206}
 207
 208/*
 209 * This routine is called to start the transmitter. It is split out from the
 210 * data handling routine so it may be called either when data becomes first
 211 * available or when an Tx interrupt occurs
 212 */
 213
 214static void
 215dp83902a_start_xmit(int start_page, int len)
 216{
 217        dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic;
 218        u8 *base = dp->base;
 219
 220        DEBUG_FUNCTION();
 221
 222#if DEBUG & 1
 223        printf("Tx pkt %d len %d\n", start_page, len);
 224        if (dp->tx_started)
 225                printf("TX already started?!?\n");
 226#endif
 227
 228        DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE));
 229        DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
 230        DP_OUT(base, DP_TBCL, len & 0xFF);
 231        DP_OUT(base, DP_TBCH, len >> 8);
 232        DP_OUT(base, DP_TPSR, start_page);
 233        DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
 234
 235        dp->tx_started = true;
 236}
 237
 238/*
 239 * This routine is called to send data to the hardware. It is known a-priori
 240 * that there is free buffer space (dp->tx_next).
 241 */
 242static void
 243dp83902a_send(u8 *data, int total_len, u32 key)
 244{
 245        struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
 246        u8 *base = dp->base;
 247        int len, start_page, pkt_len, i, isr;
 248#if DEBUG & 4
 249        int dx;
 250#endif
 251
 252        DEBUG_FUNCTION();
 253
 254        len = pkt_len = total_len;
 255        if (pkt_len < IEEE_8023_MIN_FRAME)
 256                pkt_len = IEEE_8023_MIN_FRAME;
 257
 258        start_page = dp->tx_next;
 259        if (dp->tx_next == dp->tx_buf1) {
 260                dp->tx1 = start_page;
 261                dp->tx1_len = pkt_len;
 262                dp->tx1_key = key;
 263                dp->tx_next = dp->tx_buf2;
 264        } else {
 265                dp->tx2 = start_page;
 266                dp->tx2_len = pkt_len;
 267                dp->tx2_key = key;
 268                dp->tx_next = dp->tx_buf1;
 269        }
 270
 271#if DEBUG & 5
 272        printf("TX prep page %d len %d\n", start_page, pkt_len);
 273#endif
 274
 275        DP_OUT(base, DP_ISR, DP_ISR_RDC);       /* Clear end of DMA */
 276        {
 277                /*
 278                 * Dummy read. The manual sez something slightly different,
 279                 * but the code is extended a bit to do what Hitachi's monitor
 280                 * does (i.e., also read data).
 281                 */
 282
 283                __maybe_unused u16 tmp;
 284                int len = 1;
 285
 286                DP_OUT(base, DP_RSAL, 0x100 - len);
 287                DP_OUT(base, DP_RSAH, (start_page - 1) & 0xff);
 288                DP_OUT(base, DP_RBCL, len);
 289                DP_OUT(base, DP_RBCH, 0);
 290                DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START);
 291                DP_IN_DATA(dp->data, tmp);
 292        }
 293
 294#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
 295        /*
 296         * Stall for a bit before continuing to work around random data
 297         * corruption problems on some platforms.
 298         */
 299        CYGACC_CALL_IF_DELAY_US(1);
 300#endif
 301
 302        /* Send data to device buffer(s) */
 303        DP_OUT(base, DP_RSAL, 0);
 304        DP_OUT(base, DP_RSAH, start_page);
 305        DP_OUT(base, DP_RBCL, pkt_len & 0xFF);
 306        DP_OUT(base, DP_RBCH, pkt_len >> 8);
 307        DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START);
 308
 309        /* Put data into buffer */
 310#if DEBUG & 4
 311        printf(" sg buf %08lx len %08x\n ", (u32)data, len);
 312        dx = 0;
 313#endif
 314        while (len > 0) {
 315#if DEBUG & 4
 316                printf(" %02x", *data);
 317                if (0 == (++dx % 16)) printf("\n ");
 318#endif
 319
 320                DP_OUT_DATA(dp->data, *data++);
 321                len--;
 322        }
 323#if DEBUG & 4
 324        printf("\n");
 325#endif
 326        if (total_len < pkt_len) {
 327#if DEBUG & 4
 328                printf("  + %d bytes of padding\n", pkt_len - total_len);
 329#endif
 330                /* Padding to 802.3 length was required */
 331                for (i = total_len; i < pkt_len;) {
 332                        i++;
 333                        DP_OUT_DATA(dp->data, 0);
 334                }
 335        }
 336
 337#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
 338        /*
 339         * After last data write, delay for a bit before accessing the
 340         * device again, or we may get random data corruption in the last
 341         * datum (on some platforms).
 342         */
 343        CYGACC_CALL_IF_DELAY_US(1);
 344#endif
 345
 346        /* Wait for DMA to complete */
 347        do {
 348                DP_IN(base, DP_ISR, isr);
 349        } while ((isr & DP_ISR_RDC) == 0);
 350
 351        /* Then disable DMA */
 352        DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
 353
 354        /* Start transmit if not already going */
 355        if (!dp->tx_started) {
 356                if (start_page == dp->tx1) {
 357                        dp->tx_int = 1; /* Expecting interrupt from BUF1 */
 358                } else {
 359                        dp->tx_int = 2; /* Expecting interrupt from BUF2 */
 360                }
 361                dp83902a_start_xmit(start_page, pkt_len);
 362        }
 363}
 364
 365/*
 366 * This function is called when a packet has been received. It's job is
 367 * to prepare to unload the packet from the hardware. Once the length of
 368 * the packet is known, the upper layer of the driver can be told. When
 369 * the upper layer is ready to unload the packet, the internal function
 370 * 'dp83902a_recv' will be called to actually fetch it from the hardware.
 371 */
 372static void
 373dp83902a_RxEvent(void)
 374{
 375        struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
 376        u8 *base = dp->base;
 377        __maybe_unused u8 rsr;
 378        u8 rcv_hdr[4];
 379        int i, len, pkt, cur;
 380
 381        DEBUG_FUNCTION();
 382
 383        DP_IN(base, DP_RSR, rsr);
 384        while (true) {
 385                /* Read incoming packet header */
 386                DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START);
 387                DP_IN(base, DP_P1_CURP, cur);
 388                DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
 389                DP_IN(base, DP_BNDRY, pkt);
 390
 391                pkt += 1;
 392                if (pkt == dp->rx_buf_end)
 393                        pkt = dp->rx_buf_start;
 394
 395                if (pkt == cur) {
 396                        break;
 397                }
 398                DP_OUT(base, DP_RBCL, sizeof(rcv_hdr));
 399                DP_OUT(base, DP_RBCH, 0);
 400                DP_OUT(base, DP_RSAL, 0);
 401                DP_OUT(base, DP_RSAH, pkt);
 402                if (dp->rx_next == pkt) {
 403                        if (cur == dp->rx_buf_start)
 404                                DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1);
 405                        else
 406                                DP_OUT(base, DP_BNDRY, cur - 1); /* Update pointer */
 407                        return;
 408                }
 409                dp->rx_next = pkt;
 410                DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
 411                DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
 412#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
 413                CYGACC_CALL_IF_DELAY_US(10);
 414#endif
 415
 416                /* read header (get data size)*/
 417                for (i = 0; i < sizeof(rcv_hdr);) {
 418                        DP_IN_DATA(dp->data, rcv_hdr[i++]);
 419                }
 420
 421#if DEBUG & 5
 422                printf("rx hdr %02x %02x %02x %02x\n",
 423                        rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]);
 424#endif
 425                len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr);
 426
 427                /* data read */
 428                uboot_push_packet_len(len);
 429
 430                if (rcv_hdr[1] == dp->rx_buf_start)
 431                        DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1);
 432                else
 433                        DP_OUT(base, DP_BNDRY, rcv_hdr[1] - 1); /* Update pointer */
 434        }
 435}
 436
 437/*
 438 * This function is called as a result of the "eth_drv_recv()" call above.
 439 * It's job is to actually fetch data for a packet from the hardware once
 440 * memory buffers have been allocated for the packet. Note that the buffers
 441 * may come in pieces, using a scatter-gather list. This allows for more
 442 * efficient processing in the upper layers of the stack.
 443 */
 444static void
 445dp83902a_recv(u8 *data, int len)
 446{
 447        struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
 448        u8 *base = dp->base;
 449        int i, mlen;
 450        u8 saved_char = 0;
 451        bool saved;
 452#if DEBUG & 4
 453        int dx;
 454#endif
 455
 456        DEBUG_FUNCTION();
 457
 458#if DEBUG & 5
 459        printf("Rx packet %d length %d\n", dp->rx_next, len);
 460#endif
 461
 462        /* Read incoming packet data */
 463        DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
 464        DP_OUT(base, DP_RBCL, len & 0xFF);
 465        DP_OUT(base, DP_RBCH, len >> 8);
 466        DP_OUT(base, DP_RSAL, 4);               /* Past header */
 467        DP_OUT(base, DP_RSAH, dp->rx_next);
 468        DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
 469        DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
 470#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
 471        CYGACC_CALL_IF_DELAY_US(10);
 472#endif
 473
 474        saved = false;
 475        for (i = 0; i < 1; i++) {
 476                if (data) {
 477                        mlen = len;
 478#if DEBUG & 4
 479                        printf(" sg buf %08lx len %08x \n", (u32) data, mlen);
 480                        dx = 0;
 481#endif
 482                        while (0 < mlen) {
 483                                /* Saved byte from previous loop? */
 484                                if (saved) {
 485                                        *data++ = saved_char;
 486                                        mlen--;
 487                                        saved = false;
 488                                        continue;
 489                                }
 490
 491                                {
 492                                        u8 tmp;
 493                                        DP_IN_DATA(dp->data, tmp);
 494#if DEBUG & 4
 495                                        printf(" %02x", tmp);
 496                                        if (0 == (++dx % 16)) printf("\n ");
 497#endif
 498                                        *data++ = tmp;
 499                                        mlen--;
 500                                }
 501                        }
 502#if DEBUG & 4
 503                        printf("\n");
 504#endif
 505                }
 506        }
 507}
 508
 509static void
 510dp83902a_TxEvent(void)
 511{
 512        struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
 513        u8 *base = dp->base;
 514        __maybe_unused u8 tsr;
 515        u32 key;
 516
 517        DEBUG_FUNCTION();
 518
 519        DP_IN(base, DP_TSR, tsr);
 520        if (dp->tx_int == 1) {
 521                key = dp->tx1_key;
 522                dp->tx1 = 0;
 523        } else {
 524                key = dp->tx2_key;
 525                dp->tx2 = 0;
 526        }
 527        /* Start next packet if one is ready */
 528        dp->tx_started = false;
 529        if (dp->tx1) {
 530                dp83902a_start_xmit(dp->tx1, dp->tx1_len);
 531                dp->tx_int = 1;
 532        } else if (dp->tx2) {
 533                dp83902a_start_xmit(dp->tx2, dp->tx2_len);
 534                dp->tx_int = 2;
 535        } else {
 536                dp->tx_int = 0;
 537        }
 538        /* Tell higher level we sent this packet */
 539        uboot_push_tx_done(key, 0);
 540}
 541
 542/*
 543 * Read the tally counters to clear them. Called in response to a CNT
 544 * interrupt.
 545 */
 546static void
 547dp83902a_ClearCounters(void)
 548{
 549        struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
 550        u8 *base = dp->base;
 551        __maybe_unused u8 cnt1, cnt2, cnt3;
 552
 553        DP_IN(base, DP_FER, cnt1);
 554        DP_IN(base, DP_CER, cnt2);
 555        DP_IN(base, DP_MISSED, cnt3);
 556        DP_OUT(base, DP_ISR, DP_ISR_CNT);
 557}
 558
 559/*
 560 * Deal with an overflow condition. This code follows the procedure set
 561 * out in section 7.0 of the datasheet.
 562 */
 563static void
 564dp83902a_Overflow(void)
 565{
 566        struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic;
 567        u8 *base = dp->base;
 568        u8 isr;
 569
 570        /* Issue a stop command and wait 1.6ms for it to complete. */
 571        DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA);
 572        CYGACC_CALL_IF_DELAY_US(1600);
 573
 574        /* Clear the remote byte counter registers. */
 575        DP_OUT(base, DP_RBCL, 0);
 576        DP_OUT(base, DP_RBCH, 0);
 577
 578        /* Enter loopback mode while we clear the buffer. */
 579        DP_OUT(base, DP_TCR, DP_TCR_LOCAL);
 580        DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA);
 581
 582        /*
 583         * Read in as many packets as we can and acknowledge any and receive
 584         * interrupts. Since the buffer has overflowed, a receive event of
 585         * some kind will have occurred.
 586         */
 587        dp83902a_RxEvent();
 588        DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE);
 589
 590        /* Clear the overflow condition and leave loopback mode. */
 591        DP_OUT(base, DP_ISR, DP_ISR_OFLW);
 592        DP_OUT(base, DP_TCR, DP_TCR_NORMAL);
 593
 594        /*
 595         * If a transmit command was issued, but no transmit event has occurred,
 596         * restart it here.
 597         */
 598        DP_IN(base, DP_ISR, isr);
 599        if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) {
 600                DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
 601        }
 602}
 603
 604static void
 605dp83902a_poll(void)
 606{
 607        struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
 608        u8 *base = dp->base;
 609        u8 isr;
 610
 611        DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START);
 612        DP_IN(base, DP_ISR, isr);
 613        while (0 != isr) {
 614                /*
 615                 * The CNT interrupt triggers when the MSB of one of the error
 616                 * counters is set. We don't much care about these counters, but
 617                 * we should read their values to reset them.
 618                 */
 619                if (isr & DP_ISR_CNT) {
 620                        dp83902a_ClearCounters();
 621                }
 622                /*
 623                 * Check for overflow. It's a special case, since there's a
 624                 * particular procedure that must be followed to get back into
 625                 * a running state.a
 626                 */
 627                if (isr & DP_ISR_OFLW) {
 628                        dp83902a_Overflow();
 629                } else {
 630                        /*
 631                         * Other kinds of interrupts can be acknowledged simply by
 632                         * clearing the relevant bits of the ISR. Do that now, then
 633                         * handle the interrupts we care about.
 634                         */
 635                        DP_OUT(base, DP_ISR, isr);      /* Clear set bits */
 636                        if (!dp->running) break;        /* Is this necessary? */
 637                        /*
 638                         * Check for tx_started on TX event since these may happen
 639                         * spuriously it seems.
 640                         */
 641                        if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) {
 642                                dp83902a_TxEvent();
 643                        }
 644                        if (isr & (DP_ISR_RxP|DP_ISR_RxE)) {
 645                                dp83902a_RxEvent();
 646                        }
 647                }
 648                DP_IN(base, DP_ISR, isr);
 649        }
 650}
 651
 652
 653/* U-Boot specific routines */
 654static u8 *pbuf = NULL;
 655
 656static int pkey = -1;
 657static int initialized = 0;
 658
 659void uboot_push_packet_len(int len) {
 660        PRINTK("pushed len = %d\n", len);
 661        if (len >= 2000) {
 662                printf("NE2000: packet too big\n");
 663                return;
 664        }
 665        dp83902a_recv(&pbuf[0], len);
 666
 667        /*Just pass it to the upper layer*/
 668        net_process_received_packet(&pbuf[0], len);
 669}
 670
 671void uboot_push_tx_done(int key, int val) {
 672        PRINTK("pushed key = %d\n", key);
 673        pkey = key;
 674}
 675
 676/**
 677 * Setup the driver and init MAC address according to doc/README.enetaddr
 678 * Called by ne2k_register() before registering the driver @eth layer
 679 *
 680 * @param struct ethdevice of this instance of the driver for dev->enetaddr
 681 * @return 0 on success, -1 on error (causing caller to print error msg)
 682 */
 683static int ne2k_setup_driver(struct eth_device *dev)
 684{
 685        PRINTK("### ne2k_setup_driver\n");
 686
 687        if (!pbuf) {
 688                pbuf = malloc(2000);
 689                if (!pbuf) {
 690                        printf("Cannot allocate rx buffer\n");
 691                        return -1;
 692                }
 693        }
 694
 695#ifdef CONFIG_DRIVER_NE2000_CCR
 696        {
 697                vu_char *p = (vu_char *) CONFIG_DRIVER_NE2000_CCR;
 698
 699                PRINTK("CCR before is %x\n", *p);
 700                *p = CONFIG_DRIVER_NE2000_VAL;
 701                PRINTK("CCR after is %x\n", *p);
 702        }
 703#endif
 704
 705        nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE;
 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        /*
 714         * According to doc/README.enetaddr, drivers shall give priority
 715         * to the MAC address value in the environment, so we do not read
 716         * it from the prom or eeprom if it is specified in the environment.
 717         */
 718        if (!eth_env_get_enetaddr("ethaddr", dev->enetaddr)) {
 719                /* If the MAC address is not in the environment, get it: */
 720                if (!get_prom(dev->enetaddr, nic.base)) /* get MAC from prom */
 721                        dp83902a_init(dev->enetaddr);   /* fallback: seeprom */
 722                /* And write it into the environment otherwise eth_write_hwaddr
 723                 * returns -1 due to eth_env_get_enetaddr_by_index() failing,
 724                 * and this causes "Warning: failed to set MAC address", and
 725                 * cmd_bdinfo has no ethaddr value which it can show: */
 726                eth_env_set_enetaddr("ethaddr", dev->enetaddr);
 727        }
 728        return 0;
 729}
 730
 731static int ne2k_init(struct eth_device *dev, bd_t *bd)
 732{
 733        dp83902a_start(dev->enetaddr);
 734        initialized = 1;
 735        return 0;
 736}
 737
 738static void ne2k_halt(struct eth_device *dev)
 739{
 740        debug("### ne2k_halt\n");
 741        if(initialized)
 742                dp83902a_stop();
 743        initialized = 0;
 744}
 745
 746static int ne2k_recv(struct eth_device *dev)
 747{
 748        dp83902a_poll();
 749        return 1;
 750}
 751
 752static int ne2k_send(struct eth_device *dev, void *packet, int length)
 753{
 754        int tmo;
 755
 756        debug("### ne2k_send\n");
 757
 758        pkey = -1;
 759
 760        dp83902a_send((u8 *) packet, length, 666);
 761        tmo = get_timer (0) + TOUT * CONFIG_SYS_HZ;
 762        while(1) {
 763                dp83902a_poll();
 764                if (pkey != -1) {
 765                        PRINTK("Packet sucesfully sent\n");
 766                        return 0;
 767                }
 768                if (get_timer (0) >= tmo) {
 769                        printf("transmission error (timoeut)\n");
 770                        return 0;
 771                }
 772
 773        }
 774        return 0;
 775}
 776
 777/**
 778 * Setup the driver for use and register it with the eth layer
 779 * @return 0 on success, -1 on error (causing caller to print error msg)
 780 */
 781int ne2k_register(void)
 782{
 783        struct eth_device *dev;
 784
 785        dev = calloc(sizeof(*dev), 1);
 786        if (dev == NULL)
 787                return -1;
 788
 789        if (ne2k_setup_driver(dev))
 790                return -1;
 791
 792        dev->init = ne2k_init;
 793        dev->halt = ne2k_halt;
 794        dev->send = ne2k_send;
 795        dev->recv = ne2k_recv;
 796
 797        strcpy(dev->name, "NE2000");
 798
 799        return eth_register(dev);
 800}
 801