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