Annotation of qemu/roms/ipxe/src/drivers/net/sundance.c, revision 1.1.1.1

1.1       root        1: /**************************************************************************
                      2: *
                      3: *    sundance.c -- Etherboot device driver for the Sundance ST201 "Alta".
                      4: *    Written 2002-2002 by Timothy Legge <[email protected]>
                      5: *
                      6: *    This program is free software; you can redistribute it and/or modify
                      7: *    it under the terms of the GNU General Public License as published by
                      8: *    the Free Software Foundation; either version 2 of the License, or
                      9: *    (at your option) any later version.
                     10: *
                     11: *    This program is distributed in the hope that it will be useful,
                     12: *    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: *    GNU General Public License for more details.
                     15: *
                     16: *    You should have received a copy of the GNU General Public License
                     17: *    along with this program; if not, write to the Free Software
                     18: *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     19: *
                     20: *    Portions of this code based on:
                     21: *               sundance.c: A Linux device driver for the Sundance ST201 "Alta"
                     22: *               Written 1999-2002 by Donald Becker
                     23: *
                     24: *               tulip.c: Tulip and Clone Etherboot Driver
                     25: *               By Marty Conner
                     26: *               Copyright (C) 2001 Entity Cyber, Inc.
                     27: *
                     28: *    Linux Driver Version LK1.09a, 10-Jul-2003 (2.4.25)
                     29: *
                     30: *    REVISION HISTORY:
                     31: *    ================
                     32: *    v1.1      01-01-2003      timlegge        Initial implementation
                     33: *    v1.7      04-10-2003      timlegge        Transfers Linux Kernel (30 sec)
                     34: *    v1.8      04-13-2003      timlegge        Fix multiple transmission bug
                     35: *    v1.9      08-19-2003      timlegge        Support Multicast
                     36: *    v1.10     01-17-2004      timlegge        Initial driver output cleanup
                     37: *    v1.11     03-21-2004      timlegge        Remove unused variables
                     38: *    v1.12     03-21-2004      timlegge        Remove excess MII defines
                     39: *    v1.13     03-24-2004      timlegge        Update to Linux 2.4.25 driver
                     40: *
                     41: ****************************************************************************/
                     42: 
                     43: FILE_LICENCE ( GPL2_OR_LATER );
                     44: 
                     45: /* to get some global routines like printf */
                     46: #include "etherboot.h"
                     47: /* to get the interface to the body of the program */
                     48: #include "nic.h"
                     49: /* to get the PCI support functions, if this is a PCI NIC */
                     50: #include <ipxe/pci.h>
                     51: #include "mii.h"
                     52: 
                     53: #define drv_version "v1.12"
                     54: #define drv_date "2004-03-21"
                     55: 
                     56: #define HZ 100
                     57: 
                     58: /* Condensed operations for readability. */
                     59: #define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
                     60: #define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))
                     61: 
                     62: /* Set the mtu */
                     63: static int mtu = 1514;
                     64: 
                     65: /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
                     66:    The sundance uses a 64 element hash table based on the Ethernet CRC.  */
                     67: // static int multicast_filter_limit = 32;
                     68: 
                     69: /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
                     70:    Setting to > 1518 effectively disables this feature.
                     71:    This chip can receive into any byte alignment buffers, so word-oriented
                     72:    archs do not need a copy-align of the IP header. */
                     73: static int rx_copybreak = 0;
                     74: static int flowctrl = 1;
                     75: 
                     76: /* Allow forcing the media type */
                     77: /* media[] specifies the media type the NIC operates at.
                     78:                 autosense      Autosensing active media.
                     79:                 10mbps_hd      10Mbps half duplex.
                     80:                 10mbps_fd      10Mbps full duplex.
                     81:                 100mbps_hd     100Mbps half duplex.
                     82:                 100mbps_fd     100Mbps full duplex.
                     83: */
                     84: static char media[] = "autosense";
                     85: 
                     86: /* Operational parameters that are set at compile time. */
                     87: 
                     88: /* As Etherboot uses a Polling driver  we can keep the number of rings
                     89: to the minimum number required.  In general that is 1 transmit and 4 receive receive rings.  However some cards require that
                     90: there be a minimum of 2 rings  */
                     91: #define TX_RING_SIZE   2
                     92: #define TX_QUEUE_LEN   10      /* Limit ring entries actually used.  */
                     93: #define RX_RING_SIZE   4
                     94: 
                     95: 
                     96: /* Operational parameters that usually are not changed. */
                     97: /* Time in jiffies before concluding the transmitter is hung. */
                     98: #define TX_TIME_OUT      (4*HZ)
                     99: #define PKT_BUF_SZ     1536
                    100: 
                    101: /* Offsets to the device registers.
                    102:    Unlike software-only systems, device drivers interact with complex hardware.
                    103:    It's not useful to define symbolic names for every register bit in the
                    104:    device.  The name can only partially document the semantics and make
                    105:    the driver longer and more difficult to read.
                    106:    In general, only the important configuration values or bits changed
                    107:    multiple times should be defined symbolically.
                    108: */
                    109: enum alta_offsets {
                    110:        DMACtrl = 0x00,
                    111:        TxListPtr = 0x04,
                    112:        TxDMABurstThresh = 0x08,
                    113:        TxDMAUrgentThresh = 0x09,
                    114:        TxDMAPollPeriod = 0x0a,
                    115:        RxDMAStatus = 0x0c,
                    116:        RxListPtr = 0x10,
                    117:        DebugCtrl0 = 0x1a,
                    118:        DebugCtrl1 = 0x1c,
                    119:        RxDMABurstThresh = 0x14,
                    120:        RxDMAUrgentThresh = 0x15,
                    121:        RxDMAPollPeriod = 0x16,
                    122:        LEDCtrl = 0x1a,
                    123:        ASICCtrl = 0x30,
                    124:        EEData = 0x34,
                    125:        EECtrl = 0x36,
                    126:        TxStartThresh = 0x3c,
                    127:        RxEarlyThresh = 0x3e,
                    128:        FlashAddr = 0x40,
                    129:        FlashData = 0x44,
                    130:        TxStatus = 0x46,
                    131:        TxFrameId = 0x47,
                    132:        DownCounter = 0x18,
                    133:        IntrClear = 0x4a,
                    134:        IntrEnable = 0x4c,
                    135:        IntrStatus = 0x4e,
                    136:        MACCtrl0 = 0x50,
                    137:        MACCtrl1 = 0x52,
                    138:        StationAddr = 0x54,
                    139:        MaxFrameSize = 0x5A,
                    140:        RxMode = 0x5c,
                    141:        MIICtrl = 0x5e,
                    142:        MulticastFilter0 = 0x60,
                    143:        MulticastFilter1 = 0x64,
                    144:        RxOctetsLow = 0x68,
                    145:        RxOctetsHigh = 0x6a,
                    146:        TxOctetsLow = 0x6c,
                    147:        TxOctetsHigh = 0x6e,
                    148:        TxFramesOK = 0x70,
                    149:        RxFramesOK = 0x72,
                    150:        StatsCarrierError = 0x74,
                    151:        StatsLateColl = 0x75,
                    152:        StatsMultiColl = 0x76,
                    153:        StatsOneColl = 0x77,
                    154:        StatsTxDefer = 0x78,
                    155:        RxMissed = 0x79,
                    156:        StatsTxXSDefer = 0x7a,
                    157:        StatsTxAbort = 0x7b,
                    158:        StatsBcastTx = 0x7c,
                    159:        StatsBcastRx = 0x7d,
                    160:        StatsMcastTx = 0x7e,
                    161:        StatsMcastRx = 0x7f,
                    162:        /* Aliased and bogus values! */
                    163:        RxStatus = 0x0c,
                    164: };
                    165: enum ASICCtrl_HiWord_bit {
                    166:        GlobalReset = 0x0001,
                    167:        RxReset = 0x0002,
                    168:        TxReset = 0x0004,
                    169:        DMAReset = 0x0008,
                    170:        FIFOReset = 0x0010,
                    171:        NetworkReset = 0x0020,
                    172:        HostReset = 0x0040,
                    173:        ResetBusy = 0x0400,
                    174: };
                    175: 
                    176: /* Bits in the interrupt status/mask registers. */
                    177: enum intr_status_bits {
                    178:        IntrSummary = 0x0001, IntrPCIErr = 0x0002, IntrMACCtrl = 0x0008,
                    179:        IntrTxDone = 0x0004, IntrRxDone = 0x0010, IntrRxStart = 0x0020,
                    180:        IntrDrvRqst = 0x0040,
                    181:        StatsMax = 0x0080, LinkChange = 0x0100,
                    182:        IntrTxDMADone = 0x0200, IntrRxDMADone = 0x0400,
                    183: };
                    184: 
                    185: /* Bits in the RxMode register. */
                    186: enum rx_mode_bits {
                    187:        AcceptAllIPMulti = 0x20, AcceptMultiHash = 0x10, AcceptAll = 0x08,
                    188:        AcceptBroadcast = 0x04, AcceptMulticast = 0x02, AcceptMyPhys =
                    189:            0x01,
                    190: };
                    191: /* Bits in MACCtrl. */
                    192: enum mac_ctrl0_bits {
                    193:        EnbFullDuplex = 0x20, EnbRcvLargeFrame = 0x40,
                    194:        EnbFlowCtrl = 0x100, EnbPassRxCRC = 0x200,
                    195: };
                    196: enum mac_ctrl1_bits {
                    197:        StatsEnable = 0x0020, StatsDisable = 0x0040, StatsEnabled = 0x0080,
                    198:        TxEnable = 0x0100, TxDisable = 0x0200, TxEnabled = 0x0400,
                    199:        RxEnable = 0x0800, RxDisable = 0x1000, RxEnabled = 0x2000,
                    200: };
                    201: 
                    202: /* The Rx and Tx buffer descriptors.
                    203:    Using only 32 bit fields simplifies software endian correction.
                    204:    This structure must be aligned, and should avoid spanning cache lines.
                    205: */
                    206: struct netdev_desc {
                    207:        u32 next_desc;
                    208:        u32 status;
                    209:        u32 addr;
                    210:        u32 length;
                    211: };
                    212: 
                    213: /* Bits in netdev_desc.status */
                    214: enum desc_status_bits {
                    215:        DescOwn = 0x8000,
                    216:        DescEndPacket = 0x4000,
                    217:        DescEndRing = 0x2000,
                    218:        LastFrag = 0x80000000,
                    219:        DescIntrOnTx = 0x8000,
                    220:        DescIntrOnDMADone = 0x80000000,
                    221:        DisableAlign = 0x00000001,
                    222: };
                    223: 
                    224: /**********************************************
                    225: * Descriptor Ring and Buffer defination
                    226: ***********************************************/
                    227: /* Define the TX Descriptor */
                    228: static struct netdev_desc tx_ring[TX_RING_SIZE];
                    229: 
                    230: /* Define the RX Descriptor */
                    231: static struct netdev_desc rx_ring[RX_RING_SIZE];
                    232: 
                    233: /* Create a static buffer of size PKT_BUF_SZ for each RX and TX descriptor.
                    234:    All descriptors point to a part of this buffer */
                    235: struct {
                    236:        unsigned char txb[PKT_BUF_SZ * TX_RING_SIZE];
                    237:        unsigned char rxb[RX_RING_SIZE * PKT_BUF_SZ];
                    238: } rx_tx_buf __shared;
                    239: #define rxb rx_tx_buf.rxb
                    240: #define txb rx_tx_buf.txb
                    241: 
                    242: /* FIXME: Move BASE to the private structure */
                    243: static u32 BASE;
                    244: #define EEPROM_SIZE    128
                    245: 
                    246: enum pci_id_flags_bits {
                    247:        PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4,
                    248:        PCI_ADDR0 = 0 << 4, PCI_ADDR1 = 1 << 4, PCI_ADDR2 =
                    249:            2 << 4, PCI_ADDR3 = 3 << 4,
                    250: };
                    251: 
                    252: enum chip_capability_flags { CanHaveMII = 1, KendinPktDropBug = 2, };
                    253: #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO  | PCI_ADDR0)
                    254: 
                    255: #define MII_CNT                4
                    256: static struct sundance_private {
                    257:        const char *nic_name;
                    258:        /* Frequently used values */
                    259: 
                    260:        unsigned int cur_rx;    /* Producer/consumer ring indicies */
                    261:        unsigned int mtu;
                    262: 
                    263:        /* These values keep track of the tranceiver/media in use */
                    264:        unsigned int flowctrl:1;
                    265:        unsigned int an_enable:1;
                    266: 
                    267:        unsigned int speed;
                    268: 
                    269:        /* MII tranceiver section */
                    270:        struct mii_if_info mii_if;
                    271:        int mii_preamble_required;
                    272:        unsigned char phys[MII_CNT];
                    273:        unsigned char pci_rev_id;
                    274: } sdx;
                    275: 
                    276: static struct sundance_private *sdc;
                    277: 
                    278: /* Station Address location within the EEPROM */
                    279: #define EEPROM_SA_OFFSET       0x10
                    280: #define DEFAULT_INTR (IntrRxDMADone | IntrPCIErr | \
                    281:                         IntrDrvRqst | IntrTxDone | StatsMax | \
                    282:                         LinkChange)
                    283: 
                    284: static int eeprom_read(long ioaddr, int location);
                    285: static int mdio_read(struct nic *nic, int phy_id, unsigned int location);
                    286: static void mdio_write(struct nic *nic, int phy_id, unsigned int location,
                    287:                       int value);
                    288: static void set_rx_mode(struct nic *nic);
                    289: 
                    290: static void check_duplex(struct nic *nic)
                    291: {
                    292:        int mii_lpa = mdio_read(nic, sdc->phys[0], MII_LPA);
                    293:        int negotiated = mii_lpa & sdc->mii_if.advertising;
                    294:        int duplex;
                    295: 
                    296:        /* Force media */
                    297:        if (!sdc->an_enable || mii_lpa == 0xffff) {
                    298:                if (sdc->mii_if.full_duplex)
                    299:                        outw(inw(BASE + MACCtrl0) | EnbFullDuplex,
                    300:                             BASE + MACCtrl0);
                    301:                return;
                    302:        }
                    303: 
                    304:        /* Autonegotiation */
                    305:        duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
                    306:        if (sdc->mii_if.full_duplex != duplex) {
                    307:                sdc->mii_if.full_duplex = duplex;
                    308:                DBG ("%s: Setting %s-duplex based on MII #%d "
                    309:                         "negotiated capability %4.4x.\n", sdc->nic_name,
                    310:                         duplex ? "full" : "half", sdc->phys[0],
                    311:                         negotiated );
                    312:                outw(inw(BASE + MACCtrl0) | duplex ? 0x20 : 0,
                    313:                     BASE + MACCtrl0);
                    314:        }
                    315: }
                    316: 
                    317: 
                    318: /**************************************************************************
                    319:  *  init_ring - setup the tx and rx descriptors
                    320:  *************************************************************************/
                    321: static void init_ring(struct nic *nic __unused)
                    322: {
                    323:        int i;
                    324: 
                    325:        sdc->cur_rx = 0;
                    326: 
                    327:        /* Initialize all the Rx descriptors */
                    328:        for (i = 0; i < RX_RING_SIZE; i++) {
                    329:                rx_ring[i].next_desc = virt_to_le32desc(&rx_ring[i + 1]);
                    330:                rx_ring[i].status = 0;
                    331:                rx_ring[i].length = 0;
                    332:                rx_ring[i].addr = 0;
                    333:        }
                    334: 
                    335:        /* Mark the last entry as wrapping the ring */
                    336:        rx_ring[i - 1].next_desc = virt_to_le32desc(&rx_ring[0]);
                    337: 
                    338:        for (i = 0; i < RX_RING_SIZE; i++) {
                    339:                rx_ring[i].addr = virt_to_le32desc(&rxb[i * PKT_BUF_SZ]);
                    340:                rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ | LastFrag);
                    341:        }
                    342: 
                    343:        /* We only use one transmit buffer, but two
                    344:         * descriptors so transmit engines have somewhere
                    345:         * to point should they feel the need */
                    346:        tx_ring[0].status = 0x00000000;
                    347:        tx_ring[0].addr = virt_to_bus(&txb[0]);
                    348:        tx_ring[0].next_desc = 0;       /* virt_to_bus(&tx_ring[1]); */
                    349: 
                    350:        /* This descriptor is never used */
                    351:        tx_ring[1].status = 0x00000000;
                    352:        tx_ring[1].addr = 0;    /*virt_to_bus(&txb[0]); */
                    353:        tx_ring[1].next_desc = 0;
                    354: 
                    355:        /* Mark the last entry as wrapping the ring,
                    356:         * though this should never happen */
                    357:        tx_ring[1].length = cpu_to_le32(LastFrag | PKT_BUF_SZ);
                    358: }
                    359: 
                    360: /**************************************************************************
                    361:  *  RESET - Reset Adapter
                    362:  * ***********************************************************************/
                    363: static void sundance_reset(struct nic *nic)
                    364: {
                    365:        int i;
                    366: 
                    367:        init_ring(nic);
                    368: 
                    369:        outl(virt_to_le32desc(&rx_ring[0]), BASE + RxListPtr);
                    370:        /* The Tx List Pointer is written as packets are queued */
                    371: 
                    372:        /* Initialize other registers. */
                    373:        /* __set_mac_addr(dev); */
                    374:        {
                    375:                u16 addr16;
                    376: 
                    377:                addr16 = (nic->node_addr[0] | (nic->node_addr[1] << 8));
                    378:                outw(addr16, BASE + StationAddr);
                    379:                addr16 = (nic->node_addr[2] | (nic->node_addr[3] << 8));
                    380:                outw(addr16, BASE + StationAddr + 2);
                    381:                addr16 = (nic->node_addr[4] | (nic->node_addr[5] << 8));
                    382:                outw(addr16, BASE + StationAddr + 4);
                    383:        }
                    384: 
                    385:        outw(sdc->mtu + 14, BASE + MaxFrameSize);
                    386:        if (sdc->mtu > 2047)    /* this will never happen with default options */
                    387:                outl(inl(BASE + ASICCtrl) | 0x0c, BASE + ASICCtrl);
                    388: 
                    389:        set_rx_mode(nic);
                    390: 
                    391:        outw(0, BASE + DownCounter);
                    392:        /* Set the chip to poll every N*30nsec */
                    393:        outb(100, BASE + RxDMAPollPeriod);
                    394: 
                    395:        /* Fix DFE-580TX packet drop issue */
                    396:        if (sdc->pci_rev_id >= 0x14)
                    397:                writeb(0x01, BASE + DebugCtrl1);
                    398: 
                    399:        outw(RxEnable | TxEnable, BASE + MACCtrl1);
                    400: 
                    401:        /* Construct a perfect filter frame with the mac address as first match
                    402:         * and broadcast for all others */
                    403:        for (i = 0; i < 192; i++)
                    404:                txb[i] = 0xFF;
                    405: 
                    406:        txb[0] = nic->node_addr[0];
                    407:        txb[1] = nic->node_addr[1];
                    408:        txb[2] = nic->node_addr[2];
                    409:        txb[3] = nic->node_addr[3];
                    410:        txb[4] = nic->node_addr[4];
                    411:        txb[5] = nic->node_addr[5];
                    412: 
                    413:        DBG ( "%s: Done sundance_reset, status: Rx %hX Tx %hX "
                    414:              "MAC Control %hX, %hX %hX\n",
                    415:              sdc->nic_name, (int) inl(BASE + RxStatus),
                    416:              (int) inw(BASE + TxStatus), (int) inl(BASE + MACCtrl0),
                    417:              (int) inw(BASE + MACCtrl1), (int) inw(BASE + MACCtrl0) );
                    418: }
                    419: 
                    420: /**************************************************************************
                    421: IRQ - Wait for a frame
                    422: ***************************************************************************/
                    423: static void sundance_irq ( struct nic *nic, irq_action_t action ) {
                    424:         unsigned int intr_status;
                    425: 
                    426:        switch ( action ) {
                    427:        case DISABLE :
                    428:        case ENABLE :
                    429:                intr_status = inw(nic->ioaddr + IntrStatus);
                    430:                intr_status = intr_status & ~DEFAULT_INTR;
                    431:                if ( action == ENABLE ) 
                    432:                        intr_status = intr_status | DEFAULT_INTR;
                    433:                outw(intr_status, nic->ioaddr + IntrEnable);
                    434:                break;
                    435:         case FORCE :
                    436:                outw(0x0200, BASE + ASICCtrl);
                    437:                break;
                    438:         }
                    439: }
                    440: /**************************************************************************
                    441: POLL - Wait for a frame
                    442: ***************************************************************************/
                    443: static int sundance_poll(struct nic *nic, int retreive)
                    444: {
                    445:        /* return true if there's an ethernet packet ready to read */
                    446:        /* nic->packet should contain data on return */
                    447:        /* nic->packetlen should contain length of data */
                    448:        int entry = sdc->cur_rx % RX_RING_SIZE;
                    449:        u32 frame_status = le32_to_cpu(rx_ring[entry].status);
                    450:        int intr_status;
                    451:        int pkt_len = 0;
                    452: 
                    453:        if (!(frame_status & DescOwn))
                    454:                return 0;
                    455: 
                    456:        /* There is a packet ready */
                    457:        if(!retreive)
                    458:                return 1;
                    459: 
                    460:        intr_status = inw(nic->ioaddr + IntrStatus);
                    461:        outw(intr_status, nic->ioaddr + IntrStatus);
                    462: 
                    463:        pkt_len = frame_status & 0x1fff;
                    464: 
                    465:        if (frame_status & 0x001f4000) {
                    466:                DBG ( "Polling frame_status error\n" ); /* Do we really care about this */
                    467:        } else {
                    468:                if (pkt_len < rx_copybreak) {
                    469:                        /* FIXME: What should happen Will this ever occur */
                    470:                        printf("Poll Error: pkt_len < rx_copybreak");
                    471:                } else {
                    472:                        nic->packetlen = pkt_len;
                    473:                        memcpy(nic->packet, rxb +
                    474:                               (sdc->cur_rx * PKT_BUF_SZ), nic->packetlen);
                    475: 
                    476:                }
                    477:        }
                    478:        rx_ring[entry].length = cpu_to_le32(PKT_BUF_SZ | LastFrag);
                    479:        rx_ring[entry].status = 0;
                    480:        entry++;
                    481:        sdc->cur_rx = entry % RX_RING_SIZE;
                    482:        outw(DEFAULT_INTR & ~(IntrRxDone|IntrRxDMADone), 
                    483:                nic->ioaddr + IntrStatus);
                    484:        return 1;
                    485: }
                    486: 
                    487: /**************************************************************************
                    488: TRANSMIT - Transmit a frame
                    489: ***************************************************************************/
                    490: static void sundance_transmit(struct nic *nic, const char *d,  /* Destination */
                    491:                              unsigned int t,   /* Type */
                    492:                              unsigned int s,   /* size */
                    493:                              const char *p)
                    494: {                              /* Packet */
                    495:        u16 nstype;
                    496:        u32 to;
                    497: 
                    498:        /* Disable the Tx */
                    499:        outw(TxDisable, BASE + MACCtrl1);
                    500: 
                    501:        memcpy(txb, d, ETH_ALEN);
                    502:        memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
                    503:        nstype = htons((u16) t);
                    504:        memcpy(txb + 2 * ETH_ALEN, (u8 *) & nstype, 2);
                    505:        memcpy(txb + ETH_HLEN, p, s);
                    506: 
                    507:        s += ETH_HLEN;
                    508:        s &= 0x0FFF;
                    509:        while (s < ETH_ZLEN)
                    510:                txb[s++] = '\0';
                    511: 
                    512:        /* Setup the transmit descriptor */
                    513:        tx_ring[0].length = cpu_to_le32(s | LastFrag);
                    514:        tx_ring[0].status = cpu_to_le32(0x00000001);
                    515: 
                    516:        /* Point to transmit descriptor */
                    517:        outl(virt_to_le32desc(&tx_ring[0]), BASE + TxListPtr);
                    518: 
                    519:        /* Enable Tx */
                    520:        outw(TxEnable, BASE + MACCtrl1);
                    521:        /* Trigger an immediate send */
                    522:        outw(0, BASE + TxStatus);
                    523: 
                    524:        to = currticks() + TX_TIME_OUT;
                    525:        while (!(tx_ring[0].status & 0x00010000) && (currticks() < to));        /* wait */
                    526: 
                    527:        if (currticks() >= to) {
                    528:                printf("TX Time Out");
                    529:        }
                    530:        /* Disable Tx */
                    531:        outw(TxDisable, BASE + MACCtrl1);
                    532: 
                    533: }
                    534: 
                    535: /**************************************************************************
                    536: DISABLE - Turn off ethernet interface
                    537: ***************************************************************************/
                    538: static void sundance_disable ( struct nic *nic __unused ) {
                    539:        /* put the card in its initial state */
                    540:        /* This function serves 3 purposes.
                    541:         * This disables DMA and interrupts so we don't receive
                    542:         *  unexpected packets or interrupts from the card after
                    543:         *  etherboot has finished.
                    544:         * This frees resources so etherboot may use
                    545:         *  this driver on another interface
                    546:         * This allows etherboot to reinitialize the interface
                    547:         *  if something is something goes wrong.
                    548:         */
                    549:        outw(0x0000, BASE + IntrEnable);
                    550:        /* Stop the Chipchips Tx and Rx Status */
                    551:        outw(TxDisable | RxDisable | StatsDisable, BASE + MACCtrl1);
                    552: }
                    553: 
                    554: static struct nic_operations sundance_operations = {
                    555:        .connect        = dummy_connect,
                    556:        .poll           = sundance_poll,
                    557:        .transmit       = sundance_transmit,
                    558:        .irq            = sundance_irq,
                    559: 
                    560: };
                    561: 
                    562: /**************************************************************************
                    563: PROBE - Look for an adapter, this routine's visible to the outside
                    564: ***************************************************************************/
                    565: static int sundance_probe ( struct nic *nic, struct pci_device *pci ) {
                    566: 
                    567:        u8 ee_data[EEPROM_SIZE];
                    568:        u16 mii_ctl;
                    569:        int i;
                    570:        int speed;
                    571: 
                    572:        if (pci->ioaddr == 0)
                    573:                return 0;
                    574: 
                    575:        /* BASE is used throughout to address the card */
                    576:        BASE = pci->ioaddr;
                    577:        printf(" sundance.c: Found %s Vendor=0x%hX Device=0x%hX\n",
                    578:               pci->id->name, pci->vendor, pci->device);
                    579: 
                    580:        /* Get the MAC Address by reading the EEPROM */
                    581:        for (i = 0; i < 3; i++) {
                    582:                ((u16 *) ee_data)[i] =
                    583:                    le16_to_cpu(eeprom_read(BASE, i + EEPROM_SA_OFFSET));
                    584:        }
                    585:        /* Update the nic structure with the MAC Address */
                    586:        for (i = 0; i < ETH_ALEN; i++) {
                    587:                nic->node_addr[i] = ee_data[i];
                    588:        }
                    589: 
                    590:        /* Set the card as PCI Bus Master */
                    591:        adjust_pci_device(pci);
                    592: 
                    593: //      sdc->mii_if.dev = pci;
                    594: //      sdc->mii_if.phy_id_mask = 0x1f;
                    595: //      sdc->mii_if.reg_num_mask = 0x1f;
                    596: 
                    597:        /* point to private storage */
                    598:        sdc = &sdx;
                    599: 
                    600:        sdc->nic_name = pci->id->name;
                    601:        sdc->mtu = mtu;
                    602: 
                    603:        pci_read_config_byte(pci, PCI_REVISION_ID, &sdc->pci_rev_id);
                    604: 
                    605:        DBG ( "Device revision id: %hx\n", sdc->pci_rev_id );
                    606: 
                    607:        /* Print out some hardware info */
                    608:        DBG ( "%s: %s at ioaddr %hX, ",
                    609:              pci->id->name, nic->node_addr, (unsigned int) BASE);
                    610: 
                    611:        sdc->mii_preamble_required = 0;
                    612:        if (1) {
                    613:                int phy, phy_idx = 0;
                    614:                sdc->phys[0] = 1;       /* Default Setting */
                    615:                sdc->mii_preamble_required++;
                    616:                for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) {
                    617:                        int mii_status = mdio_read(nic, phy, MII_BMSR);
                    618:                        if (mii_status != 0xffff && mii_status != 0x0000) {
                    619:                                sdc->phys[phy_idx++] = phy;
                    620:                                sdc->mii_if.advertising =
                    621:                                    mdio_read(nic, phy, MII_ADVERTISE);
                    622:                                if ((mii_status & 0x0040) == 0)
                    623:                                        sdc->mii_preamble_required++;
                    624:                                DBG 
                    625:                                    ( "%s: MII PHY found at address %d, status " "%hX advertising %hX\n", sdc->nic_name, phy, mii_status, sdc->mii_if.advertising );
                    626:                        }
                    627:                }
                    628:                sdc->mii_preamble_required--;
                    629:                if (phy_idx == 0)
                    630:                        printf("%s: No MII transceiver found!\n",
                    631:                               sdc->nic_name);
                    632:                sdc->mii_if.phy_id = sdc->phys[0];
                    633:        }
                    634: 
                    635:        /* Parse override configuration */
                    636:        sdc->an_enable = 1;
                    637:        if (strcasecmp(media, "autosense") != 0) {
                    638:                sdc->an_enable = 0;
                    639:                if (strcasecmp(media, "100mbps_fd") == 0 ||
                    640:                    strcasecmp(media, "4") == 0) {
                    641:                        sdc->speed = 100;
                    642:                        sdc->mii_if.full_duplex = 1;
                    643:                } else if (strcasecmp(media, "100mbps_hd") == 0
                    644:                           || strcasecmp(media, "3") == 0) {
                    645:                        sdc->speed = 100;
                    646:                        sdc->mii_if.full_duplex = 0;
                    647:                } else if (strcasecmp(media, "10mbps_fd") == 0 ||
                    648:                           strcasecmp(media, "2") == 0) {
                    649:                        sdc->speed = 10;
                    650:                        sdc->mii_if.full_duplex = 1;
                    651:                } else if (strcasecmp(media, "10mbps_hd") == 0 ||
                    652:                           strcasecmp(media, "1") == 0) {
                    653:                        sdc->speed = 10;
                    654:                        sdc->mii_if.full_duplex = 0;
                    655:                } else {
                    656:                        sdc->an_enable = 1;
                    657:                }
                    658:        }
                    659:        if (flowctrl == 1)
                    660:                sdc->flowctrl = 1;
                    661: 
                    662:        /* Fibre PHY? */
                    663:        if (inl(BASE + ASICCtrl) & 0x80) {
                    664:                /* Default 100Mbps Full */
                    665:                if (sdc->an_enable) {
                    666:                        sdc->speed = 100;
                    667:                        sdc->mii_if.full_duplex = 1;
                    668:                        sdc->an_enable = 0;
                    669:                }
                    670:        }
                    671: 
                    672:        /* The Linux driver uses flow control and resets the link here.  This means the
                    673:           mii section from above would need to be re done I believe.  Since it serves
                    674:           no real purpose leave it out. */
                    675: 
                    676:        /* Force media type */
                    677:        if (!sdc->an_enable) {
                    678:                mii_ctl = 0;
                    679:                mii_ctl |= (sdc->speed == 100) ? BMCR_SPEED100 : 0;
                    680:                mii_ctl |= (sdc->mii_if.full_duplex) ? BMCR_FULLDPLX : 0;
                    681:                mdio_write(nic, sdc->phys[0], MII_BMCR, mii_ctl);
                    682:                printf("Override speed=%d, %s duplex\n",
                    683:                       sdc->speed,
                    684:                       sdc->mii_if.full_duplex ? "Full" : "Half");
                    685:        }
                    686: 
                    687:        /* Reset the chip to erase previous misconfiguration */
                    688:        DBG ( "ASIC Control is %#x\n", inl(BASE + ASICCtrl) );
                    689:        outw(0x007f, BASE + ASICCtrl + 2);
                    690: 
                    691:        /*
                    692:        * wait for reset to complete
                    693:        * this is heavily inspired by the linux sundance driver
                    694:        * according to the linux driver it can take up to 1ms for the reset
                    695:        * to complete
                    696:        */
                    697:        i = 0;
                    698:        while(inl(BASE + ASICCtrl) & (ResetBusy << 16)) {
                    699:                if(i++ >= 10) {
                    700:                        DBG("sundance: NIC reset did not complete.\n");
                    701:                        break;
                    702:                }
                    703:                udelay(100);
                    704:        }
                    705: 
                    706:        DBG ( "ASIC Control is now %#x.\n", inl(BASE + ASICCtrl) );
                    707: 
                    708:        sundance_reset(nic);
                    709:        if (sdc->an_enable) {
                    710:                u16 mii_advertise, mii_lpa;
                    711:                mii_advertise =
                    712:                    mdio_read(nic, sdc->phys[0], MII_ADVERTISE);
                    713:                mii_lpa = mdio_read(nic, sdc->phys[0], MII_LPA);
                    714:                mii_advertise &= mii_lpa;
                    715:                if (mii_advertise & ADVERTISE_100FULL)
                    716:                        sdc->speed = 100;
                    717:                else if (mii_advertise & ADVERTISE_100HALF)
                    718:                        sdc->speed = 100;
                    719:                else if (mii_advertise & ADVERTISE_10FULL)
                    720:                        sdc->speed = 10;
                    721:                else if (mii_advertise & ADVERTISE_10HALF)
                    722:                        sdc->speed = 10;
                    723:        } else {
                    724:                mii_ctl = mdio_read(nic, sdc->phys[0], MII_BMCR);
                    725:                speed = (mii_ctl & BMCR_SPEED100) ? 100 : 10;
                    726:                sdc->speed = speed;
                    727:                printf("%s: Link changed: %dMbps ,", sdc->nic_name, speed);
                    728:                printf("%s duplex.\n", (mii_ctl & BMCR_FULLDPLX) ?
                    729:                       "full" : "half");
                    730:        }
                    731:        check_duplex(nic);
                    732:        if (sdc->flowctrl && sdc->mii_if.full_duplex) {
                    733:                outw(inw(BASE + MulticastFilter1 + 2) | 0x0200,
                    734:                     BASE + MulticastFilter1 + 2);
                    735:                outw(inw(BASE + MACCtrl0) | EnbFlowCtrl, BASE + MACCtrl0);
                    736:        }
                    737:        printf("%dMbps, %s-Duplex\n", sdc->speed,
                    738:               sdc->mii_if.full_duplex ? "Full" : "Half");
                    739: 
                    740:        /* point to NIC specific routines */
                    741:        nic->nic_op     = &sundance_operations;
                    742: 
                    743:        nic->irqno  = pci->irq;
                    744:        nic->ioaddr = BASE;
                    745: 
                    746:        return 1;
                    747: }
                    748: 
                    749: 
                    750: /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. */
                    751: static int eeprom_read(long ioaddr, int location)
                    752: {
                    753:        int boguscnt = 10000;   /* Typical 1900 ticks */
                    754:        outw(0x0200 | (location & 0xff), ioaddr + EECtrl);
                    755:        do {
                    756:                if (!(inw(ioaddr + EECtrl) & 0x8000)) {
                    757:                        return inw(ioaddr + EEData);
                    758:                }
                    759:        }
                    760:        while (--boguscnt > 0);
                    761:        return 0;
                    762: }
                    763: 
                    764: /*  MII transceiver control section.
                    765:        Read and write the MII registers using software-generated serial
                    766:        MDIO protocol.  See the MII specifications or DP83840A data sheet
                    767:        for details.
                    768: 
                    769:        The maximum data clock rate is 2.5 Mhz.
                    770:        The timing is decoupled from the processor clock by flushing the write
                    771:        from the CPU write buffer with a following read, and using PCI
                    772:        transaction time. */
                    773: 
                    774: #define mdio_in(mdio_addr) inb(mdio_addr)
                    775: #define mdio_out(value, mdio_addr) outb(value, mdio_addr)
                    776: #define mdio_delay(mdio_addr) inb(mdio_addr)
                    777: 
                    778: enum mii_reg_bits {
                    779:        MDIO_ShiftClk = 0x0001, MDIO_Data = 0x0002, MDIO_EnbOutput =
                    780:            0x0004,
                    781: };
                    782: #define MDIO_EnbIn  (0)
                    783: #define MDIO_WRITE0 (MDIO_EnbOutput)
                    784: #define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput)
                    785: 
                    786: /* Generate the preamble required for initial synchronization and
                    787:    a few older transceivers. */
                    788: static void mdio_sync(long mdio_addr)
                    789: {
                    790:        int bits = 32;
                    791: 
                    792:        /* Establish sync by sending at least 32 logic ones. */
                    793:        while (--bits >= 0) {
                    794:                mdio_out(MDIO_WRITE1, mdio_addr);
                    795:                mdio_delay(mdio_addr);
                    796:                mdio_out(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
                    797:                mdio_delay(mdio_addr);
                    798:        }
                    799: }
                    800: 
                    801: static int
                    802: mdio_read(struct nic *nic __unused, int phy_id, unsigned int location)
                    803: {
                    804:        long mdio_addr = BASE + MIICtrl;
                    805:        int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
                    806:        int i, retval = 0;
                    807: 
                    808:        if (sdc->mii_preamble_required)
                    809:                mdio_sync(mdio_addr);
                    810: 
                    811:        /* Shift the read command bits out. */
                    812:        for (i = 15; i >= 0; i--) {
                    813:                int dataval =
                    814:                    (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
                    815: 
                    816:                mdio_out(dataval, mdio_addr);
                    817:                mdio_delay(mdio_addr);
                    818:                mdio_out(dataval | MDIO_ShiftClk, mdio_addr);
                    819:                mdio_delay(mdio_addr);
                    820:        }
                    821:        /* Read the two transition, 16 data, and wire-idle bits. */
                    822:        for (i = 19; i > 0; i--) {
                    823:                mdio_out(MDIO_EnbIn, mdio_addr);
                    824:                mdio_delay(mdio_addr);
                    825:                retval = (retval << 1) | ((mdio_in(mdio_addr) & MDIO_Data)
                    826:                                          ? 1 : 0);
                    827:                mdio_out(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
                    828:                mdio_delay(mdio_addr);
                    829:        }
                    830:        return (retval >> 1) & 0xffff;
                    831: }
                    832: 
                    833: static void
                    834: mdio_write(struct nic *nic __unused, int phy_id,
                    835:           unsigned int location, int value)
                    836: {
                    837:        long mdio_addr = BASE + MIICtrl;
                    838:        int mii_cmd =
                    839:            (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
                    840:        int i;
                    841: 
                    842:        if (sdc->mii_preamble_required)
                    843:                mdio_sync(mdio_addr);
                    844: 
                    845:        /* Shift the command bits out. */
                    846:        for (i = 31; i >= 0; i--) {
                    847:                int dataval =
                    848:                    (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
                    849:                mdio_out(dataval, mdio_addr);
                    850:                mdio_delay(mdio_addr);
                    851:                mdio_out(dataval | MDIO_ShiftClk, mdio_addr);
                    852:                mdio_delay(mdio_addr);
                    853:        }
                    854:        /* Clear out extra bits. */
                    855:        for (i = 2; i > 0; i--) {
                    856:                mdio_out(MDIO_EnbIn, mdio_addr);
                    857:                mdio_delay(mdio_addr);
                    858:                mdio_out(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
                    859:                mdio_delay(mdio_addr);
                    860:        }
                    861:        return;
                    862: }
                    863: 
                    864: static void set_rx_mode(struct nic *nic __unused)
                    865: {
                    866:        int i;
                    867:        u16 mc_filter[4];       /* Multicast hash filter */
                    868:        u32 rx_mode;
                    869: 
                    870:        memset(mc_filter, 0xff, sizeof(mc_filter));
                    871:        rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
                    872: 
                    873:        if (sdc->mii_if.full_duplex && sdc->flowctrl)
                    874:                mc_filter[3] |= 0x0200;
                    875:        for (i = 0; i < 4; i++)
                    876:                outw(mc_filter[i], BASE + MulticastFilter0 + i * 2);
                    877:        outb(rx_mode, BASE + RxMode);
                    878:        return;
                    879: }
                    880: 
                    881: static struct pci_device_id sundance_nics[] = {
                    882:        PCI_ROM(0x13f0, 0x0201, "sundance", "ST201 Sundance 'Alta' based Adaptor", 0),
                    883:        PCI_ROM(0x1186, 0x1002, "dfe530txs", "D-Link DFE530TXS (Sundance ST201 Alta)", 0),
                    884:        PCI_ROM(0x13f0, 0x0200, "ip100a", "IC+ IP100A", 0),
                    885: };
                    886: 
                    887: PCI_DRIVER ( sundance_driver, sundance_nics, PCI_NO_CLASS );
                    888: 
                    889: DRIVER ( "SUNDANCE/PCI", nic_driver, pci_driver, sundance_driver,
                    890:         sundance_probe, sundance_disable );
                    891: 
                    892: /*
                    893:  * Local variables:
                    894:  *  c-basic-offset: 8
                    895:  *  c-indent-level: 8
                    896:  *  tab-width: 8
                    897:  * End:
                    898:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.