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 {
260 } w89c840_buf __shared;
261 
262 static int eeprom_read(long ioaddr, int location);
263 static int mdio_read(int base_address, int phy_id, int location);
264 #if 0
265 static void mdio_write(int base_address, int phy_id, int location, int value);
266 #endif
267 
268 static void check_duplex(void);
269 static void set_rx_mode(void);
270 static void init_ring(void);
271 
272 #if defined(W89C840_DEBUG)
273 static void decode_interrupt(u32 intr_status)
274 {
275  printf("Interrupt status: ");
276 
277 #define TRACE_INTR(_intr_) \
278  if (intr_status & (_intr_)) { printf (" " #_intr_); }
279 
280  TRACE_INTR(NormalIntr);
281  TRACE_INTR(AbnormalIntr);
282  TRACE_INTR(IntrPCIErr);
283  TRACE_INTR(TimerInt);
284  TRACE_INTR(IntrRxDied);
285  TRACE_INTR(RxNoBuf);
286  TRACE_INTR(IntrRxDone);
287  TRACE_INTR(TxFIFOUnderflow);
288  TRACE_INTR(RxErrIntr);
289  TRACE_INTR(TxIdle);
290  TRACE_INTR(IntrTxStopped);
291  TRACE_INTR(IntrTxDone);
292 
293  printf("\n");
294  /*sleep(1);*/
295 }
296 #endif
297 
298 /**************************************************************************
299 w89c840_reset - Reset adapter
300 ***************************************************************************/
301 static void w89c840_reset(struct nic *nic)
302 {
303  int i;
304 
305  /* Reset the chip to erase previous misconfiguration.
306  No hold time required! */
307  writel(0x00000001, ioaddr + PCIBusCfg);
308 
309  init_ring();
310 
313 
314  for (i = 0; i < ETH_ALEN; i++)
315  writeb(nic->node_addr[i], ioaddr + StationAddr + i);
316 
317  /* Initialize other registers. */
318  /* Configure the PCI bus bursts and FIFO thresholds.
319  486: Set 8 longword cache alignment, 8 longword burst.
320  586: Set 16 longword cache alignment, no burst limit.
321  Cache alignment bits 15:14 Burst length 13:8
322  0000 <not allowed> 0000 align to cache 0800 8 longwords
323  4000 8 longwords 0100 1 longword 1000 16 longwords
324  8000 16 longwords 0200 2 longwords 2000 32 longwords
325  C000 32 longwords 0400 4 longwords
326  Wait the specified 50 PCI cycles after a reset by initializing
327  Tx and Rx queues and the address filter list. */
328 
329  writel(0xE010, ioaddr + PCIBusCfg);
330 
332  w840private.csr6 = 0x20022002;
333  check_duplex();
334  set_rx_mode();
335 
336  /* Do not enable the interrupts Etherboot doesn't need them */
337 /*
338  writel(0x1A0F5, ioaddr + IntrStatus);
339  writel(0x1A0F5, ioaddr + IntrEnable);
340 */
341 #if defined(W89C840_DEBUG)
342  printf("winbond-840 : Done reset.\n");
343 #endif
344 }
345 
346 #if 0
347 static void handle_intr(u32 intr_stat)
348 {
349  if ((intr_stat & (NormalIntr|AbnormalIntr)) == 0) {
350  /* we are polling, do not return now */
351  /*return 0;*/
352  } else {
353  /* Acknowledge all of the current interrupt sources ASAP. */
354  writel(intr_stat & 0x001ffff, ioaddr + IntrStatus);
355  }
356 
357  if (intr_stat & AbnormalIntr) {
358  /* There was an abnormal interrupt */
359  printf("\n-=- Abnormal interrupt.\n");
360 
361 #if defined(W89C840_DEBUG)
362  decode_interrupt(intr_stat);
363 #endif
364 
365  if (intr_stat & RxNoBuf) {
366  /* There was an interrupt */
367  printf("-=- <=> No receive buffers available.\n");
369  }
370  }
371 }
372 #endif
373 
374 /**************************************************************************
375 w89c840_poll - Wait for a frame
376 ***************************************************************************/
377 static int w89c840_poll(struct nic *nic, int retrieve)
378 {
379  /* return true if there's an ethernet packet ready to read */
380  /* nic->packet should contain data on return */
381  /* nic->packetlen should contain length of data */
382  int packet_received = 0;
383 
384 #if defined(W89C840_DEBUG)
385  u32 intr_status = readl(ioaddr + IntrStatus);
386 #endif
387 
388  do {
389  /* Code from netdev_rx(dev) */
390 
392 
394  s32 status = desc->status;
395 
396  if (status & DescOwn) {
397  /* DescOwn bit is still set, we should wait for RX to complete */
398  packet_received = 0;
399  break;
400  }
401 
402  if ( !retrieve ) {
403  packet_received = 1;
404  break;
405  }
406 
407  if ((status & 0x38008300) != 0x0300) {
408  if ((status & 0x38000300) != 0x0300) {
409  /* Ingore earlier buffers. */
410  if ((status & 0xffff) != 0x7fff) {
411  printf("winbond-840 : Oversized Ethernet frame spanned "
412  "multiple buffers, entry %d status %X !\n",
413  w840private.cur_rx, (unsigned int) status);
414  }
415  } else if (status & 0x8000) {
416  /* There was a fatal error. */
417 #if defined(W89C840_DEBUG)
418  printf("winbond-840 : Receive error, Rx status %X :", status);
419  if (status & 0x0890) {
420  printf(" RXLEN_ERROR");
421  }
422  if (status & 0x004C) {
423  printf(", FRAME_ERROR");
424  }
425  if (status & 0x0002) {
426  printf(", CRC_ERROR");
427  }
428  printf("\n");
429 #endif
430 
431  /* Simpy do a reset now... */
433 
434  packet_received = 0;
435  break;
436  }
437  } else {
438  /* Omit the four octet CRC from the length. */
439  int pkt_len = ((status >> 16) & 0x7ff) - 4;
440 
441 #if defined(W89C840_DEBUG)
442  printf(" netdev_rx() normal Rx pkt ring %d length %d status %X\n", entry, pkt_len, status);
443 #endif
444 
445  nic->packetlen = pkt_len;
446 
447  /* Check if the packet is long enough to accept without copying
448  to a minimally-sized skbuff. */
449 
451  packet_received = 1;
452 
453  /* Release buffer to NIC */
455 
456 #if defined(W89C840_DEBUG)
457  /* You will want this info for the initial debug. */
458  printf(" Rx data %hhX:%hhX:%hhX:%hhX:%hhX:"
459  "%hhX %hhX:%hhX:%hhX:%hhX:%hhX:%hhX %hhX%hhX "
460  "%hhX.%hhX.%hhX.%hhX.\n",
461  nic->packet[0], nic->packet[1], nic->packet[2], nic->packet[3],
462  nic->packet[4], nic->packet[5], nic->packet[6], nic->packet[7],
463  nic->packet[8], nic->packet[9], nic->packet[10],
464  nic->packet[11], nic->packet[12], nic->packet[13],
465  nic->packet[14], nic->packet[15], nic->packet[16],
466  nic->packet[17]);
467 #endif
468 
469  }
470 
473  } while (0);
474 
475  return packet_received;
476 }
477 
478 /**************************************************************************
479 w89c840_transmit - Transmit a frame
480 ***************************************************************************/
481 
482 static void w89c840_transmit(
483  struct nic *nic,
484  const char *d, /* Destination */
485  unsigned int t, /* Type */
486  unsigned int s, /* size */
487  const char *p) /* Packet */
488 {
489  /* send the packet to destination */
490  unsigned entry;
491  int transmit_status;
492  unsigned long ct;
493 
494  /* Caution: the write order is important here, set the field
495  with the "ownership" bits last. */
496 
497  /* Fill in our transmit buffer */
499 
500  memcpy (w89c840_buf.tx_packet, d, ETH_ALEN); /* dst */
501  memcpy (w89c840_buf.tx_packet + ETH_ALEN, nic->node_addr, ETH_ALEN);/*src*/
502 
503  *((char *) w89c840_buf.tx_packet + 12) = t >> 8; /* type */
504  *((char *) w89c840_buf.tx_packet + 13) = t;
505 
506  memcpy (w89c840_buf.tx_packet + ETH_HLEN, p, s);
507  s += ETH_HLEN;
508 
509  while (s < ETH_ZLEN)
510  *((char *) w89c840_buf.tx_packet + ETH_HLEN + (s++)) = 0;
511 
513  = virt_to_le32desc(w89c840_buf.tx_packet);
514 
516  if (entry >= TX_RING_SIZE-1) /* Wrap ring */
520 
521  w840private.tx_q_bytes = (u16) s;
523 
524  /* Work around horrible bug in the chip by marking the queue as full
525  when we do not have FIFO room for a maximum sized packet. */
526 
528  /* Actually this is left to help finding error tails later in debugging...
529  * See Linux kernel driver in winbond-840.c for details.
530  */
531  w840private.tx_full = 1;
532  }
533 
534 #if defined(W89C840_DEBUG)
535  printf("winbond-840 : Transmit frame # %d size %d queued in slot %d.\n", w840private.cur_tx, s, entry);
536 #endif
537 
538  /* Now wait for TX to complete. */
539  transmit_status = w840private.tx_ring[entry].status;
540 
541  ct = currticks();
542  {
543 #if defined W89C840_DEBUG
544  u32 intr_stat = 0;
545 #endif
546  while (1) {
547 
548 #if defined(W89C840_DEBUG)
549  decode_interrupt(intr_stat);
550 #endif
551 
552  while ( (transmit_status & DescOwn) && ct + TX_TIMEOUT < currticks()) {
553 
554  transmit_status = w840private.tx_ring[entry].status;
555  }
556 
557  break;
558  }
559  }
560 
561  if ((transmit_status & DescOwn) == 0) {
562 
563 #if defined(W89C840_DEBUG)
564  printf("winbond-840 : transmission complete after wait loop iterations, status %X\n",
566 #endif
567 
568  return;
569  }
570 
571  /* Transmit timed out... */
572 
573  printf("winbond-840 : transmission TIMEOUT : status %X\n",
574  (unsigned int) w840private.tx_ring[entry].status);
575 
576  return;
577 }
578 
579 /**************************************************************************
580 w89c840_disable - Turn off ethernet interface
581 ***************************************************************************/
582 static void w89c840_disable ( struct nic *nic ) {
583 
585 
586  /* Don't know what to do to disable the board. Is this needed at all? */
587  /* Yes, a live NIC can corrupt the loaded memory later [Ken] */
588  /* Stop the chip's Tx and Rx processes. */
589  writel(w840private.csr6 &= ~0x20FA, ioaddr + NetworkConfig);
590 }
591 
592 /**************************************************************************
593 w89c840_irq - Enable, Disable, or Force interrupts
594 ***************************************************************************/
595 static void w89c840_irq(struct nic *nic __unused, irq_action_t action __unused)
596 {
597  switch ( action ) {
598  case DISABLE :
599  break;
600  case ENABLE :
601  break;
602  case FORCE :
603  break;
604  }
605 }
606 
609  .poll = w89c840_poll,
610  .transmit = w89c840_transmit,
611  .irq = w89c840_irq,
612 
613 };
614 
615 static struct pci_device_id w89c840_nics[] = {
616 PCI_ROM(0x1050, 0x0840, "winbond840", "Winbond W89C840F", 0),
617 PCI_ROM(0x11f6, 0x2011, "compexrl100atx", "Compex RL100ATX", 0),
618 };
619 
620 PCI_DRIVER ( w89c840_driver, w89c840_nics, PCI_NO_CLASS );
621 
622 /**************************************************************************
623 w89c840_probe - Look for an adapter, this routine's visible to the outside
624 ***************************************************************************/
625 static int w89c840_probe ( struct nic *nic, struct pci_device *p ) {
626 
627 
628  u16 sum = 0;
629  int i;
630  unsigned short value;
631 
632  if (p->ioaddr == 0)
633  return 0;
634 
635  nic->ioaddr = p->ioaddr;
636  nic->irqno = 0;
637 
638 #if defined(W89C840_DEBUG)
639  printf("winbond-840: PCI bus %hhX device function %hhX: I/O address: %hX\n", p->bus, p->devfn, ioaddr);
640 #endif
641 
642  ioaddr = ioaddr & ~3; /* Mask the bit that says "this is an io addr" */
643 
644 #define PCI_VENDOR_ID_WINBOND2 0x1050
645 #define PCI_DEVICE_ID_WINBOND2_89C840 0x0840
646 #define PCI_VENDOR_ID_COMPEX 0x11f6
647 #define PCI_DEVICE_ID_COMPEX_RL100ATX 0x2011
648 
649  /* From Matt Hortman <mbhortman@acpthinclient.com> */
652 
653  /* detected "Winbond W89c840 Fast Ethernet PCI NIC" */
654 
655  } else if ( p->vendor == PCI_VENDOR_ID_COMPEX
657 
658  /* detected "Compex RL100ATX Fast Ethernet PCI NIC" */
659 
660  } else {
661  /* Gee, guess what? They missed again. */
662  printf("device ID : %X - is not a Compex RL100ATX NIC.\n",
663  p->device);
664  return 0;
665  }
666 
667  printf(" %s\n", w89c840_version);
668 
670 
671  /* Ok. Got one. Read the eeprom. */
672  for (i = 0; i < 0x40; i++) {
673  value = eeprom_read(ioaddr, i);
674  eeprom[i] = value;
675  sum += value;
676  }
677 
678  for (i=0;i<ETH_ALEN;i++) {
679  nic->node_addr[i] = (eeprom[i/2] >> (8*(i&1))) & 0xff;
680  }
681 
682  DBG ( "Ethernet addr: %s\n", eth_ntoa ( nic->node_addr ) );
683 
684 #if defined(W89C840_DEBUG)
685  printf("winbond-840: EEPROM checksum %hX, got eeprom", sum);
686 #endif
687 
688  /* Reset the chip to erase previous misconfiguration.
689  No hold time required! */
690  writel(0x00000001, ioaddr + PCIBusCfg);
691 
692  if (driver_flags & CanHaveMII) {
693  int phy, phy_idx = 0;
694  for (phy = 1; phy < 32 && phy_idx < 4; phy++) {
695  int mii_status = mdio_read(ioaddr, phy, 1);
696  if (mii_status != 0xffff && mii_status != 0x0000) {
697  w840private.phys[phy_idx++] = phy;
699 
700 #if defined(W89C840_DEBUG)
701  printf("winbond-840 : MII PHY found at address %d, status "
702  "%X advertising %hX.\n", phy, mii_status, w840private.advertising);
703 #endif
704 
705  }
706  }
707 
708  w840private.mii_cnt = phy_idx;
709 
710  if (phy_idx == 0) {
711  printf("winbond-840 : MII PHY not found -- this device may not operate correctly.\n");
712  }
713  }
714 
715  /* point to NIC specific routines */
717 
719 
720  return 1;
721 }
722 
723 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. These are
724  often serial bit streams generated by the host processor.
725  The example below is for the common 93c46 EEPROM, 64 16 bit words. */
726 
727 /* Delay between EEPROM clock transitions.
728  No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
729  a delay. Note that pre-2.0.34 kernels had a cache-alignment bug that
730  made udelay() unreliable.
731  The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
732  depricated.
733 */
734 #define eeprom_delay(ee_addr) readl(ee_addr)
735 
737  EE_ShiftClk=0x02, EE_Write0=0x801, EE_Write1=0x805,
739 };
740 
741 /* The EEPROM commands include the alway-set leading bit. */
743  EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
744 };
745 
746 static int eeprom_read(long addr, int location)
747 {
748  int i;
749  int retval = 0;
750  int ee_addr = addr + EECtrl;
751  int read_cmd = location | EE_ReadCmd;
752  writel(EE_ChipSelect, ee_addr);
753 
754  /* Shift the read command bits out. */
755  for (i = 10; i >= 0; i--) {
756  short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
757  writel(dataval, ee_addr);
758  eeprom_delay(ee_addr);
759  writel(dataval | EE_ShiftClk, ee_addr);
760  eeprom_delay(ee_addr);
761  }
762  writel(EE_ChipSelect, ee_addr);
763 
764  for (i = 16; i > 0; i--) {
765  writel(EE_ChipSelect | EE_ShiftClk, ee_addr);
766  eeprom_delay(ee_addr);
767  retval = (retval << 1) | ((readl(ee_addr) & EE_DataIn) ? 1 : 0);
768  writel(EE_ChipSelect, ee_addr);
769  eeprom_delay(ee_addr);
770  }
771 
772  /* Terminate the EEPROM access. */
773  writel(0, ee_addr);
774  return retval;
775 }
776 
777 /* MII transceiver control section.
778  Read and write the MII registers using software-generated serial
779  MDIO protocol. See the MII specifications or DP83840A data sheet
780  for details.
781 
782  The maximum data clock rate is 2.5 Mhz. The minimum timing is usually
783  met by back-to-back 33Mhz PCI cycles. */
784 #define mdio_delay(mdio_addr) readl(mdio_addr)
785 
786 /* Set iff a MII transceiver on any interface requires mdio preamble.
787  This only set with older tranceivers, so the extra
788  code size of a per-interface flag is not worthwhile. */
789 static char mii_preamble_required = 1;
790 
791 #define MDIO_WRITE0 (MDIO_EnbOutput)
792 #define MDIO_WRITE1 (MDIO_DataOut | MDIO_EnbOutput)
793 
794 /* Generate the preamble required for initial synchronization and
795  a few older transceivers. */
796 static void mdio_sync(long mdio_addr)
797 {
798  int bits = 32;
799 
800  /* Establish sync by sending at least 32 logic ones. */
801  while (--bits >= 0) {
802  writel(MDIO_WRITE1, mdio_addr);
803  mdio_delay(mdio_addr);
804  writel(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
805  mdio_delay(mdio_addr);
806  }
807 }
808 
809 static int mdio_read(int base_address, int phy_id, int location)
810 {
811  long mdio_addr = base_address + MIICtrl;
812  int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
813  int i, retval = 0;
814 
816  mdio_sync(mdio_addr);
817 
818  /* Shift the read command bits out. */
819  for (i = 15; i >= 0; i--) {
820  int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
821 
822  writel(dataval, mdio_addr);
823  mdio_delay(mdio_addr);
824  writel(dataval | MDIO_ShiftClk, mdio_addr);
825  mdio_delay(mdio_addr);
826  }
827  /* Read the two transition, 16 data, and wire-idle bits. */
828  for (i = 20; i > 0; i--) {
829  writel(MDIO_EnbIn, mdio_addr);
830  mdio_delay(mdio_addr);
831  retval = (retval << 1) | ((readl(mdio_addr) & MDIO_DataIn) ? 1 : 0);
832  writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
833  mdio_delay(mdio_addr);
834  }
835  return (retval>>1) & 0xffff;
836 }
837 
838 #if 0
839 static void mdio_write(int base_address, int phy_id, int location, int value)
840 {
841  long mdio_addr = base_address + MIICtrl;
842  int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
843  int i;
844 
845  if (location == 4 && phy_id == w840private.phys[0])
847 
849  mdio_sync(mdio_addr);
850 
851  /* Shift the command bits out. */
852  for (i = 31; i >= 0; i--) {
853  int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
854 
855  writel(dataval, mdio_addr);
856  mdio_delay(mdio_addr);
857  writel(dataval | MDIO_ShiftClk, mdio_addr);
858  mdio_delay(mdio_addr);
859  }
860  /* Clear out extra bits. */
861  for (i = 2; i > 0; i--) {
862  writel(MDIO_EnbIn, mdio_addr);
863  mdio_delay(mdio_addr);
864  writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
865  mdio_delay(mdio_addr);
866  }
867  return;
868 }
869 #endif
870 
871 static void check_duplex(void)
872 {
873  int mii_reg5 = mdio_read(ioaddr, w840private.phys[0], 5);
874  int negotiated = mii_reg5 & w840private.advertising;
875  int duplex;
876 
877  if (w840private.duplex_lock || mii_reg5 == 0xffff)
878  return;
879 
880  duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
881  if (w840private.full_duplex != duplex) {
883 
884 #if defined(W89C840_DEBUG)
885  printf("winbond-840 : Setting %s-duplex based on MII # %d negotiated capability %X\n",
886  duplex ? "full" : "half", w840private.phys[0], negotiated);
887 #endif
888 
889  w840private.csr6 &= ~0x200;
890  w840private.csr6 |= duplex ? 0x200 : 0;
891  }
892 }
893 
894 static void set_rx_mode(void)
895 {
896  u32 mc_filter[2]; /* Multicast hash filter */
897  u32 rx_mode;
898 
899  /* Accept all multicasts from now on. */
900  memset(mc_filter, 0xff, sizeof(mc_filter));
901 
902 /*
903  * works OK with multicast enabled.
904  */
905 
907 
908  writel(mc_filter[0], ioaddr + MulticastFilter0);
909  writel(mc_filter[1], ioaddr + MulticastFilter1);
910  w840private.csr6 &= ~0x00F8;
911  w840private.csr6 |= rx_mode;
913 
914 #if defined(W89C840_DEBUG)
915  printf("winbond-840 : Done setting RX mode.\n");
916 #endif
917 }
918 
919 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
920 static void init_ring(void)
921 {
922  int i;
923  char * p;
924 
925  w840private.tx_full = 0;
928 
931 
932  /* Initial all Rx descriptors. Fill in the Rx buffers. */
933 
934  p = &w89c840_buf.rx_packet[0];
935 
936  for (i = 0; i < RX_RING_SIZE; i++) {
938  w840private.rx_ring[i].status = 0;
940 
943  }
944 
945  /* Mark the last entry as wrapping the ring. */
948 
949  w840private.dirty_rx = (unsigned int)(i - RX_RING_SIZE);
950 
951  for (i = 0; i < TX_RING_SIZE; i++) {
952  w840private.tx_ring[i].status = 0;
953  }
954  return;
955 }
956 
957 
958 DRIVER ( "W89C840F", nic_driver, pci_driver, w89c840_driver,
960 
961 /*
962  * Local variables:
963  * c-basic-offset: 8
964  * c-indent-level: 8
965  * tab-width: 8
966  * End:
967  */
#define virt_to_le32desc(addr)
Definition: w89c840.c:91
#define eeprom_delay(ee_addr)
Definition: w89c840.c:734
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:792
A PCI driver.
Definition: pci.h:247
rx_mode_bits
Definition: sundance.c:187
int32_t s32
Definition: stdint.h:22
unsigned long ioaddr
I/O address.
Definition: pci.h:221
struct @355 __shared
unsigned int dirty_rx
Definition: w89c840.c:237
s32 length
Definition: w89c840.c:211
#define MDIO_WRITE0
Definition: w89c840.c:791
static u32 driver_flags
Definition: w89c840.c:142
static void w89c840_reset(struct nic *nic)
Definition: w89c840.c:301
struct w840_tx_desc tx_ring[TX_RING_SIZE]
Definition: w89c840.c:228
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
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:809
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:746
char rx_packet[PKT_BUF_SZ *RX_RING_SIZE]
Definition: w89c840.c:258
static void w89c840_disable(struct nic *nic)
Definition: w89c840.c:582
#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:894
void adjust_pci_device(struct pci_device *pci)
Enable PCI device.
Definition: pci.c:154
struct w840_rx_desc * rx_head_desc
Definition: w89c840.c:236
int dummy_connect(struct nic *nic __unused)
Definition: legacy.c:151
#define PRIV_ALIGN_BYTES
Definition: w89c840.c:222
eeprom
Definition: 3c90x.h:232
static int ioaddr
Definition: w89c840.c:255
uint8_t status
Status.
Definition: ena.h:16
#define TX_TIMEOUT
Definition: w89c840.c:118
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:225
#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
#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:742
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:614
unsigned int default_port
Definition: w89c840.c:246
#define writel
Definition: w89c840.c:160
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
static int w89c840_probe(struct nic *nic, struct pci_device *p)
Definition: w89c840.c:625
chip_capability_flags
Definition: sundance.c:253
unsigned int packetlen
Definition: nic.h:54
mii_reg_bits
Definition: sundance.c:779
static void init_ring(void)
Definition: w89c840.c:920
static int w89c840_poll(struct nic *nic, int retrieve)
Definition: w89c840.c:377
desc_status_bits
Definition: sundance.c:215
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
PCI bus.
A PCI device.
Definition: pci.h:206
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition: ethernet.c:175
FILE_LICENCE(GPL2_OR_LATER)
A network device.
Definition: netdevice.h:352
struct pci_dev * pci_dev
Definition: w89c840.c:234
u32 addr
Definition: sky2.h:8
DRIVER("W89C840F", nic_driver, pci_driver, w89c840_driver, w89c840_probe, w89c840_disable)
EEPROM_Ctrl_Bits
Definition: w89c840.c:736
static void mdio_sync(long mdio_addr)
Definition: w89c840.c:796
#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:170
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:223
unsigned int duplex_lock
Definition: w89c840.c:244
unsigned long retval
Definition: xen.h:45
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
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:789
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
static volatile void * bits
Definition: bitops.h:27
static void check_duplex(void)
Definition: w89c840.c:871
static struct pci_device_id w89c840_nics[]
Definition: w89c840.c:615
u32 next_desc
Definition: w89c840.c:206
#define TX_BUG_FIFO_LIMIT
Definition: w89c840.c:114
uint32_t d
Definition: md4.c:31
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:607
static void w89c840_irq(struct nic *nic __unused, irq_action_t action __unused)
Definition: w89c840.c:595
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
char tx_packet[PKT_BUF_SZ *TX_RING_SIZE]
Definition: w89c840.c:259
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:63
#define PCI_ROM(_vendor, _device, _name, _description, _data)
Definition: pci.h:303
unsigned int dirty_tx
Definition: w89c840.c:239
s32 length
Definition: w89c840.c:204
#define mdio_delay(mdio_addr)
Definition: w89c840.c:784
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:482
#define readl
Definition: w89c840.c:157
void * memset(void *dest, int character, size_t len) __nonnull