uboot/drivers/net/lan91c96.c
<<
>>
Prefs
   1/*------------------------------------------------------------------------
   2 * lan91c96.c
   3 * This is a driver for SMSC's LAN91C96 single-chip Ethernet device, based
   4 * on the SMC91111 driver from U-Boot.
   5 *
   6 * (C) Copyright 2002
   7 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
   8 * Rolf Offermanns <rof@sysgo.de>
   9 *
  10 * Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
  11 *       Developed by Simple Network Magic Corporation (SNMC)
  12 * Copyright (C) 1996 by Erik Stahlman (ES)
  13 *
  14 * SPDX-License-Identifier:     GPL-2.0+
  15 *
  16 * Information contained in this file was obtained from the LAN91C96
  17 * manual from SMC.  To get a copy, if you really want one, you can find
  18 * information under www.smsc.com.
  19 *
  20 * "Features" of the SMC chip:
  21 *   6144 byte packet memory. ( for the 91C96 )
  22 *   EEPROM for configuration
  23 *   AUI/TP selection  ( mine has 10Base2/10BaseT select )
  24 *
  25 * Arguments:
  26 *      io      = for the base address
  27 *      irq     = for the IRQ
  28 *
  29 * author:
  30 *      Erik Stahlman                           ( erik@vt.edu )
  31 *      Daris A Nevil                           ( dnevil@snmc.com )
  32 *
  33 *
  34 * Hardware multicast code from Peter Cammaert ( pc@denkart.be )
  35 *
  36 * Sources:
  37 *    o   SMSC LAN91C96 databook (www.smsc.com)
  38 *    o   smc91111.c (u-boot driver)
  39 *    o   smc9194.c (linux kernel driver)
  40 *    o   lan91c96.c (Intel Diagnostic Manager driver)
  41 *
  42 * History:
  43 *      04/30/03  Mathijs Haarman       Modified smc91111.c (u-boot version)
  44 *                                      for lan91c96
  45 *---------------------------------------------------------------------------
  46 */
  47
  48#include <common.h>
  49#include <command.h>
  50#include <malloc.h>
  51#include "lan91c96.h"
  52#include <net.h>
  53#include <linux/compiler.h>
  54
  55/*------------------------------------------------------------------------
  56 *
  57 * Configuration options, for the experienced user to change.
  58 *
  59 -------------------------------------------------------------------------*/
  60
  61/* Use power-down feature of the chip */
  62#define POWER_DOWN      0
  63
  64/*
  65 * Wait time for memory to be free.  This probably shouldn't be
  66 * tuned that much, as waiting for this means nothing else happens
  67 * in the system
  68*/
  69#define MEMORY_WAIT_TIME 16
  70
  71#define SMC_DEBUG 0
  72
  73#if (SMC_DEBUG > 2 )
  74#define PRINTK3(args...) printf(args)
  75#else
  76#define PRINTK3(args...)
  77#endif
  78
  79#if SMC_DEBUG > 1
  80#define PRINTK2(args...) printf(args)
  81#else
  82#define PRINTK2(args...)
  83#endif
  84
  85#ifdef SMC_DEBUG
  86#define PRINTK(args...) printf(args)
  87#else
  88#define PRINTK(args...)
  89#endif
  90
  91
  92/*------------------------------------------------------------------------
  93 *
  94 * The internal workings of the driver.  If you are changing anything
  95 * here with the SMC stuff, you should have the datasheet and know
  96 * what you are doing.
  97 *
  98 *------------------------------------------------------------------------
  99 */
 100#define DRIVER_NAME "LAN91C96"
 101#define SMC_ALLOC_MAX_TRY 5
 102#define SMC_TX_TIMEOUT 30
 103
 104#define ETH_ZLEN 60
 105
 106#ifdef  CONFIG_LAN91C96_USE_32_BIT
 107#define USE_32_BIT  1
 108#else
 109#undef USE_32_BIT
 110#endif
 111
 112/* See if a MAC address is defined in the current environment. If so use it. If not
 113 . print a warning and set the environment and other globals with the default.
 114 . If an EEPROM is present it really should be consulted.
 115*/
 116static int smc_get_ethaddr(bd_t *bd, struct eth_device *dev);
 117static int get_rom_mac(struct eth_device *dev, unsigned char *v_rom_mac);
 118
 119/* ------------------------------------------------------------
 120 * Internal routines
 121 * ------------------------------------------------------------
 122 */
 123
 124static unsigned char smc_mac_addr[] = { 0xc0, 0x00, 0x00, 0x1b, 0x62, 0x9c };
 125
 126/*
 127 * This function must be called before smc_open() if you want to override
 128 * the default mac address.
 129 */
 130
 131static void smc_set_mac_addr(const unsigned char *addr)
 132{
 133        int i;
 134
 135        for (i = 0; i < sizeof (smc_mac_addr); i++) {
 136                smc_mac_addr[i] = addr[i];
 137        }
 138}
 139
 140/***********************************************
 141 * Show available memory                       *
 142 ***********************************************/
 143void dump_memory_info(struct eth_device *dev)
 144{
 145        __maybe_unused word mem_info;
 146        word old_bank;
 147
 148        old_bank = SMC_inw(dev, LAN91C96_BANK_SELECT) & 0xF;
 149
 150        SMC_SELECT_BANK(dev, 0);
 151        mem_info = SMC_inw(dev, LAN91C96_MIR);
 152        PRINTK2 ("Memory: %4d available\n", (mem_info >> 8) * 2048);
 153
 154        SMC_SELECT_BANK(dev, old_bank);
 155}
 156
 157/*
 158 * A rather simple routine to print out a packet for debugging purposes.
 159 */
 160#if SMC_DEBUG > 2
 161static void print_packet (byte *, int);
 162#endif
 163
 164static int poll4int (struct eth_device *dev, byte mask, int timeout)
 165{
 166        int tmo = get_timer (0) + timeout * CONFIG_SYS_HZ;
 167        int is_timeout = 0;
 168        word old_bank = SMC_inw(dev, LAN91C96_BANK_SELECT);
 169
 170        PRINTK2 ("Polling...\n");
 171        SMC_SELECT_BANK(dev, 2);
 172        while ((SMC_inw(dev, LAN91C96_INT_STATS) & mask) == 0) {
 173                if (get_timer (0) >= tmo) {
 174                        is_timeout = 1;
 175                        break;
 176                }
 177        }
 178
 179        /* restore old bank selection */
 180        SMC_SELECT_BANK(dev, old_bank);
 181
 182        if (is_timeout)
 183                return 1;
 184        else
 185                return 0;
 186}
 187
 188/*
 189 * Function: smc_reset
 190 * Purpose:
 191 *      This sets the SMC91111 chip to its normal state, hopefully from whatever
 192 *      mess that any other DOS driver has put it in.
 193 *
 194 * Maybe I should reset more registers to defaults in here?  SOFTRST  should
 195 * do that for me.
 196 *
 197 * Method:
 198 *      1.  send a SOFT RESET
 199 *      2.  wait for it to finish
 200 *      3.  enable autorelease mode
 201 *      4.  reset the memory management unit
 202 *      5.  clear all interrupts
 203 *
 204*/
 205static void smc_reset(struct eth_device *dev)
 206{
 207        PRINTK2("%s:smc_reset\n", dev->name);
 208
 209        /* This resets the registers mostly to defaults, but doesn't
 210           affect EEPROM.  That seems unnecessary */
 211        SMC_SELECT_BANK(dev, 0);
 212        SMC_outw(dev, LAN91C96_RCR_SOFT_RST, LAN91C96_RCR);
 213
 214        udelay (10);
 215
 216        /* Disable transmit and receive functionality */
 217        SMC_outw(dev, 0, LAN91C96_RCR);
 218        SMC_outw(dev, 0, LAN91C96_TCR);
 219
 220        /* set the control register */
 221        SMC_SELECT_BANK(dev, 1);
 222        SMC_outw(dev, SMC_inw(dev, LAN91C96_CONTROL) | LAN91C96_CTR_BIT_8,
 223                          LAN91C96_CONTROL);
 224
 225        /* Disable all interrupts */
 226        SMC_outb(dev, 0, LAN91C96_INT_MASK);
 227}
 228
 229/*
 230 * Function: smc_enable
 231 * Purpose: let the chip talk to the outside work
 232 * Method:
 233 *      1.  Initialize the Memory Configuration Register
 234 *      2.  Enable the transmitter
 235 *      3.  Enable the receiver
 236*/
 237static void smc_enable(struct eth_device *dev)
 238{
 239        PRINTK2("%s:smc_enable\n", dev->name);
 240        SMC_SELECT_BANK(dev, 0);
 241
 242        /* Initialize the Memory Configuration Register. See page
 243           49 of the LAN91C96 data sheet for details. */
 244        SMC_outw(dev, LAN91C96_MCR_TRANSMIT_PAGES, LAN91C96_MCR);
 245
 246        /* Initialize the Transmit Control Register */
 247        SMC_outw(dev, LAN91C96_TCR_TXENA, LAN91C96_TCR);
 248        /* Initialize the Receive Control Register
 249         * FIXME:
 250         * The promiscuous bit set because I could not receive ARP reply
 251         * packets from the server when I send a ARP request. It only works
 252         * when I set the promiscuous bit
 253         */
 254        SMC_outw(dev, LAN91C96_RCR_RXEN | LAN91C96_RCR_PRMS, LAN91C96_RCR);
 255}
 256
 257/*
 258 * Function: smc_shutdown
 259 * Purpose:  closes down the SMC91xxx chip.
 260 * Method:
 261 *      1. zero the interrupt mask
 262 *      2. clear the enable receive flag
 263 *      3. clear the enable xmit flags
 264 *
 265 * TODO:
 266 *   (1) maybe utilize power down mode.
 267 *      Why not yet?  Because while the chip will go into power down mode,
 268 *      the manual says that it will wake up in response to any I/O requests
 269 *      in the register space.   Empirical results do not show this working.
 270 */
 271static void smc_shutdown(struct eth_device *dev)
 272{
 273        PRINTK2("%s:smc_shutdown\n", dev->name);
 274
 275        /* no more interrupts for me */
 276        SMC_SELECT_BANK(dev, 2);
 277        SMC_outb(dev, 0, LAN91C96_INT_MASK);
 278
 279        /* and tell the card to stay away from that nasty outside world */
 280        SMC_SELECT_BANK(dev, 0);
 281        SMC_outb(dev, 0, LAN91C96_RCR);
 282        SMC_outb(dev, 0, LAN91C96_TCR);
 283}
 284
 285
 286/*
 287 * Function:  smc_hardware_send_packet(struct net_device * )
 288 * Purpose:
 289 *      This sends the actual packet to the SMC9xxx chip.
 290 *
 291 * Algorithm:
 292 *      First, see if a saved_skb is available.
 293 *              ( this should NOT be called if there is no 'saved_skb'
 294 *      Now, find the packet number that the chip allocated
 295 *      Point the data pointers at it in memory
 296 *      Set the length word in the chip's memory
 297 *      Dump the packet to chip memory
 298 *      Check if a last byte is needed ( odd length packet )
 299 *              if so, set the control flag right
 300 *      Tell the card to send it
 301 *      Enable the transmit interrupt, so I know if it failed
 302 *      Free the kernel data if I actually sent it.
 303 */
 304static int smc_send_packet(struct eth_device *dev, void *packet,
 305                int packet_length)
 306{
 307        byte packet_no;
 308        byte *buf;
 309        int length;
 310        int numPages;
 311        int try = 0;
 312        int time_out;
 313        byte status;
 314
 315
 316        PRINTK3("%s:smc_hardware_send_packet\n", dev->name);
 317
 318        length = ETH_ZLEN < packet_length ? packet_length : ETH_ZLEN;
 319
 320        /* allocate memory
 321         ** The MMU wants the number of pages to be the number of 256 bytes
 322         ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
 323         **
 324         ** The 91C111 ignores the size bits, but the code is left intact
 325         ** for backwards and future compatibility.
 326         **
 327         ** Pkt size for allocating is data length +6 (for additional status
 328         ** words, length and ctl!)
 329         **
 330         ** If odd size then last byte is included in this header.
 331         */
 332        numPages = ((length & 0xfffe) + 6);
 333        numPages >>= 8;                         /* Divide by 256 */
 334
 335        if (numPages > 7) {
 336                printf("%s: Far too big packet error. \n", dev->name);
 337                return 0;
 338        }
 339
 340        /* now, try to allocate the memory */
 341
 342        SMC_SELECT_BANK(dev, 2);
 343        SMC_outw(dev, LAN91C96_MMUCR_ALLOC_TX | numPages, LAN91C96_MMU);
 344
 345  again:
 346        try++;
 347        time_out = MEMORY_WAIT_TIME;
 348        do {
 349                status = SMC_inb(dev, LAN91C96_INT_STATS);
 350                if (status & LAN91C96_IST_ALLOC_INT) {
 351
 352                        SMC_outb(dev, LAN91C96_IST_ALLOC_INT,
 353                                        LAN91C96_INT_STATS);
 354                        break;
 355                }
 356        } while (--time_out);
 357
 358        if (!time_out) {
 359                PRINTK2 ("%s: memory allocation, try %d failed ...\n",
 360                                 dev->name, try);
 361                if (try < SMC_ALLOC_MAX_TRY)
 362                        goto again;
 363                else
 364                        return 0;
 365        }
 366
 367        PRINTK2 ("%s: memory allocation, try %d succeeded ...\n",
 368                         dev->name, try);
 369
 370        /* I can send the packet now.. */
 371        buf = (byte *) packet;
 372
 373        /* If I get here, I _know_ there is a packet slot waiting for me */
 374        packet_no = SMC_inb(dev, LAN91C96_ARR);
 375        if (packet_no & LAN91C96_ARR_FAILED) {
 376                /* or isn't there?  BAD CHIP! */
 377                printf("%s: Memory allocation failed. \n", dev->name);
 378                return 0;
 379        }
 380
 381        /* we have a packet address, so tell the card to use it */
 382        SMC_outb(dev, packet_no, LAN91C96_PNR);
 383
 384        /* point to the beginning of the packet */
 385        SMC_outw(dev, LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER);
 386
 387        PRINTK3("%s: Trying to xmit packet of length %x\n",
 388                         dev->name, length);
 389
 390#if SMC_DEBUG > 2
 391        printf ("Transmitting Packet\n");
 392        print_packet (buf, length);
 393#endif
 394
 395        /* send the packet length ( +6 for status, length and ctl byte )
 396           and the status word ( set to zeros ) */
 397#ifdef USE_32_BIT
 398        SMC_outl(dev, (length + 6) << 16, LAN91C96_DATA_HIGH);
 399#else
 400        SMC_outw(dev, 0, LAN91C96_DATA_HIGH);
 401        /* send the packet length ( +6 for status words, length, and ctl */
 402        SMC_outw(dev, (length + 6), LAN91C96_DATA_HIGH);
 403#endif /* USE_32_BIT */
 404
 405        /* send the actual data
 406         * I _think_ it's faster to send the longs first, and then
 407         * mop up by sending the last word.  It depends heavily
 408         * on alignment, at least on the 486.  Maybe it would be
 409         * a good idea to check which is optimal?  But that could take
 410         * almost as much time as is saved?
 411         */
 412#ifdef USE_32_BIT
 413        SMC_outsl(dev, LAN91C96_DATA_HIGH, buf, length >> 2);
 414        if (length & 0x2)
 415                SMC_outw(dev, *((word *) (buf + (length & 0xFFFFFFFC))),
 416                                  LAN91C96_DATA_HIGH);
 417#else
 418        SMC_outsw(dev, LAN91C96_DATA_HIGH, buf, (length) >> 1);
 419#endif /* USE_32_BIT */
 420
 421        /* Send the last byte, if there is one.   */
 422        if ((length & 1) == 0) {
 423                SMC_outw(dev, 0, LAN91C96_DATA_HIGH);
 424        } else {
 425                SMC_outw(dev, buf[length - 1] | 0x2000, LAN91C96_DATA_HIGH);
 426        }
 427
 428        /* and let the chipset deal with it */
 429        SMC_outw(dev, LAN91C96_MMUCR_ENQUEUE, LAN91C96_MMU);
 430
 431        /* poll for TX INT */
 432        if (poll4int (dev, LAN91C96_MSK_TX_INT, SMC_TX_TIMEOUT)) {
 433                /* sending failed */
 434                PRINTK2("%s: TX timeout, sending failed...\n", dev->name);
 435
 436                /* release packet */
 437                SMC_outw(dev, LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
 438
 439                /* wait for MMU getting ready (low) */
 440                while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
 441                        udelay (10);
 442
 443                PRINTK2("MMU ready\n");
 444
 445
 446                return 0;
 447        } else {
 448                /* ack. int */
 449                SMC_outw(dev, LAN91C96_IST_TX_INT, LAN91C96_INT_STATS);
 450
 451                PRINTK2("%s: Sent packet of length %d \n", dev->name, length);
 452
 453                /* release packet */
 454                SMC_outw(dev, LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
 455
 456                /* wait for MMU getting ready (low) */
 457                while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
 458                        udelay (10);
 459
 460                PRINTK2 ("MMU ready\n");
 461        }
 462
 463        return length;
 464}
 465
 466
 467/*
 468 * Open and Initialize the board
 469 *
 470 * Set up everything, reset the card, etc ..
 471 *
 472 */
 473static int smc_open(bd_t *bd, struct eth_device *dev)
 474{
 475        int i, err;                     /* used to set hw ethernet address */
 476
 477        PRINTK2("%s:smc_open\n", dev->name);
 478
 479        /* reset the hardware */
 480
 481        smc_reset(dev);
 482        smc_enable(dev);
 483
 484        SMC_SELECT_BANK(dev, 1);
 485        /* set smc_mac_addr, and sync it with u-boot globals */
 486        err = smc_get_ethaddr(bd, dev);
 487        if (err < 0)
 488                return -1;
 489#ifdef USE_32_BIT
 490        for (i = 0; i < 6; i += 2) {
 491                word address;
 492
 493                address = smc_mac_addr[i + 1] << 8;
 494                address |= smc_mac_addr[i];
 495                SMC_outw(dev, address, LAN91C96_IA0 + i);
 496        }
 497#else
 498        for (i = 0; i < 6; i++)
 499                SMC_outb(dev, smc_mac_addr[i], LAN91C96_IA0 + i);
 500#endif
 501        return 0;
 502}
 503
 504/*-------------------------------------------------------------
 505 *
 506 * smc_rcv -  receive a packet from the card
 507 *
 508 * There is ( at least ) a packet waiting to be read from
 509 * chip-memory.
 510 *
 511 * o Read the status
 512 * o If an error, record it
 513 * o otherwise, read in the packet
 514 *-------------------------------------------------------------
 515 */
 516static int smc_rcv(struct eth_device *dev)
 517{
 518        int packet_number;
 519        word status;
 520        word packet_length;
 521        int is_error = 0;
 522
 523#ifdef USE_32_BIT
 524        dword stat_len;
 525#endif
 526
 527
 528        SMC_SELECT_BANK(dev, 2);
 529        packet_number = SMC_inw(dev, LAN91C96_FIFO);
 530
 531        if (packet_number & LAN91C96_FIFO_RXEMPTY) {
 532                return 0;
 533        }
 534
 535        PRINTK3("%s:smc_rcv\n", dev->name);
 536        /*  start reading from the start of the packet */
 537        SMC_outw(dev, LAN91C96_PTR_READ | LAN91C96_PTR_RCV |
 538                          LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER);
 539
 540        /* First two words are status and packet_length */
 541#ifdef USE_32_BIT
 542        stat_len = SMC_inl(dev, LAN91C96_DATA_HIGH);
 543        status = stat_len & 0xffff;
 544        packet_length = stat_len >> 16;
 545#else
 546        status = SMC_inw(dev, LAN91C96_DATA_HIGH);
 547        packet_length = SMC_inw(dev, LAN91C96_DATA_HIGH);
 548#endif
 549
 550        packet_length &= 0x07ff;        /* mask off top bits */
 551
 552        PRINTK2 ("RCV: STATUS %4x LENGTH %4x\n", status, packet_length);
 553
 554        if (!(status & FRAME_FILTER)) {
 555                /* Adjust for having already read the first two words */
 556                packet_length -= 4;             /*4; */
 557
 558
 559                /* set odd length for bug in LAN91C111, */
 560                /* which never sets RS_ODDFRAME */
 561                /* TODO ? */
 562
 563
 564#ifdef USE_32_BIT
 565                PRINTK3 (" Reading %d dwords (and %d bytes) \n",
 566                         packet_length >> 2, packet_length & 3);
 567                /* QUESTION:  Like in the TX routine, do I want
 568                   to send the DWORDs or the bytes first, or some
 569                   mixture.  A mixture might improve already slow PIO
 570                   performance  */
 571                SMC_insl(dev, LAN91C96_DATA_HIGH, net_rx_packets[0],
 572                         packet_length >> 2);
 573                /* read the left over bytes */
 574                if (packet_length & 3) {
 575                        int i;
 576
 577                        byte *tail = (byte *)(net_rx_packets[0] +
 578                                (packet_length & ~3));
 579                        dword leftover = SMC_inl(dev, LAN91C96_DATA_HIGH);
 580
 581                        for (i = 0; i < (packet_length & 3); i++)
 582                                *tail++ = (byte) (leftover >> (8 * i)) & 0xff;
 583                }
 584#else
 585                PRINTK3(" Reading %d words and %d byte(s)\n",
 586                        (packet_length >> 1), packet_length & 1);
 587                SMC_insw(dev, LAN91C96_DATA_HIGH, net_rx_packets[0],
 588                         packet_length >> 1);
 589
 590#endif /* USE_32_BIT */
 591
 592#if     SMC_DEBUG > 2
 593                printf ("Receiving Packet\n");
 594                print_packet((byte *)net_rx_packets[0], packet_length);
 595#endif
 596        } else {
 597                /* error ... */
 598                /* TODO ? */
 599                is_error = 1;
 600        }
 601
 602        while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
 603                udelay (1);             /* Wait until not busy */
 604
 605        /*  error or good, tell the card to get rid of this packet */
 606        SMC_outw(dev, LAN91C96_MMUCR_RELEASE_RX, LAN91C96_MMU);
 607
 608        while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
 609                udelay (1);             /* Wait until not busy */
 610
 611        if (!is_error) {
 612                /* Pass the packet up to the protocol layers. */
 613                net_process_received_packet(net_rx_packets[0], packet_length);
 614                return packet_length;
 615        } else {
 616                return 0;
 617        }
 618
 619}
 620
 621/*----------------------------------------------------
 622 * smc_close
 623 *
 624 * this makes the board clean up everything that it can
 625 * and not talk to the outside world.   Caused by
 626 * an 'ifconfig ethX down'
 627 *
 628 -----------------------------------------------------*/
 629static int smc_close(struct eth_device *dev)
 630{
 631        PRINTK2("%s:smc_close\n", dev->name);
 632
 633        /* clear everything */
 634        smc_shutdown(dev);
 635
 636        return 0;
 637}
 638
 639#if SMC_DEBUG > 2
 640static void print_packet(byte *buf, int length)
 641{
 642#if 0
 643        int i;
 644        int remainder;
 645        int lines;
 646
 647        printf ("Packet of length %d \n", length);
 648
 649        lines = length / 16;
 650        remainder = length % 16;
 651
 652        for (i = 0; i < lines; i++) {
 653                int cur;
 654
 655                for (cur = 0; cur < 8; cur++) {
 656                        byte a, b;
 657
 658                        a = *(buf++);
 659                        b = *(buf++);
 660                        printf ("%02x%02x ", a, b);
 661                }
 662                printf ("\n");
 663        }
 664        for (i = 0; i < remainder / 2; i++) {
 665                byte a, b;
 666
 667                a = *(buf++);
 668                b = *(buf++);
 669                printf ("%02x%02x ", a, b);
 670        }
 671        printf ("\n");
 672#endif /* 0 */
 673}
 674#endif /* SMC_DEBUG > 2 */
 675
 676static int  lan91c96_init(struct eth_device *dev, bd_t *bd)
 677{
 678        return smc_open(bd, dev);
 679}
 680
 681static void lan91c96_halt(struct eth_device *dev)
 682{
 683        smc_close(dev);
 684}
 685
 686static int lan91c96_recv(struct eth_device *dev)
 687{
 688        return smc_rcv(dev);
 689}
 690
 691static int lan91c96_send(struct eth_device *dev, void *packet,
 692                int length)
 693{
 694        return smc_send_packet(dev, packet, length);
 695}
 696
 697/* smc_get_ethaddr
 698 *
 699 * This checks both the environment and the ROM for an ethernet address. If
 700 * found, the environment takes precedence.
 701 */
 702
 703static int smc_get_ethaddr(bd_t *bd, struct eth_device *dev)
 704{
 705        uchar v_mac[6];
 706
 707        if (!eth_getenv_enetaddr("ethaddr", v_mac)) {
 708                /* get ROM mac value if any */
 709                if (!get_rom_mac(dev, v_mac)) {
 710                        printf("\n*** ERROR: ethaddr is NOT set !!\n");
 711                        return -1;
 712                }
 713                eth_setenv_enetaddr("ethaddr", v_mac);
 714        }
 715
 716        smc_set_mac_addr(v_mac); /* use old function to update smc default */
 717        PRINTK("Using MAC Address %pM\n", v_mac);
 718        return 0;
 719}
 720
 721/*
 722 * get_rom_mac()
 723 * Note, this has omly been tested for the OMAP730 P2.
 724 */
 725
 726static int get_rom_mac(struct eth_device *dev, unsigned char *v_rom_mac)
 727{
 728        int i;
 729        SMC_SELECT_BANK(dev, 1);
 730        for (i=0; i<6; i++)
 731        {
 732                v_rom_mac[i] = SMC_inb(dev, LAN91C96_IA0 + i);
 733        }
 734        return (1);
 735}
 736
 737/* Structure to detect the device IDs */
 738struct id_type {
 739        u8 id;
 740        char *name;
 741};
 742static struct id_type supported_chips[] = {
 743        {0, ""}, /* Dummy entry to prevent id check failure */
 744        {9, "LAN91C110"},
 745        {8, "LAN91C100FD"},
 746        {7, "LAN91C100"},
 747        {5, "LAN91C95"},
 748        {4, "LAN91C94/96"},
 749        {3, "LAN91C90/92"},
 750};
 751/* lan91c96_detect_chip
 752 * See:
 753 * http://www.embeddedsys.com/subpages/resources/images/documents/LAN91C96_datasheet.pdf
 754 * page 71 - that is the closest we get to detect this device
 755 */
 756static int lan91c96_detect_chip(struct eth_device *dev)
 757{
 758        u8 chip_id;
 759        int r;
 760        SMC_SELECT_BANK(dev, 3);
 761        chip_id = (SMC_inw(dev, 0xA) & LAN91C96_REV_CHIPID) >> 4;
 762        SMC_SELECT_BANK(dev, 0);
 763        for (r = 0; r < ARRAY_SIZE(supported_chips); r++)
 764                if (chip_id == supported_chips[r].id)
 765                        return r;
 766        return 0;
 767}
 768
 769int lan91c96_initialize(u8 dev_num, int base_addr)
 770{
 771        struct eth_device *dev;
 772        int r = 0;
 773
 774        dev = malloc(sizeof(*dev));
 775        if (!dev) {
 776                return 0;
 777        }
 778        memset(dev, 0, sizeof(*dev));
 779
 780        dev->iobase = base_addr;
 781
 782        /* Try to detect chip. Will fail if not present. */
 783        r = lan91c96_detect_chip(dev);
 784        if (!r) {
 785                free(dev);
 786                return 0;
 787        }
 788        get_rom_mac(dev, dev->enetaddr);
 789
 790        dev->init = lan91c96_init;
 791        dev->halt = lan91c96_halt;
 792        dev->send = lan91c96_send;
 793        dev->recv = lan91c96_recv;
 794        sprintf(dev->name, "%s-%hu", supported_chips[r].name, dev_num);
 795
 796        eth_register(dev);
 797        return 0;
 798}
 799