/[grub]/grub/netboot/tulip.c
ViewVC logotype

Diff of /grub/netboot/tulip.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by okuji, Sat Jul 29 19:22:54 2000 UTC revision 1.5 by okuji, Wed Jan 2 21:56:40 2002 UTC
# Line 1  Line 1 
1    /* -*- Mode:C; c-basic-offset:4; -*- */
2    
3  /*  /*
4      Tulip and clone Etherboot Driver    Tulip and clone Etherboot Driver
5      By Marty Connor (mdc@thinguin.org)  
6      This software may be used and distributed according to the terms    By Marty Connor (mdc@thinguin.org)
7      of the GNU Public License, incorporated herein by reference.    Copyright (C) 2001 Entity Cyber, Inc.
8    
9      Based on Ken Yap's Tulip Etherboot Driver and Donald Becker's    This software may be used and distributed according to the terms
10      Linux Tulip Driver. Supports N-Way speed auto-configuration on    of the GNU Public License, incorporated herein by reference.
11      MX98715, MX98715A and MX98725. Support inexpensive PCI 10/100 cards  
12      based on the Macronix MX987x5 chip, such as the SOHOware Fast    As of April 2001 this driver should support most tulip cards that
13      model SFA110A, and the LinkSYS model LNE100TX. The NetGear    the Linux tulip driver supports because Donald Becker's Linux media
14      model FA310X, based on the LC82C168 chip is supported.    detection code is now included.
15      The TRENDnet TE100-PCIA NIC which uses a genuine Intel 21143-PD  
16      chipset is supported.    Based on Ken Yap's Tulip Etherboot Driver and Donald Becker's
17      Also, Davicom DM9102's.    Linux Tulip Driver. Supports N-Way speed auto-configuration on
18      MX98715, MX98715A and MX98725. Support inexpensive PCI 10/100 cards
19      Documentation and source code used:    based on the Macronix MX987x5 chip, such as the SOHOware Fast
20        Source for Etherboot driver at    model SFA110A, and the LinkSYS model LNE100TX. The NetGear
21          http://etherboot.sourceforge.net/    model FA310X, based on the LC82C168 chip is supported.
22        MX98715A Data Sheet and MX98715A Application Note    The TRENDnet TE100-PCIA NIC which uses a genuine Intel 21143-PD
23          on http://www.macronix.com/  (PDF format files)    chipset is supported. Also, Davicom DM9102's.
24        Source for Linux tulip driver at  
25          http://cesdis.gsfc.nasa.gov/linux/drivers/tulip.html    Documentation and source code used:
26      Source for Etherboot driver at
27      Adapted by Ken Yap from    http://etherboot.sourceforge.net/
28      FreeBSD netboot DEC 21143 driver    MX98715A Data Sheet and MX98715A Application Note
29      Author: David Sharp    on http://www.macronix.com/  (PDF format files)
30        date: Nov/98    Source for Linux tulip driver at
31      http://cesdis.gsfc.nasa.gov/linux/drivers/tulip.html
32      Some code fragments were taken from verious places, Ken Yap's  
33      etherboot, FreeBSD's if_de.c, and various Linux related files.    Adapted by Ken Yap from
34      DEC's manuals for the 21143 and SROM format were very helpful.    FreeBSD netboot DEC 21143 driver
35      The Linux de driver development page has a number of links to    Author: David Sharp
36      useful related information.  Have a look at:    date: Nov/98
37      ftp://cesdis.gsfc.nasa.gov/pub/linux/drivers/tulip-devel.html  
38      Some code fragments were taken from verious places, Ken Yap's
39      etherboot, FreeBSD's if_de.c, and various Linux related files.
40      DEC's manuals for the 21143 and SROM format were very helpful.
41      The Linux de driver development page has a number of links to
42      useful related information.  Have a look at:
43      ftp://cesdis.gsfc.nasa.gov/pub/linux/drivers/tulip-devel.html
44  */  */
45    
46  /*********************************************************************/  /*********************************************************************/
# Line 40  Line 48 
48  /*********************************************************************/  /*********************************************************************/
49    
50  /*  /*
51      11 Apr 2001  mdc     [patch to etherboot 4.7.24]
52         Major rewrite to include Linux tulip driver media detection
53         code.  This driver should support a lot more cards now.
54    16 Jul 2000  mdc     0.75b11    16 Jul 2000  mdc     0.75b11
55       Added support for ADMtek 0985 Centaur-P, a "Comet" tulip clone       Added support for ADMtek 0985 Centaur-P, a "Comet" tulip clone
56       which is used on the LinkSYS LNE100TX v4.x cards.  We already       which is used on the LinkSYS LNE100TX v4.x cards.  We already
57       support LNE100TX v2.0 cards, which use a different controller.       support LNE100TX v2.0 cards, which use a different controller.
58    04 Jul 2000   jam     ?    04 Jul 2000   jam     ?
59       Added test of status after receiving a packet from the card.       Added test of status after receiving a packet from the card.
60       Also uncommented the tulip_disable routine.  Stray packets       Also uncommented the tulip_disable routine.  Stray packets
61       seemed to be causing problems.       seemed to be causing problems.
62    27 Apr 2000   njl     ?    27 Apr 2000   njl     ?
63    29 Feb 2000   mdc     0.75b7    29 Feb 2000   mdc     0.75b7
64       Increased reset delay to 3 seconds because Macronix cards seem to       Increased reset delay to 3 seconds because Macronix cards seem to
65       need more reset time before card comes back to a usable state.       need more reset time before card comes back to a usable state.
# Line 97  Line 108 
108  #include "pci.h"  #include "pci.h"
109  #include "cards.h"  #include "cards.h"
110    
111  #undef TULIP_DEBUG  /* User settable parameters */
112  #undef TULIP_DEBUG_WHERE  
113    #undef   TULIP_DEBUG
114    #undef   TULIP_DEBUG_WHERE
115    static int tulip_debug = 2;             /* 1 normal messages, 0 quiet .. 7 verbose. */
116    
117  #define TX_TIME_OUT       2*TICKS_PER_SEC  #define TX_TIME_OUT       2*TICKS_PER_SEC
118    
# Line 109  typedef   signed short s16; Line 123  typedef   signed short s16;
123  typedef unsigned int   u32;  typedef unsigned int   u32;
124  typedef   signed int   s32;  typedef   signed int   s32;
125    
126  /* Register offsets for tulip device */  /* helpful macros if on a big_endian machine for changing byte order.
127       not strictly needed on Intel */
128    #define le16_to_cpu(val) (val)
129    #define cpu_to_le32(val) (val)
130    #define get_unaligned(ptr) (*(ptr))
131    #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
132    #define get_u16(ptr) (*(u16 *)(ptr))
133    #define virt_to_bus(x) ((unsigned long)x)
134    #define virt_to_le32desc(addr)  virt_to_bus(addr)
135    
136    #define TULIP_IOTYPE  PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0
137    #define TULIP_SIZE 0x80
138    
139    /* This is a mysterious value that can be written to CSR11 in the 21040 (only)
140       to support a pre-NWay full-duplex signaling mechanism using short frames.
141       No one knows what it should be, but if left at its default value some
142       10base2(!) packets trigger a full-duplex-request interrupt. */
143    #define FULL_DUPLEX_MAGIC       0x6969
144    
145    static const int csr0 = 0x01A00000 | 0x8000;
146    
147    /*  The possible media types that can be set in options[] are: */
148    #define MEDIA_MASK 31
149    static const char * const medianame[32] = {
150        "10baseT", "10base2", "AUI", "100baseTx",
151        "10baseT-FDX", "100baseTx-FDX", "100baseT4", "100baseFx",
152        "100baseFx-FDX", "MII 10baseT", "MII 10baseT-FDX", "MII",
153        "10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FDX", "MII 100baseT4",
154        "MII 100baseFx-HDX", "MII 100baseFx-FDX", "Home-PNA 1Mbps", "Invalid-19",
155    };
156    
157    /* This much match tulip_tbl[]!  Note 21142 == 21143. */
158    enum tulip_chips {
159        DC21040=0, DC21041=1, DC21140=2, DC21142=3, DC21143=3,
160        LC82C168, MX98713, MX98715, MX98725, AX88141, AX88140, PNIC2, COMET,
161        COMPEX9881, I21145, XIRCOM
162    };
163    
164    enum pci_id_flags_bits {
165        /* Set PCI command register bits before calling probe1(). */
166        PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
167        /* Read and map the single following PCI BAR. */
168        PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4,
169        PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400,
170        PCI_UNUSED_IRQ=0x800,
171    };
172    
173    struct pci_id_info {
174        char *name;
175        struct match_info {
176            u32 pci, pci_mask, subsystem, subsystem_mask;
177            u32 revision, revision_mask;                            /* Only 8 bits. */
178        } id;
179        enum pci_id_flags_bits pci_flags;
180        int io_size;                                /* Needed for I/O region check or ioremap(). */
181        int drv_flags;                              /* Driver use, intended as capability flags. */
182    };
183    
184    static struct pci_id_info pci_id_tbl[] = {
185        { "Digital DC21040 Tulip", { 0x00021011, 0xffffffff, 0, 0, 0, 0 },
186          TULIP_IOTYPE, 0x80, DC21040 },
187        { "Digital DC21041 Tulip", { 0x00141011, 0xffffffff, 0, 0, 0, 0 },
188          TULIP_IOTYPE, 0x80, DC21041 },
189        { "Digital DS21140A Tulip", { 0x00091011, 0xffffffff, 0,0, 0x20,0xf0 },
190          TULIP_IOTYPE, 0x80, DC21140 },
191        { "Digital DS21140 Tulip", { 0x00091011, 0xffffffff, 0, 0, 0, 0 },
192          TULIP_IOTYPE, 0x80, DC21140 },
193        { "Digital DS21143 Tulip", { 0x00191011, 0xffffffff, 0,0, 65,0xff },
194          TULIP_IOTYPE, TULIP_SIZE, DC21142 },
195        { "Digital DS21142 Tulip", { 0x00191011, 0xffffffff, 0, 0, 0, 0 },
196          TULIP_IOTYPE, TULIP_SIZE, DC21142 },
197        { "Kingston KNE110tx (PNIC)", { 0x000211AD, 0xffffffff, 0xf0022646, 0xffffffff, 0, 0 },
198          TULIP_IOTYPE, 256, LC82C168 },
199        { "Lite-On 82c168 PNIC", { 0x000211AD, 0xffffffff, 0, 0, 0, 0 },
200          TULIP_IOTYPE, 256, LC82C168 },
201        { "Macronix 98713 PMAC", { 0x051210d9, 0xffffffff, 0, 0, 0, 0 },
202          TULIP_IOTYPE, 256, MX98713 },
203        { "Macronix 98715 PMAC", { 0x053110d9, 0xffffffff, 0, 0, 0, 0 },
204          TULIP_IOTYPE, 256, MX98715 },
205        { "Macronix 98725 PMAC", { 0x053110d9, 0xffffffff, 0, 0, 0, 0 },
206          TULIP_IOTYPE, 256, MX98725 },
207        { "ASIX AX88141", { 0x1400125B, 0xffffffff, 0,0, 0x10, 0xf0 },
208          TULIP_IOTYPE, 128, AX88141 },
209        { "ASIX AX88140", { 0x1400125B, 0xffffffff, 0, 0, 0, 0 },
210          TULIP_IOTYPE, 128, AX88140 },
211        { "Lite-On LC82C115 PNIC-II", { 0xc11511AD, 0xffffffff, 0, 0, 0, 0 },
212          TULIP_IOTYPE, 256, PNIC2 },
213        { "ADMtek AN981 Comet", { 0x09811317, 0xffffffff, 0, 0, 0, 0 },
214          TULIP_IOTYPE, 256, COMET },
215        { "ADMtek Centaur-P", { 0x09851317, 0xffffffff, 0, 0, 0, 0 },
216          TULIP_IOTYPE, 256, COMET },
217        { "ADMtek Centaur-C", { 0x19851317, 0xffffffff, 0, 0, 0, 0 },
218          TULIP_IOTYPE, 256, COMET },
219        { "Compex RL100-TX", { 0x988111F6, 0xffffffff, 0, 0, 0, 0 },
220          TULIP_IOTYPE, 128, COMPEX9881 },
221        { "Intel 21145 Tulip", { 0x00398086, 0xffffffff, 0, 0, 0, 0 },
222          TULIP_IOTYPE, 128, I21145 },
223        { "Xircom Tulip clone", { 0x0003115d, 0xffffffff, 0, 0, 0, 0 },
224          TULIP_IOTYPE, 128, XIRCOM },
225        { "Davicom DM9102", { 0x91021282, 0xffffffff, 0, 0, 0, 0 },
226          TULIP_IOTYPE, 0x80, DC21140 },
227        { "Davicom DM9100", { 0x91001282, 0xffffffff, 0, 0, 0, 0 },
228          TULIP_IOTYPE, 0x80, DC21140 },
229        { "Macronix mxic-98715 (EN1217)", { 0x12171113, 0xffffffff, 0, 0, 0, 0 },
230          TULIP_IOTYPE, 256, MX98715 },
231        { 0, { 0, 0, 0, 0, 0, 0 }, 0, 0, 0 },
232    };
233    
234    enum tbl_flag {
235        HAS_MII=1, HAS_MEDIA_TABLE=2, CSR12_IN_SROM=4, ALWAYS_CHECK_MII=8,
236        HAS_PWRDWN=0x10, MC_HASH_ONLY=0x20, /* Hash-only multicast filter. */
237        HAS_PNICNWAY=0x80, HAS_NWAY=0x40,   /* Uses internal NWay xcvr. */
238        HAS_INTR_MITIGATION=0x100, IS_ASIX=0x200, HAS_8023X=0x400,
239    };
240    
241    /* Note: this table must match  enum tulip_chips  above. */
242    static struct tulip_chip_table {
243        char *chip_name;
244        int flags;
245    } tulip_tbl[] = {
246        { "Digital DC21040 Tulip", 0},
247        { "Digital DC21041 Tulip", HAS_MEDIA_TABLE | HAS_NWAY },
248        { "Digital DS21140 Tulip", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM },
249        { "Digital DS21143 Tulip", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII
250          | HAS_PWRDWN | HAS_NWAY   | HAS_INTR_MITIGATION },
251        { "Lite-On 82c168 PNIC", HAS_MII | HAS_PNICNWAY },
252        { "Macronix 98713 PMAC", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM },
253        { "Macronix 98715 PMAC", HAS_MEDIA_TABLE },
254        { "Macronix 98725 PMAC", HAS_MEDIA_TABLE },
255        { "ASIX AX88140", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM
256          | MC_HASH_ONLY | IS_ASIX },
257        { "ASIX AX88141", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY
258          | IS_ASIX },
259        { "Lite-On PNIC-II", HAS_MII | HAS_NWAY | HAS_8023X },
260        { "ADMtek Comet", MC_HASH_ONLY },
261        { "Compex 9881 PMAC",       HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM },
262        { "Intel DS21145 Tulip", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII
263          | HAS_PWRDWN | HAS_NWAY },
264        { "Xircom tulip work-alike", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII
265          | HAS_PWRDWN | HAS_NWAY },
266        { 0, 0 },
267    };
268    
269    /* A full-duplex map for media types. */
270    enum MediaIs {
271        MediaIsFD = 1, MediaAlwaysFD=2, MediaIsMII=4, MediaIsFx=8,
272        MediaIs100=16};
273    
274    static const char media_cap[32] =
275    {0,0,0,16,  3,19,16,24,  27,4,7,5, 0,20,23,20, 20,31,0,0, };
276    static u8 t21040_csr13[] = {2,0x0C,8,4,  4,0,0,0, 0,0,0,0, 4,0,0,0};
277    
278    /* 21041 transceiver register settings: 10-T, 10-2, AUI, 10-T, 10T-FD */
279    static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, };
280    static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, };
281    static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
282    
283    static u16 t21142_csr13[] = { 0x0001, 0x0009, 0x0009, 0x0000, 0x0001, };
284    static u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, };
285    static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
286    
287    /* Offsets to the Command and Status Registers, "CSRs".  All accesses
288       must be longword instructions and quadword aligned. */
289  enum tulip_offsets {  enum tulip_offsets {
290     CSR0=0,     CSR1=0x08,  CSR2=0x10,  CSR3=0x18,  CSR4=0x20,  CSR5=0x28,      CSR0=0,     CSR1=0x08,  CSR2=0x10,  CSR3=0x18,  CSR4=0x20,  CSR5=0x28,
291     CSR6=0x30,  CSR7=0x38,  CSR8=0x40,  CSR9=0x48, CSR10=0x50, CSR11=0x58,      CSR6=0x30,  CSR7=0x38,  CSR8=0x40,  CSR9=0x48, CSR10=0x50, CSR11=0x58,
292    CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0      CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0
293    };
294    
295    /* The bits in the CSR5 status registers, mostly interrupt sources. */
296    enum status_bits {
297        TimerInt=0x800, TPLnkFail=0x1000, TPLnkPass=0x10,
298        NormalIntr=0x10000, AbnormalIntr=0x8000,
299        RxJabber=0x200, RxDied=0x100, RxNoBuf=0x80, RxIntr=0x40,
300        TxFIFOUnderflow=0x20, TxJabber=0x08, TxNoBuf=0x04, TxDied=0x02, TxIntr=0x01,
301    };
302    
303    enum desc_status_bits {
304        DescOwnded=0x80000000, RxDescFatalErr=0x8000, RxWholePkt=0x0300,
305    };
306    
307    struct medialeaf {
308        u8 type;
309        u8 media;
310        unsigned char *leafdata;
311    };
312    
313    struct mediatable {
314        u16 defaultmedia;
315        u8 leafcount, csr12dir;                             /* General purpose pin directions. */
316        unsigned has_mii:1, has_nonmii:1, has_reset:6;
317        u32 csr15dir, csr15val;                             /* 21143 NWay setting. */
318        struct medialeaf mleaf[0];
319  };  };
320    
321  #define DEC_21142_CSR6_TTM      0x00400000      /* Transmit Threshold Mode */  struct mediainfo {
322  #define DEC_21142_CSR6_HBD      0x00080000      /* Heartbeat Disable */      struct mediainfo *next;
323  #define DEC_21142_CSR6_PS       0x00040000      /* Port Select */      int info_type;
324        int index;
325        unsigned char *info;
326    };
327    
328  /* EEPROM Address width definitions */  /* EEPROM Address width definitions */
329  #define EEPROM_ADDRLEN 6  #define EEPROM_ADDRLEN 6
330  #define EEPROM_SIZE    128              /* 2 << EEPROM_ADDRLEN */  #define EEPROM_SIZE    128              /* 2 << EEPROM_ADDRLEN */
331    
 /* Data Read from the EEPROM */  
 static unsigned char ee_data[EEPROM_SIZE];  
   
