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