• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 FILE_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 
87 static 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 
133 enum 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 
141 static 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 */
168 enum 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. */
180 enum 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. */
189 enum rx_mode_bits {
190     AcceptErr=0x80, AcceptRunt=0x40,
191     AcceptBroadcast=0x20, AcceptMulticast=0x10,
192     AcceptAllPhys=0x08, AcceptMyPhys=0x02,
193 };
194 
195 enum 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. */
201 struct w840_rx_desc {
202     s32 status;
203     s32 length;
204     u32 buffer1;
205     u32 next_desc;
206 };
207 
208 struct 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 */
215 enum 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 
223 static 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 
254 static int ioaddr;
255 static unsigned short eeprom [0x40];
256 struct {
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 
261 static int  eeprom_read(long ioaddr, int location);
262 static int  mdio_read(int base_address, int phy_id, int location);
263 #if 0
264 static void mdio_write(int base_address, int phy_id, int location, int value);
265 #endif
266 
267 static void check_duplex(void);
268 static void set_rx_mode(void);
269 static void init_ring(void);
270 
271 #if defined(W89C840_DEBUG)
decode_interrupt(u32 intr_status)272 static 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 /**************************************************************************
298 w89c840_reset - Reset adapter
299 ***************************************************************************/
w89c840_reset(struct nic * nic)300 static 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
346 static 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 /**************************************************************************
374 w89c840_poll - Wait for a frame
375 ***************************************************************************/
w89c840_poll(struct nic * nic,int retrieve)376 static 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 /**************************************************************************
478 w89c840_transmit - Transmit a frame
479 ***************************************************************************/
480 
w89c840_transmit(struct nic * nic,const char * d,unsigned int t,unsigned int s,const char * p)481 static 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 /**************************************************************************
579 w89c840_disable - Turn off ethernet interface
580 ***************************************************************************/
w89c840_disable(struct nic * nic)581 static 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 /**************************************************************************
592 w89c840_irq - Enable, Disable, or Force interrupts
593 ***************************************************************************/
w89c840_irq(struct nic * nic __unused,irq_action_t action __unused)594 static 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 
606 static struct nic_operations w89c840_operations = {
607 	.connect	= dummy_connect,
608 	.poll		= w89c840_poll,
609 	.transmit	= w89c840_transmit,
610 	.irq		= w89c840_irq,
611 
612 };
613 
614 static struct pci_device_id w89c840_nics[] = {
615 PCI_ROM(0x1050, 0x0840, "winbond840",     "Winbond W89C840F", 0),
616 PCI_ROM(0x11f6, 0x2011, "compexrl100atx", "Compex RL100ATX", 0),
617 };
618 
619 PCI_DRIVER ( w89c840_driver, w89c840_nics, PCI_NO_CLASS );
620 
621 /**************************************************************************
622 w89c840_probe - Look for an adapter, this routine's visible to the outside
623 ***************************************************************************/
w89c840_probe(struct nic * nic,struct pci_device * p)624 static 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 
733 enum 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. */
739 enum EEPROM_Cmds {
740     EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
741 };
742 
eeprom_read(long addr,int location)743 static 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. */
786 static 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. */
mdio_sync(long mdio_addr)793 static 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 
mdio_read(int base_address,int phy_id,int location)806 static 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
836 static 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 
check_duplex(void)868 static 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 
set_rx_mode(void)891 static 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. */
init_ring(void)917 static 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 
955 DRIVER ( "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