332  /* The EEPROM commands include the alway-set leading bit. */  /* The EEPROM commands include the alway-set leading bit. */
333  #define EE_WRITE_CMD    (5 << addr_len)  #define EE_WRITE_CMD    (5 << addr_len)
334  #define EE_READ_CMD     (6 << addr_len)  #define EE_READ_CMD     (6 << addr_len)
# Line 146  static unsigned char ee_data[EEPROM_SIZE Line 348  static unsigned char ee_data[EEPROM_SIZE
348     turn-around to insure that this remains true.  */     turn-around to insure that this remains true.  */
349  #define eeprom_delay()  inl(ee_addr)  #define eeprom_delay()  inl(ee_addr)
350    
351  /* helpful macro if on a big_endian machine for changing byte order.  /* Size of transmit and receive buffers */
352     not strictly needed on Intel */  #define BUFLEN 1536
353  #define le16_to_cpu(val) (val)  
354    /* Ring-wrap flag in length field, use for last ring entry.
355       0x01000000 means chain on buffer2 address,
356       0x02000000 means use the ring start address in CSR2/3.
357       Note: Some work-alike chips do not function correctly in chained mode.
358       The ASIX chip works only in chained mode.
359       Thus we indicate ring mode, but always write the 'next' field for
360       chained mode as well. */
361    #define DESC_RING_WRAP 0x02000000
362    
363  /* transmit and receive descriptor format */  /* transmit and receive descriptor format */
364  struct txdesc {  struct tulip_rx_desc {
365    volatile unsigned long   status;         /* owner, status */      volatile u32 status;
366    unsigned long   buf1sz:11,      /* size of buffer 1 */      u32 length;
367      buf2sz:11,                    /* size of buffer 2 */      u32 buffer1, buffer2;
     control:10;                   /* control bits */  
   const unsigned char *buf1addr;  /* buffer 1 address */  
   const unsigned char *buf2addr;  /* buffer 2 address */  
 };  
   
 struct rxdesc {  
   volatile unsigned long   status;         /* owner, status */  
   unsigned long   buf1sz:11,      /* size of buffer 1 */  
     buf2sz:11,                    /* size of buffer 2 */  
     control:10;                   /* control bits */  
   unsigned char   *buf1addr;      /* buffer 1 address */  
   unsigned char   *buf2addr;      /* buffer 2 address */  
368  };  };
369    
370  /* Size of transmit and receive buffers */  struct tulip_tx_desc {
371  #define BUFLEN 1536      volatile u32 status;
372        u32 length;
373        u32 buffer1, buffer2;
374    };
375    
376  /*********************************************************************/  /*********************************************************************/
377  /* Global Storage                                                    */  /* Global Storage                                                    */
378  /*********************************************************************/  /*********************************************************************/
379    
380  /* PCI Bus parameters */  static u32 ioaddr;
 static unsigned short vendor, dev_id;  
 static unsigned long ioaddr;  
381    
382  /* Note: transmit and receive buffers must be longword aligned and  /* Note: transmit and receive buffers must be longword aligned and
383     longword divisable */     longword divisable */
384    
385  /* transmit descriptor and buffer */  #define TX_RING_SIZE    2
386  static struct txdesc txd __attribute__ ((aligned(4)));  static struct tulip_tx_desc tx_ring[TX_RING_SIZE] __attribute__ ((aligned(4)));
387  #ifndef USE_INTERNAL_BUFFER  
388    #ifdef USE_LOWMEM_BUFFER
389  #define txb ((char *)0x10000 - BUFLEN)  #define txb ((char *)0x10000 - BUFLEN)
390  #else  #else
391  static unsigned char txb[BUFLEN] __attribute__ ((aligned(4)));  static unsigned char txb[BUFLEN] __attribute__ ((aligned(4)));
392  #endif  #endif
393    
394  /* receive descriptor(s) and buffer(s) */  #define RX_RING_SIZE    4
395  #define NRXD 4  static struct tulip_rx_desc rx_ring[RX_RING_SIZE] __attribute__ ((aligned(4)));
396  static struct rxdesc rxd[NRXD] __attribute__ ((aligned(4)));  
397  #ifndef USE_INTERNAL_BUFFER  #ifdef USE_LOWMEM_BUFFER
398  #define rxb ((char *)0x10000 - NRXD * BUFLEN - BUFLEN)  #define rxb ((char *)0x10000 - RX_RING_SIZE * BUFLEN - BUFLEN)
399  #else  #else
400  static unsigned char rxb[NRXD * BUFLEN] __attribute__ ((aligned(4)));  static unsigned char rxb[RX_RING_SIZE * BUFLEN] __attribute__ ((aligned(4)));
401  #endif  #endif
 static int rxd_tail;  
402    
403  /* buffer for ethernet header */  static struct tulip_private {
404  static unsigned char ehdr[ETHER_HDR_SIZE];      int cur_rx;
405        int chip_id;                        /* index into tulip_tbl[]  */
406        int pci_id_idx;                     /* index into pci_id_tbl[] */
407        int revision;
408        int flags;
409        unsigned short vendor_id;           /* PCI card vendor code */
410        unsigned short dev_id;              /* PCI card device code */
411        unsigned char ehdr[ETH_HLEN];       /* buffer for ethernet header */
412        const char *nic_name;
413        unsigned int csr0, csr6;            /* Current CSR0, CSR6 settings. */
414        unsigned int if_port;
415        unsigned int full_duplex;         /* Full-duplex operation requested. */
416        unsigned int full_duplex_lock;
417        unsigned int medialock;           /* Do not sense media type. */
418        unsigned int mediasense;          /* Media sensing in progress. */
419        unsigned int nway, nwayset;     /* 21143 internal NWay. */
420        unsigned int default_port;
421        unsigned char eeprom[EEPROM_SIZE];  /* Serial EEPROM contents. */
422        u8 media_table_storage[(sizeof(struct mediatable) + 32*sizeof(struct medialeaf))];
423        u16 sym_advertise, mii_advertise;   /* NWay to-advertise. */
424        struct mediatable *mtable;
425        u16 lpar;                           /* 21143 Link partner ability. */
426        u16 advertising[4];                 /* MII advertise, from SROM table. */
427        signed char phys[4], mii_cnt;       /* MII device addresses. */
428        int cur_index;                      /* Current media index. */
429        int saved_if_port;
430    } tpx;
431    
432    static struct tulip_private *tp;
433    
434    /* Known cards that have old-style EEPROMs.
435       Writing this table is described at
436       http://cesdis.gsfc.nasa.gov/linux/drivers/tulip-drivers/tulip-media.html */
437    static struct fixups {
438        char *name;
439        unsigned char addr0, addr1, addr2;
440        u16 newtable[32];                           /* Max length below. */
441    } eeprom_fixups[] = {
442        {"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c,
443                                0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }},
444        {"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f,
445                                     0x0000, 0x009E, /* 10baseT */
446                                     0x0004, 0x009E, /* 10baseT-FD */
447                                     0x0903, 0x006D, /* 100baseTx */
448                                     0x0905, 0x006D, /* 100baseTx-FD */ }},
449        {"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x063f,
450                                       0x0107, 0x8021, /* 100baseFx */
451                                       0x0108, 0x8021, /* 100baseFx-FD */
452                                       0x0100, 0x009E, /* 10baseT */
453                                       0x0104, 0x009E, /* 10baseT-FD */
454                                       0x0103, 0x006D, /* 100baseTx */
455                                       0x0105, 0x006D, /* 100baseTx-FD */ }},
456        {"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0513,
457                                         0x1001, 0x009E, /* 10base2, CSR12 0x10*/
458                                         0x0000, 0x009E, /* 10baseT */
459                                         0x0004, 0x009E, /* 10baseT-FD */
460                                         0x0303, 0x006D, /* 100baseTx, CSR12 0x03 */
461                                         0x0305, 0x006D, /* 100baseTx-FD CSR12 0x03 */}},
462        {"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x051F,
463                                        0x1B01, 0x0000, /* 10base2,   CSR12 0x1B */
464                                        0x0B00, 0x009E, /* 10baseT,   CSR12 0x0B */
465                                        0x0B04, 0x009E, /* 10baseT-FD,CSR12 0x0B */
466                                        0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */
467                                        0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */
468        }},
469        {0, 0, 0, 0, {}}};
470    
471    static const char * block_name[] = {"21140 non-MII", "21140 MII PHY",
472                                        "21142 Serial PHY", "21142 MII PHY", "21143 SYM PHY", "21143 reset method"};
473    
474    
475  /*********************************************************************/  /*********************************************************************/
476  /* Function Prototypes                                               */  /* Function Prototypes                                               */
477  /*********************************************************************/  /*********************************************************************/
478  static void whereami(const char *str);  static int mdio_read(struct nic *nic, int phy_id, int location);
479  static int lc82c168_mdio_read(int phy_id, int location);  static void mdio_write(struct nic *nic, int phy_id, int location, int value);
 static void lc82c168_mdio_write(int phy_id, int location, int value);  
 static void lc82c168_do_mii();  
