uboot/drivers/net/natsemi.c
<<
>>
Prefs
   1/*
   2   natsemi.c: A U-Boot driver for the NatSemi DP8381x series.
   3   Author: Mark A. Rakes (mark_rakes@vivato.net)
   4
   5   Adapted from an Etherboot driver written by:
   6
   7   Copyright (C) 2001 Entity Cyber, Inc.
   8
   9   This development of this Etherboot driver was funded by
  10
  11      Sicom Systems: http://www.sicompos.com/
  12
  13   Author: Marty Connor (mdc@thinguin.org)
  14   Adapted from a Linux driver which was written by Donald Becker
  15
  16   This software may be used and distributed according to the terms
  17   of the GNU Public License (GPL), incorporated herein by reference.
  18
  19   Original Copyright Notice:
  20
  21   Written/copyright 1999-2001 by Donald Becker.
  22
  23   This software may be used and distributed according to the terms of
  24   the GNU General Public License (GPL), incorporated herein by reference.
  25   Drivers based on or derived from this code fall under the GPL and must
  26   retain the authorship, copyright and license notice.  This file is not
  27   a complete program and may only be used when the entire operating
  28   system is licensed under the GPL.  License for under other terms may be
  29   available.  Contact the original author for details.
  30
  31   The original author may be reached as becker@scyld.com, or at
  32   Scyld Computing Corporation
  33   410 Severn Ave., Suite 210
  34   Annapolis MD 21403
  35
  36   Support information and updates available at
  37   http://www.scyld.com/network/netsemi.html
  38
  39   References:
  40   http://www.scyld.com/expert/100mbps.html
  41   http://www.scyld.com/expert/NWay.html
  42   Datasheet is available from:
  43   http://www.national.com/pf/DP/DP83815.html
  44*/
  45
  46/* Revision History
  47 * October 2002 mar     1.0
  48 *   Initial U-Boot Release.  Tested with Netgear FA311 board
  49 *   and dp83815 chipset on custom board
  50*/
  51
  52/* Includes */
  53#include <common.h>
  54#include <malloc.h>
  55#include <net.h>
  56#include <netdev.h>
  57#include <asm/io.h>
  58#include <pci.h>
  59#include <linux/delay.h>
  60
  61/* defines */
  62#define EEPROM_SIZE 0xb /*12 16-bit chunks, or 24 bytes*/
  63
  64#define DSIZE           0x00000FFF
  65#define CRC_SIZE        4
  66#define TOUT_LOOP       500000
  67#define TX_BUF_SIZE     1536
  68#define RX_BUF_SIZE     1536
  69#define NUM_RX_DESC     4       /* Number of Rx descriptor registers. */
  70
  71/* Offsets to the device registers.
  72   Unlike software-only systems, device drivers interact with complex hardware.
  73   It's not useful to define symbolic names for every register bit in the
  74   device.  */
  75enum register_offsets {
  76        ChipCmd = 0x00,
  77        ChipConfig      = 0x04,
  78        EECtrl          = 0x08,
  79        IntrMask        = 0x14,
  80        IntrEnable      = 0x18,
  81        TxRingPtr       = 0x20,
  82        TxConfig        = 0x24,
  83        RxRingPtr       = 0x30,
  84        RxConfig        = 0x34,
  85        ClkRun          = 0x3C,
  86        RxFilterAddr    = 0x48,
  87        RxFilterData    = 0x4C,
  88        SiliconRev      = 0x58,
  89        PCIPM           = 0x44,
  90        BasicControl    = 0x80,
  91        BasicStatus     = 0x84,
  92        /* These are from the spec, around page 78... on a separate table. */
  93        PGSEL           = 0xCC,
  94        PMDCSR          = 0xE4,
  95        TSTDAT          = 0xFC,
  96        DSPCFG          = 0xF4,
  97        SDCFG           = 0x8C
  98};
  99
 100/* Bit in ChipCmd. */
 101enum ChipCmdBits {
 102        ChipReset       = 0x100,
 103        RxReset         = 0x20,
 104        TxReset         = 0x10,
 105        RxOff           = 0x08,
 106        RxOn            = 0x04,
 107        TxOff           = 0x02,
 108        TxOn            = 0x01
 109};
 110
 111enum ChipConfigBits {
 112        LinkSts = 0x80000000,
 113        HundSpeed       = 0x40000000,
 114        FullDuplex      = 0x20000000,
 115        TenPolarity     = 0x10000000,
 116        AnegDone        = 0x08000000,
 117        AnegEnBothBoth  = 0x0000E000,
 118        AnegDis100Full  = 0x0000C000,
 119        AnegEn100Both   = 0x0000A000,
 120        AnegDis100Half  = 0x00008000,
 121        AnegEnBothHalf  = 0x00006000,
 122        AnegDis10Full   = 0x00004000,
 123        AnegEn10Both    = 0x00002000,
 124        DuplexMask      = 0x00008000,
 125        SpeedMask       = 0x00004000,
 126        AnegMask        = 0x00002000,
 127        AnegDis10Half   = 0x00000000,
 128        ExtPhy          = 0x00001000,
 129        PhyRst          = 0x00000400,
 130        PhyDis          = 0x00000200,
 131        BootRomDisable  = 0x00000004,
 132        BEMode          = 0x00000001,
 133};
 134
 135enum TxConfig_bits {
 136        TxDrthMask      = 0x3f,
 137        TxFlthMask      = 0x3f00,
 138        TxMxdmaMask     = 0x700000,
 139        TxMxdma_512     = 0x0,
 140        TxMxdma_4       = 0x100000,
 141        TxMxdma_8       = 0x200000,
 142        TxMxdma_16      = 0x300000,
 143        TxMxdma_32      = 0x400000,
 144        TxMxdma_64      = 0x500000,
 145        TxMxdma_128     = 0x600000,
 146        TxMxdma_256     = 0x700000,
 147        TxCollRetry     = 0x800000,
 148        TxAutoPad       = 0x10000000,
 149        TxMacLoop       = 0x20000000,
 150        TxHeartIgn      = 0x40000000,
 151        TxCarrierIgn    = 0x80000000
 152};
 153
 154enum RxConfig_bits {
 155        RxDrthMask      = 0x3e,
 156        RxMxdmaMask     = 0x700000,
 157        RxMxdma_512     = 0x0,
 158        RxMxdma_4       = 0x100000,
 159        RxMxdma_8       = 0x200000,
 160        RxMxdma_16      = 0x300000,
 161        RxMxdma_32      = 0x400000,
 162        RxMxdma_64      = 0x500000,
 163        RxMxdma_128     = 0x600000,
 164        RxMxdma_256     = 0x700000,
 165        RxAcceptLong    = 0x8000000,
 166        RxAcceptTx      = 0x10000000,
 167        RxAcceptRunt    = 0x40000000,
 168        RxAcceptErr     = 0x80000000
 169};
 170
 171/* Bits in the RxMode register. */
 172enum rx_mode_bits {
 173        AcceptErr       = 0x20,
 174        AcceptRunt      = 0x10,
 175        AcceptBroadcast = 0xC0000000,
 176        AcceptMulticast = 0x00200000,
 177        AcceptAllMulticast = 0x20000000,
 178        AcceptAllPhys   = 0x10000000,
 179        AcceptMyPhys    = 0x08000000
 180};
 181
 182typedef struct _BufferDesc {
 183        u32 link;
 184        vu_long cmdsts;
 185        u32 bufptr;
 186        u32 software_use;
 187} BufferDesc;
 188
 189/* Bits in network_desc.status */
 190enum desc_status_bits {
 191        DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000,
 192        DescNoCRC = 0x10000000, DescPktOK = 0x08000000,
 193        DescSizeMask = 0xfff,
 194
 195        DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000,
 196        DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000,
 197        DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000,
 198        DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000,
 199
 200        DescRxAbort = 0x04000000, DescRxOver = 0x02000000,
 201        DescRxDest = 0x01800000, DescRxLong = 0x00400000,
 202        DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000,
 203        DescRxCRC = 0x00080000, DescRxAlign = 0x00040000,
 204        DescRxLoop = 0x00020000, DesRxColl = 0x00010000,
 205};
 206
 207/* Globals */
 208#ifdef NATSEMI_DEBUG
 209static int natsemi_debug = 0;   /* 1 verbose debugging, 0 normal */
 210#endif
 211static u32 SavedClkRun;
 212static unsigned int cur_rx;
 213static unsigned int advertising;
 214static unsigned int rx_config;
 215static unsigned int tx_config;
 216
 217/* Note: transmit and receive buffers and descriptors must be
 218   longword aligned */
 219static BufferDesc txd __attribute__ ((aligned(4)));
 220static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4)));
 221
 222static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4)));
 223static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]
 224    __attribute__ ((aligned(4)));
 225
 226/* Function Prototypes */
 227#if 0
 228static void write_eeprom(struct eth_device *dev, long addr, int location,
 229                         short value);
 230#endif
 231static int read_eeprom(struct eth_device *dev, long addr, int location);
 232static int mdio_read(struct eth_device *dev, int phy_id, int location);
 233static int natsemi_init(struct eth_device *dev, struct bd_info * bis);
 234static void natsemi_reset(struct eth_device *dev);
 235static void natsemi_init_rxfilter(struct eth_device *dev);
 236static void natsemi_init_txd(struct eth_device *dev);
 237static void natsemi_init_rxd(struct eth_device *dev);
 238static void natsemi_set_rx_mode(struct eth_device *dev);
 239static void natsemi_check_duplex(struct eth_device *dev);
 240static int natsemi_send(struct eth_device *dev, void *packet, int length);
 241static int natsemi_poll(struct eth_device *dev);
 242static void natsemi_disable(struct eth_device *dev);
 243
 244static struct pci_device_id supported[] = {
 245        {PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815},
 246        {}
 247};
 248
 249#define bus_to_phys(a)  pci_mem_to_phys((pci_dev_t)dev->priv, a)
 250#define phys_to_bus(a)  pci_phys_to_mem((pci_dev_t)dev->priv, a)
 251
 252static inline int
 253INW(struct eth_device *dev, u_long addr)
 254{
 255        return le16_to_cpu(*(vu_short *) (addr + dev->iobase));
 256}
 257
 258static int
 259INL(struct eth_device *dev, u_long addr)
 260{
 261        return le32_to_cpu(*(vu_long *) (addr + dev->iobase));
 262}
 263
 264static inline void
 265OUTW(struct eth_device *dev, int command, u_long addr)
 266{
 267        *(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command);
 268}
 269
 270static inline void
 271OUTL(struct eth_device *dev, int command, u_long addr)
 272{
 273        *(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command);
 274}
 275
 276/*
 277 * Function: natsemi_initialize
 278 *
 279 * Description: Retrieves the MAC address of the card, and sets up some
 280 * globals required by other routines,  and initializes the NIC, making it
 281 * ready to send and receive packets.
 282 *
 283 * Side effects:
 284 *            leaves the natsemi initialized, and ready to receive packets.
 285 *
 286 * Returns:   struct eth_device *:          pointer to NIC data structure
 287 */
 288
 289int
 290natsemi_initialize(struct bd_info * bis)
 291{
 292        pci_dev_t devno;
 293        int card_number = 0;
 294        struct eth_device *dev;
 295        u32 iobase, status, chip_config;
 296        int i, idx = 0;
 297        int prev_eedata;
 298        u32 tmp;
 299
 300        while (1) {
 301                /* Find PCI device(s) */
 302                if ((devno = pci_find_devices(supported, idx++)) < 0) {
 303                        break;
 304                }
 305
 306                pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase);
 307                iobase &= ~0x3; /* bit 1: unused and bit 0: I/O Space Indicator */
 308
 309                pci_write_config_dword(devno, PCI_COMMAND,
 310                                       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
 311
 312                /* Check if I/O accesses and Bus Mastering are enabled. */
 313                pci_read_config_dword(devno, PCI_COMMAND, &status);
 314                if (!(status & PCI_COMMAND_MEMORY)) {
 315                        printf("Error: Can not enable MEM access.\n");
 316                        continue;
 317                } else if (!(status & PCI_COMMAND_MASTER)) {
 318                        printf("Error: Can not enable Bus Mastering.\n");
 319                        continue;
 320                }
 321
 322                dev = (struct eth_device *) malloc(sizeof *dev);
 323                if (!dev) {
 324                        printf("natsemi: Can not allocate memory\n");
 325                        break;
 326                }
 327                memset(dev, 0, sizeof(*dev));
 328
 329                sprintf(dev->name, "dp83815#%d", card_number);
 330                dev->iobase = bus_to_phys(iobase);
 331#ifdef NATSEMI_DEBUG
 332                printf("natsemi: NatSemi ns8381[56] @ %#x\n", dev->iobase);
 333#endif
 334                dev->priv = (void *) devno;
 335                dev->init = natsemi_init;
 336                dev->halt = natsemi_disable;
 337                dev->send = natsemi_send;
 338                dev->recv = natsemi_poll;
 339
 340                eth_register(dev);
 341
 342                card_number++;
 343
 344                /* Set the latency timer for value. */
 345                pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20);
 346
 347                udelay(10 * 1000);
 348
 349                /* natsemi has a non-standard PM control register
 350                 * in PCI config space.  Some boards apparently need
 351                 * to be brought to D0 in this manner.  */
 352                pci_read_config_dword(devno, PCIPM, &tmp);
 353                if (tmp & (0x03 | 0x100)) {
 354                        /* D0 state, disable PME assertion */
 355                        u32 newtmp = tmp & ~(0x03 | 0x100);
 356                        pci_write_config_dword(devno, PCIPM, newtmp);
 357                }
 358
 359                printf("natsemi: EEPROM contents:\n");
 360                for (i = 0; i <= EEPROM_SIZE; i++) {
 361                        short eedata = read_eeprom(dev, EECtrl, i);
 362                        printf(" %04hx", eedata);
 363                }
 364                printf("\n");
 365
 366                /* get MAC address */
 367                prev_eedata = read_eeprom(dev, EECtrl, 6);
 368                for (i = 0; i < 3; i++) {
 369                        int eedata = read_eeprom(dev, EECtrl, i + 7);
 370                        dev->enetaddr[i*2] = (eedata << 1) + (prev_eedata >> 15);
 371                        dev->enetaddr[i*2+1] = eedata >> 7;
 372                        prev_eedata = eedata;
 373                }
 374
 375                /* Reset the chip to erase any previous misconfiguration. */
 376                OUTL(dev, ChipReset, ChipCmd);
 377
 378                advertising = mdio_read(dev, 1, 4);
 379                chip_config = INL(dev, ChipConfig);
 380#ifdef NATSEMI_DEBUG
 381                printf("%s: Transceiver status %#08X advertising %#08X\n",
 382                        dev->name, (int) INL(dev, BasicStatus), advertising);
 383                printf("%s: Transceiver default autoneg. %s 10%s %s duplex.\n",
 384                        dev->name, chip_config & AnegMask ? "enabled, advertise" :
 385                        "disabled, force", chip_config & SpeedMask ? "0" : "",
 386                        chip_config & DuplexMask ? "full" : "half");
 387#endif
 388                chip_config |= AnegEnBothBoth;
 389#ifdef NATSEMI_DEBUG
 390                printf("%s: changed to autoneg. %s 10%s %s duplex.\n",
 391                        dev->name, chip_config & AnegMask ? "enabled, advertise" :
 392                        "disabled, force", chip_config & SpeedMask ? "0" : "",
 393                        chip_config & DuplexMask ? "full" : "half");
 394#endif
 395                /*write new autoneg bits, reset phy*/
 396                OUTL(dev, (chip_config | PhyRst), ChipConfig);
 397                /*un-reset phy*/
 398                OUTL(dev, chip_config, ChipConfig);
 399
 400                /* Disable PME:
 401                 * The PME bit is initialized from the EEPROM contents.
 402                 * PCI cards probably have PME disabled, but motherboard
 403                 * implementations may have PME set to enable WakeOnLan.
 404                 * With PME set the chip will scan incoming packets but
 405                 * nothing will be written to memory. */
 406                SavedClkRun = INL(dev, ClkRun);
 407                OUTL(dev, SavedClkRun & ~0x100, ClkRun);
 408        }
 409        return card_number;
 410}
 411
 412/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
 413   The EEPROM code is for common 93c06/46 EEPROMs w/ 6bit addresses.  */
 414
 415/* Delay between EEPROM clock transitions.
 416   No extra delay is needed with 33MHz PCI, but future 66MHz
 417   access may need a delay. */
 418#define eeprom_delay(ee_addr)   INL(dev, ee_addr)
 419
 420enum EEPROM_Ctrl_Bits {
 421        EE_ShiftClk = 0x04,
 422        EE_DataIn = 0x01,
 423        EE_ChipSelect = 0x08,
 424        EE_DataOut = 0x02
 425};
 426
 427#define EE_Write0 (EE_ChipSelect)
 428#define EE_Write1 (EE_ChipSelect | EE_DataIn)
 429/* The EEPROM commands include the alway-set leading bit. */
 430enum EEPROM_Cmds {
 431        EE_WrEnCmd = (4 << 6), EE_WriteCmd = (5 << 6),
 432        EE_ReadCmd = (6 << 6), EE_EraseCmd = (7 << 6),
 433};
 434
 435#if 0
 436static void
 437write_eeprom(struct eth_device *dev, long addr, int location, short value)
 438{
 439        int i;
 440        int ee_addr = (typeof(ee_addr))addr;
 441        short wren_cmd = EE_WrEnCmd | 0x30; /*wren is 100 + 11XXXX*/
 442        short write_cmd = location | EE_WriteCmd;
 443
 444#ifdef NATSEMI_DEBUG
 445        printf("write_eeprom: %08x, %04hx, %04hx\n",
 446                dev->iobase + ee_addr, write_cmd, value);
 447#endif
 448        /* Shift the write enable command bits out. */
 449        for (i = 9; i >= 0; i--) {
 450                short cmdval = (wren_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
 451                OUTL(dev, cmdval, ee_addr);
 452                eeprom_delay(ee_addr);
 453                OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
 454                eeprom_delay(ee_addr);
 455        }
 456
 457        OUTL(dev, 0, ee_addr); /*bring chip select low*/
 458        OUTL(dev, EE_ShiftClk, ee_addr);
 459        eeprom_delay(ee_addr);
 460
 461        /* Shift the write command bits out. */
 462        for (i = 9; i >= 0; i--) {
 463                short cmdval = (write_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
 464                OUTL(dev, cmdval, ee_addr);
 465                eeprom_delay(ee_addr);
 466                OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
 467                eeprom_delay(ee_addr);
 468        }
 469
 470        for (i = 0; i < 16; i++) {
 471                short cmdval = (value & (1 << i)) ? EE_Write1 : EE_Write0;
 472                OUTL(dev, cmdval, ee_addr);
 473                eeprom_delay(ee_addr);
 474                OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
 475                eeprom_delay(ee_addr);
 476        }
 477
 478        OUTL(dev, 0, ee_addr); /*bring chip select low*/
 479        OUTL(dev, EE_ShiftClk, ee_addr);
 480        for (i = 0; i < 200000; i++) {
 481                OUTL(dev, EE_Write0, ee_addr); /*poll for done*/
 482                if (INL(dev, ee_addr) & EE_DataOut) {
 483                    break; /*finished*/
 484                }
 485        }
 486        eeprom_delay(ee_addr);
 487
 488        /* Terminate the EEPROM access. */
 489        OUTL(dev, EE_Write0, ee_addr);
 490        OUTL(dev, 0, ee_addr);
 491        return;
 492}
 493#endif
 494
 495static int
 496read_eeprom(struct eth_device *dev, long addr, int location)
 497{
 498        int i;
 499        int retval = 0;
 500        int ee_addr = (typeof(ee_addr))addr;
 501        int read_cmd = location | EE_ReadCmd;
 502
 503        OUTL(dev, EE_Write0, ee_addr);
 504
 505        /* Shift the read command bits out. */
 506        for (i = 10; i >= 0; i--) {
 507                short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
 508                OUTL(dev, dataval, ee_addr);
 509                eeprom_delay(ee_addr);
 510                OUTL(dev, dataval | EE_ShiftClk, ee_addr);
 511                eeprom_delay(ee_addr);
 512        }
 513        OUTL(dev, EE_ChipSelect, ee_addr);
 514        eeprom_delay(ee_addr);
 515
 516        for (i = 0; i < 16; i++) {
 517                OUTL(dev, EE_ChipSelect | EE_ShiftClk, ee_addr);
 518                eeprom_delay(ee_addr);
 519                retval |= (INL(dev, ee_addr) & EE_DataOut) ? 1 << i : 0;
 520                OUTL(dev, EE_ChipSelect, ee_addr);
 521                eeprom_delay(ee_addr);
 522        }
 523
 524        /* Terminate the EEPROM access. */
 525        OUTL(dev, EE_Write0, ee_addr);
 526        OUTL(dev, 0, ee_addr);
 527#ifdef NATSEMI_DEBUG
 528        if (natsemi_debug)
 529                printf("read_eeprom: %08x, %08x, retval %08x\n",
 530                        dev->iobase + ee_addr, read_cmd, retval);
 531#endif
 532        return retval;
 533}
 534
 535/*  MII transceiver control section.
 536        The 83815 series has an internal transceiver, and we present the
 537        management registers as if they were MII connected. */
 538
 539static int
 540mdio_read(struct eth_device *dev, int phy_id, int location)
 541{
 542        if (phy_id == 1 && location < 32)
 543                return INL(dev, BasicControl+(location<<2))&0xffff;
 544        else
 545                return 0xffff;
 546}
 547
 548/* Function: natsemi_init
 549 *
 550 * Description: resets the ethernet controller chip and configures
 551 *    registers and data structures required for sending and receiving packets.
 552 *
 553 * Arguments: struct eth_device *dev:          NIC data structure
 554 *
 555 * returns:     int.
 556 */
 557
 558static int
 559natsemi_init(struct eth_device *dev, struct bd_info * bis)
 560{
 561
 562        natsemi_reset(dev);
 563
 564        /* Disable PME:
 565         * The PME bit is initialized from the EEPROM contents.
 566         * PCI cards probably have PME disabled, but motherboard
 567         * implementations may have PME set to enable WakeOnLan.
 568         * With PME set the chip will scan incoming packets but
 569         * nothing will be written to memory. */
 570        OUTL(dev, SavedClkRun & ~0x100, ClkRun);
 571
 572        natsemi_init_rxfilter(dev);
 573        natsemi_init_txd(dev);
 574        natsemi_init_rxd(dev);
 575
 576        /* Configure the PCI bus bursts and FIFO thresholds. */
 577        tx_config = TxAutoPad | TxCollRetry | TxMxdma_256 | (0x1002);
 578        rx_config = RxMxdma_256 | 0x20;
 579
 580#ifdef NATSEMI_DEBUG
 581        printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config);
 582        printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config);
 583#endif
 584        OUTL(dev, tx_config, TxConfig);
 585        OUTL(dev, rx_config, RxConfig);
 586
 587        natsemi_check_duplex(dev);
 588        natsemi_set_rx_mode(dev);
 589
 590        OUTL(dev, (RxOn | TxOn), ChipCmd);
 591        return 1;
 592}
 593
 594/*
 595 * Function: natsemi_reset
 596 *
 597 * Description: soft resets the controller chip
 598 *
 599 * Arguments: struct eth_device *dev:          NIC data structure
 600 *
 601 * Returns:   void.
 602 */
 603static void
 604natsemi_reset(struct eth_device *dev)
 605{
 606        OUTL(dev, ChipReset, ChipCmd);
 607
 608        /* On page 78 of the spec, they recommend some settings for "optimum
 609           performance" to be done in sequence.  These settings optimize some
 610           of the 100Mbit autodetection circuitry.  Also, we only want to do
 611           this for rev C of the chip.  */
 612        if (INL(dev, SiliconRev) == 0x302) {
 613                OUTW(dev, 0x0001, PGSEL);
 614                OUTW(dev, 0x189C, PMDCSR);
 615                OUTW(dev, 0x0000, TSTDAT);
 616                OUTW(dev, 0x5040, DSPCFG);
 617                OUTW(dev, 0x008C, SDCFG);
 618        }
 619        /* Disable interrupts using the mask. */
 620        OUTL(dev, 0, IntrMask);
 621        OUTL(dev, 0, IntrEnable);
 622}
 623
 624/* Function: natsemi_init_rxfilter
 625 *
 626 * Description: sets receive filter address to our MAC address
 627 *
 628 * Arguments: struct eth_device *dev:          NIC data structure
 629 *
 630 * returns:   void.
 631 */
 632
 633static void
 634natsemi_init_rxfilter(struct eth_device *dev)
 635{
 636        int i;
 637
 638        for (i = 0; i < ETH_ALEN; i += 2) {
 639                OUTL(dev, i, RxFilterAddr);
 640                OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8),
 641                     RxFilterData);
 642        }
 643}
 644
 645/*
 646 * Function: natsemi_init_txd
 647 *
 648 * Description: initializes the Tx descriptor
 649 *
 650 * Arguments: struct eth_device *dev:          NIC data structure
 651 *
 652 * returns:   void.
 653 */
 654
 655static void
 656natsemi_init_txd(struct eth_device *dev)
 657{
 658        txd.link = (u32) 0;
 659        txd.cmdsts = (u32) 0;
 660        txd.bufptr = (u32) & txb[0];
 661
 662        /* load Transmit Descriptor Register */
 663        OUTL(dev, (u32) & txd, TxRingPtr);
 664#ifdef NATSEMI_DEBUG
 665        printf("natsemi_init_txd: TX descriptor reg loaded with: %#08X\n",
 666               INL(dev, TxRingPtr));
 667#endif
 668}
 669
 670/* Function: natsemi_init_rxd
 671 *
 672 * Description: initializes the Rx descriptor ring
 673 *
 674 * Arguments: struct eth_device *dev:          NIC data structure
 675 *
 676 * Returns:   void.
 677 */
 678
 679static void
 680natsemi_init_rxd(struct eth_device *dev)
 681{
 682        int i;
 683
 684        cur_rx = 0;
 685
 686        /* init RX descriptor */
 687        for (i = 0; i < NUM_RX_DESC; i++) {
 688                rxd[i].link =
 689                    cpu_to_le32((i + 1 <
 690                                 NUM_RX_DESC) ? (u32) & rxd[i +
 691                                                            1] : (u32) &
 692                                rxd[0]);
 693                rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);
 694                rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);
 695#ifdef NATSEMI_DEBUG
 696                printf
 697                    ("natsemi_init_rxd: rxd[%d]=%p link=%X cmdsts=%lX bufptr=%X\n",
 698                        i, &rxd[i], le32_to_cpu(rxd[i].link),
 699                                rxd[i].cmdsts, rxd[i].bufptr);
 700#endif
 701        }
 702
 703        /* load Receive Descriptor Register */
 704        OUTL(dev, (u32) & rxd[0], RxRingPtr);
 705
 706#ifdef NATSEMI_DEBUG
 707        printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n",
 708               INL(dev, RxRingPtr));
 709#endif
 710}
 711
 712/* Function: natsemi_set_rx_mode
 713 *
 714 * Description:
 715 *    sets the receive mode to accept all broadcast packets and packets
 716 *    with our MAC address, and reject all multicast packets.
 717 *
 718 * Arguments: struct eth_device *dev:          NIC data structure
 719 *
 720 * Returns:   void.
 721 */
 722
 723static void
 724natsemi_set_rx_mode(struct eth_device *dev)
 725{
 726        u32 rx_mode = AcceptBroadcast | AcceptMyPhys;
 727
 728        OUTL(dev, rx_mode, RxFilterAddr);
 729}
 730
 731static void
 732natsemi_check_duplex(struct eth_device *dev)
 733{
 734        int duplex = INL(dev, ChipConfig) & FullDuplex ? 1 : 0;
 735
 736#ifdef NATSEMI_DEBUG
 737        printf("%s: Setting %s-duplex based on negotiated link"
 738               " capability.\n", dev->name, duplex ? "full" : "half");
 739#endif
 740        if (duplex) {
 741                rx_config |= RxAcceptTx;
 742                tx_config |= (TxCarrierIgn | TxHeartIgn);
 743        } else {
 744                rx_config &= ~RxAcceptTx;
 745                tx_config &= ~(TxCarrierIgn | TxHeartIgn);
 746        }
 747        OUTL(dev, tx_config, TxConfig);
 748        OUTL(dev, rx_config, RxConfig);
 749}
 750
 751/* Function: natsemi_send
 752 *
 753 * Description: transmits a packet and waits for completion or timeout.
 754 *
 755 * Returns:   void.  */
 756static int natsemi_send(struct eth_device *dev, void *packet, int length)
 757{
 758        u32 i, status = 0;
 759        u32 tx_status = 0;
 760        u32 *tx_ptr = &tx_status;
 761        vu_long *res = (vu_long *)tx_ptr;
 762
 763        /* Stop the transmitter */
 764        OUTL(dev, TxOff, ChipCmd);
 765
 766#ifdef NATSEMI_DEBUG
 767        if (natsemi_debug)
 768                printf("natsemi_send: sending %d bytes\n", (int) length);
 769#endif
 770
 771        /* set the transmit buffer descriptor and enable Transmit State Machine */
 772        txd.link = cpu_to_le32(0);
 773        txd.bufptr = cpu_to_le32(phys_to_bus((u32) packet));
 774        txd.cmdsts = cpu_to_le32(DescOwn | length);
 775
 776        /* load Transmit Descriptor Register */
 777        OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);
 778#ifdef NATSEMI_DEBUG
 779        if (natsemi_debug)
 780            printf("natsemi_send: TX descriptor register loaded with: %#08X\n",
 781             INL(dev, TxRingPtr));
 782#endif
 783        /* restart the transmitter */
 784        OUTL(dev, TxOn, ChipCmd);
 785
 786        for (i = 0;
 787             (*res = le32_to_cpu(txd.cmdsts)) & DescOwn;
 788             i++) {
 789                if (i >= TOUT_LOOP) {
 790                        printf
 791                            ("%s: tx error buffer not ready: txd.cmdsts == %#X\n",
 792                             dev->name, tx_status);
 793                        goto Done;
 794                }
 795        }
 796
 797        if (!(tx_status & DescPktOK)) {
 798                printf("natsemi_send: Transmit error, Tx status %X.\n",
 799                       tx_status);
 800                goto Done;
 801        }
 802
 803        status = 1;
 804      Done:
 805        return status;
 806}
 807
 808/* Function: natsemi_poll
 809 *
 810 * Description: checks for a received packet and returns it if found.
 811 *
 812 * Arguments: struct eth_device *dev:          NIC data structure
 813 *
 814 * Returns:   1 if    packet was received.
 815 *            0 if no packet was received.
 816 *
 817 * Side effects:
 818 *            Returns (copies) the packet to the array dev->packet.
 819 *            Returns the length of the packet.
 820 */
 821
 822static int
 823natsemi_poll(struct eth_device *dev)
 824{
 825        int retstat = 0;
 826        int length = 0;
 827        u32 rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);
 828
 829        if (!(rx_status & (u32) DescOwn))
 830                return retstat;
 831#ifdef NATSEMI_DEBUG
 832        if (natsemi_debug)
 833                printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",
 834                       cur_rx, rx_status);
 835#endif
 836        length = (rx_status & DSIZE) - CRC_SIZE;
 837
 838        if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {
 839                printf
 840                    ("natsemi_poll: Corrupted packet received, buffer status = %X\n",
 841                     rx_status);
 842                retstat = 0;
 843        } else {                /* give packet to higher level routine */
 844                net_process_received_packet((rxb + cur_rx * RX_BUF_SIZE),
 845                                            length);
 846                retstat = 1;
 847        }
 848
 849        /* return the descriptor and buffer to receive ring */
 850        rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE);
 851        rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]);
 852
 853        if (++cur_rx == NUM_RX_DESC)
 854                cur_rx = 0;
 855
 856        /* re-enable the potentially idle receive state machine */
 857        OUTL(dev, RxOn, ChipCmd);
 858
 859        return retstat;
 860}
 861
 862/* Function: natsemi_disable
 863 *
 864 * Description: Turns off interrupts and stops Tx and Rx engines
 865 *
 866 * Arguments: struct eth_device *dev:          NIC data structure
 867 *
 868 * Returns:   void.
 869 */
 870
 871static void
 872natsemi_disable(struct eth_device *dev)
 873{
 874        /* Disable interrupts using the mask. */
 875        OUTL(dev, 0, IntrMask);
 876        OUTL(dev, 0, IntrEnable);
 877
 878        /* Stop the chip's Tx and Rx processes. */
 879        OUTL(dev, RxOff | TxOff, ChipCmd);
 880
 881        /* Restore PME enable bit */
 882        OUTL(dev, SavedClkRun, ClkRun);
 883}
 884