2 * Etherboot - BOOTP/TFTP Bootstrap Program
4 * w89c840.c -- This file implements the winbond-840 driver for etherboot.
9 * Adapted by Igor V. Kovalenko
10 * -- <garrison@mail.ru>
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
38 * Aug 26 2000 V0.92 iko Fixed Rx ring handling.
39 * First Linux Kernel (TM)
40 * successfully loaded using
42 * Jan 07 2001 V0.93 iko Transmitter timeouts are handled
43 * using timer2 routines. Proposed
44 * by Ken Yap to eliminate CPU speed
46 * Dec 12 2003 V0.94 timlegge Fixed issues in 5.2, removed
47 * interrupt usage, enabled
50 * This is the etherboot driver for cards based on Winbond W89c840F chip.
52 * It was written from skeleton source, with Donald Becker's winbond-840.c
53 * kernel driver as a guideline. Mostly the w89c840 related definitions
54 * and the lower level routines have been cut-and-pasted into this source.
56 * Frankly speaking, about 90% of the code was obtained using cut'n'paste
57 * sequence :) while the remainder appeared while brainstorming
58 * Linux Kernel 2.4.0-testX source code. Thanks, Donald and Linus!
60 * There was a demand for using this card in a rather large
61 * remote boot environment at MSKP OVTI Lab of
62 * Moscow Institute for Physics and Technology (MIPT) -- http://www.mipt.ru/
63 * so you may count that for motivation.
68 * If you want to see debugging output then define W89C840_DEBUG
76 * Keep using IO_OPS for Etherboot driver!
80 #include "etherboot.h"
83 #include <gpxe/ethernet.h>
85 static const char *w89c840_version = "driver Version 0.94 - December 12, 2003";
87 /* Linux support functions */
88 #define virt_to_le32desc(addr) virt_to_bus(addr)
89 #define le32desc_to_virt(addr) bus_to_virt(addr)
92 #define cpu_to_le32(val) (val)
93 #define le32_to_cpu(val) (val)
96 /* Operational parameters that are set at compile time. */
98 /* Keep the ring sizes a power of two for compile efficiency.
99 The compiler will convert <unsigned>'%'<2^N> into a bit mask.
100 Making the Tx ring too large decreases the effectiveness of channel
101 bonding and packet priority.
102 There are no ill effects from too-large receive rings. */
103 #define TX_RING_SIZE 2
104 #define RX_RING_SIZE 2
106 /* The presumed FIFO size for working around the Tx-FIFO-overflow bug.
107 To avoid overflowing we don't queue again until we have room for a
110 #define TX_FIFO_SIZE (2048)
111 #define TX_BUG_FIFO_LIMIT (TX_FIFO_SIZE-1514-16)
113 /* Operational parameters that usually are not changed. */
114 /* Time in jiffies before concluding the transmitter is hung. */
115 #define TX_TIMEOUT (10*1000)
117 #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
120 * Used to be this much CPU loops on Celeron@400 (?),
121 * now using real timer and TX_TIMEOUT!
122 * #define TX_LOOP_COUNT 10000000
125 #if !defined(__OPTIMIZE__)
126 #warning You must compile this file with the correct options!
127 #warning See the last lines of the source file.
128 #error You must compile this driver with "-O".
131 enum chip_capability_flags {CanHaveMII=1, HasBrokenTx=2};
134 #define W840_FLAGS (PCI_USES_IO | PCI_ADDR0 | PCI_USES_MASTER)
136 #define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER)
139 static u32 driver_flags = CanHaveMII | HasBrokenTx;
141 /* This driver was written to use PCI memory space, however some x86 systems
142 work only with I/O space accesses. Pass -DUSE_IO_OPS to use PCI I/O space
143 accesses instead of memory space. */
160 /* Offsets to the Command and Status Registers, "CSRs".
161 While similar to the Tulip, these registers are longword aligned.
162 Note: It's not useful to define symbolic names for every register bit in
163 the device. The name can only partially document the semantics and make
164 the driver longer and more difficult to read.
167 PCIBusCfg=0x00, TxStartDemand=0x04, RxStartDemand=0x08,
168 RxRingPtr=0x0C, TxRingPtr=0x10,
169 IntrStatus=0x14, NetworkConfig=0x18, IntrEnable=0x1C,
170 RxMissed=0x20, EECtrl=0x24, MIICtrl=0x24, BootRom=0x28, GPTimer=0x2C,
171 CurRxDescAddr=0x30, CurRxBufAddr=0x34, /* Debug use */
172 MulticastFilter0=0x38, MulticastFilter1=0x3C, StationAddr=0x40,
173 CurTxDescAddr=0x4C, CurTxBufAddr=0x50,
176 /* Bits in the interrupt status/enable registers. */
177 /* The bits in the Intr Status/Enable registers, mostly interrupt sources. */
178 enum intr_status_bits {
179 NormalIntr=0x10000, AbnormalIntr=0x8000,
180 IntrPCIErr=0x2000, TimerInt=0x800,
181 IntrRxDied=0x100, RxNoBuf=0x80, IntrRxDone=0x40,
182 TxFIFOUnderflow=0x20, RxErrIntr=0x10,
183 TxIdle=0x04, IntrTxStopped=0x02, IntrTxDone=0x01,
186 /* Bits in the NetworkConfig register. */
188 AcceptErr=0x80, AcceptRunt=0x40,
189 AcceptBroadcast=0x20, AcceptMulticast=0x10,
190 AcceptAllPhys=0x08, AcceptMyPhys=0x02,
194 MDIO_ShiftClk=0x10000, MDIO_DataIn=0x80000, MDIO_DataOut=0x20000,
195 MDIO_EnbOutput=0x40000, MDIO_EnbIn = 0x00000,
198 /* The Tulip Rx and Tx buffer descriptors. */
199 struct w840_rx_desc {
206 struct w840_tx_desc {
209 u32 buffer1, buffer2; /* We use only buffer 1. */
212 /* Bits in network_desc.status */
213 enum desc_status_bits {
214 DescOwn=0x80000000, DescEndRing=0x02000000, DescUseLink=0x01000000,
215 DescWholePkt=0x60000000, DescStartPkt=0x20000000, DescEndPkt=0x40000000,
218 #define PRIV_ALIGN 15 /* Required alignment mask */
219 #define PRIV_ALIGN_BYTES 32
221 static struct winbond_private
223 /* Descriptor rings first for alignment. */
224 struct w840_rx_desc rx_ring[RX_RING_SIZE];
225 struct w840_tx_desc tx_ring[TX_RING_SIZE];
226 struct net_device *next_module; /* Link for devices of this type. */
227 void *priv_addr; /* Unaligned address for kfree */
228 const char *product_name;
229 /* Frequently used values: keep some adjacent for cache effect. */
230 int chip_id, drv_flags;
231 struct pci_dev *pci_dev;
233 struct w840_rx_desc *rx_head_desc;
234 unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */
235 unsigned int rx_buf_sz; /* Based on MTU+slack. */
236 unsigned int cur_tx, dirty_tx;
238 unsigned int tx_full:1; /* The Tx queue is full. */
239 /* These values are keep track of the transceiver/media in use. */
240 unsigned int full_duplex:1; /* Full-duplex operation requested. */
241 unsigned int duplex_lock:1;
242 unsigned int medialock:1; /* Do not sense media. */
243 unsigned int default_port:4; /* Last dev->if_port value. */
244 /* MII transceiver section. */
245 int mii_cnt; /* MII device addresses. */
246 u16 advertising; /* NWay media advertisement */
247 unsigned char phys[2]; /* MII device addresses. */
248 } w840private __attribute__ ((aligned (PRIV_ALIGN_BYTES)));
250 /* NIC specific static variables go here */
253 static unsigned short eeprom [0x40];
255 char rx_packet[PKT_BUF_SZ * RX_RING_SIZE];
256 char tx_packet[PKT_BUF_SZ * TX_RING_SIZE];
257 } w89c840_buf __shared;
259 static int eeprom_read(long ioaddr, int location);
260 static int mdio_read(int base_address, int phy_id, int location);
262 static void mdio_write(int base_address, int phy_id, int location, int value);
265 static void check_duplex(void);
266 static void set_rx_mode(void);
267 static void init_ring(void);
269 #if defined(W89C840_DEBUG)
270 static void decode_interrupt(u32 intr_status)
272 printf("Interrupt status: ");
274 #define TRACE_INTR(_intr_) \
275 if (intr_status & (_intr_)) { printf (" " #_intr_); }
277 TRACE_INTR(NormalIntr);
278 TRACE_INTR(AbnormalIntr);
279 TRACE_INTR(IntrPCIErr);
280 TRACE_INTR(TimerInt);
281 TRACE_INTR(IntrRxDied);
283 TRACE_INTR(IntrRxDone);
284 TRACE_INTR(TxFIFOUnderflow);
285 TRACE_INTR(RxErrIntr);
287 TRACE_INTR(IntrTxStopped);
288 TRACE_INTR(IntrTxDone);
295 /**************************************************************************
296 w89c840_reset - Reset adapter
297 ***************************************************************************/
298 static void w89c840_reset(struct nic *nic)
302 /* Reset the chip to erase previous misconfiguration.
303 No hold time required! */
304 writel(0x00000001, ioaddr + PCIBusCfg);
308 writel(virt_to_bus(w840private.rx_ring), ioaddr + RxRingPtr);
309 writel(virt_to_bus(w840private.tx_ring), ioaddr + TxRingPtr);
311 for (i = 0; i < ETH_ALEN; i++)
312 writeb(nic->node_addr[i], ioaddr + StationAddr + i);
314 /* Initialize other registers. */
315 /* Configure the PCI bus bursts and FIFO thresholds.
316 486: Set 8 longword cache alignment, 8 longword burst.
317 586: Set 16 longword cache alignment, no burst limit.
318 Cache alignment bits 15:14 Burst length 13:8
319 0000 <not allowed> 0000 align to cache 0800 8 longwords
320 4000 8 longwords 0100 1 longword 1000 16 longwords
321 8000 16 longwords 0200 2 longwords 2000 32 longwords
322 C000 32 longwords 0400 4 longwords
323 Wait the specified 50 PCI cycles after a reset by initializing
324 Tx and Rx queues and the address filter list. */
326 writel(0xE010, ioaddr + PCIBusCfg);
328 writel(0, ioaddr + RxStartDemand);
329 w840private.csr6 = 0x20022002;
333 /* Do not enable the interrupts Etherboot doesn't need them */
335 writel(0x1A0F5, ioaddr + IntrStatus);
336 writel(0x1A0F5, ioaddr + IntrEnable);
338 #if defined(W89C840_DEBUG)
339 printf("winbond-840 : Done reset.\n");
344 static void handle_intr(u32 intr_stat)
346 if ((intr_stat & (NormalIntr|AbnormalIntr)) == 0) {
347 /* we are polling, do not return now */
350 /* Acknowledge all of the current interrupt sources ASAP. */
351 writel(intr_stat & 0x001ffff, ioaddr + IntrStatus);
354 if (intr_stat & AbnormalIntr) {
355 /* There was an abnormal interrupt */
356 printf("\n-=- Abnormal interrupt.\n");
358 #if defined(W89C840_DEBUG)
359 decode_interrupt(intr_stat);
362 if (intr_stat & RxNoBuf) {
363 /* There was an interrupt */
364 printf("-=- <=> No receive buffers available.\n");
365 writel(0, ioaddr + RxStartDemand);
371 /**************************************************************************
372 w89c840_poll - Wait for a frame
373 ***************************************************************************/
374 static int w89c840_poll(struct nic *nic, int retrieve)
376 /* return true if there's an ethernet packet ready to read */
377 /* nic->packet should contain data on return */
378 /* nic->packetlen should contain length of data */
379 int packet_received = 0;
381 #if defined(W89C840_DEBUG)
382 u32 intr_status = readl(ioaddr + IntrStatus);
386 /* Code from netdev_rx(dev) */
388 int entry = w840private.cur_rx % RX_RING_SIZE;
390 struct w840_rx_desc *desc = w840private.rx_head_desc;
391 s32 status = desc->status;
393 if (status & DescOwn) {
394 /* DescOwn bit is still set, we should wait for RX to complete */
404 if ((status & 0x38008300) != 0x0300) {
405 if ((status & 0x38000300) != 0x0300) {
406 /* Ingore earlier buffers. */
407 if ((status & 0xffff) != 0x7fff) {
408 printf("winbond-840 : Oversized Ethernet frame spanned "
409 "multiple buffers, entry %d status %X !\n",
410 w840private.cur_rx, (unsigned int) status);
412 } else if (status & 0x8000) {
413 /* There was a fatal error. */
414 #if defined(W89C840_DEBUG)
415 printf("winbond-840 : Receive error, Rx status %X :", status);
416 if (status & 0x0890) {
417 printf(" RXLEN_ERROR");
419 if (status & 0x004C) {
420 printf(", FRAME_ERROR");
422 if (status & 0x0002) {
423 printf(", CRC_ERROR");
428 /* Simpy do a reset now... */
435 /* Omit the four octet CRC from the length. */
436 int pkt_len = ((status >> 16) & 0x7ff) - 4;
438 #if defined(W89C840_DEBUG)
439 printf(" netdev_rx() normal Rx pkt ring %d length %d status %X\n", entry, pkt_len, status);
442 nic->packetlen = pkt_len;
444 /* Check if the packet is long enough to accept without copying
445 to a minimally-sized skbuff. */
447 memcpy(nic->packet, le32desc_to_virt(w840private.rx_ring[entry].buffer1), pkt_len);
450 /* Release buffer to NIC */
451 w840private.rx_ring[entry].status = DescOwn;
453 #if defined(W89C840_DEBUG)
454 /* You will want this info for the initial debug. */
455 printf(" Rx data %hhX:%hhX:%hhX:%hhX:%hhX:"
456 "%hhX %hhX:%hhX:%hhX:%hhX:%hhX:%hhX %hhX%hhX "
457 "%hhX.%hhX.%hhX.%hhX.\n",
458 nic->packet[0], nic->packet[1], nic->packet[2], nic->packet[3],
459 nic->packet[4], nic->packet[5], nic->packet[6], nic->packet[7],
460 nic->packet[8], nic->packet[9], nic->packet[10],
461 nic->packet[11], nic->packet[12], nic->packet[13],
462 nic->packet[14], nic->packet[15], nic->packet[16],
468 entry = (++w840private.cur_rx) % RX_RING_SIZE;
469 w840private.rx_head_desc = &w840private.rx_ring[entry];
472 return packet_received;
475 /**************************************************************************
476 w89c840_transmit - Transmit a frame
477 ***************************************************************************/
479 static void w89c840_transmit(
481 const char *d, /* Destination */
482 unsigned int t, /* Type */
483 unsigned int s, /* size */
484 const char *p) /* Packet */
486 /* send the packet to destination */
491 /* Caution: the write order is important here, set the field
492 with the "ownership" bits last. */
494 /* Fill in our transmit buffer */
495 entry = w840private.cur_tx % TX_RING_SIZE;
497 memcpy (w89c840_buf.tx_packet, d, ETH_ALEN); /* dst */
498 memcpy (w89c840_buf.tx_packet + ETH_ALEN, nic->node_addr, ETH_ALEN);/*src*/
500 *((char *) w89c840_buf.tx_packet + 12) = t >> 8; /* type */
501 *((char *) w89c840_buf.tx_packet + 13) = t;
503 memcpy (w89c840_buf.tx_packet + ETH_HLEN, p, s);
507 *((char *) w89c840_buf.tx_packet + ETH_HLEN + (s++)) = 0;
509 w840private.tx_ring[entry].buffer1
510 = virt_to_le32desc(w89c840_buf.tx_packet);
512 w840private.tx_ring[entry].length = (DescWholePkt | (u32) s);
513 if (entry >= TX_RING_SIZE-1) /* Wrap ring */
514 w840private.tx_ring[entry].length |= (DescIntr | DescEndRing);
515 w840private.tx_ring[entry].status = (DescOwn);
516 w840private.cur_tx++;
518 w840private.tx_q_bytes = (u16) s;
519 writel(0, ioaddr + TxStartDemand);
521 /* Work around horrible bug in the chip by marking the queue as full
522 when we do not have FIFO room for a maximum sized packet. */
524 if ((w840private.drv_flags & HasBrokenTx) && w840private.tx_q_bytes > TX_BUG_FIFO_LIMIT) {
525 /* Actually this is left to help finding error tails later in debugging...
526 * See Linux kernel driver in winbond-840.c for details.
528 w840private.tx_full = 1;
531 #if defined(W89C840_DEBUG)
532 printf("winbond-840 : Transmit frame # %d size %d queued in slot %d.\n", w840private.cur_tx, s, entry);
535 /* Now wait for TX to complete. */
536 transmit_status = w840private.tx_ring[entry].status;
540 #if defined W89C840_DEBUG
545 #if defined(W89C840_DEBUG)
546 decode_interrupt(intr_stat);
549 while ( (transmit_status & DescOwn) && ct + TX_TIMEOUT < currticks()) {
551 transmit_status = w840private.tx_ring[entry].status;
558 if ((transmit_status & DescOwn) == 0) {
560 #if defined(W89C840_DEBUG)
561 printf("winbond-840 : transmission complete after wait loop iterations, status %X\n",
562 w840private.tx_ring[entry].status);
568 /* Transmit timed out... */
570 printf("winbond-840 : transmission TIMEOUT : status %X\n",
571 (unsigned int) w840private.tx_ring[entry].status);
576 /**************************************************************************
577 w89c840_disable - Turn off ethernet interface
578 ***************************************************************************/
579 static void w89c840_disable ( struct nic *nic ) {
583 /* Don't know what to do to disable the board. Is this needed at all? */
584 /* Yes, a live NIC can corrupt the loaded memory later [Ken] */
585 /* Stop the chip's Tx and Rx processes. */
586 writel(w840private.csr6 &= ~0x20FA, ioaddr + NetworkConfig);
589 /**************************************************************************
590 w89c840_irq - Enable, Disable, or Force interrupts
591 ***************************************************************************/
592 static void w89c840_irq(struct nic *nic __unused, irq_action_t action __unused)
604 static struct nic_operations w89c840_operations = {
605 .connect = dummy_connect,
606 .poll = w89c840_poll,
607 .transmit = w89c840_transmit,
612 static struct pci_device_id w89c840_nics[] = {
613 PCI_ROM(0x1050, 0x0840, "winbond840", "Winbond W89C840F"),
614 PCI_ROM(0x11f6, 0x2011, "compexrl100atx", "Compex RL100ATX"),
617 PCI_DRIVER ( w89c840_driver, w89c840_nics, PCI_NO_CLASS );
619 /**************************************************************************
620 w89c840_probe - Look for an adapter, this routine's visible to the outside
621 ***************************************************************************/
622 static int w89c840_probe ( struct nic *nic, struct pci_device *p ) {
627 unsigned short value;
632 nic->ioaddr = p->ioaddr;
635 #if defined(W89C840_DEBUG)
636 printf("winbond-840: PCI bus %hhX device function %hhX: I/O address: %hX\n", p->bus, p->devfn, ioaddr);
639 ioaddr = ioaddr & ~3; /* Mask the bit that says "this is an io addr" */
641 #define PCI_DEVICE_ID_WINBOND2_89C840 0x0840
642 #define PCI_DEVICE_ID_COMPEX_RL100ATX 0x2011
644 /* From Matt Hortman <mbhortman@acpthinclient.com> */
645 if (p->vendor == PCI_VENDOR_ID_WINBOND2
646 && p->device == PCI_DEVICE_ID_WINBOND2_89C840) {
648 /* detected "Winbond W89c840 Fast Ethernet PCI NIC" */
650 } else if ( p->vendor == PCI_VENDOR_ID_COMPEX
651 && p->device == PCI_DEVICE_ID_COMPEX_RL100ATX) {
653 /* detected "Compex RL100ATX Fast Ethernet PCI NIC" */
656 /* Gee, guess what? They missed again. */
657 printf("device ID : %X - is not a Compex RL100ATX NIC.\n",
662 printf(" %s\n", w89c840_version);
664 adjust_pci_device(p);
666 /* Ok. Got one. Read the eeprom. */
667 for (j = 0, i = 0; i < 0x40; i++) {
668 value = eeprom_read(ioaddr, i);
673 for (i=0;i<ETH_ALEN;i++) {
674 nic->node_addr[i] = (eeprom[i/2] >> (8*(i&1))) & 0xff;
677 DBG ( "Ethernet addr: %s\n", eth_ntoa ( nic->node_addr ) );
679 #if defined(W89C840_DEBUG)
680 printf("winbond-840: EEPROM checksum %hX, got eeprom", sum);
683 /* Reset the chip to erase previous misconfiguration.
684 No hold time required! */
685 writel(0x00000001, ioaddr + PCIBusCfg);
687 if (driver_flags & CanHaveMII) {
688 int phy, phy_idx = 0;
689 for (phy = 1; phy < 32 && phy_idx < 4; phy++) {
690 int mii_status = mdio_read(ioaddr, phy, 1);
691 if (mii_status != 0xffff && mii_status != 0x0000) {
692 w840private.phys[phy_idx++] = phy;
693 w840private.advertising = mdio_read(ioaddr, phy, 4);
695 #if defined(W89C840_DEBUG)
696 printf("winbond-840 : MII PHY found at address %d, status "
697 "%X advertising %hX.\n", phy, mii_status, w840private.advertising);
703 w840private.mii_cnt = phy_idx;
706 printf("winbond-840 : MII PHY not found -- this device may not operate correctly.\n");
710 /* point to NIC specific routines */
711 nic->nic_op = &w89c840_operations;
718 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. These are
719 often serial bit streams generated by the host processor.
720 The example below is for the common 93c46 EEPROM, 64 16 bit words. */
722 /* Delay between EEPROM clock transitions.
723 No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
724 a delay. Note that pre-2.0.34 kernels had a cache-alignment bug that
725 made udelay() unreliable.
726 The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
729 #define eeprom_delay(ee_addr) readl(ee_addr)
731 enum EEPROM_Ctrl_Bits {
732 EE_ShiftClk=0x02, EE_Write0=0x801, EE_Write1=0x805,
733 EE_ChipSelect=0x801, EE_DataIn=0x08,
736 /* The EEPROM commands include the alway-set leading bit. */
738 EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
741 static int eeprom_read(long addr, int location)
745 int ee_addr = addr + EECtrl;
746 int read_cmd = location | EE_ReadCmd;
747 writel(EE_ChipSelect, ee_addr);
749 /* Shift the read command bits out. */
750 for (i = 10; i >= 0; i--) {
751 short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
752 writel(dataval, ee_addr);
753 eeprom_delay(ee_addr);
754 writel(dataval | EE_ShiftClk, ee_addr);
755 eeprom_delay(ee_addr);
757 writel(EE_ChipSelect, ee_addr);
759 for (i = 16; i > 0; i--) {
760 writel(EE_ChipSelect | EE_ShiftClk, ee_addr);
761 eeprom_delay(ee_addr);
762 retval = (retval << 1) | ((readl(ee_addr) & EE_DataIn) ? 1 : 0);
763 writel(EE_ChipSelect, ee_addr);
764 eeprom_delay(ee_addr);
767 /* Terminate the EEPROM access. */
772 /* MII transceiver control section.
773 Read and write the MII registers using software-generated serial
774 MDIO protocol. See the MII specifications or DP83840A data sheet
777 The maximum data clock rate is 2.5 Mhz. The minimum timing is usually
778 met by back-to-back 33Mhz PCI cycles. */
779 #define mdio_delay(mdio_addr) readl(mdio_addr)
781 /* Set iff a MII transceiver on any interface requires mdio preamble.
782 This only set with older tranceivers, so the extra
783 code size of a per-interface flag is not worthwhile. */
784 static char mii_preamble_required = 1;
786 #define MDIO_WRITE0 (MDIO_EnbOutput)
787 #define MDIO_WRITE1 (MDIO_DataOut | MDIO_EnbOutput)
789 /* Generate the preamble required for initial synchronization and
790 a few older transceivers. */
791 static void mdio_sync(long mdio_addr)
795 /* Establish sync by sending at least 32 logic ones. */
796 while (--bits >= 0) {
797 writel(MDIO_WRITE1, mdio_addr);
798 mdio_delay(mdio_addr);
799 writel(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
800 mdio_delay(mdio_addr);
804 static int mdio_read(int base_address, int phy_id, int location)
806 long mdio_addr = base_address + MIICtrl;
807 int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
810 if (mii_preamble_required)
811 mdio_sync(mdio_addr);
813 /* Shift the read command bits out. */
814 for (i = 15; i >= 0; i--) {
815 int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
817 writel(dataval, mdio_addr);
818 mdio_delay(mdio_addr);
819 writel(dataval | MDIO_ShiftClk, mdio_addr);
820 mdio_delay(mdio_addr);
822 /* Read the two transition, 16 data, and wire-idle bits. */
823 for (i = 20; i > 0; i--) {
824 writel(MDIO_EnbIn, mdio_addr);
825 mdio_delay(mdio_addr);
826 retval = (retval << 1) | ((readl(mdio_addr) & MDIO_DataIn) ? 1 : 0);
827 writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
828 mdio_delay(mdio_addr);
830 return (retval>>1) & 0xffff;
834 static void mdio_write(int base_address, int phy_id, int location, int value)
836 long mdio_addr = base_address + MIICtrl;
837 int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
840 if (location == 4 && phy_id == w840private.phys[0])
841 w840private.advertising = value;
843 if (mii_preamble_required)
844 mdio_sync(mdio_addr);
846 /* Shift the command bits out. */
847 for (i = 31; i >= 0; i--) {
848 int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
850 writel(dataval, mdio_addr);
851 mdio_delay(mdio_addr);
852 writel(dataval | MDIO_ShiftClk, mdio_addr);
853 mdio_delay(mdio_addr);
855 /* Clear out extra bits. */
856 for (i = 2; i > 0; i--) {
857 writel(MDIO_EnbIn, mdio_addr);
858 mdio_delay(mdio_addr);
859 writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
860 mdio_delay(mdio_addr);
866 static void check_duplex(void)
868 int mii_reg5 = mdio_read(ioaddr, w840private.phys[0], 5);
869 int negotiated = mii_reg5 & w840private.advertising;
872 if (w840private.duplex_lock || mii_reg5 == 0xffff)
875 duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
876 if (w840private.full_duplex != duplex) {
877 w840private.full_duplex = duplex;
879 #if defined(W89C840_DEBUG)
880 printf("winbond-840 : Setting %s-duplex based on MII # %d negotiated capability %X\n",
881 duplex ? "full" : "half", w840private.phys[0], negotiated);
884 w840private.csr6 &= ~0x200;
885 w840private.csr6 |= duplex ? 0x200 : 0;
889 static void set_rx_mode(void)
891 u32 mc_filter[2]; /* Multicast hash filter */
894 /* Accept all multicasts from now on. */
895 memset(mc_filter, 0xff, sizeof(mc_filter));
898 * works OK with multicast enabled.
901 rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast;
903 writel(mc_filter[0], ioaddr + MulticastFilter0);
904 writel(mc_filter[1], ioaddr + MulticastFilter1);
905 w840private.csr6 &= ~0x00F8;
906 w840private.csr6 |= rx_mode;
907 writel(w840private.csr6, ioaddr + NetworkConfig);
909 #if defined(W89C840_DEBUG)
910 printf("winbond-840 : Done setting RX mode.\n");
914 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
915 static void init_ring(void)
920 w840private.tx_full = 0;
921 w840private.tx_q_bytes = w840private.cur_rx = w840private.cur_tx = 0;
922 w840private.dirty_rx = w840private.dirty_tx = 0;
924 w840private.rx_buf_sz = PKT_BUF_SZ;
925 w840private.rx_head_desc = &w840private.rx_ring[0];
927 /* Initial all Rx descriptors. Fill in the Rx buffers. */
929 p = &w89c840_buf.rx_packet[0];
931 for (i = 0; i < RX_RING_SIZE; i++) {
932 w840private.rx_ring[i].length = w840private.rx_buf_sz;
933 w840private.rx_ring[i].status = 0;
934 w840private.rx_ring[i].next_desc = virt_to_le32desc(&w840private.rx_ring[i+1]);
936 w840private.rx_ring[i].buffer1 = virt_to_le32desc(p + (PKT_BUF_SZ * i));
937 w840private.rx_ring[i].status = DescOwn | DescIntr;
940 /* Mark the last entry as wrapping the ring. */
941 w840private.rx_ring[i-1].length |= DescEndRing;
942 w840private.rx_ring[i-1].next_desc = virt_to_le32desc(&w840private.rx_ring[0]);
944 w840private.dirty_rx = (unsigned int)(i - RX_RING_SIZE);
946 for (i = 0; i < TX_RING_SIZE; i++) {
947 w840private.tx_ring[i].status = 0;
953 DRIVER ( "W89C840F", nic_driver, pci_driver, w89c840_driver,
954 w89c840_probe, w89c840_disable );