480  static int read_eeprom(unsigned long ioaddr, int location, int addr_len);  static int read_eeprom(unsigned long ioaddr, int location, int addr_len);
481    static void parse_eeprom(struct nic *nic);
482  struct nic *tulip_probe(struct nic *nic, unsigned short *io_addrs,  struct nic *tulip_probe(struct nic *nic, unsigned short *io_addrs,
483                          struct pci_device *pci);                          struct pci_device *pci);
484  static void tulip_init_ring(struct nic *nic);  static void tulip_init_ring(struct nic *nic);
485  static void tulip_reset(struct nic *nic);  static void tulip_reset(struct nic *nic);
486  static void tulip_transmit(struct nic *nic, const char *d, unsigned int t,  static void tulip_transmit(struct nic *nic, const char *d, unsigned int t,
487                             unsigned int s, const char *p);                             unsigned int s, const char *p);
488  static int tulip_poll(struct nic *nic);  static int tulip_poll(struct nic *nic);
489  static void tulip_disable(struct nic *nic);  static void tulip_disable(struct nic *nic);
490  static void whereami (const char *str);  static void nway_start(struct nic *nic);
491  #ifdef  TULIP_DEBUG  static void pnic_do_nway(struct nic *nic);
492  static void tulip_more(void);  static void select_media(struct nic *nic, int startup);
493  #endif /* TULIP_DEBUG */  static void init_media(struct nic *nic);
494    static void start_link(struct nic *nic);
495    static int tulip_check_duplex(struct nic *nic);
496    
497  static void tulip_wait(unsigned int nticks);  static void tulip_wait(unsigned int nticks);
498    
499    #ifdef TULIP_DEBUG_WHERE
500    static void whereami(const char *str);
501    #endif
502    
503    #ifdef TULIP_DEBUG
504    static void tulip_more(void);
505    #endif
506    
507    
508  /*********************************************************************/  /*********************************************************************/
509  /* Utility Routines                                                  */  /* Utility Routines                                                  */
510  /*********************************************************************/  /*********************************************************************/
511    
512  static inline void whereami (const char *str)  #ifdef TULIP_DEBUG_WHERE
513    static void whereami (const char *str)
514  {  {
515  #ifdef  TULIP_DEBUG_WHERE      printf("%s: %s\n", tp->nic_name, str);
516    printf("%s\n", str);      /* sleep(2); */
   /* sleep(2); */  
 #endif  
517  }  }
518    #endif
519    
520  #ifdef  TULIP_DEBUG  #ifdef  TULIP_DEBUG
521  static void tulip_more()  static void tulip_more(void)
522  {  {
523    printf("\n\n-- more --");      printf("\n\n-- more --");
524    while (!iskey())      while (!iskey())
525      /* wait */;          /* wait */;
526    getchar();      getchar();
527    printf("\n\n");      printf("\n\n");
528  }  }
529  #endif /* TULIP_DEBUG */  #endif /* TULIP_DEBUG */
530    
531  static void tulip_wait(unsigned int nticks)  static void tulip_wait(unsigned int nticks)
532  {  {
533    unsigned int to = currticks() + nticks;      unsigned int to = currticks() + nticks;
534    while (currticks() < to)      while (currticks() < to)
535      /* wait */ ;          /* wait */ ;
536  }  }
537    
538    
539  /*********************************************************************/  /*********************************************************************/
540  /* Media Descriptor Code                                             */  /* Media Descriptor Code                                             */
541  /*********************************************************************/  /*********************************************************************/
 static int lc82c168_mdio_read(int phy_id, int location)  
 {  
   int i = 1000;  
   int retval = 0;  
542    
543    whereami("mdio_read\n");  /* MII transceiver control section.
544       Read and write the MII registers using software-generated serial
545       MDIO protocol.  See the MII specifications or DP83840A data sheet
546       for details. */
547    
548    /* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
549       met by back-to-back PCI I/O cycles, but we insert a delay to avoid
550       "overclocking" issues or future 66Mhz PCI. */
551    #define mdio_delay() inl(mdio_addr)
552    
553    /* Read and write the MII registers using software-generated serial
554       MDIO protocol.  It is just different enough from the EEPROM protocol
555       to not share code.  The maxium data clock rate is 2.5 Mhz. */
556    #define MDIO_SHIFT_CLK  0x10000
557    #define MDIO_DATA_WRITE0 0x00000
558    #define MDIO_DATA_WRITE1 0x20000
559    #define MDIO_ENB                0x00000         /* Ignore the 0x02000 databook setting. */
560    #define MDIO_ENB_IN             0x40000
561    #define MDIO_DATA_READ  0x80000
562    
563    /* MII transceiver control section.
564       Read and write the MII registers using software-generated serial
565       MDIO protocol.  See the MII specifications or DP83840A data sheet
566       for details. */
567    
568    outl(0x60020000 | (phy_id<<23) | (location<<18), ioaddr + 0xA0);  int mdio_read(struct nic *nic, int phy_id, int location)
   inl(ioaddr + 0xA0);  
   inl(ioaddr + 0xA0);  
   while (--i > 0)  
     if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))  
       return retval & 0xFFFF;  
   if (i == 0) printf("mdio read timeout!\n");  
   return 0xFFFF;  
 }  
   
 static void lc82c168_mdio_write(int phy_id, int location, int value)  
569  {  {
570    int i = 1000;      int i;
571    int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;      int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
572        int retval = 0;
573    whereami("mdio_write\n");      long mdio_addr = ioaddr + CSR9;
   
   outl(cmd, ioaddr + 0xA0);  
   do  
     if ( ! (inl(ioaddr + 0xA0) & 0x80000000))  
       break;  
   while (--i > 0);  
   if (i == 0) printf("mdio write timeout!\n");  
   return;  
 }  
574    
575  static void lc82c168_do_mii(void)  #ifdef TULIP_DEBUG_WHERE
576  {      whereami("mdio_read\n");
577    int phy, phy_idx;  #endif
578    
579    whereami("do_mii\n");      if (tp->chip_id == LC82C168) {
580            int i = 1000;
581            outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
582            inl(ioaddr + 0xA0);
583            inl(ioaddr + 0xA0);
584            while (--i > 0)
585                if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
586                    return retval & 0xffff;
587            return 0xffff;
588        }
589    
590    for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < 4; phy++) {      if (tp->chip_id == COMET) {
591            if (phy_id == 1) {
592                if (location < 7)
593                    return inl(ioaddr + 0xB4 + (location<<2));
594                else if (location == 17)
595                    return inl(ioaddr + 0xD0);
596                else if (location >= 29 && location <= 31)
597                    return inl(ioaddr + 0xD4 + ((location-29)<<2));
598            }
599            return 0xffff;
600        }
601    
602      int mii_status = lc82c168_mdio_read(phy, 1);      /* Establish sync by sending at least 32 logic ones. */
603        for (i = 32; i >= 0; i--) {
604            outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
605            mdio_delay();
606            outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
607            mdio_delay();
608        }
609        /* Shift the read command bits out. */
610        for (i = 15; i >= 0; i--) {
611            int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
612    
613            outl(MDIO_ENB | dataval, mdio_addr);
614            mdio_delay();
615            outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
616            mdio_delay();
617        }
618        /* Read the two transition, 16 data, and wire-idle bits. */
619        for (i = 19; i > 0; i--) {
620            outl(MDIO_ENB_IN, mdio_addr);
621            mdio_delay();
622            retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
623            outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
624            mdio_delay();
625        }
626        return (retval>>1) & 0xffff;
627    }
628    
629      if ((mii_status & 0x8301) == 0x8001 ||  void mdio_write(struct nic *nic, int phy_id, int location, int value)
630          ((mii_status & 0x8000) == 0  && (mii_status & 0x7800) != 0)) {  {
631        int i;
632        int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
633        long mdio_addr = ioaddr + CSR9;
634    
635        int mii_reg0 = lc82c168_mdio_read(phy, 0);  #ifdef TULIP_DEBUG_WHERE
636        int mii_advert = lc82c168_mdio_read(phy, 4);      whereami("mdio_write\n");
637        int mii_reg4 = ((mii_status >> 6) & 0x01E1) | 1;  #endif
638    
639        phy_idx++;      if (tp->chip_id == LC82C168) {
640        printf("%s:  MII trcvr #%d "          int i = 1000;
641               "config %x status %x advertising %x reg4 %x.\n",          outl(cmd, ioaddr + 0xA0);
642               "LC82C168", phy, mii_reg0, mii_status, mii_advert, mii_reg4);          do
643                if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
644                    break;
645            while (--i > 0);
646            return;
647        }
648    
649        lc82c168_mdio_write(phy, 0, mii_reg0 | 0x1000);      if (tp->chip_id == COMET) {
650        if (mii_advert != mii_reg4)          if (phy_id != 1)
651          lc82c168_mdio_write(phy, 4, mii_reg4);              return;
652            if (location < 7)
653                outl(value, ioaddr + 0xB4 + (location<<2));
654            else if (location == 17)
655                outl(value, ioaddr + 0xD0);
656            else if (location >= 29 && location <= 31)
657                outl(value, ioaddr + 0xD4 + ((location-29)<<2));
658            return;
659      }      }
   }  
 #ifdef  TULIP_DEBUG  
   printf("mii_cnt = %d\n", phy_idx);  
 #endif  
660    
661        /* Establish sync by sending 32 logic ones. */
662        for (i = 32; i >= 0; i--) {
663            outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
664            mdio_delay();
665            outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
666            mdio_delay();
667        }
668        /* Shift the command bits out. */
669        for (i = 31; i >= 0; i--) {
670            int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
671            outl(MDIO_ENB | dataval, mdio_addr);
672            mdio_delay();
673            outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
674            mdio_delay();
675        }
676        /* Clear out extra bits. */
677        for (i = 2; i > 0; i--) {
678            outl(MDIO_ENB_IN, mdio_addr);
679            mdio_delay();
680            outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
681            mdio_delay();
682        }
683  }  }
684    
685    
# Line 338  static void lc82c168_do_mii(void) Line 692  static void lc82c168_do_mii(void)
692  */  */
693  static int read_eeprom(unsigned long ioaddr, int location, int addr_len)  static int read_eeprom(unsigned long ioaddr, int location, int addr_len)
694  {  {
695    int i;      int i;
696    unsigned short retval = 0;      unsigned short retval = 0;
697    long ee_addr = ioaddr + CSR9;      long ee_addr = ioaddr + CSR9;
698    int read_cmd = location | EE_READ_CMD;      int read_cmd = location | EE_READ_CMD;
699    
700    whereami("read_eeprom\n");  #ifdef TULIP_DEBUG_WHERE
701        whereami("read_eeprom\n");
702    outl(EE_ENB & ~EE_CS, ee_addr);  #endif
703    outl(EE_ENB, ee_addr);  
704        outl(EE_ENB & ~EE_CS, ee_addr);
705    /* Shift the read command bits out. */      outl(EE_ENB, ee_addr);
706    for (i = 4 + addr_len; i >= 0; i--) {  
707      short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;      /* Shift the read command bits out. */
708      outl(EE_ENB | dataval, ee_addr);      for (i = 4 + addr_len; i >= 0; i--) {
709      eeprom_delay();          short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
710      outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);          outl(EE_ENB | dataval, ee_addr);
711      eeprom_delay();          eeprom_delay();
712    }          outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
713    outl(EE_ENB, ee_addr);          eeprom_delay();
714        }
   for (i = 16; i > 0; i--) {  
     outl(EE_ENB | EE_SHIFT_CLK, ee_addr);  
     eeprom_delay();  
     retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);  
715      outl(EE_ENB, ee_addr);      outl(EE_ENB, ee_addr);
     eeprom_delay();  
   }  
