tulip.c

Go to the documentation of this file.
00001 /* -*- Mode:C; c-basic-offset:4; -*- */
00002 
00003 /*
00004   Tulip and clone Etherboot Driver
00005 
00006   By Marty Connor (mdc@etherboot.org)
00007   Copyright (C) 2001 Entity Cyber, Inc.
00008 
00009   This software may be used and distributed according to the terms
00010   of the GNU Public License, incorporated herein by reference.
00011 
00012   As of April 2001 this driver should support most tulip cards that 
00013   the Linux tulip driver supports because Donald Becker's Linux media 
00014   detection code is now included.
00015 
00016   Based on Ken Yap's Tulip Etherboot Driver and Donald Becker's
00017   Linux Tulip Driver. Supports N-Way speed auto-configuration on
00018   MX98715, MX98715A and MX98725. Support inexpensive PCI 10/100 cards
00019   based on the Macronix MX987x5 chip, such as the SOHOware Fast
00020   model SFA110A, and the LinkSYS model LNE100TX. The NetGear
00021   model FA310X, based on the LC82C168 chip is supported.
00022   The TRENDnet TE100-PCIA NIC which uses a genuine Intel 21143-PD
00023   chipset is supported. Also, Davicom DM9102's.
00024 
00025   Documentation and source code used:
00026   Source for Etherboot driver at
00027   http://etherboot.sourceforge.net/
00028   MX98715A Data Sheet and MX98715A Application Note
00029   on http://www.macronix.com/  (PDF format files)
00030   Source for Linux tulip driver at
00031   http://cesdis.gsfc.nasa.gov/linux/drivers/tulip.html
00032 
00033   Adapted by Ken Yap from
00034   FreeBSD netboot DEC 21143 driver
00035   Author: David Sharp
00036   date: Nov/98
00037 
00038   Some code fragments were taken from verious places, Ken Yap's
00039   etherboot, FreeBSD's if_de.c, and various Linux related files.
00040   DEC's manuals for the 21143 and SROM format were very helpful.
00041   The Linux de driver development page has a number of links to
00042   useful related information.  Have a look at:
00043   ftp://cesdis.gsfc.nasa.gov/pub/linux/drivers/tulip-devel.html
00044 */
00045 
00046 FILE_LICENCE ( GPL_ANY );
00047 
00048 /*********************************************************************/
00049 /* Revision History                                                  */
00050 /*********************************************************************/
00051 
00052 /*
00053   08 Feb 2005  Ramesh Chander chhabaramesh at yahoo.co.in added table entries
00054                for SGThomson STE10/100A
00055   07 Sep 2003  timlegge Multicast Support Added
00056   11 Apr 2001  mdc     [patch to etherboot 4.7.24]
00057      Major rewrite to include Linux tulip driver media detection
00058      code.  This driver should support a lot more cards now.
00059   16 Jul 2000  mdc     0.75b11
00060      Added support for ADMtek 0985 Centaur-P, a "Comet" tulip clone
00061      which is used on the LinkSYS LNE100TX v4.x cards.  We already
00062      support LNE100TX v2.0 cards, which use a different controller.
00063   04 Jul 2000   jam     ?
00064      Added test of status after receiving a packet from the card.
00065      Also uncommented the tulip_disable routine.  Stray packets
00066      seemed to be causing problems.
00067   27 Apr 2000   njl     ?
00068   29 Feb 2000   mdc     0.75b7
00069      Increased reset delay to 3 seconds because Macronix cards seem to
00070      need more reset time before card comes back to a usable state.
00071   26 Feb 2000   mdc     0.75b6
00072      Added a 1 second delay after initializing the transmitter because
00073      some cards seem to need the time or they drop the first packet 
00074      transmitted.
00075   23 Feb 2000   mdc     0.75b5
00076      removed udelay code and used currticks() for more reliable delay
00077      code in reset pause and sanity timeouts.  Added function prototypes
00078      and TX debugging code.
00079   21 Feb 2000   mdc     patch to Etherboot 4.4.3
00080      Incorporated patches from Bob Edwards and Paul Mackerras of 
00081      Linuxcare's OZLabs to deal with inefficiencies in tulip_transmit
00082      and udelay.  We now wait for packet transmission to complete
00083      (or sanity timeout).
00084   04 Feb 2000   Robert.Edwards@anu.edu.au patch to Etherboot 4.4.2
00085      patch to tulip.c that implements the automatic selection of the MII
00086      interface on cards using the Intel/DEC 21143 reference design, in
00087      particular, the TRENDnet TE100-PCIA NIC which uses a genuine Intel
00088      21143-PD chipset.
00089   11 Jan 2000   mdc     0.75b4
00090      Added support for NetGear FA310TX card based on the LC82C168
00091      chip.  This should also support Lite-On LC82C168 boards.
00092      Added simple MII support. Re-arranged code to better modularize
00093      initializations.
00094   04 Dec 1999   mdc     0.75b3
00095      Added preliminary support for LNE100TX PCI cards.  Should work for
00096      PNIC2 cards. No MII support, but single interface (RJ45) tulip
00097      cards seem to not care.
00098   03 Dec 1999   mdc     0.75b2
00099      Renamed from mx987x5 to tulip, merged in original tulip init code
00100      from tulip.c to support other tulip compatible cards.
00101   02 Dec 1999   mdc     0.75b1
00102      Released Beta MX987x5 Driver for code review and testing to netboot
00103      and thinguin mailing lists.
00104 */
00105 
00106 
00107 /*********************************************************************/
00108 /* Declarations                                                      */
00109 /*********************************************************************/
00110 
00111 #include "etherboot.h"
00112 #include "nic.h"
00113 
00114 #include <gpxe/ethernet.h>
00115 #include <gpxe/pci.h>
00116 
00117 /* User settable parameters */
00118 
00119 #undef  TULIP_DEBUG
00120 #undef  TULIP_DEBUG_WHERE
00121 #ifdef  TULIP_DEBUG
00122 static int tulip_debug = 2;             /* 1 normal messages, 0 quiet .. 7 verbose. */
00123 #endif
00124 
00125 #define TX_TIME_OUT       2*TICKS_PER_SEC
00126 
00127 /* helpful macros if on a big_endian machine for changing byte order.
00128    not strictly needed on Intel */
00129 #define get_unaligned(ptr) (*(ptr))
00130 #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
00131 #define get_u16(ptr) (*(u16 *)(ptr))
00132 #define virt_to_le32desc(addr)  virt_to_bus(addr)
00133 
00134 #define TULIP_IOTYPE  PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0
00135 #define TULIP_SIZE 0x80
00136 
00137 /* This is a mysterious value that can be written to CSR11 in the 21040 (only)
00138    to support a pre-NWay full-duplex signaling mechanism using short frames.
00139    No one knows what it should be, but if left at its default value some
00140    10base2(!) packets trigger a full-duplex-request interrupt. */
00141 #define FULL_DUPLEX_MAGIC       0x6969
00142 
00143 static const int csr0 = 0x01A00000 | 0x8000;
00144 
00145 /*  The possible media types that can be set in options[] are: */
00146 #define MEDIA_MASK 31
00147 static const char * const medianame[32] = {
00148     "10baseT", "10base2", "AUI", "100baseTx",
00149     "10baseT-FDX", "100baseTx-FDX", "100baseT4", "100baseFx",
00150     "100baseFx-FDX", "MII 10baseT", "MII 10baseT-FDX", "MII",
00151     "10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FDX", "MII 100baseT4",
00152     "MII 100baseFx-HDX", "MII 100baseFx-FDX", "Home-PNA 1Mbps", "Invalid-19",
00153 };
00154 
00155 /* This much match tulip_tbl[]!  Note 21142 == 21143. */
00156 enum tulip_chips {
00157     DC21040=0, DC21041=1, DC21140=2, DC21142=3, DC21143=3,
00158     LC82C168, MX98713, MX98715, MX98725, AX88141, AX88140, PNIC2, COMET,
00159     COMPEX9881, I21145, XIRCOM, SGThomson,      /*Ramesh Chander*/
00160 };
00161 
00162 enum pci_id_flags_bits {
00163     /* Set PCI command register bits before calling probe1(). */
00164     PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
00165     /* Read and map the single following PCI BAR. */
00166     PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4,
00167     PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400,
00168     PCI_UNUSED_IRQ=0x800,
00169 };
00170 
00171 struct pci_id_info {
00172     char *name;
00173     struct match_info {
00174         u32 pci, pci_mask, subsystem, subsystem_mask;
00175         u32 revision, revision_mask;                            /* Only 8 bits. */
00176     } id;
00177     enum pci_id_flags_bits pci_flags;
00178     int io_size;                                /* Needed for I/O region check or ioremap(). */
00179     int drv_flags;                              /* Driver use, intended as capability flags. */
00180 };
00181 
00182 static const struct pci_id_info pci_id_tbl[] = {
00183     { "Digital DC21040 Tulip", { 0x00021011, 0xffffffff, 0, 0, 0, 0 },
00184       TULIP_IOTYPE, 0x80, DC21040 },
00185     { "Digital DC21041 Tulip", { 0x00141011, 0xffffffff, 0, 0, 0, 0 },
00186       TULIP_IOTYPE, 0x80, DC21041 },
00187     { "Digital DS21140A Tulip", { 0x00091011, 0xffffffff, 0,0, 0x20,0xf0 },
00188       TULIP_IOTYPE, 0x80, DC21140 },
00189     { "Digital DS21140 Tulip", { 0x00091011, 0xffffffff, 0, 0, 0, 0 },
00190       TULIP_IOTYPE, 0x80, DC21140 },
00191     { "Digital DS21143 Tulip", { 0x00191011, 0xffffffff, 0,0, 65,0xff },
00192       TULIP_IOTYPE, TULIP_SIZE, DC21142 },
00193     { "Digital DS21142 Tulip", { 0x00191011, 0xffffffff, 0, 0, 0, 0 },
00194       TULIP_IOTYPE, TULIP_SIZE, DC21142 },
00195     { "Kingston KNE110tx (PNIC)", { 0x000211AD, 0xffffffff, 0xf0022646, 0xffffffff, 0, 0 },
00196       TULIP_IOTYPE, 256, LC82C168 },
00197     { "Lite-On 82c168 PNIC", { 0x000211AD, 0xffffffff, 0, 0, 0, 0 },
00198       TULIP_IOTYPE, 256, LC82C168 },
00199     { "Macronix 98713 PMAC", { 0x051210d9, 0xffffffff, 0, 0, 0, 0 },
00200       TULIP_IOTYPE, 256, MX98713 },
00201     { "Macronix 98715 PMAC", { 0x053110d9, 0xffffffff, 0, 0, 0, 0 },
00202       TULIP_IOTYPE, 256, MX98715 },
00203     { "Macronix 98725 PMAC", { 0x053110d9, 0xffffffff, 0, 0, 0, 0 },
00204       TULIP_IOTYPE, 256, MX98725 },
00205     { "ASIX AX88141", { 0x1400125B, 0xffffffff, 0,0, 0x10, 0xf0 },
00206       TULIP_IOTYPE, 128, AX88141 },
00207     { "ASIX AX88140", { 0x1400125B, 0xffffffff, 0, 0, 0, 0 },
00208       TULIP_IOTYPE, 128, AX88140 },
00209     { "Lite-On LC82C115 PNIC-II", { 0xc11511AD, 0xffffffff, 0, 0, 0, 0 },
00210       TULIP_IOTYPE, 256, PNIC2 },
00211     { "ADMtek AN981 Comet", { 0x09811317, 0xffffffff, 0, 0, 0, 0 },
00212       TULIP_IOTYPE, 256, COMET },
00213     { "ADMTek AN983 Comet", { 0x12161113, 0xffffffff, 0, 0, 0, 0 },
00214       TULIP_IOTYPE, 256, COMET },
00215     { "ADMTek Comet AN983b", { 0x95111317, 0xffffffff, 0, 0, 0, 0 },
00216       TULIP_IOTYPE, 256, COMET },
00217     { "ADMtek Centaur-P", { 0x09851317, 0xffffffff, 0, 0, 0, 0 },
00218       TULIP_IOTYPE, 256, COMET },
00219     { "ADMtek Centaur-C", { 0x19851317, 0xffffffff, 0, 0, 0, 0 },
00220       TULIP_IOTYPE, 256, COMET },
00221     { "Compex RL100-TX", { 0x988111F6, 0xffffffff, 0, 0, 0, 0 },
00222       TULIP_IOTYPE, 128, COMPEX9881 },
00223     { "Intel 21145 Tulip", { 0x00398086, 0xffffffff, 0, 0, 0, 0 },
00224       TULIP_IOTYPE, 128, I21145 },
00225     { "Xircom Tulip clone", { 0x0003115d, 0xffffffff, 0, 0, 0, 0 },
00226       TULIP_IOTYPE, 128, XIRCOM },
00227     { "Davicom DM9102", { 0x91021282, 0xffffffff, 0, 0, 0, 0 },
00228       TULIP_IOTYPE, 0x80, DC21140 },
00229     { "Davicom DM9100", { 0x91001282, 0xffffffff, 0, 0, 0, 0 },
00230       TULIP_IOTYPE, 0x80, DC21140 },
00231     { "Macronix mxic-98715 (EN1217)", { 0x12171113, 0xffffffff, 0, 0, 0, 0 },
00232       TULIP_IOTYPE, 256, MX98715 },
00233     { "3Com 3cSOHO100B-TX (ADMtek Centuar)", { 0x930010b7, 0xffffffff, 0, 0, 0, 0 },
00234       TULIP_IOTYPE, TULIP_SIZE, COMET },
00235     { "SG Thomson STE10/100A", { 0x2774104a, 0xffffffff, 0, 0, 0, 0 },
00236       TULIP_IOTYPE, 256, COMET },       /*Ramesh Chander*/
00237     { 0, { 0, 0, 0, 0, 0, 0 }, 0, 0, 0 },
00238 };
00239 
00240 enum tbl_flag {
00241     HAS_MII=1, HAS_MEDIA_TABLE=2, CSR12_IN_SROM=4, ALWAYS_CHECK_MII=8,
00242     HAS_PWRDWN=0x10, MC_HASH_ONLY=0x20, /* Hash-only multicast filter. */
00243     HAS_PNICNWAY=0x80, HAS_NWAY=0x40,   /* Uses internal NWay xcvr. */
00244     HAS_INTR_MITIGATION=0x100, IS_ASIX=0x200, HAS_8023X=0x400,
00245 };
00246 
00247 /* Note: this table must match  enum tulip_chips  above. */
00248 static struct tulip_chip_table {
00249     char *chip_name;
00250     int flags;
00251 } tulip_tbl[] = {
00252     { "Digital DC21040 Tulip", 0},
00253     { "Digital DC21041 Tulip", HAS_MEDIA_TABLE | HAS_NWAY },
00254     { "Digital DS21140 Tulip", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM },
00255     { "Digital DS21143 Tulip", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII 
00256       | HAS_PWRDWN | HAS_NWAY   | HAS_INTR_MITIGATION },
00257     { "Lite-On 82c168 PNIC", HAS_MII | HAS_PNICNWAY },
00258     { "Macronix 98713 PMAC", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM },
00259     { "Macronix 98715 PMAC", HAS_MEDIA_TABLE },
00260     { "Macronix 98725 PMAC", HAS_MEDIA_TABLE },
00261     { "ASIX AX88140", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM 
00262       | MC_HASH_ONLY | IS_ASIX },
00263     { "ASIX AX88141", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY 
00264       | IS_ASIX },
00265     { "Lite-On PNIC-II", HAS_MII | HAS_NWAY | HAS_8023X },
00266     { "ADMtek Comet", HAS_MII | MC_HASH_ONLY },
00267     { "Compex 9881 PMAC",       HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM },
00268     { "Intel DS21145 Tulip", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII 
00269       | HAS_PWRDWN | HAS_NWAY },
00270     { "Xircom tulip work-alike", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII 
00271       | HAS_PWRDWN | HAS_NWAY },
00272     { "SGThomson STE10/100A", HAS_MII | MC_HASH_ONLY }, /*Ramesh Chander*/   
00273     { 0, 0 },
00274 };
00275 
00276 /* A full-duplex map for media types. */
00277 enum MediaIs {
00278     MediaIsFD = 1, MediaAlwaysFD=2, MediaIsMII=4, MediaIsFx=8,
00279     MediaIs100=16};
00280 
00281 static const char media_cap[32] =
00282 {0,0,0,16,  3,19,16,24,  27,4,7,5, 0,20,23,20, 20,31,0,0, };
00283 static u8 t21040_csr13[] = {2,0x0C,8,4,  4,0,0,0, 0,0,0,0, 4,0,0,0};
00284 
00285 /* 21041 transceiver register settings: 10-T, 10-2, AUI, 10-T, 10T-FD */
00286 static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, };
00287 static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, };
00288 static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
00289 
00290 /* not used
00291 static u16 t21142_csr13[] = { 0x0001, 0x0009, 0x0009, 0x0000, 0x0001, };
00292 */
00293 static u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, };
00294 /* not used
00295 static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
00296 */
00297 
00298 /* Offsets to the Command and Status Registers, "CSRs".  All accesses
00299    must be longword instructions and quadword aligned. */
00300 enum tulip_offsets {
00301     CSR0=0,     CSR1=0x08,  CSR2=0x10,  CSR3=0x18,  CSR4=0x20,  CSR5=0x28,
00302     CSR6=0x30,  CSR7=0x38,  CSR8=0x40,  CSR9=0x48, CSR10=0x50, CSR11=0x58,
00303     CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0
00304 };
00305 
00306 /* The bits in the CSR5 status registers, mostly interrupt sources. */
00307 enum status_bits {
00308     TimerInt=0x800, TPLnkFail=0x1000, TPLnkPass=0x10,
00309     NormalIntr=0x10000, AbnormalIntr=0x8000,
00310     RxJabber=0x200, RxDied=0x100, RxNoBuf=0x80, RxIntr=0x40,
00311     TxFIFOUnderflow=0x20, TxJabber=0x08, TxNoBuf=0x04, TxDied=0x02, TxIntr=0x01,
00312 };
00313 
00314 /* The configuration bits in CSR6. */
00315 enum csr6_mode_bits {
00316         TxOn=0x2000, RxOn=0x0002, FullDuplex=0x0200,
00317         AcceptBroadcast=0x0100, AcceptAllMulticast=0x0080,
00318         AcceptAllPhys=0x0040, AcceptRunt=0x0008,
00319 };
00320 
00321 
00322 enum desc_status_bits {
00323     DescOwnded=0x80000000, RxDescFatalErr=0x8000, RxWholePkt=0x0300,
00324 };
00325 
00326 struct medialeaf {
00327     u8 type;
00328     u8 media;
00329     unsigned char *leafdata;
00330 };
00331 
00332 struct mediatable {
00333     u16 defaultmedia;
00334     u8 leafcount, csr12dir;                             /* General purpose pin directions. */
00335     unsigned has_mii:1, has_nonmii:1, has_reset:6;
00336     u32 csr15dir, csr15val;                             /* 21143 NWay setting. */
00337     struct medialeaf mleaf[0];
00338 };
00339 
00340 struct mediainfo {
00341     struct mediainfo *next;
00342     int info_type;
00343     int index;
00344     unsigned char *info;
00345 };
00346 
00347 /* EEPROM Address width definitions */
00348 #define EEPROM_ADDRLEN 6
00349 #define EEPROM_SIZE    128              /* 2 << EEPROM_ADDRLEN */
00350 
00351 /* The EEPROM commands include the alway-set leading bit. */
00352 #define EE_WRITE_CMD    (5 << addr_len)
00353 #define EE_READ_CMD     (6 << addr_len)
00354 #define EE_ERASE_CMD    (7 << addr_len)
00355 
00356 /* EEPROM_Ctrl bits. */
00357 #define EE_SHIFT_CLK    0x02    /* EEPROM shift clock. */
00358 #define EE_CS           0x01    /* EEPROM chip select. */
00359 #define EE_DATA_WRITE   0x04    /* EEPROM chip data in. */
00360 #define EE_WRITE_0      0x01
00361 #define EE_WRITE_1      0x05
00362 #define EE_DATA_READ    0x08    /* EEPROM chip data out. */
00363 #define EE_ENB          (0x4800 | EE_CS)
00364 
00365 /* Delay between EEPROM clock transitions.  Even at 33Mhz current PCI
00366    implementations don't overrun the EEPROM clock.  We add a bus
00367    turn-around to insure that this remains true.  */
00368 #define eeprom_delay()  inl(ee_addr)
00369 
00370 /* Size of transmit and receive buffers */
00371 #define BUFLEN 1536
00372 
00373 /* Ring-wrap flag in length field, use for last ring entry.
00374    0x01000000 means chain on buffer2 address,
00375    0x02000000 means use the ring start address in CSR2/3.
00376    Note: Some work-alike chips do not function correctly in chained mode.
00377    The ASIX chip works only in chained mode.
00378    Thus we indicate ring mode, but always write the 'next' field for
00379    chained mode as well. */
00380 #define DESC_RING_WRAP 0x02000000
00381 
00382 /* transmit and receive descriptor format */
00383 struct tulip_rx_desc {
00384     volatile u32 status;
00385     u32 length;
00386     u32 buffer1, buffer2;
00387 };
00388 
00389 struct tulip_tx_desc {
00390     volatile u32 status;
00391     u32 length;
00392     u32 buffer1, buffer2;
00393 };
00394 
00395 /*********************************************************************/
00396 /* Global Storage                                                    */
00397 /*********************************************************************/
00398 
00399 static u32 ioaddr;
00400 
00401 struct tulip_private {
00402     int cur_rx;
00403     int chip_id;                        /* index into tulip_tbl[]  */
00404     int pci_id_idx;                     /* index into pci_id_tbl[] */
00405     int revision;
00406     int flags;
00407     unsigned short vendor_id;           /* PCI card vendor code */
00408     unsigned short dev_id;              /* PCI card device code */
00409     unsigned char ehdr[ETH_HLEN];       /* buffer for ethernet header */
00410     const char *nic_name;
00411     unsigned int csr0, csr6;            /* Current CSR0, CSR6 settings. */
00412     unsigned int if_port;
00413     unsigned int full_duplex;         /* Full-duplex operation requested. */
00414     unsigned int full_duplex_lock;
00415     unsigned int medialock;           /* Do not sense media type. */
00416     unsigned int mediasense;          /* Media sensing in progress. */
00417     unsigned int nway, nwayset;     /* 21143 internal NWay. */
00418     unsigned int default_port;
00419     unsigned char eeprom[EEPROM_SIZE];  /* Serial EEPROM contents. */
00420     u8 media_table_storage[(sizeof(struct mediatable) + 32*sizeof(struct medialeaf))];
00421     u16 sym_advertise, mii_advertise;   /* NWay to-advertise. */
00422     struct mediatable *mtable;
00423     u16 lpar;                           /* 21143 Link partner ability. */
00424     u16 advertising[4];                 /* MII advertise, from SROM table. */
00425     signed char phys[4], mii_cnt;       /* MII device addresses. */
00426     int cur_index;                      /* Current media index. */
00427     int saved_if_port;
00428 };
00429 
00430 /* Note: transmit and receive buffers must be longword aligned and
00431    longword divisable */
00432 
00433 #define TX_RING_SIZE    2
00434 #define RX_RING_SIZE    4
00435 struct {
00436     struct tulip_tx_desc tx_ring[TX_RING_SIZE];
00437     unsigned char txb[BUFLEN];
00438     struct tulip_rx_desc rx_ring[RX_RING_SIZE];
00439     unsigned char rxb[RX_RING_SIZE * BUFLEN];
00440     struct tulip_private tpx;
00441 } tulip_bss __shared __attribute__ ((aligned(4)));
00442 #define tx_ring tulip_bss.tx_ring
00443 #define txb tulip_bss.txb
00444 #define rx_ring tulip_bss.rx_ring
00445 #define rxb tulip_bss.rxb
00446 
00447 static struct tulip_private *tp;
00448 
00449 /* Known cards that have old-style EEPROMs.
00450    Writing this table is described at
00451    http://cesdis.gsfc.nasa.gov/linux/drivers/tulip-drivers/tulip-media.html */
00452 static struct fixups {
00453     char *name;
00454     unsigned char addr0, addr1, addr2;
00455     u16 newtable[32];                           /* Max length below. */
00456 } eeprom_fixups[] = {
00457     {"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c,
00458                             0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }},
00459     {"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f,
00460                                  0x0000, 0x009E, /* 10baseT */
00461                                  0x0004, 0x009E, /* 10baseT-FD */
00462                                  0x0903, 0x006D, /* 100baseTx */
00463                                  0x0905, 0x006D, /* 100baseTx-FD */ }},
00464     {"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x063f,
00465                                    0x0107, 0x8021, /* 100baseFx */
00466                                    0x0108, 0x8021, /* 100baseFx-FD */
00467                                    0x0100, 0x009E, /* 10baseT */
00468                                    0x0104, 0x009E, /* 10baseT-FD */
00469                                    0x0103, 0x006D, /* 100baseTx */
00470                                    0x0105, 0x006D, /* 100baseTx-FD */ }},
00471     {"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0513,
00472                                      0x1001, 0x009E, /* 10base2, CSR12 0x10*/
00473                                      0x0000, 0x009E, /* 10baseT */
00474                                      0x0004, 0x009E, /* 10baseT-FD */
00475                                      0x0303, 0x006D, /* 100baseTx, CSR12 0x03 */
00476                                      0x0305, 0x006D, /* 100baseTx-FD CSR12 0x03 */}},
00477     {"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x051F,
00478                                     0x1B01, 0x0000, /* 10base2,   CSR12 0x1B */
00479                                     0x0B00, 0x009E, /* 10baseT,   CSR12 0x0B */
00480                                     0x0B04, 0x009E, /* 10baseT-FD,CSR12 0x0B */
00481                                     0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */
00482                                     0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */
00483     }},
00484     {0, 0, 0, 0, {}}};
00485 
00486 static const char * block_name[] = {"21140 non-MII", "21140 MII PHY",
00487                                     "21142 Serial PHY", "21142 MII PHY", "21143 SYM PHY", "21143 reset method"};
00488 
00489 
00490 /*********************************************************************/
00491 /* Function Prototypes                                               */
00492 /*********************************************************************/
00493 static int mdio_read(struct nic *nic, int phy_id, int location);
00494 static void mdio_write(struct nic *nic, int phy_id, int location, int value);
00495 static int read_eeprom(unsigned long ioaddr, int location, int addr_len);
00496 static void parse_eeprom(struct nic *nic);
00497 static int tulip_probe(struct nic *nic,struct pci_device *pci);
00498 static void tulip_init_ring(struct nic *nic);
00499 static void tulip_reset(struct nic *nic);
00500 static void tulip_transmit(struct nic *nic, const char *d, unsigned int t,
00501                            unsigned int s, const char *p);
00502 static int tulip_poll(struct nic *nic, int retrieve);
00503 static void tulip_disable(struct nic *nic);
00504 static void nway_start(struct nic *nic);
00505 static void pnic_do_nway(struct nic *nic);
00506 static void select_media(struct nic *nic, int startup);
00507 static void init_media(struct nic *nic);
00508 static void start_link(struct nic *nic);
00509 static int tulip_check_duplex(struct nic *nic);
00510 
00511 static void tulip_wait(unsigned int nticks);
00512 
00513 #ifdef TULIP_DEBUG_WHERE
00514 static void whereami(const char *str);
00515 #endif
00516 
00517 #ifdef TULIP_DEBUG
00518 static void tulip_more(void);
00519 #endif
00520 
00521 
00522 /*********************************************************************/
00523 /* Utility Routines                                                  */
00524 /*********************************************************************/
00525 
00526 #ifdef TULIP_DEBUG_WHERE
00527 static void whereami (const char *str, struct pci_device *pci)
00528 {
00529     printf("%s: %s\n", tp->nic_name, str);
00530     /* sleep(2); */
00531 }
00532 #endif
00533 
00534 #ifdef  TULIP_DEBUG
00535 static void tulip_more(void)
00536 {
00537     printf("\n\n-- more --");
00538     while (!iskey())
00539         /* wait */;
00540     getchar();
00541     printf("\n\n");
00542 }
00543 #endif /* TULIP_DEBUG */
00544 
00545 static void tulip_wait(unsigned int nticks)
00546 {
00547     unsigned int to = currticks() + nticks;
00548     while (currticks() < to)
00549         /* wait */ ;
00550 }
00551 
00552 
00553 /*********************************************************************/
00554 /* Media Descriptor Code                                             */
00555 /*********************************************************************/
00556 
00557 /* MII transceiver control section.
00558    Read and write the MII registers using software-generated serial
00559    MDIO protocol.  See the MII specifications or DP83840A data sheet
00560    for details. */
00561 
00562 /* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
00563    met by back-to-back PCI I/O cycles, but we insert a delay to avoid
00564    "overclocking" issues or future 66Mhz PCI. */
00565 #define mdio_delay() inl(mdio_addr)
00566 
00567 /* Read and write the MII registers using software-generated serial
00568    MDIO protocol.  It is just different enough from the EEPROM protocol
00569    to not share code.  The maxium data clock rate is 2.5 Mhz. */
00570 #define MDIO_SHIFT_CLK  0x10000
00571 #define MDIO_DATA_WRITE0 0x00000
00572 #define MDIO_DATA_WRITE1 0x20000
00573 #define MDIO_ENB                0x00000         /* Ignore the 0x02000 databook setting. */
00574 #define MDIO_ENB_IN             0x40000
00575 #define MDIO_DATA_READ  0x80000
00576 
00577 /* MII transceiver control section.
00578    Read and write the MII registers using software-generated serial
00579    MDIO protocol.  See the MII specifications or DP83840A data sheet
00580    for details. */
00581 
00582 int mdio_read(struct nic *nic __unused, int phy_id, int location)
00583 {
00584     int i;
00585     int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
00586     int retval = 0;
00587     long mdio_addr = ioaddr + CSR9;
00588 
00589 #ifdef TULIP_DEBUG_WHERE
00590     whereami("mdio_read\n");
00591 #endif
00592 
00593     if (tp->chip_id == LC82C168) {
00594         int i = 1000;
00595         outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
00596         inl(ioaddr + 0xA0);
00597         inl(ioaddr + 0xA0);
00598         while (--i > 0)
00599             if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
00600                 return retval & 0xffff;
00601         return 0xffff;
00602     }
00603 
00604     if (tp->chip_id == COMET) {
00605         if (phy_id == 1) {
00606             if (location < 7)
00607                 return inl(ioaddr + 0xB4 + (location<<2));
00608             else if (location == 17)
00609                 return inl(ioaddr + 0xD0);
00610             else if (location >= 29 && location <= 31)
00611                 return inl(ioaddr + 0xD4 + ((location-29)<<2));
00612         }
00613         return 0xffff;
00614     }
00615 
00616     /* Establish sync by sending at least 32 logic ones. */
00617     for (i = 32; i >= 0; i--) {
00618         outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
00619         mdio_delay();
00620         outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
00621         mdio_delay();
00622     }
00623     /* Shift the read command bits out. */
00624     for (i = 15; i >= 0; i--) {
00625         int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
00626 
00627         outl(MDIO_ENB | dataval, mdio_addr);
00628         mdio_delay();
00629         outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
00630         mdio_delay();
00631     }
00632     /* Read the two transition, 16 data, and wire-idle bits. */
00633     for (i = 19; i > 0; i--) {
00634         outl(MDIO_ENB_IN, mdio_addr);
00635         mdio_delay();
00636         retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
00637         outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
00638         mdio_delay();
00639     }
00640     return (retval>>1) & 0xffff;
00641 }
00642 
00643 void mdio_write(struct nic *nic __unused, int phy_id, int location, int value)
00644 {
00645     int i;
00646     int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
00647     long mdio_addr = ioaddr + CSR9;
00648 
00649 #ifdef TULIP_DEBUG_WHERE
00650     whereami("mdio_write\n");
00651 #endif
00652 
00653     if (tp->chip_id == LC82C168) {
00654         int i = 1000;
00655         outl(cmd, ioaddr + 0xA0);
00656         do
00657             if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
00658                 break;
00659         while (--i > 0);
00660         return;
00661     }
00662 
00663     if (tp->chip_id == COMET) {
00664         if (phy_id != 1)
00665             return;
00666         if (location < 7)
00667             outl(value, ioaddr + 0xB4 + (location<<2));
00668         else if (location == 17)
00669             outl(value, ioaddr + 0xD0);
00670         else if (location >= 29 && location <= 31)
00671             outl(value, ioaddr + 0xD4 + ((location-29)<<2));
00672         return;
00673     }
00674 
00675     /* Establish sync by sending 32 logic ones. */
00676     for (i = 32; i >= 0; i--) {
00677         outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
00678         mdio_delay();
00679         outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
00680         mdio_delay();
00681     }
00682     /* Shift the command bits out. */
00683     for (i = 31; i >= 0; i--) {
00684         int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
00685         outl(MDIO_ENB | dataval, mdio_addr);
00686         mdio_delay();
00687         outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
00688         mdio_delay();
00689     }
00690     /* Clear out extra bits. */
00691     for (i = 2; i > 0; i--) {
00692         outl(MDIO_ENB_IN, mdio_addr);
00693         mdio_delay();
00694         outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
00695         mdio_delay();
00696     }
00697 }
00698 
00699 
00700 /*********************************************************************/
00701 /* EEPROM Reading Code                                               */
00702 /*********************************************************************/
00703 /* EEPROM routines adapted from the Linux Tulip Code */
00704 /* Reading a serial EEPROM is a "bit" grungy, but we work our way
00705    through:->.
00706 */
00707 static int read_eeprom(unsigned long ioaddr, int location, int addr_len)
00708 {
00709     int i;
00710     unsigned short retval = 0;
00711     long ee_addr = ioaddr + CSR9;
00712     int read_cmd = location | EE_READ_CMD;
00713 
00714 #ifdef TULIP_DEBUG_WHERE
00715     whereami("read_eeprom\n");
00716 #endif
00717 
00718     outl(EE_ENB & ~EE_CS, ee_addr);
00719     outl(EE_ENB, ee_addr);
00720 
00721     /* Shift the read command bits out. */
00722     for (i = 4 + addr_len; i >= 0; i--) {
00723         short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
00724         outl(EE_ENB | dataval, ee_addr);
00725         eeprom_delay();
00726         outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
00727         eeprom_delay();
00728     }
00729     outl(EE_ENB, ee_addr);
00730 
00731     for (i = 16; i > 0; i--) {
00732         outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
00733         eeprom_delay();
00734         retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
00735         outl(EE_ENB, ee_addr);
00736         eeprom_delay();
00737     }
00738 
00739     /* Terminate the EEPROM access. */
00740     outl(EE_ENB & ~EE_CS, ee_addr);
00741     return retval;
00742 }
00743 
00744 
00745 /*********************************************************************/
00746 /* EEPROM Parsing Code                                               */
00747 /*********************************************************************/
00748 static void parse_eeprom(struct nic *nic)
00749 {
00750     unsigned char *p, *ee_data = tp->eeprom;
00751     int new_advertise = 0;
00752     int i;
00753 
00754 #ifdef TULIP_DEBUG_WHERE
00755     whereami("parse_eeprom\n");
00756 #endif
00757 
00758     tp->mtable = 0;
00759     /* Detect an old-style (SA only) EEPROM layout:
00760        memcmp(ee_data, ee_data+16, 8). */
00761     for (i = 0; i < 8; i ++)
00762         if (ee_data[i] != ee_data[16+i])
00763             break;
00764     if (i >= 8) {
00765         /* Do a fix-up based on the vendor half of the station address. */
00766         for (i = 0; eeprom_fixups[i].name; i++) {
00767             if (nic->node_addr[0] == eeprom_fixups[i].addr0
00768                 &&  nic->node_addr[1] == eeprom_fixups[i].addr1
00769                 &&  nic->node_addr[2] == eeprom_fixups[i].addr2) {
00770                 if (nic->node_addr[2] == 0xE8  &&  ee_data[0x1a] == 0x55)
00771                     i++;                /* An Accton EN1207, not an outlaw Maxtech. */
00772                 memcpy(ee_data + 26, eeprom_fixups[i].newtable,
00773                        sizeof(eeprom_fixups[i].newtable));
00774 #ifdef TULIP_DEBUG
00775                 printf("%s: Old format EEPROM on '%s' board.\n%s: Using substitute media control info.\n",
00776                        tp->nic_name, eeprom_fixups[i].name, tp->nic_name);
00777 #endif
00778                 break;
00779             }
00780         }
00781         if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
00782 #ifdef TULIP_DEBUG
00783             printf("%s: Old style EEPROM with no media selection information.\n",
00784                    tp->nic_name);
00785 #endif
00786             return;
00787         }
00788     }
00789 
00790     if (ee_data[19] > 1) {
00791 #ifdef TULIP_DEBUG
00792         printf("%s:  Multiport cards (%d ports) may not work correctly.\n", 
00793                tp->nic_name, ee_data[19]);
00794 #endif
00795     }
00796 
00797     p = (void *)ee_data + ee_data[27];
00798 
00799     if (ee_data[27] == 0) {             /* No valid media table. */
00800 #ifdef TULIP_DEBUG
00801         if (tulip_debug > 1) {
00802             printf("%s:  No Valid Media Table. ee_data[27] = %hhX\n", 
00803                    tp->nic_name, ee_data[27]);
00804         }
00805 #endif
00806     } else if (tp->chip_id == DC21041) {
00807         int media = get_u16(p);
00808         int count = p[2];
00809         p += 3;
00810 
00811         printf("%s: 21041 Media table, default media %hX (%s).\n",
00812                tp->nic_name, media,
00813                media & 0x0800 ? "Autosense" : medianame[media & 15]);
00814         for (i = 0; i < count; i++) {
00815             unsigned char media_block = *p++;
00816             int media_code = media_block & MEDIA_MASK;
00817             if (media_block & 0x40)
00818                 p += 6;
00819             switch(media_code) {
00820             case 0: new_advertise |= 0x0020; break;
00821             case 4: new_advertise |= 0x0040; break;
00822             }
00823             printf("%s:  21041 media #%d, %s.\n",
00824                    tp->nic_name, media_code, medianame[media_code]);
00825         }
00826     } else {
00827         unsigned char csr12dir = 0;
00828         int count;
00829         struct mediatable *mtable;
00830         u16 media = get_u16(p);
00831 
00832         p += 2;
00833         if (tp->flags & CSR12_IN_SROM)
00834             csr12dir = *p++;
00835         count = *p++;
00836 
00837         tp->mtable = mtable = (struct mediatable *)&tp->media_table_storage[0];
00838 
00839         mtable->defaultmedia = media;
00840         mtable->leafcount = count;
00841         mtable->csr12dir = csr12dir;
00842         mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
00843         mtable->csr15dir = mtable->csr15val = 0;
00844 
00845         printf("%s:  EEPROM default media type %s.\n", tp->nic_name,
00846                media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]);
00847 
00848         for (i = 0; i < count; i++) {
00849             struct medialeaf *leaf = &mtable->mleaf[i];
00850 
00851             if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */
00852                 leaf->type = 0;
00853                 leaf->media = p[0] & 0x3f;
00854                 leaf->leafdata = p;
00855                 if ((p[2] & 0x61) == 0x01)      /* Bogus, but Znyx boards do it. */
00856                     mtable->has_mii = 1;
00857                 p += 4;
00858             } else {
00859                 switch(leaf->type = p[1]) {
00860                 case 5:
00861                     mtable->has_reset = i;
00862                     leaf->media = p[2] & 0x0f;
00863                     break;
00864                 case 1: case 3:
00865                     mtable->has_mii = 1;
00866                     leaf->media = 11;
00867                     break;
00868                 case 2:
00869                     if ((p[2] & 0x3f) == 0) {
00870                         u32 base15 = (p[2] & 0x40) ? get_u16(p + 7) : 0x0008;
00871                         u16 *p1 = (u16 *)(p + (p[2] & 0x40 ? 9 : 3));
00872                         mtable->csr15dir = (get_unaligned(p1 + 0)<<16) + base15;
00873                         mtable->csr15val = (get_unaligned(p1 + 1)<<16) + base15;
00874                     }
00875                     /* Fall through. */
00876                 case 0: case 4:
00877                     mtable->has_nonmii = 1;
00878                     leaf->media = p[2] & MEDIA_MASK;
00879                     switch (leaf->media) {
00880                     case 0: new_advertise |= 0x0020; break;
00881                     case 4: new_advertise |= 0x0040; break;
00882                     case 3: new_advertise |= 0x0080; break;
00883                     case 5: new_advertise |= 0x0100; break;
00884                     case 6: new_advertise |= 0x0200; break;
00885                     }
00886                     break;
00887                 default:
00888                     leaf->media = 19;
00889                 }
00890                 leaf->leafdata = p + 2;
00891                 p += (p[0] & 0x3f) + 1;
00892             }
00893 #ifdef TULIP_DEBUG
00894             if (tulip_debug > 1  &&  leaf->media == 11) {
00895                 unsigned char *bp = leaf->leafdata;
00896                 printf("%s:  MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %hhX %hhX.\n",
00897                        tp->nic_name, bp[0], bp[1], bp[2 + bp[1]*2],
00898                        bp[5 + bp[2 + bp[1]*2]*2], bp[4 + bp[2 + bp[1]*2]*2]);
00899             }
00900 #endif
00901             printf("%s:  Index #%d - Media %s (#%d) described "
00902                    "by a %s (%d) block.\n",
00903                    tp->nic_name, i, medianame[leaf->media], leaf->media,
00904                    leaf->type < 6 ? block_name[leaf->type] : "UNKNOWN",
00905                    leaf->type);
00906         }
00907         if (new_advertise)
00908             tp->sym_advertise = new_advertise;
00909     }
00910 }
00911 
00912 
00913 /*********************************************************************/
00914 /* tulip_init_ring - setup the tx and rx descriptors                */
00915 /*********************************************************************/
00916 static void tulip_init_ring(struct nic *nic __unused)
00917 {
00918     int i;
00919 
00920 #ifdef TULIP_DEBUG_WHERE
00921     whereami("tulip_init_ring\n");
00922 #endif
00923 
00924     tp->cur_rx = 0;
00925 
00926     for (i = 0; i < RX_RING_SIZE; i++) {
00927         rx_ring[i].status  = cpu_to_le32(0x80000000);
00928         rx_ring[i].length  = cpu_to_le32(BUFLEN);
00929         rx_ring[i].buffer1 = virt_to_le32desc(&rxb[i * BUFLEN]);
00930         rx_ring[i].buffer2 = virt_to_le32desc(&rx_ring[i+1]);
00931     }
00932     /* Mark the last entry as wrapping the ring. */
00933     rx_ring[i-1].length    = cpu_to_le32(DESC_RING_WRAP | BUFLEN);
00934     rx_ring[i-1].buffer2   = virt_to_le32desc(&rx_ring[0]);
00935 
00936     /* We only use 1 transmit buffer, but we use 2 descriptors so
00937        transmit engines have somewhere to point to if they feel the need */
00938 
00939     tx_ring[0].status  = 0x00000000;
00940     tx_ring[0].buffer1 = virt_to_le32desc(&txb[0]);
00941     tx_ring[0].buffer2 = virt_to_le32desc(&tx_ring[1]);
00942 
00943     /* this descriptor should never get used, since it will never be owned
00944        by the machine (status will always == 0) */
00945     tx_ring[1].status  = 0x00000000;
00946     tx_ring[1].buffer1 = virt_to_le32desc(&txb[0]);
00947     tx_ring[1].buffer2 = virt_to_le32desc(&tx_ring[0]);
00948 
00949     /* Mark the last entry as wrapping the ring, though this should never happen */
00950     tx_ring[1].length  = cpu_to_le32(DESC_RING_WRAP | BUFLEN);
00951 }
00952 
00953 
00954 static void set_rx_mode(struct nic *nic __unused) {
00955         int csr6 = inl(ioaddr + CSR6) & ~0x00D5;
00956 
00957         tp->csr6 &= ~0x00D5;
00958  
00959         /* !IFF_PROMISC */
00960         tp->csr6 |= AcceptAllMulticast;
00961         csr6 |= AcceptAllMulticast;
00962 
00963         outl(csr6, ioaddr + CSR6);
00964 
00965         
00966         
00967 }
00968 
00969 /*********************************************************************/
00970 /* eth_reset - Reset adapter                                         */
00971 /*********************************************************************/
00972 static void tulip_reset(struct nic *nic)
00973 {
00974     int i;
00975     unsigned long to;
00976 
00977 #ifdef TULIP_DEBUG_WHERE
00978     whereami("tulip_reset\n");
00979 #endif
00980 
00981     /* Stop Tx and RX */
00982     outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
00983 
00984     /* On some chip revs we must set the MII/SYM port before the reset!? */
00985     if (tp->mii_cnt  ||  (tp->mtable  &&  tp->mtable->has_mii)) {
00986         outl(0x814C0000, ioaddr + CSR6);
00987     }
00988  
00989     /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
00990     outl(0x00000001, ioaddr + CSR0);
00991     tulip_wait(1);
00992 
00993     /* turn off reset and set cache align=16lword, burst=unlimit */
00994     outl(tp->csr0, ioaddr + CSR0);
00995 
00996     /*  Wait the specified 50 PCI cycles after a reset */
00997     tulip_wait(1);
00998 
00999     /* set up transmit and receive descriptors */
01000     tulip_init_ring(nic);
01001 
01002     if (tp->chip_id == PNIC2) {
01003         u32 addr_high = (nic->node_addr[1]<<8) + (nic->node_addr[0]<<0);
01004         /* This address setting does not appear to impact chip operation?? */
01005         outl((nic->node_addr[5]<<8) + nic->node_addr[4] +
01006              (nic->node_addr[3]<<24) + (nic->node_addr[2]<<16),
01007              ioaddr + 0xB0);
01008         outl(addr_high + (addr_high<<16), ioaddr + 0xB8);
01009     }
01010 
01011     /* MC_HASH_ONLY boards don't support setup packets */
01012     if (tp->flags & MC_HASH_ONLY) {
01013         u32 addr_low = cpu_to_le32(get_unaligned((u32 *)nic->node_addr));
01014         u32 addr_high = cpu_to_le32(get_unaligned((u16 *)(nic->node_addr+4)));
01015 
01016         /* clear multicast hash filters and setup MAC address filters */
01017         if (tp->flags & IS_ASIX) {
01018             outl(0, ioaddr + CSR13);
01019             outl(addr_low,  ioaddr + CSR14);
01020             outl(1, ioaddr + CSR13);
01021             outl(addr_high, ioaddr + CSR14);
01022             outl(2, ioaddr + CSR13);
01023             outl(0, ioaddr + CSR14);
01024             outl(3, ioaddr + CSR13);
01025             outl(0, ioaddr + CSR14);
01026         } else if (tp->chip_id == COMET) {
01027             outl(addr_low,  ioaddr + 0xA4);
01028             outl(addr_high, ioaddr + 0xA8);
01029             outl(0, ioaddr + 0xAC);
01030             outl(0, ioaddr + 0xB0);
01031         }
01032     } else {
01033         /* for other boards we send a setup packet to initialize
01034            the filters */
01035         u32 tx_flags = 0x08000000 | 192;
01036 
01037         /* construct perfect filter frame with mac address as first match
01038            and broadcast address for all others */
01039         for (i=0; i<192; i++) 
01040             txb[i] = 0xFF;
01041         txb[0] = nic->node_addr[0];
01042         txb[1] = nic->node_addr[1];
01043         txb[4] = nic->node_addr[2];
01044         txb[5] = nic->node_addr[3];
01045         txb[8] = nic->node_addr[4];
01046         txb[9] = nic->node_addr[5];
01047 
01048         tx_ring[0].length  = cpu_to_le32(tx_flags);
01049         tx_ring[0].buffer1 = virt_to_le32desc(&txb[0]);
01050         tx_ring[0].status  = cpu_to_le32(0x80000000);
01051     }
01052 
01053     /* Point to rx and tx descriptors */
01054     outl(virt_to_le32desc(&rx_ring[0]), ioaddr + CSR3);
01055     outl(virt_to_le32desc(&tx_ring[0]), ioaddr + CSR4);
01056 
01057     init_media(nic);
01058 
01059     /* set the chip's operating mode (but don't turn on xmit and recv yet) */
01060     outl((tp->csr6 & ~0x00002002), ioaddr + CSR6);
01061 
01062     /* send setup packet for cards that support it */
01063     if (!(tp->flags & MC_HASH_ONLY)) {
01064         /* enable transmit  wait for completion */
01065         outl(tp->csr6 | 0x00002000, ioaddr + CSR6);
01066         /* immediate transmit demand */
01067         outl(0, ioaddr + CSR1);
01068 
01069         to = currticks() + TX_TIME_OUT;
01070         while ((tx_ring[0].status & 0x80000000) && (currticks() < to))
01071             /* wait */ ;
01072 
01073         if (currticks() >= to) {
01074             printf ("%s: TX Setup Timeout.\n", tp->nic_name);
01075         }
01076     }
01077 
01078     if (tp->chip_id == LC82C168)
01079         tulip_check_duplex(nic);
01080 
01081     set_rx_mode(nic);   
01082         
01083     /* enable transmit and receive */
01084     outl(tp->csr6 | 0x00002002, ioaddr + CSR6);
01085 }
01086 
01087 
01088 /*********************************************************************/
01089 /* eth_transmit - Transmit a frame                                   */
01090 /*********************************************************************/
01091 static void tulip_transmit(struct nic *nic, const char *d, unsigned int t,
01092                            unsigned int s, const char *p)
01093 {
01094     u16 nstype;
01095     u32 to;
01096     u32 csr6 = inl(ioaddr + CSR6);
01097 
01098 #ifdef TULIP_DEBUG_WHERE    
01099     whereami("tulip_transmit\n");
01100 #endif
01101 
01102     /* Disable Tx */
01103     outl(csr6 & ~0x00002000, ioaddr + CSR6);
01104 
01105     memcpy(txb, d, ETH_ALEN);
01106     memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
01107     nstype = htons((u16) t);
01108     memcpy(txb + 2 * ETH_ALEN, (u8 *)&nstype, 2);
01109     memcpy(txb + ETH_HLEN, p, s);
01110 
01111     s += ETH_HLEN;
01112     s &= 0x0FFF;
01113 
01114     /* pad to minimum packet size */
01115     while (s < ETH_ZLEN)  
01116         txb[s++] = '\0';
01117 
01118 #ifdef TULIP_DEBUG
01119     if (tulip_debug > 1)
01120         printf("%s: sending %d bytes ethtype %hX\n", tp->nic_name, s, t);
01121 #endif
01122         
01123     /* setup the transmit descriptor */
01124     /* 0x60000000 = no interrupt on completion */
01125     tx_ring[0].length = cpu_to_le32(0x60000000 | s);
01126     tx_ring[0].status = cpu_to_le32(0x80000000);
01127 
01128     /* Point to transmit descriptor */
01129     outl(virt_to_le32desc(&tx_ring[0]), ioaddr + CSR4);
01130 
01131     /* Enable Tx */
01132     outl(csr6 | 0x00002000, ioaddr + CSR6);
01133     /* immediate transmit demand */
01134     outl(0, ioaddr + CSR1);
01135 
01136     to = currticks() + TX_TIME_OUT;
01137     while ((tx_ring[0].status & 0x80000000) && (currticks() < to))
01138         /* wait */ ;
01139 
01140     if (currticks() >= to) {
01141         printf ("TX Timeout!\n");
01142     }
01143 
01144     /* Disable Tx */
01145     outl(csr6 & ~0x00002000, ioaddr + CSR6);
01146 }
01147 
01148 /*********************************************************************/
01149 /* eth_poll - Wait for a frame                                       */
01150 /*********************************************************************/
01151 static int tulip_poll(struct nic *nic, int retrieve)
01152 {
01153 
01154 #ifdef TULIP_DEBUG_WHERE
01155     whereami("tulip_poll\n");
01156 #endif
01157 
01158     /* no packet waiting. packet still owned by NIC */
01159     if (rx_ring[tp->cur_rx].status & 0x80000000)
01160         return 0;
01161 
01162     if ( ! retrieve ) return 1;
01163 
01164 #ifdef TULIP_DEBUG_WHERE
01165     whereami("tulip_poll got one\n");
01166 #endif
01167 
01168     nic->packetlen = (rx_ring[tp->cur_rx].status & 0x3FFF0000) >> 16;
01169 
01170     /* if we get a corrupted packet. throw it away and move on */
01171     if (rx_ring[tp->cur_rx].status & 0x00008000) {
01172         /* return the descriptor and buffer to receive ring */
01173         rx_ring[tp->cur_rx].status = 0x80000000;
01174         tp->cur_rx = (++tp->cur_rx) % RX_RING_SIZE;
01175         return 0;
01176     }
01177 
01178     /* copy packet to working buffer */
01179     memcpy(nic->packet, rxb + tp->cur_rx * BUFLEN, nic->packetlen);
01180 
01181     /* return the descriptor and buffer to receive ring */
01182     rx_ring[tp->cur_rx].status = 0x80000000;
01183     tp->cur_rx = (++tp->cur_rx) % RX_RING_SIZE;
01184 
01185     return 1;
01186 }
01187 
01188 /*********************************************************************/
01189 /* eth_disable - Disable the interface                               */
01190 /*********************************************************************/
01191 static void tulip_disable ( struct nic *nic ) {
01192 
01193 #ifdef TULIP_DEBUG_WHERE
01194     whereami("tulip_disable\n");
01195 #endif
01196 
01197     tulip_reset(nic);
01198 
01199     /* disable interrupts */
01200     outl(0x00000000, ioaddr + CSR7);
01201 
01202     /* Stop the chip's Tx and Rx processes. */
01203     outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
01204 
01205     /* Clear the missed-packet counter. */
01206     inl(ioaddr + CSR8);
01207 }
01208 
01209 /*********************************************************************/
01210 /*IRQ - Enable, Disable, or Force interrupts                         */
01211 /*********************************************************************/
01212 static void tulip_irq(struct nic *nic __unused, irq_action_t action __unused)
01213 {
01214   switch ( action ) {
01215   case DISABLE :
01216     break;
01217   case ENABLE :
01218     break;
01219   case FORCE :
01220     break;
01221   }
01222 }
01223 
01224 static struct nic_operations tulip_operations = {
01225         .connect        = dummy_connect,
01226         .poll           = tulip_poll,
01227         .transmit       = tulip_transmit,
01228         .irq            = tulip_irq,
01229 
01230 };
01231 
01232 /*********************************************************************/
01233 /* eth_probe - Look for an adapter                                   */
01234 /*********************************************************************/
01235 static int tulip_probe ( struct nic *nic, struct pci_device *pci ) {
01236 
01237     u32 i;
01238     u8  chip_rev;
01239     u8 ee_data[EEPROM_SIZE];
01240     unsigned short sum;
01241     int chip_idx;
01242     static unsigned char last_phys_addr[ETH_ALEN] = {0x00, 'L', 'i', 'n', 'u', 'x'};
01243 
01244     if (pci->ioaddr == 0)
01245         return 0;
01246 
01247     ioaddr         = pci->ioaddr;
01248     nic->ioaddr    = pci->ioaddr & ~3;
01249     nic->irqno     = 0;
01250 
01251     /* point to private storage */
01252     tp = &tulip_bss.tpx;
01253 
01254     tp->vendor_id  = pci->vendor;
01255     tp->dev_id     = pci->device;
01256     tp->nic_name   = pci->driver_name;
01257 
01258     tp->if_port = 0;
01259     tp->default_port = 0;
01260 
01261     adjust_pci_device(pci);
01262 
01263     /* disable interrupts */
01264     outl(0x00000000, ioaddr + CSR7);
01265 
01266     /* Stop the chip's Tx and Rx processes. */
01267     outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
01268 
01269     /* Clear the missed-packet counter. */
01270     inl(ioaddr + CSR8);
01271 
01272     printf("\n");                /* so we start on a fresh line */
01273 #ifdef TULIP_DEBUG_WHERE
01274     whereami("tulip_probe\n");
01275 #endif
01276 
01277 #ifdef TULIP_DEBUG
01278     if (tulip_debug > 1)
01279         printf ("%s: Looking for Tulip Chip: Vendor=%hX  Device=%hX\n", tp->nic_name,
01280                 tp->vendor, tp->dev_id);
01281 #endif
01282 
01283     /* Figure out which chip we're dealing with */
01284     i = 0;
01285     chip_idx = -1;
01286   
01287     while (pci_id_tbl[i].name) {
01288         if ( (((u32) tp->dev_id << 16) | tp->vendor_id) == 
01289              (pci_id_tbl[i].id.pci & pci_id_tbl[i].id.pci_mask) ) {
01290             chip_idx = pci_id_tbl[i].drv_flags;
01291             break;
01292         }
01293         i++;
01294     }
01295 
01296     if (chip_idx == -1) {
01297         printf ("%s: Unknown Tulip Chip: Vendor=%hX  Device=%hX\n", tp->nic_name,
01298                 tp->vendor_id, tp->dev_id);
01299         return 0;
01300     }
01301 
01302     tp->pci_id_idx = i;
01303     tp->flags = tulip_tbl[chip_idx].flags;
01304 
01305 #ifdef TULIP_DEBUG
01306     if (tulip_debug > 1) {
01307         printf ("%s: tp->pci_id_idx == %d,  name == %s\n", tp->nic_name, 
01308                 tp->pci_id_idx, pci_id_tbl[tp->pci_id_idx].name);
01309         printf ("%s: chip_idx == %d, name == %s\n", tp->nic_name, chip_idx, 
01310                 tulip_tbl[chip_idx].chip_name);
01311     }
01312 #endif
01313   
01314     /* Bring the 21041/21143 out of sleep mode.
01315        Caution: Snooze mode does not work with some boards! */
01316     if (tp->flags & HAS_PWRDWN)
01317         pci_write_config_dword(pci, 0x40, 0x00000000);
01318 
01319     if (inl(ioaddr + CSR5) == 0xFFFFFFFF) {
01320         printf("%s: The Tulip chip at %X is not functioning.\n",
01321                tp->nic_name, (unsigned int) ioaddr);
01322         return 0;
01323     }
01324    
01325     pci_read_config_byte(pci, PCI_REVISION, &chip_rev);
01326 
01327     printf("%s: [chip: %s] rev %d at %hX\n", tp->nic_name,
01328            tulip_tbl[chip_idx].chip_name, chip_rev, (unsigned int) ioaddr);
01329     printf("%s: Vendor=%hX  Device=%hX", tp->nic_name, tp->vendor_id, tp->dev_id);
01330 
01331     if (chip_idx == DC21041  &&  inl(ioaddr + CSR9) & 0x8000) {
01332         printf(" 21040 compatible mode.");
01333         chip_idx = DC21040;
01334     }
01335 
01336     printf("\n");
01337 
01338     /* The SROM/EEPROM interface varies dramatically. */
01339     sum = 0;
01340     if (chip_idx == DC21040) {
01341         outl(0, ioaddr + CSR9);         /* Reset the pointer with a dummy write. */
01342         for (i = 0; i < ETH_ALEN; i++) {
01343             int value, boguscnt = 100000;
01344             do
01345                 value = inl(ioaddr + CSR9);
01346             while (value < 0  && --boguscnt > 0);
01347             nic->node_addr[i] = value;
01348             sum += value & 0xff;
01349         }
01350     } else if (chip_idx == LC82C168) {
01351         for (i = 0; i < 3; i++) {
01352             int value, boguscnt = 100000;
01353             outl(0x600 | i, ioaddr + 0x98);
01354             do
01355                 value = inl(ioaddr + CSR9);
01356             while (value < 0  && --boguscnt > 0);
01357             put_unaligned(le16_to_cpu(value), ((u16*)nic->node_addr) + i);
01358             sum += value & 0xffff;
01359         }
01360     } else if (chip_idx == COMET) {
01361         /* No need to read the EEPROM. */
01362         put_unaligned(inl(ioaddr + 0xA4), (u32 *)nic->node_addr);
01363         put_unaligned(inl(ioaddr + 0xA8), (u16 *)(nic->node_addr + 4));
01364         for (i = 0; i < ETH_ALEN; i ++)
01365             sum += nic->node_addr[i];
01366     } else {
01367         /* A serial EEPROM interface, we read now and sort it out later. */
01368         int sa_offset = 0;
01369         int ee_addr_size = read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
01370 
01371         for (i = 0; i < sizeof(ee_data)/2; i++)
01372             ((u16 *)ee_data)[i] =
01373                 le16_to_cpu(read_eeprom(ioaddr, i, ee_addr_size));
01374 
01375         /* DEC now has a specification (see Notes) but early board makers
01376            just put the address in the first EEPROM locations. */
01377         /* This does  memcmp(eedata, eedata+16, 8) */
01378         for (i = 0; i < 8; i ++)
01379             if (ee_data[i] != ee_data[16+i])
01380                 sa_offset = 20;
01381         if (ee_data[0] == 0xff  &&  ee_data[1] == 0xff &&  ee_data[2] == 0) {
01382             sa_offset = 2;              /* Grrr, damn Matrox boards. */
01383         }
01384         for (i = 0; i < ETH_ALEN; i ++) {
01385             nic->node_addr[i] = ee_data[i + sa_offset];
01386             sum += ee_data[i + sa_offset];
01387         }
01388     }
01389     /* Lite-On boards have the address byte-swapped. */
01390     if ((nic->node_addr[0] == 0xA0  ||  nic->node_addr[0] == 0xC0)
01391         &&  nic->node_addr[1] == 0x00)
01392         for (i = 0; i < ETH_ALEN; i+=2) {
01393             char tmp = nic->node_addr[i];
01394             nic->node_addr[i] = nic->node_addr[i+1];
01395             nic->node_addr[i+1] = tmp;
01396         }
01397 
01398     if (sum == 0  || sum == ETH_ALEN*0xff) {
01399         printf("%s: EEPROM not present!\n", tp->nic_name);
01400         for (i = 0; i < ETH_ALEN-1; i++)
01401             nic->node_addr[i] = last_phys_addr[i];
01402         nic->node_addr[i] = last_phys_addr[i] + 1;
01403     }
01404 
01405     for (i = 0; i < ETH_ALEN; i++)
01406         last_phys_addr[i] = nic->node_addr[i];
01407 
01408     DBG ( "%s: %s at ioaddr %hX\n", tp->nic_name, eth_ntoa ( nic->node_addr ), 
01409           (unsigned int) ioaddr );
01410 
01411     tp->chip_id = chip_idx;
01412     tp->revision = chip_rev;
01413     tp->csr0 = csr0;
01414 
01415     /* BugFixes: The 21143-TD hangs with PCI Write-and-Invalidate cycles.
01416        And the ASIX must have a burst limit or horrible things happen. */
01417     if (chip_idx == DC21143  &&  chip_rev == 65)
01418         tp->csr0 &= ~0x01000000;
01419     else if (tp->flags & IS_ASIX)
01420         tp->csr0 |= 0x2000;
01421 
01422     if (media_cap[tp->default_port] & MediaIsMII) {
01423         static const u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60,
01424                                             0x80, 0x100, 0x200 };
01425         tp->mii_advertise = media2advert[tp->default_port - 9];
01426         tp->mii_advertise |= (tp->flags & HAS_8023X); /* Matching bits! */
01427     }
01428 
01429     /* This is logically part of the probe routine, but too complex
01430        to write inline. */
01431     if (tp->flags & HAS_MEDIA_TABLE) {
01432         memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom));
01433         parse_eeprom(nic);
01434     }
01435 
01436     start_link(nic);
01437 
01438     /* reset the device and make ready for tx and rx of packets */
01439     tulip_reset(nic);
01440     nic->nic_op = &tulip_operations;
01441 
01442     /* give the board a chance to reset before returning */
01443     tulip_wait(4*TICKS_PER_SEC);
01444 
01445     return 1;
01446 }
01447 
01448 static void start_link(struct nic *nic)
01449 {
01450     int i;
01451 
01452 #ifdef TULIP_DEBUG_WHERE
01453     whereami("start_link\n");
01454 #endif
01455 
01456     if ((tp->flags & ALWAYS_CHECK_MII) ||
01457         (tp->mtable  &&  tp->mtable->has_mii) ||
01458         ( ! tp->mtable  &&  (tp->flags & HAS_MII))) {
01459         unsigned int phy, phy_idx;
01460         if (tp->mtable  &&  tp->mtable->has_mii) {
01461             for (i = 0; i < tp->mtable->leafcount; i++)
01462                 if (tp->mtable->mleaf[i].media == 11) {
01463                     tp->cur_index = i;
01464                     tp->saved_if_port = tp->if_port;
01465                     select_media(nic, 2);
01466                     tp->if_port = tp->saved_if_port;
01467                     break;
01468                 }
01469         }
01470 
01471         /* Find the connected MII xcvrs. */
01472         for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys);
01473              phy++) {
01474             int mii_status = mdio_read(nic, phy, 1);
01475             if ((mii_status & 0x8301) == 0x8001 ||
01476                 ((mii_status & 0x8000) == 0  && (mii_status & 0x7800) != 0)) {
01477                 int mii_reg0 = mdio_read(nic, phy, 0);
01478                 int mii_advert = mdio_read(nic, phy, 4);
01479                 int to_advert;
01480 
01481                 if (tp->mii_advertise)
01482                     to_advert = tp->mii_advertise;
01483                 else if (tp->advertising[phy_idx])
01484                     to_advert = tp->advertising[phy_idx];
01485                 else                    /* Leave unchanged. */
01486                     tp->mii_advertise = to_advert = mii_advert;
01487 
01488                 tp->phys[phy_idx++] = phy;
01489                 printf("%s:  MII transceiver %d config %hX status %hX advertising %hX.\n",
01490                        tp->nic_name, phy, mii_reg0, mii_status, mii_advert);
01491                                 /* Fixup for DLink with miswired PHY. */
01492                 if (mii_advert != to_advert) {
01493                     printf("%s:  Advertising %hX on PHY %d previously advertising %hX.\n",
01494                            tp->nic_name, to_advert, phy, mii_advert);
01495                     mdio_write(nic, phy, 4, to_advert);
01496                 }
01497                                 /* Enable autonegotiation: some boards default to off. */
01498                 mdio_write(nic, phy, 0, mii_reg0 |
01499                            (tp->full_duplex ? 0x1100 : 0x1000) |
01500                            (media_cap[tp->default_port]&MediaIs100 ? 0x2000:0));
01501             }
01502         }
01503         tp->mii_cnt = phy_idx;
01504         if (tp->mtable  &&  tp->mtable->has_mii  &&  phy_idx == 0) {
01505             printf("%s: ***WARNING***: No MII transceiver found!\n",
01506                    tp->nic_name);
01507             tp->phys[0] = 1;
01508         }
01509     }
01510 
01511     /* Reset the xcvr interface and turn on heartbeat. */
01512     switch (tp->chip_id) {
01513     case DC21040:
01514         outl(0x00000000, ioaddr + CSR13);
01515         outl(0x00000004, ioaddr + CSR13);
01516         break;
01517     case DC21041:
01518         /* This is nway_start(). */
01519         if (tp->sym_advertise == 0)
01520             tp->sym_advertise = 0x0061;
01521         outl(0x00000000, ioaddr + CSR13);
01522         outl(0xFFFFFFFF, ioaddr + CSR14);
01523         outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */
01524         outl(inl(ioaddr + CSR6) | 0x0200, ioaddr + CSR6);
01525         outl(0x0000EF01, ioaddr + CSR13);
01526         break;
01527     case DC21140: default:
01528         if (tp->mtable)
01529             outl(tp->mtable->csr12dir | 0x100, ioaddr + CSR12);
01530         break;
01531     case DC21142:
01532     case PNIC2:
01533         if (tp->mii_cnt  ||  media_cap[tp->if_port] & MediaIsMII) {
01534             outl(0x82020000, ioaddr + CSR6);
01535             outl(0x0000, ioaddr + CSR13);
01536             outl(0x0000, ioaddr + CSR14);
01537             outl(0x820E0000, ioaddr + CSR6);
01538         } else
01539             nway_start(nic);
01540         break;
01541     case LC82C168:
01542         if ( ! tp->mii_cnt) {
01543             tp->nway = 1;
01544             tp->nwayset = 0;
01545             outl(0x00420000, ioaddr + CSR6);
01546             outl(0x30, ioaddr + CSR12);
01547             outl(0x0001F078, ioaddr + 0xB8);
01548             outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */
01549         }
01550         break;
01551     case MX98713: case COMPEX9881:
01552         outl(0x00000000, ioaddr + CSR6);
01553         outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */
01554         outl(0x00000001, ioaddr + CSR13);
01555         break;
01556     case MX98715: case MX98725:
01557         outl(0x01a80000, ioaddr + CSR6);
01558         outl(0xFFFFFFFF, ioaddr + CSR14);
01559         outl(0x00001000, ioaddr + CSR12);
01560         break;
01561     case COMET:
01562         /* No initialization necessary. */
01563         break;
01564     }
01565 }
01566 
01567 static void nway_start(struct nic *nic __unused)
01568 {
01569     int csr14 = ((tp->sym_advertise & 0x0780) << 9)  |
01570         ((tp->sym_advertise&0x0020)<<1) | 0xffbf;
01571 
01572 #ifdef TULIP_DEBUG_WHERE
01573     whereami("nway_start\n");
01574 #endif
01575 
01576     tp->if_port = 0;
01577     tp->nway = tp->mediasense = 1;
01578     tp->nwayset = tp->lpar = 0;
01579     if (tp->chip_id == PNIC2) {
01580         tp->csr6 = 0x01000000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0);
01581         return;
01582     }
01583 #ifdef TULIP_DEBUG
01584     if (tulip_debug > 1)
01585         printf("%s: Restarting internal NWay autonegotiation, %X.\n",
01586                tp->nic_name, csr14);
01587 #endif
01588     outl(0x0001, ioaddr + CSR13);
01589     outl(csr14, ioaddr + CSR14);
01590     tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0);
01591     outl(tp->csr6, ioaddr + CSR6);
01592     if (tp->mtable  &&  tp->mtable->csr15dir) {
01593         outl(tp->mtable->csr15dir, ioaddr + CSR15);
01594         outl(tp->mtable->csr15val, ioaddr + CSR15);
01595     } else if (tp->chip_id != PNIC2)
01596         outw(0x0008, ioaddr + CSR15);
01597     if (tp->chip_id == DC21041)                 /* Trigger NWAY. */
01598         outl(0xEF01, ioaddr + CSR12);
01599     else
01600         outl(0x1301, ioaddr + CSR12);
01601 }
01602 
01603 static void init_media(struct nic *nic)
01604 {
01605     int i;
01606 
01607 #ifdef TULIP_DEBUG_WHERE
01608     whereami("init_media\n");
01609 #endif
01610 
01611     tp->saved_if_port = tp->if_port;
01612     if (tp->if_port == 0)
01613         tp->if_port = tp->default_port;
01614 
01615     /* Allow selecting a default media. */
01616     i = 0;
01617     if (tp->mtable == NULL)
01618         goto media_picked;
01619     if (tp->if_port) {
01620         int looking_for = media_cap[tp->if_port] & MediaIsMII ? 11 :
01621             (tp->if_port == 12 ? 0 : tp->if_port);
01622         for (i = 0; i < tp->mtable->leafcount; i++)
01623             if (tp->mtable->mleaf[i].media == looking_for) {
01624                 printf("%s: Using user-specified media %s.\n",
01625                        tp->nic_name, medianame[tp->if_port]);
01626                 goto media_picked;
01627             }
01628     }
01629     if ((tp->mtable->defaultmedia & 0x0800) == 0) {
01630         int looking_for = tp->mtable->defaultmedia & 15;
01631         for (i = 0; i < tp->mtable->leafcount; i++)
01632             if (tp->mtable->mleaf[i].media == looking_for) {
01633                 printf("%s: Using EEPROM-set media %s.\n",
01634                        tp->nic_name, medianame[looking_for]);
01635                 goto media_picked;
01636             }
01637     }
01638     /* Start sensing first non-full-duplex media. */
01639     for (i = tp->mtable->leafcount - 1;
01640          (media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--)
01641         ;
01642  media_picked:
01643 
01644     tp->csr6 = 0;
01645     tp->cur_index = i;
01646     tp->nwayset = 0;
01647 
01648     if (tp->if_port) {
01649         if (tp->chip_id == DC21143  &&  media_cap[tp->if_port] & MediaIsMII) {
01650             /* We must reset the media CSRs when we force-select MII mode. */
01651             outl(0x0000, ioaddr + CSR13);
01652             outl(0x0000, ioaddr + CSR14);
01653             outl(0x0008, ioaddr + CSR15);
01654         }
01655         select_media(nic, 1);
01656         return;
01657     }
01658     switch(tp->chip_id) {
01659     case DC21041:
01660         /* tp->nway = 1;*/
01661         nway_start(nic);
01662         break;
01663     case DC21142:
01664         if (tp->mii_cnt) {
01665             select_media(nic, 1);
01666 #ifdef TULIP_DEBUG
01667             if (tulip_debug > 1)
01668                 printf("%s: Using MII transceiver %d, status %hX.\n",
01669                        tp->nic_name, tp->phys[0], mdio_read(nic, tp->phys[0], 1));
01670 #endif
01671             outl(0x82020000, ioaddr + CSR6);
01672             tp->csr6 = 0x820E0000;
01673             tp->if_port = 11;
01674             outl(0x0000, ioaddr + CSR13);
01675             outl(0x0000, ioaddr + CSR14);
01676         } else
01677             nway_start(nic);
01678         break;
01679     case PNIC2:
01680         nway_start(nic);
01681         break;
01682     case LC82C168:
01683         if (tp->mii_cnt) {
01684             tp->if_port = 11;
01685             tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0);
01686             outl(0x0001, ioaddr + CSR15);
01687         } else if (inl(ioaddr + CSR5) & TPLnkPass)
01688             pnic_do_nway(nic);
01689         else {
01690             /* Start with 10mbps to do autonegotiation. */
01691             outl(0x32, ioaddr + CSR12);
01692             tp->csr6 = 0x00420000;
01693             outl(0x0001B078, ioaddr + 0xB8);
01694             outl(0x0201B078, ioaddr + 0xB8);
01695         }
01696         break;
01697     case MX98713: case COMPEX9881:
01698         tp->if_port = 0;
01699         tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0);
01700         outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
01701         break;
01702     case MX98715: case MX98725:
01703         /* Provided by BOLO, Macronix - 12/10/1998. */
01704         tp->if_port = 0;
01705         tp->csr6 = 0x01a80200;
01706         outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
01707         outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0);
01708         break;
01709     case COMET:
01710         /* Enable automatic Tx underrun recovery */
01711         outl(inl(ioaddr + 0x88) | 1, ioaddr + 0x88);
01712         tp->if_port = 0;
01713         tp->csr6 = 0x00040000;
01714         break;
01715     case AX88140: case AX88141:
01716         tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100;
01717         break;
01718     default:
01719         select_media(nic, 1);
01720     }
01721 }
01722 
01723 static void pnic_do_nway(struct nic *nic __unused)
01724 {
01725     u32 phy_reg = inl(ioaddr + 0xB8);
01726     u32 new_csr6 = tp->csr6 & ~0x40C40200;
01727 
01728 #ifdef TULIP_DEBUG_WHERE
01729     whereami("pnic_do_nway\n");
01730 #endif
01731 
01732     if (phy_reg & 0x78000000) { /* Ignore baseT4 */
01733         if (phy_reg & 0x20000000)               tp->if_port = 5;
01734         else if (phy_reg & 0x40000000)  tp->if_port = 3;
01735         else if (phy_reg & 0x10000000)  tp->if_port = 4;
01736         else if (phy_reg & 0x08000000)  tp->if_port = 0;
01737         tp->nwayset = 1;
01738         new_csr6 = (tp->if_port & 1) ? 0x01860000 : 0x00420000;
01739         outl(0x32 | (tp->if_port & 1), ioaddr + CSR12);
01740         if (tp->if_port & 1)
01741             outl(0x1F868, ioaddr + 0xB8);
01742         if (phy_reg & 0x30000000) {
01743             tp->full_duplex = 1;
01744             new_csr6 |= 0x00000200;
01745         }
01746 #ifdef TULIP_DEBUG
01747         if (tulip_debug > 1)
01748             printf("%s: PNIC autonegotiated status %X, %s.\n",
01749                    tp->nic_name, phy_reg, medianame[tp->if_port]);
01750 #endif
01751         if (tp->csr6 != new_csr6) {
01752             tp->csr6 = new_csr6;
01753             outl(tp->csr6 | 0x0002, ioaddr + CSR6);     /* Restart Tx */
01754             outl(tp->csr6 | 0x2002, ioaddr + CSR6);
01755         }
01756     }
01757 }
01758 
01759 /* Set up the transceiver control registers for the selected media type. */
01760 static void select_media(struct nic *nic, int startup)
01761 {
01762     struct mediatable *mtable = tp->mtable;
01763     u32 new_csr6;
01764     int i;
01765 
01766 #ifdef TULIP_DEBUG_WHERE
01767     whereami("select_media\n");
01768 #endif
01769 
01770     if (mtable) {
01771         struct medialeaf *mleaf = &mtable->mleaf[tp->cur_index];
01772         unsigned char *p = mleaf->leafdata;
01773         switch (mleaf->type) {
01774         case 0:                                 /* 21140 non-MII xcvr. */
01775 #ifdef TULIP_DEBUG
01776             if (tulip_debug > 1)
01777                 printf("%s: Using a 21140 non-MII transceiver"
01778                        " with control setting %hhX.\n",
01779                        tp->nic_name, p[1]);
01780 #endif
01781             tp->if_port = p[0];
01782             if (startup)
01783                 outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
01784             outl(p[1], ioaddr + CSR12);
01785             new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18);
01786             break;
01787         case 2: case 4: {
01788             u16 setup[5];
01789             u32 csr13val, csr14val, csr15dir, csr15val;
01790             for (i = 0; i < 5; i++)
01791                 setup[i] = get_u16(&p[i*2 + 1]);
01792 
01793             tp->if_port = p[0] & 15;
01794             if (media_cap[tp->if_port] & MediaAlwaysFD)
01795                 tp->full_duplex = 1;
01796 
01797             if (startup && mtable->has_reset) {
01798                 struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
01799                 unsigned char *rst = rleaf->leafdata;
01800 #ifdef TULIP_DEBUG
01801                 if (tulip_debug > 1)
01802                     printf("%s: Resetting the transceiver.\n",
01803                            tp->nic_name);
01804 #endif
01805                 for (i = 0; i < rst[0]; i++)
01806                     outl(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
01807             }
01808 #ifdef TULIP_DEBUG
01809             if (tulip_debug > 1)
01810                 printf("%s: 21143 non-MII %s transceiver control "
01811                        "%hX/%hX.\n",
01812                        tp->nic_name, medianame[tp->if_port], setup[0], setup[1]);
01813 #endif
01814             if (p[0] & 0x40) {  /* SIA (CSR13-15) setup values are provided. */
01815                 csr13val = setup[0];
01816                 csr14val = setup[1];
01817                 csr15dir = (setup[3]<<16) | setup[2];
01818                 csr15val = (setup[4]<<16) | setup[2];
01819                 outl(0, ioaddr + CSR13);
01820                 outl(csr14val, ioaddr + CSR14);
01821                 outl(csr15dir, ioaddr + CSR15); /* Direction */
01822                 outl(csr15val, ioaddr + CSR15); /* Data */
01823                 outl(csr13val, ioaddr + CSR13);
01824             } else {
01825                 csr13val = 1;
01826                 csr14val = 0x0003FF7F;
01827                 csr15dir = (setup[0]<<16) | 0x0008;
01828                 csr15val = (setup[1]<<16) | 0x0008;
01829                 if (tp->if_port <= 4)
01830                     csr14val = t21142_csr14[tp->if_port];
01831                 if (startup) {
01832                     outl(0, ioaddr + CSR13);
01833                     outl(csr14val, ioaddr + CSR14);
01834                 }
01835                 outl(csr15dir, ioaddr + CSR15); /* Direction */
01836                 outl(csr15val, ioaddr + CSR15); /* Data */
01837                 if (startup) outl(csr13val, ioaddr + CSR13);
01838             }
01839 #ifdef TULIP_DEBUG
01840             if (tulip_debug > 1)
01841                 printf("%s:  Setting CSR15 to %X/%X.\n",
01842                        tp->nic_name, csr15dir, csr15val);
01843 #endif
01844             if (mleaf->type == 4)
01845                 new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18);
01846             else
01847                 new_csr6 = 0x82420000;
01848             break;
01849         }
01850         case 1: case 3: {
01851             int phy_num = p[0];
01852             int init_length = p[1];
01853             u16 *misc_info;
01854 
01855             tp->if_port = 11;
01856             new_csr6 = 0x020E0000;
01857             if (mleaf->type == 3) {     /* 21142 */
01858                 u16 *init_sequence = (u16*)(p+2);
01859                 u16 *reset_sequence = &((u16*)(p+3))[init_length];
01860                 int reset_length = p[2 + init_length*2];
01861                 misc_info = reset_sequence + reset_length;
01862                 if (startup)
01863                     for (i = 0; i < reset_length; i++)
01864                         outl(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
01865                 for (i = 0; i < init_length; i++)
01866                     outl(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
01867             } else {
01868                 u8 *init_sequence = p + 2;
01869                 u8 *reset_sequence = p + 3 + init_length;
01870                 int reset_length = p[2 + init_length];
01871                 misc_info = (u16*)(reset_sequence + reset_length);
01872                 if (startup) {
01873                     outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
01874                     for (i = 0; i < reset_length; i++)
01875                         outl(reset_sequence[i], ioaddr + CSR12);
01876                 }
01877                 for (i = 0; i < init_length; i++)
01878                     outl(init_sequence[i], ioaddr + CSR12);
01879             }
01880             tp->advertising[phy_num] = get_u16(&misc_info[1]) | 1;
01881             if (startup < 2) {
01882                 if (tp->mii_advertise == 0)
01883                     tp->mii_advertise = tp->advertising[phy_num];
01884 #ifdef TULIP_DEBUG
01885                 if (tulip_debug > 1)
01886                     printf("%s:  Advertising %hX on MII %d.\n",
01887                            tp->nic_name, tp->mii_advertise, tp->phys[phy_num]);
01888 #endif
01889                 mdio_write(nic, tp->phys[phy_num], 4, tp->mii_advertise);
01890             }
01891             break;
01892         }
01893         default:
01894             printf("%s:  Invalid media table selection %d.\n",
01895                    tp->nic_name, mleaf->type);
01896             new_csr6 = 0x020E0000;
01897         }
01898 #ifdef TULIP_DEBUG
01899         if (tulip_debug > 1)
01900             printf("%s: Using media type %s, CSR12 is %hhX.\n",
01901                    tp->nic_name, medianame[tp->if_port],
01902                    inl(ioaddr + CSR12) & 0xff);
01903 #endif
01904     } else if (tp->chip_id == DC21041) {
01905         int port = tp->if_port <= 4 ? tp->if_port : 0;
01906 #ifdef TULIP_DEBUG
01907         if (tulip_debug > 1)
01908             printf("%s: 21041 using media %s, CSR12 is %hX.\n",
01909                    tp->nic_name, medianame[port == 3 ? 12: port],
01910                    inl(ioaddr + CSR12));
01911 #endif
01912         outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */
01913         outl(t21041_csr14[port], ioaddr + CSR14);
01914         outl(t21041_csr15[port], ioaddr + CSR15);
01915         outl(t21041_csr13[port], ioaddr + CSR13);
01916         new_csr6 = 0x80020000;
01917     } else if (tp->chip_id == LC82C168) {
01918         if (startup && ! tp->medialock)
01919             tp->if_port = tp->mii_cnt ? 11 : 0;
01920 #ifdef TULIP_DEBUG
01921         if (tulip_debug > 1)
01922             printf("%s: PNIC PHY status is %hX, media %s.\n",
01923                    tp->nic_name, inl(ioaddr + 0xB8), medianame[tp->if_port]);
01924 #endif
01925         if (tp->mii_cnt) {
01926             new_csr6 = 0x810C0000;
01927             outl(0x0001, ioaddr + CSR15);
01928             outl(0x0201B07A, ioaddr + 0xB8);
01929         } else if (startup) {
01930             /* Start with 10mbps to do autonegotiation. */
01931             outl(0x32, ioaddr + CSR12);
01932             new_csr6 = 0x00420000;
01933             outl(0x0001B078, ioaddr + 0xB8);
01934             outl(0x0201B078, ioaddr + 0xB8);
01935         } else if (tp->if_port == 3  ||  tp->if_port == 5) {
01936             outl(0x33, ioaddr + CSR12);
01937             new_csr6 = 0x01860000;
01938             /* Trigger autonegotiation. */
01939             outl(startup ? 0x0201F868 : 0x0001F868, ioaddr + 0xB8);
01940         } else {
01941             outl(0x32, ioaddr + CSR12);
01942             new_csr6 = 0x00420000;
01943             outl(0x1F078, ioaddr + 0xB8);
01944         }
01945     } else if (tp->chip_id == DC21040) {                                        /* 21040 */
01946         /* Turn on the xcvr interface. */
01947 #ifdef TULIP_DEBUG
01948         int csr12 = inl(ioaddr + CSR12);
01949         if (tulip_debug > 1)
01950             printf("%s: 21040 media type is %s, CSR12 is %hhX.\n",
01951                    tp->nic_name, medianame[tp->if_port], csr12);
01952 #endif
01953         if (media_cap[tp->if_port] & MediaAlwaysFD)
01954             tp->full_duplex = 1;
01955         new_csr6 = 0x20000;
01956         /* Set the full duplux match frame. */
01957         outl(FULL_DUPLEX_MAGIC, ioaddr + CSR11);
01958         outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */
01959         if (t21040_csr13[tp->if_port] & 8) {
01960             outl(0x0705, ioaddr + CSR14);
01961             outl(0x0006, ioaddr + CSR15);
01962         } else {
01963             outl(0xffff, ioaddr + CSR14);
01964             outl(0x0000, ioaddr + CSR15);
01965         }
01966         outl(0x8f01 | t21040_csr13[tp->if_port], ioaddr + CSR13);
01967     } else {                                    /* Unknown chip type with no media table. */
01968         if (tp->default_port == 0)
01969             tp->if_port = tp->mii_cnt ? 11 : 3;
01970         if (media_cap[tp->if_port] & MediaIsMII) {
01971             new_csr6 = 0x020E0000;
01972         } else if (media_cap[tp->if_port] & MediaIsFx) {
01973             new_csr6 = 0x028600000;
01974         } else
01975             new_csr6 = 0x038600000;
01976 #ifdef TULIP_DEBUG
01977         if (tulip_debug > 1)
01978             printf("%s: No media description table, assuming "
01979                    "%s transceiver, CSR12 %hhX.\n",
01980                    tp->nic_name, medianame[tp->if_port],
01981                    inl(ioaddr + CSR12));
01982 #endif
01983     }
01984 
01985     tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0);
01986     return;
01987 }
01988 
01989 /*
01990   Check the MII negotiated duplex and change the CSR6 setting if
01991   required.
01992   Return 0 if everything is OK.
01993   Return < 0 if the transceiver is missing or has no link beat.
01994 */
01995 static int tulip_check_duplex(struct nic *nic)
01996 {
01997         unsigned int bmsr, lpa, negotiated, new_csr6;
01998 
01999         bmsr = mdio_read(nic, tp->phys[0], 1);
02000         lpa = mdio_read(nic, tp->phys[0], 5);
02001 
02002 #ifdef TULIP_DEBUG
02003         if (tulip_debug > 1)
02004                 printf("%s: MII status %#x, Link partner report "
02005                            "%#x.\n", tp->nic_name, bmsr, lpa);
02006 #endif
02007 
02008         if (bmsr == 0xffff)
02009                 return -2;
02010         if ((bmsr & 4) == 0) { 
02011                 int new_bmsr = mdio_read(nic, tp->phys[0], 1); 
02012                 if ((new_bmsr & 4) == 0) { 
02013 #ifdef TULIP_DEBUG
02014                         if (tulip_debug  > 1)
02015                                 printf("%s: No link beat on the MII interface,"
02016                                            " status %#x.\n", tp->nic_name, 
02017                                            new_bmsr);
02018 #endif
02019                         return -1;
02020                 }
02021         }
02022         tp->full_duplex = lpa & 0x140;
02023 
02024         new_csr6 = tp->csr6;
02025         negotiated = lpa & tp->advertising[0];
02026 
02027         if(negotiated & 0x380) new_csr6 &= ~0x400000; 
02028         else                   new_csr6 |= 0x400000;
02029         if (tp->full_duplex)   new_csr6 |= 0x200; 
02030         else                   new_csr6 &= ~0x200;
02031 
02032         if (new_csr6 != tp->csr6) {
02033                 tp->csr6 = new_csr6;
02034 
02035 #ifdef TULIP_DEBUG
02036                 if (tulip_debug > 0)
02037                         printf("%s: Setting %s-duplex based on MII"
02038                                    "#%d link partner capability of %#x.\n",
02039                                    tp->nic_name, 
02040                                    tp->full_duplex ? "full" : "half",
02041                                    tp->phys[0], lpa);
02042 #endif
02043                 return 1;
02044         }
02045 
02046         return 0;
02047 }
02048 
02049 static struct pci_device_id tulip_nics[] = {
02050 PCI_ROM(0x1011, 0x0002, "dc21040",     "Digital Tulip", 0),
02051 PCI_ROM(0x1011, 0x0009, "ds21140",     "Digital Tulip Fast", 0),
02052 PCI_ROM(0x1011, 0x0014, "dc21041",     "Digital Tulip+", 0),
02053 PCI_ROM(0x1011, 0x0019, "ds21142",     "Digital Tulip 21142", 0),
02054 PCI_ROM(0x10b7, 0x9300, "3csoho100b-tx","3ComSOHO100B-TX", 0),
02055 PCI_ROM(0x10b9, 0x5261, "ali1563",     "ALi 1563 integrated ethernet", 0),
02056 PCI_ROM(0x10d9, 0x0512, "mx98713",     "Macronix MX987x3", 0),
02057 PCI_ROM(0x10d9, 0x0531, "mx98715",     "Macronix MX987x5", 0),
02058 PCI_ROM(0x1113, 0x1217, "mxic-98715",  "Macronix MX987x5", 0),
02059 PCI_ROM(0x11ad, 0xc115, "lc82c115",    "LinkSys LNE100TX", 0),
02060 PCI_ROM(0x11ad, 0x0002, "82c168",      "Netgear FA310TX", 0),
02061 PCI_ROM(0x1282, 0x9100, "dm9100",      "Davicom 9100", 0),
02062 PCI_ROM(0x1282, 0x9102, "dm9102",      "Davicom 9102", 0),
02063 PCI_ROM(0x1282, 0x9009, "dm9009",      "Davicom 9009", 0),
02064 PCI_ROM(0x1282, 0x9132, "dm9132",      "Davicom 9132", 0),
02065 PCI_ROM(0x1317, 0x0985, "centaur-p",   "ADMtek Centaur-P", 0),
02066 PCI_ROM(0x1317, 0x0981, "an981",       "ADMtek AN981 Comet", 0),                /* ADMTek Centaur-P (stmicro) */
02067 PCI_ROM(0x1113, 0x1216, "an983",       "ADMTek AN983 Comet", 0),
02068 PCI_ROM(0x1317, 0x9511, "an983b",      "ADMTek Comet 983b", 0),
02069 PCI_ROM(0x1317, 0x1985, "centaur-c",   "ADMTek Centaur-C", 0),
02070 PCI_ROM(0x8086, 0x0039, "intel21145",  "Intel Tulip", 0),
02071 PCI_ROM(0x125b, 0x1400, "ax88140",     "ASIX AX88140", 0),
02072 PCI_ROM(0x11f6, 0x9881, "rl100tx",     "Compex RL100-TX", 0),
02073 PCI_ROM(0x115d, 0x0003, "xircomtulip", "Xircom Tulip", 0),
02074 PCI_ROM(0x104a, 0x0981, "tulip-0981",  "Tulip 0x104a 0x0981", 0),
02075 PCI_ROM(0x104a, 0x2774, "SGThomson-STE10100A", "Tulip 0x104a 0x2774", 0),       /*Modified by Ramesh Chander*/
02076 PCI_ROM(0x1113, 0x9511, "tulip-9511",  "Tulip 0x1113 0x9511", 0),
02077 PCI_ROM(0x1186, 0x1561, "tulip-1561",  "Tulip 0x1186 0x1561", 0),
02078 PCI_ROM(0x1259, 0xa120, "tulip-a120",  "Tulip 0x1259 0xa120", 0),
02079 PCI_ROM(0x13d1, 0xab02, "tulip-ab02",  "Tulip 0x13d1 0xab02", 0),
02080 PCI_ROM(0x13d1, 0xab03, "tulip-ab03",  "Tulip 0x13d1 0xab03", 0),
02081 PCI_ROM(0x13d1, 0xab08, "tulip-ab08",  "Tulip 0x13d1 0xab08", 0),
02082 PCI_ROM(0x14f1, 0x1803, "lanfinity",   "Conexant LANfinity", 0),
02083 PCI_ROM(0x1626, 0x8410, "tulip-8410",  "Tulip 0x1626 0x8410", 0),
02084 PCI_ROM(0x1737, 0xab08, "tulip-1737-ab08","Tulip 0x1737 0xab08", 0),
02085 PCI_ROM(0x1737, 0xab09, "tulip-ab09",  "Tulip 0x1737 0xab09", 0),
02086 };
02087 
02088 PCI_DRIVER ( tulip_driver, tulip_nics, PCI_NO_CLASS );
02089 
02090 DRIVER ( "Tulip", nic_driver, pci_driver, tulip_driver,
02091          tulip_probe, tulip_disable );
02092 
02093 /*
02094  * Local variables:
02095  *  c-basic-offset: 8
02096  *  c-indent-level: 8
02097  *  tab-width: 8
02098  * End:
02099  */

Generated on Tue Apr 6 20:01:04 2010 for gPXE by  doxygen 1.5.7.1