|
|
1.1 root 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: * -- <[email protected]>
11: * OR
12: * -- <[email protected]>
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 <ipxe/pci.h>
85: #include <ipxe/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)
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: ***************************************************************************/
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: ***************************************************************************/
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:
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: ***************************************************************************/
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: ***************************************************************************/
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: ***************************************************************************/
624: static int w89c840_probe ( struct nic *nic, struct pci_device *p ) {
625:
626:
627: u16 sum = 0;
628: int i;
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 <[email protected]> */
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 (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:
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. */
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:
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:
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:
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. */
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: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.