716    
717    /* Terminate the EEPROM access. */      for (i = 16; i > 0; i--) {
718    outl(EE_ENB & ~EE_CS, ee_addr);          outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
719    return retval;          eeprom_delay();
720            retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
721            outl(EE_ENB, ee_addr);
722            eeprom_delay();
723        }
724    
725        /* Terminate the EEPROM access. */
726        outl(EE_ENB & ~EE_CS, ee_addr);
727        return retval;
728    }
729    
730    
731    /*********************************************************************/
732    /* EEPROM Parsing Code                                               */
733    /*********************************************************************/
734    static void parse_eeprom(struct nic *nic)
735    {
736        unsigned char *p, *ee_data = tp->eeprom;
737        int new_advertise = 0;
738        int i;
739    
740    #ifdef TULIP_DEBUG_WHERE
741        whereami("parse_eeprom\n");
742    #endif
743    
744        tp->mtable = 0;
745        /* Detect an old-style (SA only) EEPROM layout:
746           memcmp(ee_data, ee_data+16, 8). */
747        for (i = 0; i < 8; i ++)
748            if (ee_data[i] != ee_data[16+i])
749                break;
750        if (i >= 8) {
751            /* Do a fix-up based on the vendor half of the station address. */
752            for (i = 0; eeprom_fixups[i].name; i++) {
753                if (nic->node_addr[0] == eeprom_fixups[i].addr0
754                    &&  nic->node_addr[1] == eeprom_fixups[i].addr1
755                    &&  nic->node_addr[2] == eeprom_fixups[i].addr2) {
756                    if (nic->node_addr[2] == 0xE8  &&  ee_data[0x1a] == 0x55)
757                        i++;                /* An Accton EN1207, not an outlaw Maxtech. */
758                    memcpy(ee_data + 26, eeprom_fixups[i].newtable,
759                           sizeof(eeprom_fixups[i].newtable));
760    #ifdef TULIP_DEBUG
761                    printf("%s: Old format EEPROM on '%s' board.\n%s: Using substitute media control info.\n",
762                           tp->nic_name, eeprom_fixups[i].name, tp->nic_name);
763    #endif
764                    break;
765                }
766            }
767            if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
768    #ifdef TULIP_DEBUG
769                printf("%s: Old style EEPROM with no media selection information.\n",
770                       tp->nic_name);
771    #endif
772                return;
773            }
774        }
775    
776        if (ee_data[19] > 1) {
777    #ifdef TULIP_DEBUG
778            printf("%s:  Multiport cards (%d ports) may not work correctly.\n",
779                   tp->nic_name, ee_data[19]);
780    #endif
781        }
782    
783        p = (void *)ee_data + ee_data[27];
784    
785        if (ee_data[27] == 0) {             /* No valid media table. */
786    #ifdef TULIP_DEBUG
787            if (tulip_debug > 1) {
788                printf("%s:  No Valid Media Table. ee_data[27] = %hhX\n",
789                       tp->nic_name, ee_data[27]);
790            }
791    #endif
792        } else if (tp->chip_id == DC21041) {
793            int media = get_u16(p);
794            int count = p[2];
795            p += 3;
796    
797            printf("%s: 21041 Media table, default media %hX (%s).\n",
798                   tp->nic_name, media,
799                   media & 0x0800 ? "Autosense" : medianame[media & 15]);
800            for (i = 0; i < count; i++) {
801                unsigned char media_block = *p++;
802                int media_code = media_block & MEDIA_MASK;
803                if (media_block & 0x40)
804                    p += 6;
805                switch(media_code) {
806                case 0: new_advertise |= 0x0020; break;
807                case 4: new_advertise |= 0x0040; break;
808                }
809                printf("%s:  21041 media #%d, %s.\n",
810                       tp->nic_name, media_code, medianame[media_code]);
811            }
812        } else {
813            unsigned char csr12dir = 0;
814            int count;
815            struct mediatable *mtable;
816            u16 media = get_u16(p);
817    
818            p += 2;
819            if (tp->flags & CSR12_IN_SROM)
820                csr12dir = *p++;
821            count = *p++;
822    
823            tp->mtable = mtable = (struct mediatable *)&tp->media_table_storage[0];
824    
825            mtable->defaultmedia = media;
826            mtable->leafcount = count;
827            mtable->csr12dir = csr12dir;
828            mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
829            mtable->csr15dir = mtable->csr15val = 0;
830    
831            printf("%s:  EEPROM default media type %s.\n", tp->nic_name,
832                   media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]);
833    
834            for (i = 0; i < count; i++) {
835                struct medialeaf *leaf = &mtable->mleaf[i];
836    
837                if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */
838                    leaf->type = 0;
839                    leaf->media = p[0] & 0x3f;
840                    leaf->leafdata = p;
841                    if ((p[2] & 0x61) == 0x01)      /* Bogus, but Znyx boards do it. */
842                        mtable->has_mii = 1;
843                    p += 4;
844                } else {
845                    switch(leaf->type = p[1]) {
846                    case 5:
847                        mtable->has_reset = i;
848                        leaf->media = p[2] & 0x0f;
849                        break;
850                    case 1: case 3:
851                        mtable->has_mii = 1;
852                        leaf->media = 11;
853                        break;
854                    case 2:
855                        if ((p[2] & 0x3f) == 0) {
856                            u32 base15 = (p[2] & 0x40) ? get_u16(p + 7) : 0x0008;
857                            u16 *p1 = (u16 *)(p + (p[2] & 0x40 ? 9 : 3));
858                            mtable->csr15dir = (get_unaligned(p1 + 0)<<16) + base15;
859                            mtable->csr15val = (get_unaligned(p1 + 1)<<16) + base15;
860                        }
861                        /* Fall through. */
862                    case 0: case 4:
863                        mtable->has_nonmii = 1;
864                        leaf->media = p[2] & MEDIA_MASK;
865                        switch (leaf->media) {
866                        case 0: new_advertise |= 0x0020; break;
867                        case 4: new_advertise |= 0x0040; break;
868                        case 3: new_advertise |= 0x0080; break;
869                        case 5: new_advertise |= 0x0100; break;
870                        case 6: new_advertise |= 0x0200; break;
871                        }
872                        break;
873                    default:
874                        leaf->media = 19;
875                    }
876                    leaf->leafdata = p + 2;
877                    p += (p[0] & 0x3f) + 1;
878                }
879    #ifdef TULIP_DEBUG
880                if (tulip_debug > 1  &&  leaf->media == 11) {
881                    unsigned char *bp = leaf->leafdata;
882                    printf("%s:  MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %hhX %hhX.\n",
883                           tp->nic_name, bp[0], bp[1], bp[2 + bp[1]*2],
884                           bp[5 + bp[2 + bp[1]*2]*2], bp[4 + bp[2 + bp[1]*2]*2]);
885                }
886    #endif
887                printf("%s:  Index #%d - Media %s (#%d) described "
888                       "by a %s (%d) block.\n",
889                       tp->nic_name, i, medianame[leaf->media], leaf->media,
890                       leaf->type < 6 ? block_name[leaf->type] : "UNKNOWN",
891                       leaf->type);
892            }
893            if (new_advertise)
894                tp->sym_advertise = new_advertise;
895        }
896  }  }
897    
898    
899  /*********************************************************************/  /*********************************************************************/
900  /* tulip_init_ring - setup the tx and rx descriptors                */  /* tulip_init_ring - setup the tx and rx descriptors                */
901  /*********************************************************************/  /*********************************************************************/
902  static void tulip_init_ring(struct nic *nic)  static void tulip_init_ring(struct nic *nic)
903  {  {
904    int i;      int i;
905    
906    #ifdef TULIP_DEBUG_WHERE
907        whereami("tulip_init_ring\n");
908    #endif
909    
910    /* setup the transmit descriptor */      tp->cur_rx = 0;
911    txd.buf1addr = &txb[0];  
912    txd.buf2addr = &txb[0];         /* just in case */      for (i = 0; i < RX_RING_SIZE; i++) {
913    txd.buf1sz   = 192;             /* setup packet must be 192 bytes */          rx_ring[i].status  = cpu_to_le32(0x80000000);
914    txd.buf2sz   = 0;          rx_ring[i].length  = cpu_to_le32(BUFLEN);
915    txd.control  = 0x028;           /* setup packet + TER */          rx_ring[i].buffer1 = virt_to_le32desc(&rxb[i * BUFLEN]);
916    txd.status   = 0x80000000;      /* give ownership to device */          rx_ring[i].buffer2 = virt_to_le32desc(&rx_ring[i+1]);
917        }
918    /* construct perfect filter frame with mac address as first match      /* Mark the last entry as wrapping the ring. */
919       and broadcast address for all others */      rx_ring[i-1].length    = cpu_to_le32(DESC_RING_WRAP | BUFLEN);
920    for (i=0; i<192; i++) txb[i] = 0xFF;      rx_ring[i-1].buffer2   = virt_to_le32desc(&rx_ring[0]);
921    txb[0] = nic->node_addr[0];  
922    txb[1] = nic->node_addr[1];      /* We only use 1 transmit buffer, but we use 2 descriptors so
923    txb[4] = nic->node_addr[2];         transmit engines have somewhere to point to if they feel the need */
924    txb[5] = nic->node_addr[3];  
925    txb[8] = nic->node_addr[4];      tx_ring[0].status  = 0x00000000;
926    txb[9] = nic->node_addr[5];      tx_ring[0].buffer1 = virt_to_le32desc(&txb[0]);
927        tx_ring[0].buffer2 = virt_to_le32desc(&tx_ring[1]);
928    /* setup receive descriptor */  
929    for (i=0; i<NRXD; i++) {      /* this descriptor should never get used, since it will never be owned
930      rxd[i].buf1addr = &rxb[i * BUFLEN];         by the machine (status will always == 0) */
931      rxd[i].buf2addr = 0;        /* not used */      tx_ring[1].status  = 0x00000000;
932      rxd[i].buf1sz   = BUFLEN;      tx_ring[1].buffer1 = virt_to_le32desc(&txb[0]);
933      rxd[i].buf2sz   = 0;        /* not used */      tx_ring[1].buffer2 = virt_to_le32desc(&tx_ring[0]);
934      rxd[i].control  = 0x0;  
935      rxd[i].status   = 0x80000000;   /* give ownership to device */      /* Mark the last entry as wrapping the ring, though this should never happen */
936    }      tx_ring[1].length  = cpu_to_le32(DESC_RING_WRAP | BUFLEN);
   
   /* Set Receive end of ring on last descriptor */  
   rxd[NRXD - 1].control = 0x008;  
   rxd_tail = 0;  
937  }  }
938    
939  /*********************************************************************/  /*********************************************************************/
# Line 416  static void tulip_init_ring(struct nic * Line 941  static void tulip_init_ring(struct nic *
941  /*********************************************************************/  /*********************************************************************/
942  static void tulip_reset(struct nic *nic)  static void tulip_reset(struct nic *nic)
943  {  {
944    unsigned long to, csr6;      int i;
945    u32 addr_low, addr_high;      unsigned long to;
946        u32 addr_low, addr_high;
947    
948    #ifdef TULIP_DEBUG_WHERE
949        whereami("tulip_reset\n");
950    #endif
951    
952        /* Stop Tx and RX */
953        outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
954    
955        /* On some chip revs we must set the MII/SYM port before the reset!? */
956        if (tp->mii_cnt  ||  (tp->mtable  &&  tp->mtable->has_mii)) {
957            outl(0x814C0000, ioaddr + CSR6);
958        }
959      
960        /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
961        outl(0x00000001, ioaddr + CSR0);
962        tulip_wait(1);
963    
964        /* turn off reset and set cache align=16lword, burst=unlimit */
965        outl(tp->csr0, ioaddr + CSR0);
966    
967        /*  Wait the specified 50 PCI cycles after a reset */
968        tulip_wait(1);
969    
970        /* set up transmit and receive descriptors */
971        tulip_init_ring(nic);
972    
973        if (tp->chip_id == PNIC2) {
974            u32 addr_high = (nic->node_addr[1]<<8) + (nic->node_addr[0]<<0);
975            /* This address setting does not appear to impact chip operation?? */
976            outl((nic->node_addr[5]<<8) + nic->node_addr[4] +
977                 (nic->node_addr[3]<<24) + (nic->node_addr[2]<<16),
978                 ioaddr + 0xB0);
979            outl(addr_high + (addr_high<<16), ioaddr + 0xB8);
980        }
981    
982        /* MC_HASH_ONLY boards don't support setup packets */
983        if (tp->flags & MC_HASH_ONLY) {
984            u32 addr_low = cpu_to_le32(get_unaligned((u32 *)nic->node_addr));
985            u32 addr_high = cpu_to_le32(get_unaligned((u16 *)(nic->node_addr+4)));
986    
987            /* clear multicast hash filters and setup MAC address filters */
988            if (tp->flags & IS_ASIX) {
989                outl(0, ioaddr + CSR13);
990                outl(addr_low,  ioaddr + CSR14);
991                outl(1, ioaddr + CSR13);
992                outl(addr_high, ioaddr + CSR14);
993                outl(2, ioaddr + CSR13);
994                outl(0, ioaddr + CSR14);
995                outl(3, ioaddr + CSR13);
996                outl(0, ioaddr + CSR14);
997            } else if (tp->chip_id == COMET) {
998                outl(addr_low,  ioaddr + 0xA4);
999                outl(addr_high, ioaddr + 0xA8);
1000                outl(0, ioaddr + 0xAC);
1001                outl(0, ioaddr + 0xB0);
1002            }
1003        } else {
1004            /* for other boards we send a setup packet to initialize
1005               the filters */
1006            u32 tx_flags = 0x08000000 | 192;
1007    
1008            /* construct perfect filter frame with mac address as first match
1009               and broadcast address for all others */
1010            for (i=0; i<192; i++)
1011                txb[i] = 0xFF;
1012            txb[0] = nic->node_addr[0];
1013            txb[1] = nic->node_addr[1];
1014            txb[4] = nic->node_addr[2];
1015            txb[5] = nic->node_addr[3];
1016            txb[8] = nic->node_addr[4];
1017            txb[9] = nic->node_addr[5];
1018    
1019            tx_ring[0].length  = cpu_to_le32(tx_flags);
1020            tx_ring[0].buffer1 = virt_to_le32desc(&txb[0]);
1021            tx_ring[0].status  = cpu_to_le32(0x80000000);
1022        }
1023    
1024    whereami("tulip_reset\n");      /* Point to rx and tx descriptors */
1025        outl((unsigned long)&rx_ring[0], ioaddr + CSR3);
1026        outl((unsigned long)&tx_ring[0], ioaddr + CSR4);
1027    
1028        init_media(nic);
1029    
1030        /* set the chip's operating mode (but don't turn on xmit and recv yet) */
1031        outl((tp->csr6 & ~0x00002002), ioaddr + CSR6);
1032    
1033        /* send setup packet for cards that support it */
1034        if (!(tp->flags & MC_HASH_ONLY)) {
1035            /* enable transmit  wait for completion */
1036            outl(tp->csr6 | 0x00002000, ioaddr + CSR6);
1037            /* immediate transmit demand */
1038            outl(0, ioaddr + CSR1);
1039    
1040            to = currticks() + TX_TIME_OUT;
1041            while ((tx_ring[0].status & 0x80000000) && (currticks() < to))
1042                /* wait */ ;
1043    
1044            if (currticks() >= to) {
1045                printf ("%s: TX Setup Timeout.\n", tp->nic_name);
1046            }
1047        }
1048    
1049    /* Stop Tx and RX */      if (tp->chip_id == LC82C168)
1050    outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);          tulip_check_duplex(nic);
1051    
1052    if (vendor == PCI_VENDOR_ID_MACRONIX && dev_id == PCI_DEVICE_ID_MX987x5) {      /* enable transmit and receive */
1053      /* set up 10-BASE-T Control Port */      outl(tp->csr6 | 0x00002002, ioaddr + CSR6);
     outl(0xFFFFFFFF, ioaddr + CSR14);  
     /* set up 10-BASE-T Status Port  */  
     outl(0x00001000, ioaddr + CSR12);  
     /* Set Operation Control Register (CSR6) for MX987x5  
        to allow N-Way Active Speed selection, and  
        start the chip's Tx to process setup frame.  
        While it is possible to force speed selection,  
        this is probably more useful most of the time.  
     */  
     outl(0x01A80200, ioaddr + CSR6);  
   
   } else if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_LC82C115) {  
     /* This is MX987x5 init code. It seems to work for the LNE100TX  
        but should be replaced when we figure out the right way  
        to do this initialization  
     */  
     outl(0xFFFFFFFF, ioaddr + CSR14);  
     outl(0x00001000, ioaddr + CSR12);  
     outl(0x01A80200, ioaddr + CSR6);  
   
   } else if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_DEC_TULIP) {  
   
     lc82c168_do_mii();  
   
   } else if (vendor == PCI_VENDOR_ID_DEC && dev_id == PCI_DEVICE_ID_DEC_21142) {  
     /* nothing */  
   
   } else if (vendor == PCI_VENDOR_ID_ADMTEK && dev_id == PCI_DEVICE_ID_ADMTEK_0985) {  
     /* nothing */  
   
   } else {  
     /* If we don't know what to do with the card, set to 10Mbps half-duplex */  
   
     outl(0x00000000, ioaddr + CSR13);  
     outl(0x7F3F0000, ioaddr + CSR14);  
     outl(0x08000008, ioaddr + CSR15);  
     outl(0x00000000, ioaddr + CSR13);  
     outl(0x00000001, ioaddr + CSR13);  
     outl(0x02404000, ioaddr + CSR6);  
     outl(0x08AF0008, ioaddr + CSR15);  
     outl(0x00050008, ioaddr + CSR15);  
   
   }  
   
   /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */  
   outl(0x00000001, ioaddr + CSR0);  
   
   tulip_wait(3*TICKS_PER_SEC);  
   
   /* turn off reset and set cache align=16lword, burst=unlimit */  
   outl(0x01A08000, ioaddr + CSR0);  
   
   /* set up transmit and receive descriptors */  
   tulip_init_ring(nic);  
   
   /* set up multicast hash address for Comet (ADKTEK 0985) */  
   /* possibly not needed for Etherboot, but seems to do no harm  -mdc */  
   if (vendor == PCI_VENDOR_ID_ADMTEK && dev_id == PCI_DEVICE_ID_ADMTEK_0985) {  
     addr_low  = nic->node_addr[0] + (nic->node_addr[1] << 8)  
       + (nic->node_addr[2] << 16) + (nic->node_addr[3] << 24);  
     addr_high = nic->node_addr[4] + (nic->node_addr[5] << 8);  
     outl(addr_low,  ioaddr + 0xA4);  
     outl(addr_high, ioaddr + 0xA8);  
     outl(0, ioaddr + 0xAC);  
     outl(0, ioaddr + 0xB0);  
   }  
   
   /* Point to receive descriptor */  
   outl((unsigned long)&rxd[0], ioaddr + CSR3);  
   outl((unsigned long)&txd   , ioaddr + CSR4);  
   
   csr6 = 0x02404000;  
   
   /* Chip specific init code */  
   
   if (vendor == PCI_VENDOR_ID_MACRONIX && dev_id == PCI_DEVICE_ID_MX987x5) {  
     csr6 = 0x01880200;  
     /* Set CSR16 and CSR20 to values that allow device modification */  
     outl(0x0B3C0000 | inl(ioaddr + CSR16), ioaddr + CSR16);  
     outl(0x00011000 | inl(ioaddr + CSR20), ioaddr + CSR20);  
   
   } else if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_LC82C115) {  
     /* This is MX987x5 init code. It seems to work for the LNE100TX  
        but should be replaced when we figure out the right way  
        to do this initialization.  
     */  
     csr6 = 0x01880200;  
     outl(0x0B3C0000 | inl(ioaddr + CSR16), ioaddr + CSR16);  
     outl(0x00011000 | inl(ioaddr + CSR20), ioaddr + CSR20);  
   
   } else if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_DEC_TULIP) {  
   
     csr6 = 0x814C0000;  
     outl(0x00000001, ioaddr + CSR15);  
   
   } else if (vendor == PCI_VENDOR_ID_DEC && dev_id == PCI_DEVICE_ID_DEC_21142) {  
      /* check SROM for evidence of an MII interface */  
      /* get Controller_0 Info Leaf Offset from SROM - assume already in ee_data */  
      int offset = ee_data [27] + (ee_data [28] << 8);  
   
      /* check offset range and if we have an extended type 3 Info Block */  
      if ((offset >= 30) && (offset < 120) && (ee_data [offset + 3] > 128) &&  
        (ee_data [offset + 4] == 3)) {  
        /* must have an MII interface - disable heartbeat, select port etc. */  
        csr6 |= (DEC_21142_CSR6_HBD | DEC_21142_CSR6_PS);  
        csr6 &= ~(DEC_21142_CSR6_TTM);  
      }  
   } else if (vendor == PCI_VENDOR_ID_DAVICOM && dev_id == PCI_DEVICE_ID_DM9102){  
       /* setup CR12 */  
       outl(0x180, ioaddr + CSR12);    /* Let bit 7 output port */  
       outl(0x80, ioaddr + CSR12);     /* RESET DM9102 phyxcer */  
       outl(0x0, ioaddr + CSR12);      /* Clear RESET signal */  
   
   } else if (vendor == PCI_VENDOR_ID_ADMTEK && dev_id == PCI_DEVICE_ID_ADMTEK_0985) {  
     /* nothing */  
   
   }  
   
   /* set the chip's operating mode */  
   outl(csr6, ioaddr + CSR6);  
   
   /* Start Tx */  
   outl(inl(ioaddr + CSR6) | 0x00002000, ioaddr + CSR6);  
   /* immediate transmit demand */  
   outl(0, ioaddr + CSR1);  
   
   to = currticks() + TX_TIME_OUT;  
   while ((txd.status & 0x80000000) && (currticks() < to))  
     /* wait */ ;  
   
   if (currticks() >= to) {  
     printf ("TX Setup Timeout!\n");  
   }  
   
 #ifdef TULIP_DEBUG  
   printf("txd.status = %X\n", txd.status);  
   printf("ticks = %d\n", currticks() - (to - TX_TIME_OUT));  
   tulip_more();  
 #endif  
   
   /* enable RX */  
   outl(inl(ioaddr + CSR6) | 0x00000002, ioaddr + CSR6);  
   /* immediate poll demand */  
   outl(0, ioaddr + CSR2);  
