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