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