1054  }  }
1055    
1056    
# Line 579  static void tulip_reset(struct nic *nic) Line 1060  static void tulip_reset(struct nic *nic)
1060  static void tulip_transmit(struct nic *nic, const char *d, unsigned int t,  static void tulip_transmit(struct nic *nic, const char *d, unsigned int t,
1061                             unsigned int s, const char *p)                             unsigned int s, const char *p)
1062  {  {
1063    unsigned long to;      u16 nstype;
1064        u32 to;
1065        u32 csr6 = inl(ioaddr + CSR6);
1066    
1067    whereami("tulip_transmit\n");  #ifdef TULIP_DEBUG_WHERE    
1068        whereami("tulip_transmit\n");
1069    #endif
1070    
1071        /* Disable Tx */
1072        outl(csr6 & ~0x00002000, ioaddr + CSR6);
1073    
1074    /* Stop Tx */      memcpy(txb, d, ETH_ALEN);
1075    outl(inl(ioaddr + CSR6) & ~0x00002000, ioaddr + CSR6);      memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
1076        nstype = htons((u16) t);
1077        memcpy(txb + 2 * ETH_ALEN, (u8 *)&nstype, 2);
1078        memcpy(txb + ETH_HLEN, p, s);
1079    
1080        s += ETH_HLEN;
1081        s &= 0x0FFF;
1082    
1083        /* pad to minimum packet size */
1084        while (s < ETH_ZLEN)  
1085            txb[s++] = '\0';
1086    
1087    #ifdef TULIP_DEBUG
1088        if (tulip_debug > 1)
1089            printf("%s: sending %d bytes ethtype %hX\n", tp->nic_name, s, t);
1090    #endif
1091            
1092        /* setup the transmit descriptor */
1093        /* 0x60000000 = no interrupt on completion */
1094        tx_ring[0].length = cpu_to_le32(0x60000000 | s);
1095        tx_ring[0].status = cpu_to_le32(0x80000000);
1096    
1097        /* Point to transmit descriptor */
1098        outl((u32)&tx_ring[0], ioaddr + CSR4);
1099    
1100        /* Enable Tx */
1101        outl(csr6 | 0x00002000, ioaddr + CSR6);
1102        /* immediate transmit demand */
1103        outl(0, ioaddr + CSR1);
1104    
1105        to = currticks() + TX_TIME_OUT;
1106        while ((tx_ring[0].status & 0x80000000) && (currticks() < to))
1107            /* wait */ ;
1108    
1109    /* setup ethernet header */      if (currticks() >= to) {
1110    memcpy(ehdr, d, ETHER_ADDR_SIZE);          printf ("TX Timeout!\n");
1111    memcpy(&ehdr[ETHER_ADDR_SIZE], nic->node_addr, ETHER_ADDR_SIZE);      }
   ehdr[ETHER_ADDR_SIZE*2] = (t >> 8) & 0xFF;  
   ehdr[ETHER_ADDR_SIZE*2+1] = t & 0xFF;  
   
   /* setup the transmit descriptor */  
   txd.buf1addr = &ehdr[0];        /* ethernet header */  
   txd.buf1sz   = ETHER_HDR_SIZE;  
   txd.buf2addr = p;               /* packet to transmit */  
   txd.buf2sz   = s;  
   txd.control  = 0x00000188;      /* LS+FS+TER */  
   txd.status   = 0x80000000;      /* give ownership to device */  
   
   /* Point to transmit descriptor */  
   outl((unsigned long)&txd, ioaddr + CSR4);  
   
   /* Start Tx */  
   outl(inl(ioaddr + CSR6) |  0x00002000, ioaddr + CSR6);  
   
   /* immediate transmit demand */  
   outl(0, ioaddr + CSR1);  
   
   to = currticks() + TX_TIME_OUT;  
   while ((txd.status & 0x80000000) && (currticks() < to))  
     /* wait */ ;  
   
   if (currticks() >= to) {  
     printf ("TX Timeout!\n");  
   }  
1112    
1113        /* Disable Tx */
1114        outl(csr6 & ~0x00002000, ioaddr + CSR6);
1115  }  }
1116    
1117  /*********************************************************************/  /*********************************************************************/
# Line 624  static void tulip_transmit(struct nic *n Line 1119  static void tulip_transmit(struct nic *n
1119  /*********************************************************************/  /*********************************************************************/
1120  static int tulip_poll(struct nic *nic)  static int tulip_poll(struct nic *nic)
1121  {  {
   whereami("tulip_poll\n");  
1122    
1123    if (rxd[rxd_tail].status & 0x80000000)  #ifdef TULIP_DEBUG_WHERE
1124      return 0;      whereami("tulip_poll\n");
1125    #endif
1126    
1127    whereami("tulip_poll got one\n");      /* no packet waiting. packet still owned by NIC */
1128        if (rx_ring[tp->cur_rx].status & 0x80000000)
1129            return 0;
1130    
1131    nic->packetlen = (rxd[rxd_tail].status & 0x3FFF0000) >> 16;  #ifdef TULIP_DEBUG_WHERE
1132        whereami("tulip_poll got one\n");
1133    #endif
1134    
1135    if( rxd[rxd_tail].status & 0x00008000){      nic->packetlen = (rx_ring[tp->cur_rx].status & 0x3FFF0000) >> 16;
       rxd[rxd_tail].status = 0x80000000;  
       rxd_tail++;  
       if (rxd_tail == NRXD) rxd_tail = 0;  
       return 0;  
   }  
1136    
1137    /* copy packet to working buffer */      /* if we get a corrupted packet. throw it away and move on */
1138    /* XXX - this copy could be avoided with a little more work      if (rx_ring[tp->cur_rx].status & 0x00008000) {
1139       but for now we are content with it because the optimised          /* return the descriptor and buffer to receive ring */
1140       memcpy is quite fast */          rx_ring[tp->cur_rx].status = 0x80000000;
1141            tp->cur_rx = (++tp->cur_rx) % RX_RING_SIZE;
1142            return 0;
1143        }
1144    
1145    memcpy(nic->packet, rxb + rxd_tail * BUFLEN, nic->packetlen);      /* copy packet to working buffer */
1146        memcpy(nic->packet, rxb + tp->cur_rx * BUFLEN, nic->packetlen);
1147    
1148    /* return the descriptor and buffer to receive ring */      /* return the descriptor and buffer to receive ring */
1149    rxd[rxd_tail].status = 0x80000000;      rx_ring[tp->cur_rx].status = 0x80000000;
1150    rxd_tail++;      tp->cur_rx = (++tp->cur_rx) % RX_RING_SIZE;
   if (rxd_tail == NRXD) rxd_tail = 0;  
1151    
1152    return 1;      return 1;
1153  }  }
1154    
1155  /*********************************************************************/  /*********************************************************************/
# Line 660  static int tulip_poll(struct nic *nic) Line 1157  static int tulip_poll(struct nic *nic)
1157  /*********************************************************************/  /*********************************************************************/
1158  static void tulip_disable(struct nic *nic)  static void tulip_disable(struct nic *nic)
1159  {  {
   whereami("tulip_disable\n");  
1160    
1161    /* disable interrupts */  #ifdef TULIP_DEBUG_WHERE
1162    outl(0x00000000, ioaddr + CSR7);      whereami("tulip_disable\n");
1163    #endif
1164    
1165        /* disable interrupts */
1166        outl(0x00000000, ioaddr + CSR7);
1167    
1168    /* Stop the chip's Tx and Rx processes. */      /* Stop the chip's Tx and Rx processes. */
1169    outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);      outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
1170    
1171    /* Clear the missed-packet counter. */      /* Clear the missed-packet counter. */
1172    (volatile unsigned long)inl(ioaddr + CSR8);      (volatile unsigned long)inl(ioaddr + CSR8);
1173  }  }
1174    
1175  /*********************************************************************/  /*********************************************************************/
1176  /* eth_probe - Look for an adapter                                   */  /* eth_probe - Look for an adapter                                   */
1177  /*********************************************************************/  /*********************************************************************/
1178  struct nic *tulip_probe(struct nic *nic, unsigned short *io_addrs,  struct nic *tulip_probe(struct nic *nic, unsigned short *io_addrs,
1179                            struct pci_device *pci)                          struct pci_device *pci)
1180  {  {
1181    unsigned int i;      u32 i, l1, l2;
1182    u32 l1, l2;      u8  chip_rev;
1183        u8 ee_data[EEPROM_SIZE];
1184        unsigned short sum;
1185        int chip_idx;
1186        static unsigned char last_phys_addr[ETH_ALEN] = {0x00, 'L', 'i', 'n', 'u', 'x'};
1187    
1188        if (io_addrs == 0 || *io_addrs == 0)
1189            return 0;
1190    
1191        ioaddr         = *io_addrs;
1192    
1193        /* point to private storage */
1194        tp = &tpx;
1195    
1196        tp->vendor_id  = pci->vendor;
1197        tp->dev_id     = pci->dev_id;
1198        tp->nic_name   = pci->name;
1199    
1200        tp->if_port = 0;
1201        tp->default_port = 0;
1202    
1203        adjust_pci_device(pci);
1204    
1205        /* disable interrupts */
1206        outl(0x00000000, ioaddr + CSR7);
1207    
1208        /* Stop the chip's Tx and Rx processes. */
1209        outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
1210    
1211        /* Clear the missed-packet counter. */
1212        (volatile unsigned long)inl(ioaddr + CSR8);
1213    
1214        printf("\n");                /* so we start on a fresh line */
1215    #ifdef TULIP_DEBUG_WHERE
1216        whereami("tulip_probe\n");
1217    #endif
1218    
1219    #ifdef TULIP_DEBUG
1220        if (tulip_debug > 1)
1221            printf ("%s: Looking for Tulip Chip: Vendor=%hX  Device=%hX\n", tp->nic_name,
1222                    tp->vendor_id, tp->dev_id);
1223    #endif
1224    
1225        /* Figure out which chip we're dealing with */
1226        i = 0;
1227        chip_idx = -1;
1228      
1229        while (pci_id_tbl[i].name) {
1230            if ( (((u32) tp->dev_id << 16) | tp->vendor_id) ==
1231                 (pci_id_tbl[i].id.pci & pci_id_tbl[i].id.pci_mask) ) {
1232                chip_idx = pci_id_tbl[i].drv_flags;
1233                break;
1234            }
1235            i++;
1236        }
1237    
1238        if (chip_idx == -1) {
1239            printf ("%s: Unknown Tulip Chip: Vendor=%hX  Device=%hX\n", tp->nic_name,
1240                    tp->vendor_id, tp->dev_id);
1241            return 0;
1242        }
1243    
1244        tp->pci_id_idx = i;
1245        tp->flags = tulip_tbl[chip_idx].flags;
1246    
1247    #ifdef TULIP_DEBUG
1248        if (tulip_debug > 1) {
1249            printf ("%s: tp->pci_id_idx == %d,  name == %s\n", tp->nic_name,
1250                    tp->pci_id_idx, pci_id_tbl[tp->pci_id_idx].name);
1251            printf ("%s: chip_idx == %d, name == %s\n", tp->nic_name, chip_idx,
1252                    tulip_tbl[chip_idx].chip_name);
1253        }
1254    #endif
1255      
1256        /* Bring the 21041/21143 out of sleep mode.
1257           Caution: Snooze mode does not work with some boards! */
1258        if (tp->flags & HAS_PWRDWN)
1259            pcibios_write_config_dword(pci->bus, pci->devfn, 0x40, 0x00000000);
1260    
1261        if (inl(ioaddr + CSR5) == 0xFFFFFFFF) {
1262            printf("%s: The Tulip chip at %X is not functioning.\n",
1263                   tp->nic_name, ioaddr);
1264            return 0;
1265        }
1266      
1267        pcibios_read_config_byte(pci->bus, pci->devfn, PCI_REVISION, &chip_rev);
1268    
1269        printf("%s: [chip: %s] rev %d at %hX\n", tp->nic_name,
1270               tulip_tbl[chip_idx].chip_name, chip_rev, ioaddr);
1271        printf("%s: Vendor=%hX  Device=%hX", tp->nic_name, tp->vendor_id, tp->dev_id);
1272    
1273        if (chip_idx == DC21041  &&  inl(ioaddr + CSR9) & 0x8000) {
1274            printf(" 21040 compatible mode.");
1275            chip_idx = DC21040;
1276        }
1277    
1278    whereami("tulip_probe\n");      printf("\n");
1279    
1280    if (io_addrs == 0 || *io_addrs == 0)      /* The SROM/EEPROM interface varies dramatically. */
1281      return 0;      sum = 0;
1282        if (chip_idx == DC21040) {
1283    vendor  = pci->vendor;          outl(0, ioaddr + CSR9);         /* Reset the pointer with a dummy write. */
1284    dev_id  = pci->dev_id;          for (i = 0; i < ETH_ALEN; i++) {
1285    ioaddr  = *io_addrs;              int value, boguscnt = 100000;
1286                do
1287    /* wakeup chip */                  value = inl(ioaddr + CSR9);
1288    pcibios_write_config_dword(0, pci->devfn, 0x40, 0x00000000);              while (value < 0  && --boguscnt > 0);
1289                nic->node_addr[i] = value;
1290    /* Stop the chip's Tx and Rx processes. */              sum += value & 0xff;
1291    outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);          }
1292        } else if (chip_idx == LC82C168) {
1293    /* Clear the missed-packet counter. */          for (i = 0; i < 3; i++) {
1294    (volatile unsigned long)inl(ioaddr + CSR8);              int value, boguscnt = 100000;
1295                outl(0x600 | i, ioaddr + 0x98);
1296    /* Get MAC Address */              do
1297                    value = inl(ioaddr + CSR9);
1298    /* Hardware Address retrieval method for LC82C168 */              while (value < 0  && --boguscnt > 0);
1299    if (vendor == PCI_VENDOR_ID_LINKSYS && dev_id == PCI_DEVICE_ID_DEC_TULIP) {              put_unaligned(le16_to_cpu(value), ((u16*)nic->node_addr) + i);
1300      for (i = 0; i < 3; i++) {              sum += value & 0xffff;
1301        int value, boguscnt = 100000;          }
1302        outl(0x600 | i, ioaddr + 0x98);      } else if (chip_idx == COMET) {
1303        do          /* No need to read the EEPROM. */
1304          value = inl(ioaddr + CSR9);          put_unaligned(inl(ioaddr + 0xA4), (u32 *)nic->node_addr);
1305        while (value < 0  && --boguscnt > 0);          put_unaligned(inl(ioaddr + 0xA8), (u16 *)(nic->node_addr + 4));
1306        nic->node_addr[i*2]     = (u8)((value >> 8) & 0xFF);          for (i = 0; i < ETH_ALEN; i ++)
1307        nic->node_addr[i*2 + 1] = (u8)( value       & 0xFF);              sum += nic->node_addr[i];
1308      }      } else {
1309    } else if (vendor == PCI_VENDOR_ID_ADMTEK &&          /* A serial EEPROM interface, we read now and sort it out later. */
1310              dev_id == PCI_DEVICE_ID_ADMTEK_0985) {          int sa_offset = 0;
1311      l1 = inl(ioaddr + 0xA4);          int ee_addr_size = read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
1312      l2 = inl(ioaddr + 0xA8);  
1313      nic->node_addr[0] = (l1      ) & 0xFF;          for (i = 0; i < sizeof(ee_data)/2; i++)
1314      nic->node_addr[1] = (l1 >>  8) & 0xFF;              ((u16 *)ee_data)[i] =
1315      nic->node_addr[2] = (l1 >> 16) & 0xFF;                  le16_to_cpu(read_eeprom(ioaddr, i, ee_addr_size));
1316      nic->node_addr[3] = (l1 >> 24) & 0xFF;  
1317      nic->node_addr[4] = (l2      ) & 0xFF;          /* DEC now has a specification (see Notes) but early board makers
1318      nic->node_addr[5] = (l2 >>  8) & 0xFF;             just put the address in the first EEPROM locations. */
1319    } else {          /* This does  memcmp(eedata, eedata+16, 8) */
1320      /* read EEPROM data */          for (i = 0; i < 8; i ++)
1321      for (i = 0; i < sizeof(ee_data)/2; i++)              if (ee_data[i] != ee_data[16+i])
1322        ((unsigned short *)ee_data)[i] =                  sa_offset = 20;
1323          le16_to_cpu(read_eeprom(ioaddr, i, EEPROM_ADDRLEN));          if (ee_data[0] == 0xff  &&  ee_data[1] == 0xff &&  ee_data[2] == 0) {
1324                sa_offset = 2;              /* Grrr, damn Matrox boards. */
1325      /* extract MAC address from EEPROM buffer */          }
1326      for (i=0; i<6; i++)          for (i = 0; i < ETH_ALEN; i ++) {
1327        nic->node_addr[i] = ee_data[20+i];              nic->node_addr[i] = ee_data[i + sa_offset];
1328    }              sum += ee_data[i + sa_offset];
1329            }
1330    printf("Tulip %b:%b:%b:%b:%b:%b at ioaddr 0x%x\n",      }
1331      nic->node_addr[0],nic->node_addr[1],nic->node_addr[2],nic->node_addr[3],      /* Lite-On boards have the address byte-swapped. */
1332      nic->node_addr[4],nic->node_addr[5],ioaddr);      if ((nic->node_addr[0] == 0xA0  ||  nic->node_addr[0] == 0xC0)
1333            &&  nic->node_addr[1] == 0x00)
1334    /* initialize device */          for (i = 0; i < ETH_ALEN; i+=2) {
1335    tulip_reset(nic);              char tmp = nic->node_addr[i];
1336                nic->node_addr[i] = nic->node_addr[i+1];
1337    nic->reset    = tulip_reset;              nic->node_addr[i+1] = tmp;
1338    nic->poll     = tulip_poll;          }
1339    nic->transmit = tulip_transmit;  
1340    nic->disable  = tulip_disable;      if (sum == 0  || sum == ETH_ALEN*0xff) {
1341            printf("%s: EEPROM not present!\n", tp->nic_name);
1342            for (i = 0; i < ETH_ALEN-1; i++)
1343                nic->node_addr[i] = last_phys_addr[i];
1344            nic->node_addr[i] = last_phys_addr[i] + 1;
1345        }
1346    
1347        for (i = 0; i < ETH_ALEN; i++)
1348            last_phys_addr[i] = nic->node_addr[i];
1349    
1350        printf("%s: %! at ioaddr %hX\n", tp->nic_name, nic->node_addr, ioaddr);
1351    
1352        tp->chip_id = chip_idx;
1353        tp->revision = chip_rev;
1354        tp->csr0 = csr0;
1355    
1356        /* BugFixes: The 21143-TD hangs with PCI Write-and-Invalidate cycles.
1357           And the ASIX must have a burst limit or horrible things happen. */
1358        if (chip_idx == DC21143  &&  chip_rev == 65)
1359            tp->csr0 &= ~0x01000000;
1360        else if (tp->flags & IS_ASIX)
1361            tp->csr0 |= 0x2000;
1362    
1363        if (media_cap[tp->default_port] & MediaIsMII) {
1364            u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 };
1365            tp->mii_advertise = media2advert[tp->default_port - 9];
1366            tp->mii_advertise |= (tp->flags & HAS_8023X); /* Matching bits! */
1367        }
1368    
1369        /* This is logically part of the probe routine, but too complex
1370           to write inline. */
1371        if (tp->flags & HAS_MEDIA_TABLE) {
1372            memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom));
1373            parse_eeprom(nic);
1374        }
1375    
1376        start_link(nic);
1377    
1378        /* reset the device and make ready for tx and rx of packets */
1379        tulip_reset(nic);
1380    
1381        nic->reset    = tulip_reset;
1382        nic->poll     = tulip_poll;
1383        nic->transmit = tulip_transmit;
1384        nic->disable  = tulip_disable;
1385    
1386        /* give the board a chance to reset before returning */
1387        tulip_wait(4*TICKS_PER_SEC);
1388    
1389        return nic;
1390    }
1391    
1392    static void start_link(struct nic *nic)
1393    {
1394        int i;
1395    
1396    #ifdef TULIP_DEBUG_WHERE
1397        whereami("start_link\n");
1398    #endif
1399    
1400        if ((tp->flags & ALWAYS_CHECK_MII) ||
1401            (tp->mtable  &&  tp->mtable->has_mii) ||
1402            ( ! tp->mtable  &&  (tp->flags & HAS_MII))) {
1403            unsigned int phy, phy_idx;
1404            if (tp->mtable  &&  tp->mtable->has_mii) {
1405                for (i = 0; i < tp->mtable->leafcount; i++)
1406                    if (tp->mtable->mleaf[i].media == 11) {
1407                        tp->cur_index = i;
1408                        tp->saved_if_port = tp->if_port;
1409                        select_media(nic, 2);
1410                        tp->if_port = tp->saved_if_port;
1411                        break;
1412                    }
1413            }
1414    
1415            /* Find the connected MII xcvrs. */
1416            for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys);
1417                 phy++) {
1418                int mii_status = mdio_read(nic, phy, 1);
1419                if ((mii_status & 0x8301) == 0x8001 ||
1420                    ((mii_status & 0x8000) == 0  && (mii_status & 0x7800) != 0)) {
1421                    int mii_reg0 = mdio_read(nic, phy, 0);
1422                    int mii_advert = mdio_read(nic, phy, 4);
1423                    int to_advert;
1424    
1425                    if (tp->mii_advertise)
1426                        to_advert = tp->mii_advertise;
1427                    else if (tp->advertising[phy_idx])
1428                        to_advert = tp->advertising[phy_idx];
1429                    else                    /* Leave unchanged. */
1430                        tp->mii_advertise = to_advert = mii_advert;
1431    
1432                    tp->phys[phy_idx++] = phy;
1433                    printf("%s:  MII transceiver %d config %hX status %hX advertising %hX.\n",
1434                           tp->nic_name, phy, mii_reg0, mii_status, mii_advert);
1435                                    /* Fixup for DLink with miswired PHY. */
1436                    if (mii_advert != to_advert) {
1437                        printf("%s:  Advertising %hX on PHY %d previously advertising %hX.\n",
1438                               tp->nic_name, to_advert, phy, mii_advert);
1439                        mdio_write(nic, phy, 4, to_advert);
1440                    }
1441                                    /* Enable autonegotiation: some boards default to off. */
1442                    mdio_write(nic, phy, 0, mii_reg0 |
1443                               (tp->full_duplex ? 0x1100 : 0x1000) |
1444                               (media_cap[tp->default_port]&MediaIs100 ? 0x2000:0));
1445                }
1446            }
1447            tp->mii_cnt = phy_idx;
1448            if (tp->mtable  &&  tp->mtable->has_mii  &&  phy_idx == 0) {
1449                printf("%s: ***WARNING***: No MII transceiver found!\n",
1450                       tp->nic_name);
1451                tp->phys[0] = 1;
1452            }
1453        }
1454    
1455        /* Reset the xcvr interface and turn on heartbeat. */
1456        switch (tp->chip_id) {
1457        case DC21040:
1458            outl(0x00000000, ioaddr + CSR13);
1459            outl(0x00000004, ioaddr + CSR13);
1460            break;
1461        case DC21041:
1462            /* This is nway_start(). */
1463            if (tp->sym_advertise == 0)
1464                tp->sym_advertise = 0x0061;
1465            outl(0x00000000, ioaddr + CSR13);
1466            outl(0xFFFFFFFF, ioaddr + CSR14);
1467            outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */
1468            outl(inl(ioaddr + CSR6) | 0x0200, ioaddr + CSR6);
1469            outl(0x0000EF01, ioaddr + CSR13);
1470            break;
1471        case DC21140: default:
1472            if (tp->mtable)
1473                outl(tp->mtable->csr12dir | 0x100, ioaddr + CSR12);
1474            break;
1475        case DC21142:
1476        case PNIC2:
1477            if (tp->mii_cnt  ||  media_cap[tp->if_port] & MediaIsMII) {
1478                outl(0x82020000, ioaddr + CSR6);
1479                outl(0x0000, ioaddr + CSR13);
1480                outl(0x0000, ioaddr + CSR14);
1481                outl(0x820E0000, ioaddr + CSR6);
1482            } else
1483                nway_start(nic);
1484            break;
1485        case LC82C168:
1486            if ( ! tp->mii_cnt) {
1487                tp->nway = 1;
1488                tp->nwayset = 0;
1489                outl(0x00420000, ioaddr + CSR6);
1490                outl(0x30, ioaddr + CSR12);
1491                outl(0x0001F078, ioaddr + 0xB8);
1492                outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */
1493            }
1494            break;
1495        case MX98713: case COMPEX9881:
1496            outl(0x00000000, ioaddr + CSR6);
1497            outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */
1498            outl(0x00000001, ioaddr + CSR13);
1499            break;
1500        case MX98715: case MX98725:
1501            outl(0x01a80000, ioaddr + CSR6);
1502            outl(0xFFFFFFFF, ioaddr + CSR14);
1503            outl(0x00001000, ioaddr + CSR12);
1504            break;
1505        case COMET:
1506            /* No initialization necessary. */
1507            break;
1508        }
1509    }
1510    
1511    static void nway_start(struct nic *nic)
1512    {
1513        int csr14 = ((tp->sym_advertise & 0x0780) << 9)  |
1514            ((tp->sym_advertise&0x0020)<<1) | 0xffbf;
1515    
1516    #ifdef TULIP_DEBUG_WHERE
1517        whereami("nway_start\n");
1518    #endif
1519    
1520        tp->if_port = 0;
1521        tp->nway = tp->mediasense = 1;
1522        tp->nwayset = tp->lpar = 0;
1523        if (tp->chip_id == PNIC2) {
1524            tp->csr6 = 0x01000000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0);
1525            return;
1526        }
1527    #ifdef TULIP_DEBUG
1528        if (tulip_debug > 1)
1529            printf("%s: Restarting internal NWay autonegotiation, %X.\n",
1530                   tp->nic_name, csr14);
1531    #endif
1532        outl(0x0001, ioaddr + CSR13);
1533        outl(csr14, ioaddr + CSR14);
1534        tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0);
1535        outl(tp->csr6, ioaddr + CSR6);
1536        if (tp->mtable  &&  tp->mtable->csr15dir) {
1537            outl(tp->mtable->csr15dir, ioaddr + CSR15);
1538            outl(tp->mtable->csr15val, ioaddr + CSR15);
1539        } else if (tp->chip_id != PNIC2)
1540            outw(0x0008, ioaddr + CSR15);
1541        if (tp->chip_id == DC21041)                 /* Trigger NWAY. */
1542            outl(0xEF01, ioaddr + CSR12);
1543        else
1544            outl(0x1301, ioaddr + CSR12);
1545    }
1546    
1547    static void init_media(struct nic *nic)
1548    {
1549        int i;
1550    
1551    #ifdef TULIP_DEBUG_WHERE
1552        whereami("init_media\n");
1553    #endif
1554    
1555        tp->saved_if_port = tp->if_port;
1556        if (tp->if_port == 0)
1557            tp->if_port = tp->default_port;
1558    
1559        /* Allow selecting a default media. */
1560        i = 0;
1561        if (tp->mtable == NULL)
1562            goto media_picked;
1563        if (tp->if_port) {
1564            int looking_for = media_cap[tp->if_port] & MediaIsMII ? 11 :
1565                (tp->if_port == 12 ? 0 : tp->if_port);
1566            for (i = 0; i < tp->mtable->leafcount; i++)
1567                if (tp->mtable->mleaf[i].media == looking_for) {
1568                    printf("%s: Using user-specified media %s.\n",
1569                           tp->nic_name, medianame[tp->if_port]);
1570                    goto media_picked;
1571                }
1572        }
1573        if ((tp->mtable->defaultmedia & 0x0800) == 0) {
1574            int looking_for = tp->mtable->defaultmedia & 15;
1575            for (i = 0; i < tp->mtable->leafcount; i++)
1576                if (tp->mtable->mleaf[i].media == looking_for) {
1577                    printf("%s: Using EEPROM-set media %s.\n",
1578                           tp->nic_name, medianame[looking_for]);
1579                    goto media_picked;
1580                }
1581        }
1582        /* Start sensing first non-full-duplex media. */
1583        for (i = tp->mtable->leafcount - 1;
1584             (media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--)
1585            ;
1586     media_picked:
1587    
1588        tp->csr6 = 0;
1589        tp->cur_index = i;
1590        tp->nwayset = 0;
1591    
1592        if (tp->if_port) {
1593            if (tp->chip_id == DC21143  &&  media_cap[tp->if_port] & MediaIsMII) {
1594                /* We must reset the media CSRs when we force-select MII mode. */
1595                outl(0x0000, ioaddr + CSR13);
1596                outl(0x0000, ioaddr + CSR14);
1597                outl(0x0008, ioaddr + CSR15);
1598            }
1599            select_media(nic, 1);
1600            return;
1601        }
1602        switch(tp->chip_id) {
1603        case DC21041:
1604            /* tp->nway = 1;*/
1605            nway_start(nic);
1606            break;
1607        case DC21142:
1608            if (tp->mii_cnt) {
1609                select_media(nic, 1);
1610    #ifdef TULIP_DEBUG
1611                if (tulip_debug > 1)
1612                    printf("%s: Using MII transceiver %d, status %hX.\n",
1613                           tp->nic_name, tp->phys[0], mdio_read(nic, tp->phys[0], 1));
1614    #endif
1615                outl(0x82020000, ioaddr + CSR6);
1616                tp->csr6 = 0x820E0000;
1617                tp->if_port = 11;
1618                outl(0x0000, ioaddr + CSR13);
1619                outl(0x0000, ioaddr + CSR14);
1620            } else
1621                nway_start(nic);
1622            break;
1623        case PNIC2:
1624            nway_start(nic);
1625            break;
1626        case LC82C168:
1627            if (tp->mii_cnt) {
1628                tp->if_port = 11;
1629                tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0);
1630                outl(0x0001, ioaddr + CSR15);
1631            } else if (inl(ioaddr + CSR5) & TPLnkPass)
1632                pnic_do_nway(nic);
1633            else {
1634                /* Start with 10mbps to do autonegotiation. */
1635                outl(0x32, ioaddr + CSR12);
1636                tp->csr6 = 0x00420000;
1637                outl(0x0001B078, ioaddr + 0xB8);
1638                outl(0x0201B078, ioaddr + 0xB8);
1639            }
1640            break;
1641        case MX98713: case COMPEX9881:
1642            tp->if_port = 0;
1643            tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0);
1644            outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
1645            break;
1646        case MX98715: case MX98725:
1647            /* Provided by BOLO, Macronix - 12/10/1998. */
1648            tp->if_port = 0;
1649            tp->csr6 = 0x01a80200;
1650            outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
1651            outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0);
1652            break;
1653        case COMET:
1654            tp->if_port = 0;
1655            tp->csr6 = 0x00040000;
1656            break;
1657        case AX88140: case AX88141:
1658            tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100;
1659            break;
1660        default:
1661            select_media(nic, 1);
1662        }
1663    }
1664    
1665    static void pnic_do_nway(struct nic *nic)
1666    {
1667        u32 phy_reg = inl(ioaddr + 0xB8);
1668        u32 new_csr6 = tp->csr6 & ~0x40C40200;
1669    
1670    #ifdef TULIP_DEBUG_WHERE
1671        whereami("pnic_do_nway\n");
1672    #endif
1673    
1674        if (phy_reg & 0x78000000) { /* Ignore baseT4 */
1675            if (phy_reg & 0x20000000)               tp->if_port = 5;
1676            else if (phy_reg & 0x40000000)  tp->if_port = 3;
1677            else if (phy_reg & 0x10000000)  tp->if_port = 4;
1678            else if (phy_reg & 0x08000000)  tp->if_port = 0;
1679            tp->nwayset = 1;
1680            new_csr6 = (tp->if_port & 1) ? 0x01860000 : 0x00420000;
1681            outl(0x32 | (tp->if_port & 1), ioaddr + CSR12);
1682            if (tp->if_port & 1)
1683                outl(0x1F868, ioaddr + 0xB8);
1684            if (phy_reg & 0x30000000) {
1685                tp->full_duplex = 1;
1686                new_csr6 |= 0x00000200;
1687            }
1688    #ifdef TULIP_DEBUG
1689            if (tulip_debug > 1)
1690                printf("%s: PNIC autonegotiated status %X, %s.\n",
1691                       tp->nic_name, phy_reg, medianame[tp->if_port]);
1692    #endif
1693            if (tp->csr6 != new_csr6) {
1694                tp->csr6 = new_csr6;
1695                outl(tp->csr6 | 0x0002, ioaddr + CSR6);     /* Restart Tx */
1696                outl(tp->csr6 | 0x2002, ioaddr + CSR6);
1697            }
1698        }
1699    }
1700    
1701    /* Set up the transceiver control registers for the selected media type. */
1702    static void select_media(struct nic *nic, int startup)
1703    {
1704        struct mediatable *mtable = tp->mtable;
1705        u32 new_csr6;
1706        int i;
1707    
1708    #ifdef TULIP_DEBUG_WHERE
1709        whereami("select_media\n");
1710    #endif
1711    
1712        if (mtable) {
1713            struct medialeaf *mleaf = &mtable->mleaf[tp->cur_index];
1714            unsigned char *p = mleaf->leafdata;
1715            switch (mleaf->type) {
1716            case 0:                                 /* 21140 non-MII xcvr. */
1717    #ifdef TULIP_DEBUG
1718                if (tulip_debug > 1)
1719                    printf("%s: Using a 21140 non-MII transceiver"
1720                           " with control setting %hhX.\n",
1721                           tp->nic_name, p[1]);
1722    #endif
1723                tp->if_port = p[0];
1724                if (startup)
1725                    outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
1726                outl(p[1], ioaddr + CSR12);
1727                new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18);
1728                break;
1729            case 2: case 4: {
1730                u16 setup[5];
1731                u32 csr13val, csr14val, csr15dir, csr15val;
1732                for (i = 0; i < 5; i++)
1733                    setup[i] = get_u16(&p[i*2 + 1]);
1734    
1735                tp->if_port = p[0] & 15;
1736                if (media_cap[tp->if_port] & MediaAlwaysFD)
1737                    tp->full_duplex = 1;
1738    
1739                if (startup && mtable->has_reset) {
1740                    struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
1741                    unsigned char *rst = rleaf->leafdata;
1742    #ifdef TULIP_DEBUG
1743                    if (tulip_debug > 1)
1744                        printf("%s: Resetting the transceiver.\n",
1745                               tp->nic_name);
1746    #endif
1747                    for (i = 0; i < rst[0]; i++)
1748                        outl(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
1749                }
1750    #ifdef TULIP_DEBUG
1751                if (tulip_debug > 1)
1752                    printf("%s: 21143 non-MII %s transceiver control "
1753                           "%hX/%hX.\n",
1754                           tp->nic_name, medianame[tp->if_port], setup[0], setup[1]);
1755    #endif
1756                if (p[0] & 0x40) {  /* SIA (CSR13-15) setup values are provided. */
1757                    csr13val = setup[0];
1758                    csr14val = setup[1];
1759                    csr15dir = (setup[3]<<16) | setup[2];
1760                    csr15val = (setup[4]<<16) | setup[2];
1761                    outl(0, ioaddr + CSR13);
1762                    outl(csr14val, ioaddr + CSR14);
1763                    outl(csr15dir, ioaddr + CSR15); /* Direction */
1764                    outl(csr15val, ioaddr + CSR15); /* Data */
1765                    outl(csr13val, ioaddr + CSR13);
1766                } else {
1767                    csr13val = 1;
1768                    csr14val = 0x0003FF7F;
1769                    csr15dir = (setup[0]<<16) | 0x0008;
1770                    csr15val = (setup[1]<<16) | 0x0008;
1771                    if (tp->if_port <= 4)
1772                        csr14val = t21142_csr14[tp->if_port];
1773                    if (startup) {
1774                        outl(0, ioaddr + CSR13);
1775                        outl(csr14val, ioaddr + CSR14);
1776                    }
1777                    outl(csr15dir, ioaddr + CSR15); /* Direction */
1778                    outl(csr15val, ioaddr + CSR15); /* Data */
1779                    if (startup) outl(csr13val, ioaddr + CSR13);
1780                }
1781    #ifdef TULIP_DEBUG
1782                if (tulip_debug > 1)
1783                    printf("%s:  Setting CSR15 to %X/%X.\n",
1784                           tp->nic_name, csr15dir, csr15val);
1785    #endif
1786                if (mleaf->type == 4)
1787                    new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18);
1788                else
1789                    new_csr6 = 0x82420000;
1790                break;
1791            }
1792            case 1: case 3: {
1793                int phy_num = p[0];
1794                int init_length = p[1];
1795                u16 *misc_info;
1796    
1797                tp->if_port = 11;
1798                new_csr6 = 0x020E0000;
1799                if (mleaf->type == 3) {     /* 21142 */
1800                    u16 *init_sequence = (u16*)(p+2);
1801                    u16 *reset_sequence = &((u16*)(p+3))[init_length];
1802                    int reset_length = p[2 + init_length*2];
1803                    misc_info = reset_sequence + reset_length;
1804                    if (startup)
1805                        for (i = 0; i < reset_length; i++)
1806                            outl(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
1807                    for (i = 0; i < init_length; i++)
1808                        outl(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
1809                } else {
1810                    u8 *init_sequence = p + 2;
1811                    u8 *reset_sequence = p + 3 + init_length;
1812                    int reset_length = p[2 + init_length];
1813                    misc_info = (u16*)(reset_sequence + reset_length);
1814                    if (startup) {
1815                        outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
1816                        for (i = 0; i < reset_length; i++)
1817                            outl(reset_sequence[i], ioaddr + CSR12);
1818                    }
1819                    for (i = 0; i < init_length; i++)
1820                        outl(init_sequence[i], ioaddr + CSR12);
1821                }
1822                tp->advertising[phy_num] = get_u16(&misc_info[1]) | 1;
1823                if (startup < 2) {
1824                    if (tp->mii_advertise == 0)
1825                        tp->mii_advertise = tp->advertising[phy_num];
1826    #ifdef TULIP_DEBUG
1827                    if (tulip_debug > 1)
1828                        printf("%s:  Advertising %hX on MII %d.\n",
1829                               tp->nic_name, tp->mii_advertise, tp->phys[phy_num]);
1830    #endif
1831                    mdio_write(nic, tp->phys[phy_num], 4, tp->mii_advertise);
1832                }
1833                break;
1834            }
1835            default:
1836                printf("%s:  Invalid media table selection %d.\n",
1837                       tp->nic_name, mleaf->type);
1838                new_csr6 = 0x020E0000;
1839            }
1840    #ifdef TULIP_DEBUG
1841            if (tulip_debug > 1)
1842                printf("%s: Using media type %s, CSR12 is %hhX.\n",
1843                       tp->nic_name, medianame[tp->if_port],
1844                       inl(ioaddr + CSR12) & 0xff);
1845    #endif
1846        } else if (tp->chip_id == DC21041) {
1847            int port = tp->if_port <= 4 ? tp->if_port : 0;
1848    #ifdef TULIP_DEBUG
1849            if (tulip_debug > 1)
1850                printf("%s: 21041 using media %s, CSR12 is %hX.\n",
1851                       tp->nic_name, medianame[port == 3 ? 12: port],
1852                       inl(ioaddr + CSR12));
1853    #endif
1854            outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */
1855            outl(t21041_csr14[port], ioaddr + CSR14);
1856            outl(t21041_csr15[port], ioaddr + CSR15);
1857            outl(t21041_csr13[port], ioaddr + CSR13);
1858            new_csr6 = 0x80020000;
1859        } else if (tp->chip_id == LC82C168) {
1860            if (startup && ! tp->medialock)
1861                tp->if_port = tp->mii_cnt ? 11 : 0;
1862    #ifdef TULIP_DEBUG
1863            if (tulip_debug > 1)
1864                printf("%s: PNIC PHY status is %hX, media %s.\n",
1865                       tp->nic_name, inl(ioaddr + 0xB8), medianame[tp->if_port]);
1866    #endif
1867            if (tp->mii_cnt) {
1868                new_csr6 = 0x810C0000;
1869                outl(0x0001, ioaddr + CSR15);
1870                outl(0x0201B07A, ioaddr + 0xB8);
1871            } else if (startup) {
1872                /* Start with 10mbps to do autonegotiation. */
1873                outl(0x32, ioaddr + CSR12);
1874                new_csr6 = 0x00420000;
1875                outl(0x0001B078, ioaddr + 0xB8);
1876                outl(0x0201B078, ioaddr + 0xB8);
1877            } else if (tp->if_port == 3  ||  tp->if_port == 5) {
1878                outl(0x33, ioaddr + CSR12);
1879                new_csr6 = 0x01860000;
1880                /* Trigger autonegotiation. */
1881                outl(startup ? 0x0201F868 : 0x0001F868, ioaddr + 0xB8);
1882            } else {
1883                outl(0x32, ioaddr + CSR12);
1884                new_csr6 = 0x00420000;
1885                outl(0x1F078, ioaddr + 0xB8);
1886            }
1887        } else if (tp->chip_id == DC21040) {                                        /* 21040 */
1888            /* Turn on the xcvr interface. */
1889            int csr12 = inl(ioaddr + CSR12);
1890    #ifdef TULIP_DEBUG
1891            if (tulip_debug > 1)
1892                printf("%s: 21040 media type is %s, CSR12 is %hhX.\n",
1893                       tp->nic_name, medianame[tp->if_port], csr12);
1894    #endif
1895            if (media_cap[tp->if_port] & MediaAlwaysFD)
1896                tp->full_duplex = 1;
1897            new_csr6 = 0x20000;
1898            /* Set the full duplux match frame. */
1899            outl(FULL_DUPLEX_MAGIC, ioaddr + CSR11);
1900            outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */
1901            if (t21040_csr13[tp->if_port] & 8) {
1902                outl(0x0705, ioaddr + CSR14);
1903                outl(0x0006, ioaddr + CSR15);
1904            } else {
1905                outl(0xffff, ioaddr + CSR14);
1906                outl(0x0000, ioaddr + CSR15);
1907            }
1908            outl(0x8f01 | t21040_csr13[tp->if_port], ioaddr + CSR13);
1909        } else {                                    /* Unknown chip type with no media table. */
1910            if (tp->default_port == 0)
1911                tp->if_port = tp->mii_cnt ? 11 : 3;
1912            if (media_cap[tp->if_port] & MediaIsMII) {
1913                new_csr6 = 0x020E0000;
1914            } else if (media_cap[tp->if_port] & MediaIsFx) {
1915                new_csr6 = 0x028600000;
1916            } else
1917                new_csr6 = 0x038600000;
1918    #ifdef TULIP_DEBUG
1919            if (tulip_debug > 1)
1920                printf("%s: No media description table, assuming "
1921                       "%s transceiver, CSR12 %hhX.\n",
1922                       tp->nic_name, medianame[tp->if_port],
1923                       inl(ioaddr + CSR12));
1924    #endif
1925        }
1926    
1927        tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0);
1928        return;
1929    }
1930    
1931    /*
1932      Check the MII negotiated duplex and change the CSR6 setting if
1933      required.
1934      Return 0 if everything is OK.
1935      Return < 0 if the transceiver is missing or has no link beat.
1936    */
1937    static int tulip_check_duplex(struct nic *nic)
1938    {
1939            unsigned int bmsr, lpa, negotiated, new_csr6;
1940    
1941            bmsr = mdio_read(nic, tp->phys[0], 1);
1942            lpa = mdio_read(nic, tp->phys[0], 5);
1943    
1944    #ifdef TULIP_DEBUG
1945            if (tulip_debug > 1)
1946                    printf("%s: MII status %#x, Link partner report "
1947                               "%#x.\n", tp->nic_name, bmsr, lpa);
1948    #endif
1949    
1950            if (bmsr == 0xffff)
1951                    return -2;
1952            if ((bmsr & 4) == 0) {
1953                    int new_bmsr = mdio_read(nic, tp->phys[0], 1);
1954                    if ((new_bmsr & 4) == 0) {
1955    #ifdef TULIP_DEBUG
1956                            if (tulip_debug  > 1)
1957                                    printf("%s: No link beat on the MII interface,"
1958                                               " status %#x.\n", tp->nic_name,
1959                                               new_bmsr);
1960    #endif
1961                            return -1;
1962                    }
1963            }
1964            tp->full_duplex = lpa & 0x140;
1965    
1966            new_csr6 = tp->csr6;
1967            negotiated = lpa & tp->advertising[0];
1968    
1969            if(negotiated & 0x380) new_csr6 &= ~0x400000;
1970            else                   new_csr6 |= 0x400000;
1971            if (tp->full_duplex)   new_csr6 |= 0x200;
1972            else                   new_csr6 &= ~0x200;
1973    
1974            if (new_csr6 != tp->csr6) {
1975                    tp->csr6 = new_csr6;
1976    
1977    #ifdef TULIP_DEBUG
1978                    if (tulip_debug > 0)
1979                            printf("%s: Setting %s-duplex based on MII"
1980                                       "#%d link partner capability of %#x.\n",
1981                                       tp->nic_name,
1982                                       tp->full_duplex ? "full" : "half",
1983                                       tp->phys[0], lpa);
1984    #endif
1985                    return 1;
1986            }
1987    
1988    return nic;          return 0;
1989  }  }

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26