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