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