iPXE
3c515.c
Go to the documentation of this file.
1 /*
2 * 3c515.c -- 3COM 3C515 Fast Etherlink ISA 10/100BASE-TX driver for etherboot
3 * Copyright (C) 2002 Timothy Legge <tlegge@rogers.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA.
19 *
20 * Portions of this code:
21 * Copyright (C) 1997-2002 Donald Becker 3c515.c: A 3Com ISA EtherLink XL "Corkscrew" ethernet driver for linux.
22 * Copyright (C) 2001 P.J.H.Fox (fox@roestock.demon.co.uk) ISAPNP Tools
23 * Copyright (c) 2002 Jaroslav Kysela <perex@suse.cz> ISA Plug & Play support Linux Kernel
24 * Copyright (C) 2000 Shusuke Nisiyama <shu@athena.qe.eng.hokudai.ac.jp> etherboot-5.0.5 3c595.c
25 * Coptright (C) 1995 Martin Renters etherboot-5.0.5 3c509.c
26 * Copyright (C) 1999 LightSys Technology Services, Inc. etherboot-5.0.5 3c90x.c
27 * Portions Copyright (C) 1999 Steve Smith etherboot-5.0.5 3c90x.c
28 *
29 * The probe and reset functions and defines are direct copies from the
30 * Becker code modified where necessary to make it work for etherboot
31 *
32 * The poll and transmit functions either contain code from or were written by referencing
33 * the above referenced etherboot drivers. This driver would not have been
34 * possible without this prior work
35 *
36 * REVISION HISTORY:
37 * ================
38 * v0.10 4-17-2002 TJL Initial implementation.
39 * v0.11 4-17-2002 TJL Cleanup of the code
40 * v0.12 4-26-2002 TJL Added ISA Plug and Play for Non-PNP Bioses
41 * v0.13 6-10-2002 TJL Fixed ISA_PNP MAC Address problem
42 * v0.14 9-23-2003 TJL Replaced delay with currticks
43 *
44 * Indent Options: indent -kr -i8
45 * *********************************************************/
46 
47 FILE_LICENCE ( GPL2_OR_LATER );
48 
49 /* to get some global routines like printf */
50 #include "etherboot.h"
51 /* to get the interface to the body of the program */
52 #include "nic.h"
53 #include <ipxe/isapnp.h>
54 #include <ipxe/isa.h> /* for ISA_ROM */
55 #include <ipxe/ethernet.h>
56 
57 static void t3c515_wait(unsigned int nticks)
58 {
59  unsigned int to = currticks() + nticks;
60  while (currticks() < to)
61  /* wait */ ;
62 }
63 
64 /* TJL definations */
65 #define HZ 100
66 static int if_port;
67 static struct corkscrew_private *vp;
68 /* Brought directly from 3c515.c by Becker */
69 #define CORKSCREW 1
70 
71 /* Maximum events (Rx packets, etc.) to handle at each interrupt.
72 static int max_interrupt_work = 20;
73 */
74 
75 /* Enable the automatic media selection code -- usually set. */
76 #define AUTOMEDIA 1
77 
78 /* Allow the use of fragment bus master transfers instead of only
79  programmed-I/O for Vortex cards. Full-bus-master transfers are always
80  enabled by default on Boomerang cards. If VORTEX_BUS_MASTER is defined,
81  the feature may be turned on using 'options'. */
82 #define VORTEX_BUS_MASTER
83 
84 /* A few values that may be tweaked. */
85 /* Keep the ring sizes a power of two for efficiency. */
86 #define TX_RING_SIZE 16
87 #define RX_RING_SIZE 16
88 #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer. */
89 
90 /* "Knobs" for adjusting internal parameters. */
91 /* Put out somewhat more debugging messages. (0 - no msg, 1 minimal msgs). */
92 #define DRIVER_DEBUG 1
93 /* Some values here only for performance evaluation and path-coverage
94  debugging.
95 static int rx_nocopy, rx_copy, queued_packet;
96 */
97 
98 #define CORKSCREW_ID 10
99 
100 #define EL3WINDOW(win_num) \
101  outw(SelectWindow + (win_num), nic->ioaddr + EL3_CMD)
102 #define EL3_CMD 0x0e
103 #define EL3_STATUS 0x0e
104 #define RX_BYTES_MASK (unsigned short) (0x07ff)
105 
107  TotalReset = 0 << 11, SelectWindow = 1 << 11, StartCoax = 2 << 11,
108  RxDisable = 3 << 11, RxEnable = 4 << 11, RxReset = 5 << 11,
109  UpStall = 6 << 11, UpUnstall = (6 << 11) + 1,
110  DownStall = (6 << 11) + 2, DownUnstall = (6 << 11) + 3,
111  RxDiscard = 8 << 11, TxEnable = 9 << 11, TxDisable =
112  10 << 11, TxReset = 11 << 11,
113  FakeIntr = 12 << 11, AckIntr = 13 << 11, SetIntrEnb = 14 << 11,
114  SetStatusEnb = 15 << 11, SetRxFilter = 16 << 11, SetRxThreshold =
115  17 << 11,
116  SetTxThreshold = 18 << 11, SetTxStart = 19 << 11,
117  StartDMAUp = 20 << 11, StartDMADown = (20 << 11) + 1, StatsEnable =
118  21 << 11,
119  StatsDisable = 22 << 11, StopCoax = 23 << 11,
120 };
121 
122 /* The SetRxFilter command accepts the following classes: */
123 enum RxFilter {
125 };
126 
127 /* Bits in the general status register. */
129  IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
130  TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
131  IntReq = 0x0040, StatsFull = 0x0080,
132  DMADone = 1 << 8, DownComplete = 1 << 9, UpComplete = 1 << 10,
133  DMAInProgress = 1 << 11, /* DMA controller is still busy. */
134  CmdInProgress = 1 << 12, /* EL3_CMD is still busy. */
135 };
136 
137 /* Register window 1 offsets, the window used in normal operation.
138  On the Corkscrew this window is always mapped at offsets 0x10-0x1f. */
139 enum Window1 {
140  TX_FIFO = 0x10, RX_FIFO = 0x10, RxErrors = 0x14,
141  RxStatus = 0x18, Timer = 0x1A, TxStatus = 0x1B,
142  TxFree = 0x1C, /* Remaining free bytes in Tx buffer. */
143 };
144 enum Window0 {
145  Wn0IRQ = 0x08,
146 #if defined(CORKSCREW)
147  Wn0EepromCmd = 0x200A, /* Corkscrew EEPROM command register. */
148  Wn0EepromData = 0x200C, /* Corkscrew EEPROM results register. */
149 #else
150  Wn0EepromCmd = 10, /* Window 0: EEPROM command register. */
151  Wn0EepromData = 12, /* Window 0: EEPROM results register. */
152 #endif
153 };
155  EEPROM_Read = 0x80, EEPROM_WRITE = 0x40, EEPROM_ERASE = 0xC0,
156  EEPROM_EWENB = 0x30, /* Enable erasing/writing for 10 msec. */
157  EEPROM_EWDIS = 0x00, /* Disable EWENB before 10 msec timeout. */
158 };
159 
160 enum Window3 { /* Window 3: MAC/config bits. */
162 };
163 union wn3_config {
164  int i;
166  unsigned int ram_size:3, ram_width:1, ram_speed:2,
167  rom_size:2;
168  int pad8:8;
169  unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1,
170  autoselect:1;
171  int pad24:7;
172  } u;
173 };
174 
175 enum Window4 {
176  Wn4_NetDiag = 6, Wn4_Media = 10, /* Window 4: Xcvr/media bits. */
177 };
179  Media_SQE = 0x0008, /* Enable SQE error counting for AUI. */
180  Media_10TP = 0x00C0, /* Enable link beat and jabber for 10baseT. */
181  Media_Lnk = 0x0080, /* Enable just link beat for 100TX/100FX. */
182  Media_LnkBeat = 0x0800,
183 };
184 enum Window7 { /* Window 7: Bus Master control. */
186 };
187 
188 /* Boomerang-style bus master control registers. Note ISA aliases! */
190  PktStatus = 0x400, DownListPtr = 0x404, FragAddr = 0x408, FragLen =
191  0x40c,
192  TxFreeThreshold = 0x40f, UpPktStatus = 0x410, UpListPtr = 0x418,
193 };
194 
195 /* The Rx and Tx descriptor lists.
196  Caution Alpha hackers: these types are 32 bits! Note also the 8 byte
197  alignment contraint on tx_ring[] and rx_ring[]. */
198 struct boom_rx_desc {
203 };
204 
205 /* Values for the Rx status entry. */
207  RxDComplete = 0x00008000, RxDError = 0x4000,
208  /* See boomerang_rx() for actual error bits */
209 };
210 
211 struct boom_tx_desc {
216 };
217 
219  const char *product_name;
221  /* The Rx and Tx rings are here to keep them quad-word-aligned. */
224  /* The addresses of transmit- and receive-in-place skbuffs. */
225  struct sk_buff *rx_skbuff[RX_RING_SIZE];
226  struct sk_buff *tx_skbuff[TX_RING_SIZE];
227  unsigned int cur_rx, cur_tx; /* The next free ring entry */
228  unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
229  struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */
230  int capabilities; /* Adapter capabilities word. */
231  int options; /* User-settable misc. driver options. */
232  int last_rx_packets; /* For media autoselection. */
233  unsigned int available_media:8, /* From Wn3_Options */
234  media_override:3, /* Passed-in media type. */
235  default_media:3, /* Read from the EEPROM. */
236  full_duplex:1, autoselect:1, bus_master:1, /* Vortex can only do a fragment bus-m. */
237  full_bus_master_tx:1, full_bus_master_rx:1, /* Boomerang */
238  tx_full:1;
239 };
240 
241 /* The action to take with a media selection timer tick.
242  Note that we deviate from the 3Com order by checking 10base2 before AUI.
243  */
248 };
249 
250 static struct media_table {
251  char *name;
252  unsigned int media_bits:16, /* Bits to set in Wn4_Media register. */
253  mask:8, /* The transceiver-present bit in Wn3_Config. */
254  next:8; /* The media type to try next. */
255  short wait; /* Time before we check media status. */
256 } media_tbl[] = {
257  {
258  "10baseT", Media_10TP, 0x08, XCVR_10base2, (14 * HZ) / 10}
259  , {
260  "10Mbs AUI", Media_SQE, 0x20, XCVR_Default, (1 * HZ) / 10}
261  , {
262  "undefined", 0, 0x80, XCVR_10baseT, 10000}
263  , {
264  "10base2", 0, 0x10, XCVR_AUI, (1 * HZ) / 10}
265  , {
266  "100baseTX", Media_Lnk, 0x02, XCVR_100baseFx,
267  (14 * HZ) / 10}
268  , {
269  "100baseFX", Media_Lnk, 0x04, XCVR_MII, (14 * HZ) / 10}
270  , {
271  "MII", 0, 0x40, XCVR_10baseT, 3 * HZ}
272  , {
273  "undefined", 0, 0x01, XCVR_10baseT, 10000}
274  , {
275  "Default", 0, 0xFF, XCVR_10baseT, 10000}
276 ,};
277 
278 /* TILEG Modified to remove reference to dev */
279 static int corkscrew_found_device(int ioaddr, int irq, int product_index,
280  int options, struct nic *nic);
281 static int corkscrew_probe1(int ioaddr, int irq, int product_index,
282  struct nic *nic);
283 
284 /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
285 /* Note: this is the only limit on the number of cards supported!! */
286 static int options = -1;
287 
288 /* End Brought directly from 3c515.c by Becker */
289 
290 /**************************************************************************
291 RESET - Reset adapter
292 ***************************************************************************/
293 static void t515_reset(struct nic *nic)
294 {
295  union wn3_config config;
296  int i;
297 
298  /* Before initializing select the active media port. */
299  EL3WINDOW(3);
300  if (vp->full_duplex)
301  outb(0x20, nic->ioaddr + Wn3_MAC_Ctrl); /* Set the full-duplex bit. */
302  config.i = inl(nic->ioaddr + Wn3_Config);
303 
304  if (vp->media_override != 7) {
305  DBG ( "Media override to transceiver %d (%s).\n",
309  } else if (vp->autoselect) {
310  /* Find first available media type, starting with 100baseTx. */
311  if_port = 4;
312  while (!(vp->available_media & media_tbl[if_port].mask))
314 
315  DBG ( "Initial media type %s.\n",
317  } else
319 
320  config.u.xcvr = if_port;
321  outl(config.i, nic->ioaddr + Wn3_Config);
322 
323  DBG ( "corkscrew_open() InternalConfig 0x%hX.\n",
324  config.i);
325 
327  for (i = 20; i >= 0; i--)
328  if (!(inw(nic->ioaddr + EL3_STATUS) & CmdInProgress))
329  break;
330 
332  /* Wait a few ticks for the RxReset command to complete. */
333  for (i = 20; i >= 0; i--)
334  if (!(inw(nic->ioaddr + EL3_STATUS) & CmdInProgress))
335  break;
336 
337  outw(SetStatusEnb | 0x00, nic->ioaddr + EL3_CMD);
338 
339 #ifdef debug_3c515
340  EL3WINDOW(4);
341  DBG ( "FIXME: fix print for irq, not 9" );
342  DBG ( "corkscrew_open() irq %d media status 0x%hX.\n",
343  9, inw(nic->ioaddr + Wn4_Media) );
344 #endif
345 
346  /* Set the station address and mask in window 2 each time opened. */
347  EL3WINDOW(2);
348  for (i = 0; i < 6; i++)
349  outb(nic->node_addr[i], nic->ioaddr + i);
350  for (; i < 12; i += 2)
351  outw(0, nic->ioaddr + i);
352 
353  if (if_port == 3)
354  /* Start the thinnet transceiver. We should really wait 50ms... */
356  EL3WINDOW(4);
359 
360  /* Switch to the stats window, and clear all stats by reading. */
361 /* outw(StatsDisable, nic->ioaddr + EL3_CMD);*/
362  EL3WINDOW(6);
363  for (i = 0; i < 10; i++)
364  inb(nic->ioaddr + i);
365  inw(nic->ioaddr + 10);
366  inw(nic->ioaddr + 12);
367  /* New: On the Vortex we must also clear the BadSSD counter. */
368  EL3WINDOW(4);
369  inb(nic->ioaddr + 12);
370  /* ..and on the Boomerang we enable the extra statistics bits. */
371  outw(0x0040, nic->ioaddr + Wn4_NetDiag);
372 
373  /* Switch to register set 7 for normal use. */
374  EL3WINDOW(7);
375 
376  /* Temporarily left in place. If these FIXMEs are printed
377  it meand that special logic for that card may need to be added
378  see Becker's 3c515.c driver */
379  if (vp->full_bus_master_rx) { /* Boomerang bus master. */
380  printf("FIXME: Is this if necessary");
381  vp->cur_rx = vp->dirty_rx = 0;
382  DBG ( " Filling in the Rx ring.\n" );
383  for (i = 0; i < RX_RING_SIZE; i++) {
384  printf("FIXME: Is this if necessary");
385  }
386  }
387  if (vp->full_bus_master_tx) { /* Boomerang bus master Tx. */
388  vp->cur_tx = vp->dirty_tx = 0;
389  outb(PKT_BUF_SZ >> 8, nic->ioaddr + TxFreeThreshold); /* Room for a packet. */
390  /* Clear the Tx ring. */
391  for (i = 0; i < TX_RING_SIZE; i++)
392  vp->tx_skbuff[i] = NULL;
393  outl(0, nic->ioaddr + DownListPtr);
394  }
395  /* Set receiver mode: presumably accept b-case and phys addr only. */
397  nic->ioaddr + EL3_CMD);
398 
399  outw(RxEnable, nic->ioaddr + EL3_CMD); /* Enable the receiver. */
400  outw(TxEnable, nic->ioaddr + EL3_CMD); /* Enable transmitter. */
401  /* Allow status bits to be seen. */
405  (vp->bus_master ? DMADone : 0), nic->ioaddr + EL3_CMD);
406  /* Ack all pending events, and set active indicator mask. */
408  nic->ioaddr + EL3_CMD);
411  nic->ioaddr + EL3_CMD);
412 
413 }
414 
415 /**************************************************************************
416 POLL - Wait for a frame
417 ***************************************************************************/
418 static int t515_poll(struct nic *nic, int retrieve)
419 {
420  short status, cst;
421  register short rx_fifo;
422 
423  cst = inw(nic->ioaddr + EL3_STATUS);
424 
425  if ((cst & RxComplete) == 0) {
426  /* Ack all pending events, and set active indicator mask. */
428  nic->ioaddr + EL3_CMD);
430  StatsFull | (vp->
431  bus_master ? DMADone : 0) | UpComplete |
433  return 0;
434  }
435  status = inw(nic->ioaddr + RxStatus);
436 
437  if (status & RxDError) {
438  printf("RxDError\n");
440  return 0;
441  }
442 
443  rx_fifo = status & RX_BYTES_MASK;
444  if (rx_fifo == 0)
445  return 0;
446 
447  if ( ! retrieve ) return 1;
448 
449  DBG ( "[l=%d", rx_fifo );
450  insw(nic->ioaddr + RX_FIFO, nic->packet, rx_fifo / 2);
451  if (rx_fifo & 1)
452  nic->packet[rx_fifo - 1] = inb(nic->ioaddr + RX_FIFO);
453  nic->packetlen = rx_fifo;
454 
455  while (1) {
456  status = inw(nic->ioaddr + RxStatus);
457  DBG ( "0x%hX*", status );
458  rx_fifo = status & RX_BYTES_MASK;
459 
460  if (rx_fifo > 0) {
462  rx_fifo / 2);
463  if (rx_fifo & 1)
464  nic->packet[nic->packetlen + rx_fifo - 1] =
465  inb(nic->ioaddr + RX_FIFO);
466  nic->packetlen += rx_fifo;
467  DBG ( "+%d", rx_fifo );
468  }
469  if ((status & RxComplete) == 0) {
470  DBG ( "=%d", nic->packetlen );
471  break;
472  }
473  udelay(1000);
474  }
475 
476  /* acknowledge reception of packet */
478  while (inw(nic->ioaddr + EL3_STATUS) & CmdInProgress);
479 #ifdef debug_3c515
480  {
481  unsigned short type = 0;
482  type = (nic->packet[12] << 8) | nic->packet[13];
483  if (nic->packet[0] + nic->packet[1] + nic->packet[2] +
484  nic->packet[3] + nic->packet[4] + nic->packet[5] ==
485  0xFF * ETH_ALEN)
486  DBG ( ",t=0x%hX,b]", type );
487  else
488  DBG ( ",t=0x%hX]", type );
489  }
490 #endif
491 
492  return 1;
493 }
494 
495 /*************************************************************************
496  3Com 515 - specific routines
497 **************************************************************************/
498 static char padmap[] = {
499  0, 3, 2, 1
500 };
501 /**************************************************************************
502 TRANSMIT - Transmit a frame
503 ***************************************************************************/
504 static void t515_transmit(struct nic *nic, const char *d, /* Destination */
505  unsigned int t, /* Type */
506  unsigned int s, /* size */
507  const char *p)
508 { /* Packet */
509  register int len;
510  int pad;
511  int status;
512 
513  DBG ( "{l=%d,t=0x%hX}", s + ETH_HLEN, t );
514 
515  /* swap bytes of type */
516  t = htons(t);
517 
518  len = s + ETH_HLEN; /* actual length of packet */
519  pad = padmap[len & 3];
520 
521  /*
522  * The 3c515 automatically pads short packets to minimum ethernet length,
523  * but we drop packets that are too large. Perhaps we should truncate
524  * them instead?
525  Copied from 3c595. Is this true for the 3c515?
526  */
527  if (len + pad > ETH_FRAME_LEN) {
528  return;
529  }
530  /* drop acknowledgements */
531  while ((status = inb(nic->ioaddr + TxStatus)) & TxComplete) {
532  /*if(status & (TXS_UNDERRUN|0x88|TXS_STATUS_OVERFLOW)) { */
535 /* } */
536 
537  outb(0x0, nic->ioaddr + TxStatus);
538  }
539 
540  while (inw(nic->ioaddr + TxFree) < len + pad + 4) {
541  /* no room in FIFO */
542  }
543 
544  outw(len, nic->ioaddr + TX_FIFO);
545  outw(0x0, nic->ioaddr + TX_FIFO); /* Second dword meaningless */
546 
547  /* write packet */
548  outsw(nic->ioaddr + TX_FIFO, d, ETH_ALEN / 2);
550  outw(t, nic->ioaddr + TX_FIFO);
551  outsw(nic->ioaddr + TX_FIFO, p, s / 2);
552 
553  if (s & 1)
554  outb(*(p + s - 1), nic->ioaddr + TX_FIFO);
555 
556  while (pad--)
557  outb(0, nic->ioaddr + TX_FIFO); /* Padding */
558 
559  /* wait for Tx complete */
560  while ((inw(nic->ioaddr + EL3_STATUS) & CmdInProgress) != 0);
561 }
562 
563 /**************************************************************************
564 DISABLE - Turn off ethernet interface
565 ***************************************************************************/
566 static void t515_disable ( struct nic *nic,
567  struct isapnp_device *isapnp ) {
568 
569  t515_reset(nic);
570 
571  /* This is a hack. Since ltsp worked on my
572  system without any disable functionality I
573  have no way to determine if this works */
574 
575  /* Disable the receiver and transmitter. */
578 
579  if (if_port == XCVR_10base2)
580  /* Turn off thinnet power. Green! */
582 
583 
584  outw(SetIntrEnb | 0x0000, nic->ioaddr + EL3_CMD);
585 
586  deactivate_isapnp_device ( isapnp );
587  return;
588 }
589 
590 static void t515_irq(struct nic *nic __unused, irq_action_t action __unused)
591 {
592  switch ( action ) {
593  case DISABLE :
594  break;
595  case ENABLE :
596  break;
597  case FORCE :
598  break;
599  }
600 }
601 
604  .poll = t515_poll,
605  .transmit = t515_transmit,
606  .irq = t515_irq,
607 
608 };
609 
610 /**************************************************************************
611 PROBE - Look for an adapter, this routine's visible to the outside
612 You should omit the last argument struct pci_device * for a non-PCI NIC
613 ***************************************************************************/
614 static int t515_probe ( struct nic *nic, struct isapnp_device *isapnp ) {
615 
616  /* Direct copy from Beckers 3c515.c removing any ISAPNP sections */
617 
618  nic->ioaddr = isapnp->ioaddr;
619  nic->irqno = isapnp->irqno;
620  activate_isapnp_device ( isapnp );
621 
622  /* Check the resource configuration for a matching ioaddr. */
623  if ((unsigned)(inw(nic->ioaddr + 0x2002) & 0x1f0)
624  != (nic->ioaddr & 0x1f0)) {
625  DBG ( "3c515 ioaddr mismatch\n" );
626  return 0;
627  }
628 
629  /* Verify by reading the device ID from the EEPROM. */
630  {
631  int timer;
633  /* Pause for at least 162 us. for the read to take place. */
634  for (timer = 4; timer >= 0; timer--) {
635  t3c515_wait(1);
636  if ((inw(nic->ioaddr + Wn0EepromCmd) & 0x0200) == 0)
637  break;
638  }
639  if (inw(nic->ioaddr + Wn0EepromData) != 0x6d50) {
640  DBG ( "3c515 read incorrect vendor ID from EEPROM" );
641  return 0;
642  }
643 
644  }
645  DBG ( "3c515 Resource configuration register 0x%X, DCR 0x%hX.\n",
646  inl(nic->ioaddr + 0x2002), inw(nic->ioaddr + 0x2000) );
648  options, nic);
649 
650  t515_reset(nic);
652  return 1;
653 }
654 
655 static int
657  int product_index, int options, struct nic *nic)
658 {
659  /* Direct copy from Becker 3c515.c with unnecessary parts removed */
660  vp->product_name = "3c515";
661  vp->options = options;
662  if (options >= 0) {
663  vp->media_override =
664  ((options & 7) == 2) ? 0 : options & 7;
665  vp->full_duplex = (options & 8) ? 1 : 0;
666  vp->bus_master = (options & 16) ? 1 : 0;
667  } else {
668  vp->media_override = 7;
669  vp->full_duplex = 0;
670  vp->bus_master = 0;
671  }
672 
673  corkscrew_probe1(ioaddr, irq, product_index, nic);
674  return 0;
675 }
676 
677 static int
678 corkscrew_probe1(int ioaddr, int irq, int product_index __unused,
679  struct nic *nic)
680 {
681  unsigned int eeprom[0x40], checksum = 0; /* EEPROM contents */
682  int i;
683 
684  printf("3Com %s at 0x%hX, ", vp->product_name, ioaddr);
685 
686  /* Read the station address from the EEPROM. */
687  EL3WINDOW(0);
688  for (i = 0; i < 0x18; i++) {
689  short *phys_addr = (short *) nic->node_addr;
690  int timer;
692  /* Pause for at least 162 us. for the read to take place. */
693  for (timer = 4; timer >= 0; timer--) {
694  t3c515_wait(1);
695  if ((inw(ioaddr + Wn0EepromCmd) & 0x0200) == 0)
696  break;
697  }
698  eeprom[i] = inw(ioaddr + Wn0EepromData);
699  DBG ( "Value %d: %hX ", i, eeprom[i] );
700  checksum ^= eeprom[i];
701  if (i < 3)
702  phys_addr[i] = htons(eeprom[i]);
703  }
704  checksum = (checksum ^ (checksum >> 8)) & 0xff;
705  if (checksum != 0x00)
706  printf(" ***INVALID CHECKSUM 0x%hX*** ", checksum);
707 
708  DBG ( "%s", eth_ntoa ( nic->node_addr ) );
709 
710  if (eeprom[16] == 0x11c7) { /* Corkscrew */
711 
712  }
713  printf(", IRQ %d\n", irq);
714  /* Tell them about an invalid IRQ. */
715  if ( (irq <= 0 || irq > 15) ) {
716  DBG (" *** Warning: this IRQ is unlikely to work! ***\n" );
717  }
718 
719  {
720  char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" };
721  union wn3_config config;
722  EL3WINDOW(3);
724  config.i = inl(ioaddr + Wn3_Config);
725  DBG ( " Internal config register is %4.4x, "
726  "transceivers 0x%hX.\n",
727  config.i, inw(ioaddr + Wn3_Options) );
728  printf
729  (" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
730  8 << config.u.ram_size,
731  config.u.ram_width ? "word" : "byte",
732  ram_split[config.u.ram_split],
733  config.u.autoselect ? "autoselect/" : "",
734  media_tbl[config.u.xcvr].name);
735  if_port = config.u.xcvr;
736  vp->default_media = config.u.xcvr;
737  vp->autoselect = config.u.autoselect;
738  }
739  if (vp->media_override != 7) {
740  printf(" Media override to transceiver type %d (%s).\n",
744  }
745 
746  vp->capabilities = eeprom[16];
747  vp->full_bus_master_tx = (vp->capabilities & 0x20) ? 1 : 0;
748  /* Rx is broken at 10mbps, so we always disable it. */
749  /* vp->full_bus_master_rx = 0; */
750  vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0;
751 
752  return 0;
753 }
754 
755 static struct isapnp_device_id t515_adapters[] = {
756  { "3c515 (ISAPnP)", ISAPNP_VENDOR('T','C','M'), 0x5051 },
757 };
758 
759 ISAPNP_DRIVER ( t515_driver, t515_adapters );
760 
761 DRIVER ( "3c515", nic_driver, isapnp_driver, t515_driver,
763 
764 ISA_ROM ( "3c515", "3c515 Fast EtherLink ISAPnP" );
struct sk_buff * tx_skbuff[TX_RING_SIZE]
Definition: 3c515.c:226
unsigned char irqno
Definition: nic.h:56
Definition: nic.h:35
const char * name
Definition: ath9k_hw.c:1984
static void t515_irq(struct nic *nic __unused, irq_action_t action __unused)
Definition: 3c515.c:590
Win0_EEPROM_bits
Definition: 3c515.c:154
u32 next
Definition: 3c515.c:199
uint8_t checksum
Checksum.
Definition: pnpbios.c:37
struct boom_tx_desc tx_ring[TX_RING_SIZE]
Definition: 3c515.c:223
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
uint16_t inw(volatile uint16_t *io_addr)
Read 16-bit word from I/O-mapped device.
s32 status
Definition: 3c515.c:200
Window0
Definition: 3c515.c:144
static void deactivate_isapnp_device(struct isapnp_device *isapnp)
Deactivate ISAPnP device.
Definition: isapnp.h:256
MasterCtrl
Definition: 3c515.c:189
const char * product_name
Definition: 3c515.c:219
An ISAPnP driver.
Definition: isapnp.h:209
unsigned int autoselect
Definition: 3c515.c:233
#define outw(data, io_addr)
Definition: io.h:319
RxFilter
Definition: 3c515.c:123
int32_t s32
Definition: stdint.h:22
unsigned int tx_full
Definition: 3c515.c:233
An ISAPnP device ID list entry.
Definition: isapnp.h:173
Definition: 3c515.c:109
Definition: 3c515.c:140
unsigned int full_bus_master_rx
Definition: 3c515.c:233
unsigned int bus_master
Definition: 3c515.c:233
uint8_t type
Type.
Definition: ena.h:16
static int corkscrew_probe1(int ioaddr, int irq, int product_index, struct nic *nic)
Definition: 3c515.c:678
void outsw(volatile uint16_t *io_addr, const uint16_t *data, unsigned int count)
Write 16-bit words to I/O-mapped device.
Window1
Definition: 3c515.c:139
Definition: 3c515.c:142
int capabilities
Definition: 3c515.c:230
#define PKT_BUF_SZ
Definition: 3c515.c:88
void(* irq)(struct nic *, irq_action_t)
Definition: nic.h:67
u32 pad[9]
Padding.
Definition: ar9003_mac.h:90
u32 next
Definition: 3c515.c:212
uint16_t ioaddr
I/O address.
Definition: isapnp.h:191
int dummy_connect(struct nic *nic __unused)
Definition: legacy.c:151
static int t515_probe(struct nic *nic, struct isapnp_device *isapnp)
Definition: 3c515.c:614
u32 addr
Definition: 3c515.c:214
Definition: 3c515.c:141
A timer.
Definition: timer.h:28
eeprom
Definition: 3c90x.h:232
unsigned int ram_speed
Definition: 3c515.c:166
uint8_t status
Status.
Definition: ena.h:16
unsigned int available_media
Definition: 3c515.c:233
#define HZ
Definition: 3c515.c:65
FILE_LICENCE(GPL2_OR_LATER)
static void t515_disable(struct nic *nic, struct isapnp_device *isapnp)
Definition: 3c515.c:566
static unsigned long ioaddr
Definition: davicom.c:129
unsigned int ioaddr
Definition: nic.h:55
#define EL3_CMD
Definition: 3c515.c:102
Definition: 3c515.c:130
#define ETH_HLEN
Definition: if_ether.h:9
Definition: 3c515.c:112
struct sk_buff * rx_skbuff[RX_RING_SIZE]
Definition: 3c515.c:225
Ethernet protocol.
struct boom_rx_desc rx_ring[RX_RING_SIZE]
Definition: 3c515.c:222
#define ETH_FRAME_LEN
Definition: if_ether.h:11
static int options
Definition: 3c515.c:286
static struct nic_operations t515_operations
Definition: 3c515.c:602
xcvr_types
Definition: 3c515.c:244
unsigned int full_duplex
Definition: 3c515.c:233
Window4
Definition: 3c515.c:175
static void t515_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
Definition: 3c515.c:504
unsigned int dirty_rx
Definition: 3c515.c:228
unsigned int mask
Definition: 3c515.c:252
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition: timer.c:60
#define EL3WINDOW(win_num)
Definition: 3c515.c:100
irq_action_t
Definition: nic.h:34
unsigned int next
Definition: 3c515.c:252
unsigned int default_media
Definition: 3c515.c:233
s32 length
Definition: 3c515.c:202
Window7
Definition: 3c515.c:184
Definition: 3c515.c:132
corkscrew_status
Definition: 3c515.c:128
static void t3c515_wait(unsigned int nticks)
Definition: 3c515.c:57
Definition: 3c515.c:145
unsigned int packetlen
Definition: nic.h:54
s32 length
Definition: 3c515.c:215
An ISAPnP device.
Definition: isapnp.h:183
UpPktStatus
Definition: 3c90x.h:213
#define ISAPNP_VENDOR(a, b, c)
Definition: isa_ids.h:35
int last_rx_packets
Definition: 3c515.c:232
#define RX_BYTES_MASK
Definition: 3c515.c:104
#define outl(data, io_addr)
Definition: io.h:329
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition: ethernet.c:175
static char padmap[]
Definition: 3c515.c:498
struct sk_buff * tx_skb
Definition: 3c515.c:229
A network device.
Definition: netdevice.h:348
char * name
Definition: 3c515.c:251
int i
Definition: 3c515.c:164
unsigned int ram_size
Definition: 3c515.c:166
void insw(volatile uint16_t *io_addr, uint16_t *data, unsigned int count)
Read 16-bit words from I/O-mapped device.
unsigned int rom_size
Definition: 3c515.c:166
uint8_t inb(volatile uint8_t *io_addr)
Read byte from I/O-mapped device.
#define ETH_ALEN
Definition: if_ether.h:8
Definition: nic.h:37
Definition: nic.h:49
static struct isapnp_device_id t515_adapters[]
Definition: 3c515.c:755
Definition: 3c515.c:108
#define RX_RING_SIZE
Definition: 3c515.c:87
corkscrew_cmd
Definition: 3c515.c:106
struct net_device * next_module
Definition: 3c515.c:220
struct wn3_config::w3_config_fields u
Definition: 3c515.c:113
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
static struct corkscrew_private * vp
Definition: 3c515.c:67
Definition: nic.h:36
unsigned char * packet
Definition: nic.h:53
uint8_t irqno
Interrupt number.
Definition: isapnp.h:193
unsigned char * node_addr
Definition: nic.h:52
#define outb(data, io_addr)
Definition: io.h:309
Definition: 3c515.c:190
Definition: 3c515.c:131
uint32_t len
Length.
Definition: ena.h:14
static void t515_reset(struct nic *nic)
Definition: 3c515.c:293
s32 status
Definition: 3c515.c:213
u32 addr
Definition: 3c515.c:201
static void activate_isapnp_device(struct isapnp_device *isapnp)
Activate ISAPnP device.
Definition: isapnp.h:247
static struct timer * timer
Current timer.
Definition: timer.c:35
unsigned int dirty_tx
Definition: 3c515.c:228
uint32_t inl(volatile uint32_t *io_addr)
Read 32-bit dword from I/O-mapped device.
unsigned int full_bus_master_tx
Definition: 3c515.c:233
unsigned int ram_split
Definition: 3c515.c:169
static int if_port
Definition: 3c515.c:66
unsigned int autoselect
Definition: 3c515.c:169
static int t515_poll(struct nic *nic, int retrieve)
Definition: 3c515.c:418
unsigned int media_override
Definition: 3c515.c:233
unsigned int cur_tx
Definition: 3c515.c:227
unsigned int ram_width
Definition: 3c515.c:166
unsigned int cur_rx
Definition: 3c515.c:227
Definition: 3c515.c:140
#define CORKSCREW_ID
Definition: 3c515.c:98
Definition: 3c515.c:124
rx_desc_status
Definition: 3c515.c:206
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
int(* connect)(struct nic *)
Definition: nic.h:63
Win4_Media_bits
Definition: 3c515.c:178
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static struct media_table media_tbl[]
static int corkscrew_found_device(int ioaddr, int irq, int product_index, int options, struct nic *nic)
Definition: 3c515.c:656
#define EL3_STATUS
Definition: 3c515.c:103
#define htons(value)
Definition: byteswap.h:135
ISAPNP_DRIVER(t515_driver, t515_adapters)
uint32_t u32
Definition: stdint.h:23
#define TX_RING_SIZE
Definition: 3c515.c:86
unsigned int media_bits
Definition: 3c515.c:252
if(natsemi->flags &NATSEMI_64BIT) return 1
Window3
Definition: 3c515.c:160
DRIVER("3c515", nic_driver, isapnp_driver, t515_driver, t515_probe, t515_disable)
short wait
Definition: 3c515.c:255
ISA_ROM("3c515", "3c515 Fast EtherLink ISAPnP")