Home | History | Annotate | Download | only in netboot
      1 /*
      2  * Etherboot -  BOOTP/TFTP Bootstrap Program
      3  *
      4  * w89c840.c -- This file implements the winbond-840 driver for etherboot.
      5  *
      6  */
      7 
      8 /*
      9  * Adapted by Igor V. Kovalenko
     10  *  -- <garrison (at) mail.ru>
     11  *   OR
     12  *  -- <iko (at) crec.mipt.ru>
     13  * Initial adaptaion stage, including testing, completed 23 August 2000.
     14  */
     15 
     16 /*
     17  * This program is free software; you can redistribute it and/or
     18  * modify it under the terms of the GNU General Public License as
     19  * published by the Free Software Foundation; either version 2, or (at
     20  * your option) any later version.
     21  *
     22  * This program is distributed in the hope that it will be useful, but
     23  * WITHOUT ANY WARRANTY; without even the implied warranty of
     24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     25  * General Public License for more details.
     26  *
     27  * You should have received a copy of the GNU General Public License
     28  * along with this program; if not, write to the Free Software
     29  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     30  */
     31 
     32 /*
     33  *              date       version  by   what
     34  *  Written:    Aug 20 2000  V0.10  iko  Initial revision.
     35  * changes:     Aug 22 2000  V0.90  iko  Works!
     36  *              Aug 23 2000  V0.91  iko  Cleanup, posted to etherboot
     37  *                                       maintainer.
     38  *              Aug 26 2000  V0.92  iko  Fixed Rx ring handling.
     39  *                                       First Linux Kernel (TM)
     40  *                                       successfully loaded using
     41  *                                       this driver.
     42  *              Jan 07 2001  V0.93  iko  Transmitter timeouts are handled
     43  *                                       using timer2 routines. Proposed
     44  *                                       by Ken Yap to eliminate CPU speed
     45  *                                       dependency.
     46  *
     47  * This is the etherboot driver for cards based on Winbond W89c840F chip.
     48  *
     49  * It was written from skeleton source, with Donald Becker's winbond-840.c
     50  * kernel driver as a guideline. Mostly the w89c840 related definitions
     51  * and the lower level routines have been cut-and-pasted into this source.
     52  *
     53  * Frankly speaking, about 90% of the code was obtained using cut'n'paste
     54  * sequence :) while the remainder appeared while brainstorming
     55  * Linux Kernel 2.4.0-testX source code. Thanks, Donald and Linus!
     56  *
     57  * There was a demand for using this card in a rather large
     58  * remote boot environment at MSKP OVTI Lab of
     59  * Moscow Institute for Physics and Technology (MIPT) -- http://www.mipt.ru/
     60  * so you may count that for motivation.
     61  *
     62  */
     63 
     64 /*
     65  * If you want to see debugging output then define W89C840_DEBUG
     66  */
     67 
     68 /*
     69 #define W89C840_DEBUG
     70 */
     71 
     72 /*
     73  * Keep using IO_OPS for Etherboot driver!
     74  */
     75 #define USE_IO_OPS
     76 
     77 #include "etherboot.h"
     78 #include "nic.h"
     79 #include "pci.h"
     80 #include "cards.h"
     81 #include "timer.h"
     82 
     83 static const char *w89c840_version = "diver Version 0.92 - August 27, 2000";
     84 
     85 typedef unsigned char  u8;
     86 typedef   signed char  s8;
     87 typedef unsigned short u16;
     88 typedef   signed short s16;
     89 typedef unsigned int   u32;
     90 typedef   signed int   s32;
     91 
     92 /* Linux support functions */
     93 #define virt_to_bus(x) ((unsigned long)x)
     94 #define bus_to_virt(x) ((void *)x)
     95 
     96 #define virt_to_le32desc(addr)  virt_to_bus(addr)
     97 #define le32desc_to_virt(addr)  bus_to_virt(addr)
     98 
     99 /*
    100 #define cpu_to_le32(val) (val)
    101 #define le32_to_cpu(val) (val)
    102 */
    103 
    104 /* Operational parameters that are set at compile time. */
    105 
    106 /* Keep the ring sizes a power of two for compile efficiency.
    107    The compiler will convert <unsigned>'%'<2^N> into a bit mask.
    108    Making the Tx ring too large decreases the effectiveness of channel
    109    bonding and packet priority.
    110    There are no ill effects from too-large receive rings. */
    111 #define TX_RING_SIZE    2
    112 
    113 #define RX_RING_SIZE    2
    114 
    115 /* The presumed FIFO size for working around the Tx-FIFO-overflow bug.
    116    To avoid overflowing we don't queue again until we have room for a
    117    full-size packet.
    118  */
    119 #define TX_FIFO_SIZE (2048)
    120 #define TX_BUG_FIFO_LIMIT (TX_FIFO_SIZE-1514-16)
    121 
    122 /* Operational parameters that usually are not changed. */
    123 /* Time in jiffies before concluding the transmitter is hung. */
    124 #define TX_TIMEOUT  (10*TICKS_PER_MS)
    125 
    126 #define PKT_BUF_SZ  1536  /* Size of each temporary Rx buffer.*/
    127 
    128 /*
    129  * Used to be this much CPU loops on Celeron@400 (?),
    130  * now using real timer and TX_TIMEOUT!
    131  * #define TX_LOOP_COUNT 10000000
    132  */
    133 
    134 #if !defined(__OPTIMIZE__)
    135 #warning  You must compile this file with the correct options!
    136 #warning  See the last lines of the source file.
    137 #error You must compile this driver with "-O".
    138 #endif
    139 
    140 enum chip_capability_flags {CanHaveMII=1, HasBrokenTx=2};
    141 
    142 #ifdef USE_IO_OPS
    143 #define W840_FLAGS (PCI_USES_IO | PCI_ADDR0 | PCI_USES_MASTER)
    144 #else
    145 #define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER)
    146 #endif
    147 
    148 static u32 driver_flags = CanHaveMII | HasBrokenTx;
    149 
    150 /* This driver was written to use PCI memory space, however some x86 systems
    151    work only with I/O space accesses.  Pass -DUSE_IO_OPS to use PCI I/O space
    152    accesses instead of memory space. */
    153 
    154 #ifdef USE_IO_OPS
    155 #undef readb
    156 #undef readw
    157 #undef readl
    158 #undef writeb
    159 #undef writew
    160 #undef writel
    161 #define readb inb
    162 #define readw inw
    163 #define readl inl
    164 #define writeb outb
    165 #define writew outw
    166 #define writel outl
    167 #endif
    168 
    169 /* Offsets to the Command and Status Registers, "CSRs".
    170    While similar to the Tulip, these registers are longword aligned.
    171    Note: It's not useful to define symbolic names for every register bit in
    172    the device.  The name can only partially document the semantics and make
    173    the driver longer and more difficult to read.
    174 */
    175 enum w840_offsets {
    176     PCIBusCfg=0x00, TxStartDemand=0x04, RxStartDemand=0x08,
    177     RxRingPtr=0x0C, TxRingPtr=0x10,
    178     IntrStatus=0x14, NetworkConfig=0x18, IntrEnable=0x1C,
    179     RxMissed=0x20, EECtrl=0x24, MIICtrl=0x24, BootRom=0x28, GPTimer=0x2C,
    180     CurRxDescAddr=0x30, CurRxBufAddr=0x34,            /* Debug use */
    181     MulticastFilter0=0x38, MulticastFilter1=0x3C, StationAddr=0x40,
    182     CurTxDescAddr=0x4C, CurTxBufAddr=0x50,
    183 };
    184 
    185 /* Bits in the interrupt status/enable registers. */
    186 /* The bits in the Intr Status/Enable registers, mostly interrupt sources. */
    187 enum intr_status_bits {
    188     NormalIntr=0x10000, AbnormalIntr=0x8000,
    189     IntrPCIErr=0x2000, TimerInt=0x800,
    190     IntrRxDied=0x100, RxNoBuf=0x80, IntrRxDone=0x40,
    191     TxFIFOUnderflow=0x20, RxErrIntr=0x10,
    192     TxIdle=0x04, IntrTxStopped=0x02, IntrTxDone=0x01,
    193 };
    194 
    195 /* Bits in the NetworkConfig register. */
    196 enum rx_mode_bits {
    197     AcceptErr=0x80, AcceptRunt=0x40,
    198     AcceptBroadcast=0x20, AcceptMulticast=0x10,
    199     AcceptAllPhys=0x08, AcceptMyPhys=0x02,
    200 };
    201 
    202 enum mii_reg_bits {
    203     MDIO_ShiftClk=0x10000, MDIO_DataIn=0x80000, MDIO_DataOut=0x20000,
    204     MDIO_EnbOutput=0x40000, MDIO_EnbIn = 0x00000,
    205 };
    206 
    207 /* The Tulip Rx and Tx buffer descriptors. */
    208 struct w840_rx_desc {
    209     s32 status;
    210     s32 length;
    211     u32 buffer1;
    212     u32 next_desc;
    213 };
    214 
    215 struct w840_tx_desc {
    216     s32 status;
    217     s32 length;
    218     u32 buffer1, buffer2;                /* We use only buffer 1.  */
    219 };
    220 
    221 /* Bits in network_desc.status */
    222 enum desc_status_bits {
    223     DescOwn=0x80000000, DescEndRing=0x02000000, DescUseLink=0x01000000,
    224     DescWholePkt=0x60000000, DescStartPkt=0x20000000, DescEndPkt=0x40000000,
    225     DescIntr=0x80000000,
    226 };
    227 #define PRIV_ALIGN    15     /* Required alignment mask */
    228 #define PRIV_ALIGN_BYTES 32
    229 
    230 static struct winbond_private
    231 {
    232     /* Descriptor rings first for alignment. */
    233     struct w840_rx_desc rx_ring[RX_RING_SIZE];
    234     struct w840_tx_desc tx_ring[TX_RING_SIZE];
    235     struct net_device *next_module;        /* Link for devices of this type. */
    236     void *priv_addr;                    /* Unaligned address for kfree */
    237     const char *product_name;
    238     /* Frequently used values: keep some adjacent for cache effect. */
    239     int chip_id, drv_flags;
    240     struct pci_dev *pci_dev;
    241     int csr6;
    242     struct w840_rx_desc *rx_head_desc;
    243     unsigned int cur_rx, dirty_rx;        /* Producer/consumer ring indices */
    244     unsigned int rx_buf_sz;                /* Based on MTU+slack. */
    245     unsigned int cur_tx, dirty_tx;
    246     int tx_q_bytes;
    247     unsigned int tx_full:1;                /* The Tx queue is full. */
    248     /* These values are keep track of the transceiver/media in use. */
    249     unsigned int full_duplex:1;            /* Full-duplex operation requested. */
    250     unsigned int duplex_lock:1;
    251     unsigned int medialock:1;            /* Do not sense media. */
    252     unsigned int default_port:4;        /* Last dev->if_port value. */
    253     /* MII transceiver section. */
    254     int mii_cnt;                        /* MII device addresses. */
    255     u16 advertising;                    /* NWay media advertisement */
    256     unsigned char phys[2];                /* MII device addresses. */
    257 } w840private __attribute__ ((aligned (PRIV_ALIGN_BYTES)));
    258 
    259 /* NIC specific static variables go here */
    260 
    261 static int ioaddr;
    262 static unsigned short eeprom [0x40];
    263 
    264 #ifdef    USE_LOWMEM_BUFFER
    265 #define rx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE)
    266 #define tx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE - PKT_BUF_SZ * TX_RING_SIZE)
    267 #else
    268 static char        rx_packet[PKT_BUF_SZ * RX_RING_SIZE];
    269 static char        tx_packet[PKT_BUF_SZ * TX_RING_SIZE];
    270 #endif
    271 
    272 static int  eeprom_read(long ioaddr, int location);
    273 static int  mdio_read(int base_address, int phy_id, int location);
    274 static void mdio_write(int base_address, int phy_id, int location, int value);
    275 
    276 static void check_duplex(void);
    277 static void set_rx_mode(void);
    278 static void init_ring(void);
    279 
    280 /*
    281 static void wait_long_time(void)
    282 {
    283     printf("Paused - please read output above this line\n");
    284     sleep(3);
    285 }
    286 */
    287 
    288 #if defined W89C840_DEBUG
    289 static void decode_interrupt(u32 intr_status)
    290 {
    291     printf("Interrupt status: ");
    292 
    293 #define TRACE_INTR(_intr_) \
    294     if (intr_status & (_intr_)) { printf (" " #_intr_); }
    295 
    296     TRACE_INTR(NormalIntr);
    297     TRACE_INTR(AbnormalIntr);
    298     TRACE_INTR(IntrPCIErr);
    299     TRACE_INTR(TimerInt);
    300     TRACE_INTR(IntrRxDied);
    301     TRACE_INTR(RxNoBuf);
    302     TRACE_INTR(IntrRxDone);
    303     TRACE_INTR(TxFIFOUnderflow);
    304     TRACE_INTR(RxErrIntr);
    305     TRACE_INTR(TxIdle);
    306     TRACE_INTR(IntrTxStopped);
    307     TRACE_INTR(IntrTxDone);
    308 
    309     printf("\n");
    310     /*sleep(1);*/
    311 }
    312 #endif
    313 
    314 /**************************************************************************
    315 w89c840_reset - Reset adapter
    316 ***************************************************************************/
    317 static void w89c840_reset(struct nic *nic)
    318 {
    319     int i;
    320 
    321     /* Reset the chip to erase previous misconfiguration.
    322        No hold time required! */
    323     writel(0x00000001, ioaddr + PCIBusCfg);
    324 
    325     init_ring();
    326 
    327     writel(virt_to_bus(w840private.rx_ring), ioaddr + RxRingPtr);
    328     writel(virt_to_bus(w840private.tx_ring), ioaddr + TxRingPtr);
    329 
    330     for (i = 0; i < ETH_ALEN; i++)
    331         writeb(nic->node_addr[i], ioaddr + StationAddr + i);
    332 
    333     /* Initialize other registers. */
    334     /* Configure the PCI bus bursts and FIFO thresholds.
    335        486: Set 8 longword cache alignment, 8 longword burst.
    336        586: Set 16 longword cache alignment, no burst limit.
    337        Cache alignment bits 15:14         Burst length 13:8
    338         0000    <not allowed>         0000 align to cache    0800 8 longwords
    339         4000    8  longwords        0100 1 longword        1000 16 longwords
    340         8000    16 longwords        0200 2 longwords    2000 32 longwords
    341         C000    32  longwords        0400 4 longwords
    342        Wait the specified 50 PCI cycles after a reset by initializing
    343        Tx and Rx queues and the address filter list. */
    344 
    345     writel(0xE010, ioaddr + PCIBusCfg);
    346 
    347     writel(0, ioaddr + RxStartDemand);
    348     w840private.csr6 = 0x20022002;
    349     check_duplex();
    350     set_rx_mode();
    351 
    352     /* Clear and Enable interrupts by setting the interrupt mask. */
    353     writel(0x1A0F5, ioaddr + IntrStatus);
    354     writel(0x1A0F5, ioaddr + IntrEnable);
    355 
    356 #if defined(W89C840_DEBUG)
    357     printf("winbond-840 : Done reset.\n");
    358 #endif
    359 }
    360 
    361 static void handle_intr(u32 intr_stat)
    362 {
    363     if ((intr_stat & (NormalIntr|AbnormalIntr)) == 0) {
    364         /* we are polling, do not return now */
    365         /*return 0;*/
    366     } else {
    367         /* Acknowledge all of the current interrupt sources ASAP. */
    368         writel(intr_stat & 0x001ffff, ioaddr + IntrStatus);
    369     }
    370 
    371     if (intr_stat & AbnormalIntr) {
    372         /* There was an abnormal interrupt */
    373         printf("\n-=- Abnormal interrupt.\n");
    374 
    375 #if defined (W89C840_DEBUG)
    376         decode_interrupt(intr_stat);
    377 #endif
    378 
    379         if (intr_stat & RxNoBuf) {
    380             /* There was an interrupt */
    381             printf("-=- <=> No receive buffers available.\n");
    382             writel(0, ioaddr + RxStartDemand);
    383         }
    384     }
    385 }
    386 
    387 /**************************************************************************
    388 w89c840_poll - Wait for a frame
    389 ***************************************************************************/
    390 static int w89c840_poll(struct nic *nic)
    391 {
    392     /* return true if there's an ethernet packet ready to read */
    393     /* nic->packet should contain data on return */
    394     /* nic->packetlen should contain length of data */
    395     int packet_received = 0;
    396 
    397     u32 intr_status = readl(ioaddr + IntrStatus);
    398     /* handle_intr(intr_status); */ /* -- handled later */
    399 
    400     do {
    401         /* Code from netdev_rx(dev) */
    402 
    403         int entry = w840private.cur_rx % RX_RING_SIZE;
    404 
    405         struct w840_rx_desc *desc = w840private.rx_head_desc;
    406         s32 status = desc->status;
    407 
    408         if (status & DescOwn) {
    409             /* DescOwn bit is still set, we should wait for RX to complete */
    410             packet_received = 0;
    411             break;
    412         }
    413 
    414         if ((status & 0x38008300) != 0x0300) {
    415             if ((status & 0x38000300) != 0x0300) {
    416                 /* Ingore earlier buffers. */
    417                 if ((status & 0xffff) != 0x7fff) {
    418                     printf("winbond-840 : Oversized Ethernet frame spanned "
    419                            "multiple buffers, entry %d status %X !\n",
    420                            w840private.cur_rx, status);
    421                 }
    422             } else if (status & 0x8000) {
    423                 /* There was a fatal error. */
    424 #if defined(W89C840_DEBUG)
    425                 printf("winbond-840 : Receive error, Rx status %X :", status);
    426                 if (status & 0x0890) {
    427                     printf(" RXLEN_ERROR");
    428                 }
    429                 if (status & 0x004C) {
    430                     printf(", FRAME_ERROR");
    431                 }
    432                 if (status & 0x0002) {
    433                     printf(", CRC_ERROR");
    434                 }
    435                 printf("\n");
    436 #endif
    437 
    438                 /* Simpy do a reset now... */
    439                 w89c840_reset(nic);
    440 
    441                 packet_received = 0;
    442                 break;
    443             }
    444         } else {
    445             /* Omit the four octet CRC from the length. */
    446             int pkt_len = ((status >> 16) & 0x7ff) - 4;
    447 
    448 #if defined(W89C840_DEBUG)
    449             printf(" netdev_rx() normal Rx pkt ring %d length %d status %X\n", entry, pkt_len, status);
    450 #endif
    451 
    452             nic->packetlen = pkt_len;
    453 
    454             /* Check if the packet is long enough to accept without copying
    455                to a minimally-sized skbuff. */
    456 
    457             memcpy(nic->packet, le32desc_to_virt(w840private.rx_ring[entry].buffer1), pkt_len);
    458             packet_received = 1;
    459 
    460             /* Release buffer to NIC */
    461             w840private.rx_ring[entry].status = DescOwn;
    462 
    463 #if defined(W89C840_DEBUG)
    464             /* You will want this info for the initial debug. */
    465             printf("  Rx data %hhX:%hhX:%hhX:%hhX:%hhX:"
    466                    "%hhX %hhX:%hhX:%hhX:%hhX:%hhX:%hhX %hhX%hhX "
    467                    "%hhX.%hhX.%hhX.%hhX.\n",
    468                    nic->packet[0],  nic->packet[1],  nic->packet[2], nic->packet[3],
    469                    nic->packet[4],  nic->packet[5],  nic->packet[6], nic->packet[7],
    470                    nic->packet[8],  nic->packet[9],  nic->packet[10],
    471                    nic->packet[11], nic->packet[12], nic->packet[13],
    472                    nic->packet[14], nic->packet[15], nic->packet[16],
    473                    nic->packet[17]);
    474 #endif
    475 
    476         }
    477 
    478         entry = (++w840private.cur_rx) % RX_RING_SIZE;
    479         w840private.rx_head_desc = &w840private.rx_ring[entry];
    480     } while (0);
    481 
    482     if (intr_status & (AbnormalIntr | TxFIFOUnderflow | IntrPCIErr |TimerInt | IntrTxStopped)) {
    483         handle_intr(intr_status);
    484     }
    485 
    486     return packet_received;
    487 }
    488 
    489 /**************************************************************************
    490 w89c840_transmit - Transmit a frame
    491 ***************************************************************************/
    492 
    493 static void w89c840_transmit(
    494     struct nic *nic,
    495     const char *d,            /* Destination */
    496     unsigned int t,            /* Type */
    497     unsigned int s,            /* size */
    498     const char *p)            /* Packet */
    499 {
    500     /* send the packet to destination */
    501     unsigned entry;
    502     int transmit_status;
    503 
    504     /* Caution: the write order is important here, set the field
    505        with the "ownership" bits last. */
    506 
    507     /* Fill in our transmit buffer */
    508     entry = w840private.cur_tx % TX_RING_SIZE;
    509 
    510     memcpy (tx_packet, d, ETH_ALEN);    /* dst */
    511     memcpy (tx_packet + ETH_ALEN, nic->node_addr, ETH_ALEN);/* src */
    512 
    513     *((char *) tx_packet + 12) = t >> 8;    /* type */
    514     *((char *) tx_packet + 13) = t;
    515 
    516     memcpy (tx_packet + ETH_HLEN, p, s);
    517     s += ETH_HLEN;
    518 
    519     while (s < ETH_ZLEN)
    520     *((char *) tx_packet + ETH_HLEN + (s++)) = 0;
    521 
    522     w840private.tx_ring[entry].buffer1 = virt_to_le32desc(tx_packet);
    523 
    524     w840private.tx_ring[entry].length = (DescWholePkt | s);
    525     if (entry >= TX_RING_SIZE-1)         /* Wrap ring */
    526         w840private.tx_ring[entry].length |= (DescIntr | DescEndRing);
    527     w840private.tx_ring[entry].status = (DescOwn);
    528     w840private.cur_tx++;
    529 
    530     w840private.tx_q_bytes += s;
    531     writel(0, ioaddr + TxStartDemand);
    532 
    533     /* Work around horrible bug in the chip by marking the queue as full
    534        when we do not have FIFO room for a maximum sized packet. */
    535 
    536     if ((w840private.drv_flags & HasBrokenTx) && w840private.tx_q_bytes > TX_BUG_FIFO_LIMIT) {
    537         /* Actually this is left to help finding error tails later in debugging...
    538          * See Linux kernel driver in winbond-840.c for details.
    539          */
    540         w840private.tx_full = 1;
    541     }
    542 
    543 #if defined(W89C840_DEBUG)
    544     printf("winbond-840 : Transmit frame # %d size %d queued in slot %d.\n", w840private.cur_tx, s, entry);
    545 #endif
    546 
    547     /* Now wait for TX to complete. */
    548     transmit_status = w840private.tx_ring[entry].status;
    549 
    550     load_timer2(TX_TIMEOUT);
    551 
    552     {
    553         u32 intr_stat = 0;
    554 
    555         while (1) {
    556 
    557             intr_stat = readl(ioaddr + IntrStatus);
    558 #if defined(W89C840_DEBUG)
    559             decode_interrupt(intr_stat);
    560 #endif
    561 
    562             if (intr_stat & (NormalIntr | IntrTxDone)) {
    563 
    564                 while ( (transmit_status & DescOwn) && timer2_running()) {
    565 
    566                     transmit_status = w840private.tx_ring[entry].status;
    567                 }
    568 
    569                 writel(intr_stat & 0x0001ffff, ioaddr + IntrStatus);
    570                 break;
    571             }
    572         }
    573     }
    574 
    575     if ((transmit_status & DescOwn) == 0) {
    576 
    577 #if defined(W89C840_DEBUG)
    578         printf("winbond-840 : transmission complete after %d wait loop iterations, status %X\n",
    579                TX_LOOP_COUNT - transmit_loop_counter, w840private.tx_ring[entry].status);
    580 #endif
    581 
    582         return;
    583     }
    584 
    585     /* Transmit timed out... */
    586 
    587     printf("winbond-840 : transmission TIMEOUT : status %X\n", w840private.tx_ring[entry].status);
    588 
    589     return;
    590 }
    591 
    592 /**************************************************************************
    593 w89c840_disable - Turn off ethernet interface
    594 ***************************************************************************/
    595 static void w89c840_disable(struct nic *nic)
    596 {
    597     /* Don't know what to do to disable the board. Is this needed at all? */
    598     /* Yes, a live NIC can corrupt the loaded memory later [Ken] */
    599     /* Stop the chip's Tx and Rx processes. */
    600     writel(w840private.csr6 &= ~0x20FA, ioaddr + NetworkConfig);
    601 }
    602 
    603 /**************************************************************************
    604 w89c840_probe - Look for an adapter, this routine's visible to the outside
    605 ***************************************************************************/
    606 struct nic *w89c840_probe(struct nic *nic, unsigned short *probe_addrs, struct pci_device *p)
    607 {
    608     u16 sum = 0;
    609     int i, j, to;
    610     unsigned short value;
    611     int options;
    612     int promisc;
    613 
    614     if (probe_addrs == 0 || probe_addrs[0] == 0)
    615         return 0;
    616 
    617     ioaddr = probe_addrs[0]; /* Mask the bit that says "this is an io addr" */
    618 
    619 #if defined(W89C840_DEBUG)
    620     printf("winbond-840: PCI bus %hhX device function %hhX: I/O address: %hX\n", p->bus, p->devfn, ioaddr);
    621 #endif
    622 
    623     ioaddr = ioaddr & ~3; /* Mask the bit that says "this is an io addr" */
    624 
    625     /* if probe_addrs is 0, then routine can use a hardwired default */
    626 
    627     /* From Matt Hortman <mbhortman (at) acpthinclient.com> */
    628     if (p->vendor == PCI_VENDOR_ID_WINBOND2
    629         && p->dev_id == PCI_DEVICE_ID_WINBOND2_89C840) {
    630 
    631         /* detected "Winbond W89c840 Fast Ethernet PCI NIC" */
    632 
    633     } else if ( p->vendor == PCI_VENDOR_ID_COMPEX
    634                 && p->dev_id == PCI_DEVICE_ID_COMPEX_RL100ATX) {
    635 
    636         /* detected "Compex RL100ATX Fast Ethernet PCI NIC" */
    637 
    638     } else {
    639         /* Gee, guess what? They missed again. */
    640         printf("device ID : %X - is not a Compex RL100ATX NIC.\n", p->dev_id);
    641         return 0;
    642     }
    643 
    644     printf(" %s\n", w89c840_version);
    645 
    646     adjust_pci_device(p);
    647 
    648     /* Ok. Got one. Read the eeprom. */
    649     for (j = 0, i = 0; i < 0x40; i++) {
    650         value = eeprom_read(ioaddr, i);
    651         eeprom[i] = value;
    652         sum += value;
    653     }
    654 
    655     for (i=0;i<ETH_ALEN;i++) {
    656         nic->node_addr[i] =  (eeprom[i/2] >> (8*(i&1))) & 0xff;
    657     }
    658     printf ("Ethernet addr: %!\n", nic->node_addr);
    659 
    660 #if defined(W89C840_DEBUG)
    661     printf("winbond-840: EEPROM checksum %hX, got eeprom", sum);
    662 #endif
    663 
    664     /* Reset the chip to erase previous misconfiguration.
    665        No hold time required! */
    666     writel(0x00000001, ioaddr + PCIBusCfg);
    667 
    668     if (driver_flags & CanHaveMII) {
    669         int phy, phy_idx = 0;
    670         for (phy = 1; phy < 32 && phy_idx < 4; phy++) {
    671             int mii_status = mdio_read(ioaddr, phy, 1);
    672             if (mii_status != 0xffff  &&  mii_status != 0x0000) {
    673                 w840private.phys[phy_idx++] = phy;
    674                 w840private.advertising = mdio_read(ioaddr, phy, 4);
    675 
    676 #if defined(W89C840_DEBUG)
    677                 printf("winbond-840 : MII PHY found at address %d, status "
    678                        "%X advertising %hX.\n", phy, mii_status, w840private.advertising);
    679 #endif
    680 
    681             }
    682         }
    683 
    684         w840private.mii_cnt = phy_idx;
    685 
    686         if (phy_idx == 0) {
    687                 printf("winbond-840 : MII PHY not found -- this device may not operate correctly.\n");
    688         }
    689     }
    690 
    691     /* point to NIC specific routines */
    692     nic->reset = w89c840_reset;
    693     nic->poll = w89c840_poll;
    694     nic->transmit = w89c840_transmit;
    695     nic->disable = w89c840_disable;
    696 
    697     w89c840_reset(nic);
    698 
    699     return nic;
    700 }
    701 
    702 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.  These are
    703    often serial bit streams generated by the host processor.
    704    The example below is for the common 93c46 EEPROM, 64 16 bit words. */
    705 
    706 /* Delay between EEPROM clock transitions.
    707    No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
    708    a delay.  Note that pre-2.0.34 kernels had a cache-alignment bug that
    709    made udelay() unreliable.
    710    The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
    711    depricated.
    712 */
    713 #define eeprom_delay(ee_addr)    readl(ee_addr)
    714 
    715 enum EEPROM_Ctrl_Bits {
    716     EE_ShiftClk=0x02, EE_Write0=0x801, EE_Write1=0x805,
    717     EE_ChipSelect=0x801, EE_DataIn=0x08,
    718 };
    719 
    720 /* The EEPROM commands include the alway-set leading bit. */
    721 enum EEPROM_Cmds {
    722     EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
    723 };
    724 
    725 static int eeprom_read(long addr, int location)
    726 {
    727     int i;
    728     int retval = 0;
    729     int ee_addr = addr + EECtrl;
    730     int read_cmd = location | EE_ReadCmd;
    731     writel(EE_ChipSelect, ee_addr);
    732 
    733     /* Shift the read command bits out. */
    734     for (i = 10; i >= 0; i--) {
    735         short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
    736         writel(dataval, ee_addr);
    737         eeprom_delay(ee_addr);
    738         writel(dataval | EE_ShiftClk, ee_addr);
    739         eeprom_delay(ee_addr);
    740     }
    741     writel(EE_ChipSelect, ee_addr);
    742 
    743     for (i = 16; i > 0; i--) {
    744         writel(EE_ChipSelect | EE_ShiftClk, ee_addr);
    745         eeprom_delay(ee_addr);
    746         retval = (retval << 1) | ((readl(ee_addr) & EE_DataIn) ? 1 : 0);
    747         writel(EE_ChipSelect, ee_addr);
    748         eeprom_delay(ee_addr);
    749     }
    750 
    751     /* Terminate the EEPROM access. */
    752     writel(0, ee_addr);
    753     return retval;
    754 }
    755 
    756 /*  MII transceiver control section.
    757     Read and write the MII registers using software-generated serial
    758     MDIO protocol.  See the MII specifications or DP83840A data sheet
    759     for details.
    760 
    761     The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
    762     met by back-to-back 33Mhz PCI cycles. */
    763 #define mdio_delay(mdio_addr) readl(mdio_addr)
    764 
    765 /* Set iff a MII transceiver on any interface requires mdio preamble.
    766    This only set with older tranceivers, so the extra
    767    code size of a per-interface flag is not worthwhile. */
    768 static char mii_preamble_required = 1;
    769 
    770 #define MDIO_WRITE0 (MDIO_EnbOutput)
    771 #define MDIO_WRITE1 (MDIO_DataOut | MDIO_EnbOutput)
    772 
    773 /* Generate the preamble required for initial synchronization and
    774    a few older transceivers. */
    775 static void mdio_sync(long mdio_addr)
    776 {
    777     int bits = 32;
    778 
    779     /* Establish sync by sending at least 32 logic ones. */
    780     while (--bits >= 0) {
    781         writel(MDIO_WRITE1, mdio_addr);
    782         mdio_delay(mdio_addr);
    783         writel(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
    784         mdio_delay(mdio_addr);
    785     }
    786 }
    787 
    788 static int mdio_read(int base_address, int phy_id, int location)
    789 {
    790     long mdio_addr = base_address + MIICtrl;
    791     int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
    792     int i, retval = 0;
    793 
    794     if (mii_preamble_required)
    795         mdio_sync(mdio_addr);
    796 
    797     /* Shift the read command bits out. */
    798     for (i = 15; i >= 0; i--) {
    799         int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
    800 
    801         writel(dataval, mdio_addr);
    802         mdio_delay(mdio_addr);
    803         writel(dataval | MDIO_ShiftClk, mdio_addr);
    804         mdio_delay(mdio_addr);
    805     }
    806     /* Read the two transition, 16 data, and wire-idle bits. */
    807     for (i = 20; i > 0; i--) {
    808         writel(MDIO_EnbIn, mdio_addr);
    809         mdio_delay(mdio_addr);
    810         retval = (retval << 1) | ((readl(mdio_addr) & MDIO_DataIn) ? 1 : 0);
    811         writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
    812         mdio_delay(mdio_addr);
    813     }
    814     return (retval>>1) & 0xffff;
    815 }
    816 
    817 static void mdio_write(int base_address, int phy_id, int location, int value)
    818 {
    819     long mdio_addr = base_address + MIICtrl;
    820     int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
    821     int i;
    822 
    823     if (location == 4  &&  phy_id == w840private.phys[0])
    824         w840private.advertising = value;
    825 
    826     if (mii_preamble_required)
    827         mdio_sync(mdio_addr);
    828 
    829     /* Shift the command bits out. */
    830     for (i = 31; i >= 0; i--) {
    831         int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
    832 
    833         writel(dataval, mdio_addr);
    834         mdio_delay(mdio_addr);
    835         writel(dataval | MDIO_ShiftClk, mdio_addr);
    836         mdio_delay(mdio_addr);
    837     }
    838     /* Clear out extra bits. */
    839     for (i = 2; i > 0; i--) {
    840         writel(MDIO_EnbIn, mdio_addr);
    841         mdio_delay(mdio_addr);
    842         writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
    843         mdio_delay(mdio_addr);
    844     }
    845     return;
    846 }
    847 
    848 static void check_duplex(void)
    849 {
    850     int mii_reg5 = mdio_read(ioaddr, w840private.phys[0], 5);
    851     int negotiated =  mii_reg5 & w840private.advertising;
    852     int duplex;
    853 
    854     if (w840private.duplex_lock  ||  mii_reg5 == 0xffff)
    855         return;
    856 
    857     duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
    858     if (w840private.full_duplex != duplex) {
    859         w840private.full_duplex = duplex;
    860 
    861 #if defined(W89C840_DEBUG)
    862         printf("winbond-840 : Setting %s-duplex based on MII # %d negotiated capability %X\n",
    863                duplex ? "full" : "half", w840private.phys[0], negotiated);
    864 #endif
    865 
    866         w840private.csr6 &= ~0x200;
    867         w840private.csr6 |= duplex ? 0x200 : 0;
    868     }
    869 }
    870 
    871 static void set_rx_mode(void)
    872 {
    873     u32 mc_filter[2];            /* Multicast hash filter */
    874     u32 rx_mode;
    875 
    876     /* Accept all multicasts from now on. */
    877     memset(mc_filter, 0xff, sizeof(mc_filter));
    878 
    879 /*
    880  * Actually, should work OK with multicast enabled. -- iko
    881  */
    882 /*
    883  *  rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast;
    884  */
    885     rx_mode = AcceptBroadcast | AcceptMyPhys;
    886 
    887     writel(mc_filter[0], ioaddr + MulticastFilter0);
    888     writel(mc_filter[1], ioaddr + MulticastFilter1);
    889     w840private.csr6 &= ~0x00F8;
    890     w840private.csr6 |= rx_mode;
    891     writel(w840private.csr6, ioaddr + NetworkConfig);
    892 
    893 #if defined(W89C840_DEBUG)
    894     printf("winbond-840 : Done setting RX mode.\n");
    895 #endif
    896 }
    897 
    898 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
    899 static void init_ring(void)
    900 {
    901     int i;
    902     char * p;
    903 
    904     w840private.tx_full = 0;
    905     w840private.tx_q_bytes = w840private.cur_rx = w840private.cur_tx = 0;
    906     w840private.dirty_rx = w840private.dirty_tx = 0;
    907 
    908     w840private.rx_buf_sz = PKT_BUF_SZ;
    909     w840private.rx_head_desc = &w840private.rx_ring[0];
    910 
    911     /* Initial all Rx descriptors. Fill in the Rx buffers. */
    912 
    913     p = &rx_packet[0];
    914 
    915     for (i = 0; i < RX_RING_SIZE; i++) {
    916         w840private.rx_ring[i].length = w840private.rx_buf_sz;
    917         w840private.rx_ring[i].status = 0;
    918         w840private.rx_ring[i].next_desc = virt_to_le32desc(&w840private.rx_ring[i+1]);
    919 
    920         w840private.rx_ring[i].buffer1 = virt_to_le32desc(p + (PKT_BUF_SZ * i));
    921         w840private.rx_ring[i].status = DescOwn | DescIntr;
    922     }
    923 
    924     /* Mark the last entry as wrapping the ring. */
    925     w840private.rx_ring[i-1].length |= DescEndRing;
    926     w840private.rx_ring[i-1].next_desc = virt_to_le32desc(&w840private.rx_ring[0]);
    927 
    928     w840private.dirty_rx = (unsigned int)(i - RX_RING_SIZE);
    929 
    930     for (i = 0; i < TX_RING_SIZE; i++) {
    931         w840private.tx_ring[i].status = 0;
    932     }
    933     return;
    934 }
    935