if_de.c revision 16357
1/*-
2 * Copyright (c) 1994, 1995, 1996 Matt Thomas (matt@3am-software.com)
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. The name of the author may not be used to endorse or promote products
11 *    derived from this software withough specific prior written permission
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * $Id: if_de.c,v 1.47 1996/05/21 19:05:31 wollman Exp $
25 *
26 */
27
28/*
29 * DEC DC21040 PCI Ethernet Controller
30 *
31 * Written by Matt Thomas
32 * BPF support code stolen directly from if_ec.c
33 *
34 *   This driver supports the DEC DE435 or any other PCI
35 *   board which support DC21040, DC21041, or DC21140 (mostly).
36 */
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/mbuf.h>
41#include <sys/protosw.h>
42#include <sys/socket.h>
43#include <sys/ioctl.h>
44#include <sys/errno.h>
45#include <sys/malloc.h>
46#include <sys/kernel.h>
47#include <sys/proc.h>	/* only for declaration of wakeup() used by vm.h */
48#if defined(__FreeBSD__)
49#include <sys/devconf.h>
50#include <machine/clock.h>
51#elif defined(__bsdi__) || defined(__NetBSD__)
52#include <sys/device.h>
53#endif
54
55#include <net/if.h>
56#include <net/if_types.h>
57#include <net/if_dl.h>
58#include <net/route.h>
59
60#include "bpfilter.h"
61#if NBPFILTER > 0
62#include <net/bpf.h>
63#include <net/bpfdesc.h>
64#endif
65
66#ifdef INET
67#include <netinet/in.h>
68#include <netinet/in_systm.h>
69#include <netinet/in_var.h>
70#include <netinet/ip.h>
71#include <netinet/if_ether.h>
72#endif
73
74#ifdef NS
75#include <netns/ns.h>
76#include <netns/ns_if.h>
77#endif
78
79#include <vm/vm.h>
80#include <vm/vm_param.h>
81#include <vm/vm_kern.h>
82
83#if defined(__FreeBSD__)
84#include <vm/pmap.h>
85#include <pci.h>
86#if NPCI > 0
87#include <pci/pcivar.h>
88#include <pci/dc21040.h>
89#endif
90#endif /* __FreeBSD__ */
91
92#if defined(__bsdi__)
93#include <i386/pci/pci.h>
94#include <i386/pci/ic/dc21040.h>
95#include <i386/isa/isa.h>
96#include <i386/isa/icu.h>
97#include <i386/isa/dma.h>
98#include <i386/isa/isavar.h>
99#if _BSDI_VERSION < 199510
100#include <eisa.h>
101#else
102#define	NEISA 0
103#endif
104#if NEISA > 0 && _BSDI_VERSION >= 199401
105#include <i386/eisa/eisa.h>
106#define	TULIP_EISA
107#endif
108#endif /* __bsdi__ */
109
110#if defined(__NetBSD__)
111#include <machine/bus.h>
112#if defined(__alpha__)
113#include <machine/intr.h>
114#endif
115#include <dev/pci/pcireg.h>
116#include <dev/pci/pcivar.h>
117#include <dev/ic/dc21040reg.h>
118#endif /* __NetBSD__ */
119
120/*
121 * Intel CPUs should use I/O mapped access.
122 */
123#if defined(__i386__) || defined(TULIP_EISA)
124#define	TULIP_IOMAPPED
125#endif
126
127#if 0
128/*
129 * This turns on all sort of debugging stuff and make the
130 * driver much larger.
131 */
132#define TULIP_DEBUG
133#endif
134
135/*
136 * This module supports
137 *	the DEC DC21040 PCI Ethernet Controller.
138 *	the DEC DC21041 PCI Ethernet Controller.
139 *	the DEC DC21140 PCI Fast Ethernet Controller.
140 */
141
142#ifdef TULIP_IOMAPPED
143#define	TULIP_EISA_CSRSIZE	16
144#define	TULIP_EISA_CSROFFSET	0
145#define	TULIP_PCI_CSRSIZE	8
146#define	TULIP_PCI_CSROFFSET	0
147
148#if defined(__NetBSD__)
149typedef bus_io_size_t tulip_csrptr_t;
150
151#define TULIP_CSR_READ(sc, csr) \
152    bus_io_read_4((sc)->tulip_bc, (sc)->tulip_ioh, (sc)->tulip_csrs.csr)
153#define TULIP_CSR_WRITE(sc, csr, val) \
154    bus_io_write_4((sc)->tulip_bc, (sc)->tulip_ioh, (sc)->tulip_csrs.csr, (val))
155
156#define TULIP_CSR_READBYTE(sc, csr) \
157    bus_io_read_1((sc)->tulip_bc, (sc)->tulip_ioh, (sc)->tulip_csrs.csr)
158#define TULIP_CSR_WRITEBYTE(sc, csr, val) \
159    bus_io_write_1((sc)->tulip_bc, (sc)->tulip_ioh, (sc)->tulip_csrs.csr, (val))
160#else
161typedef tulip_uint16_t tulip_csrptr_t;
162
163#define	TULIP_CSR_READ(sc, csr)			(inl((sc)->tulip_csrs.csr))
164#define	TULIP_CSR_WRITE(sc, csr, val)   	outl((sc)->tulip_csrs.csr, val)
165
166#define	TULIP_CSR_READBYTE(sc, csr)		(inb((sc)->tulip_csrs.csr))
167#define	TULIP_CSR_WRITEBYTE(sc, csr, val)	outb((sc)->tulip_csrs.csr, val)
168#endif /* __NetBSD__ */
169
170#else /* TULIP_IOMAPPED */
171
172#define	TULIP_PCI_CSRSIZE	8
173#define	TULIP_PCI_CSROFFSET	0
174
175#if defined(__NetBSD__)
176typedef bus_mem_size_t tulip_csrptr_t;
177
178#define TULIP_CSR_READ(sc, csr) \
179    bus_mem_read_4((sc)->tulip_bc, (sc)->tulip_memh, (sc)->tulip_csrs.csr)
180#define TULIP_CSR_WRITE(sc, csr, val) \
181    bus_mem_write_4((sc)->tulip_bc, (sc)->tulip_memh, (sc)->tulip_csrs.csr, \
182      (val))
183#else
184typedef volatile tulip_uint32_t *tulip_csrptr_t;
185
186/*
187 * macros to read and write CSRs.  Note that the "0 +" in
188 * READ_CSR is to prevent the macro from being an lvalue
189 * and WRITE_CSR shouldn't be assigned from.
190 */
191#define	TULIP_CSR_READ(sc, csr)		(0 + *(sc)->tulip_csrs.csr)
192#define	TULIP_CSR_WRITE(sc, csr, val)	((void)(*(sc)->tulip_csrs.csr = (val)))
193#endif /* __NetBSD__ */
194
195#endif /* TULIP_IOMAPPED */
196
197/*
198 * This structure contains "pointers" for the registers on
199 * the various 21x4x chips.  CSR0 through CSR8 are common
200 * to all chips.  After that, it gets messy...
201 */
202typedef struct {
203    tulip_csrptr_t csr_busmode;			/* CSR0 */
204    tulip_csrptr_t csr_txpoll;			/* CSR1 */
205    tulip_csrptr_t csr_rxpoll;			/* CSR2 */
206    tulip_csrptr_t csr_rxlist;			/* CSR3 */
207    tulip_csrptr_t csr_txlist;			/* CSR4 */
208    tulip_csrptr_t csr_status;			/* CSR5 */
209    tulip_csrptr_t csr_command;			/* CSR6 */
210    tulip_csrptr_t csr_intr;			/* CSR7 */
211    tulip_csrptr_t csr_missed_frames;		/* CSR8 */
212
213    /* DC21040 specific registers */
214
215    tulip_csrptr_t csr_enetrom;			/* CSR9 */
216    tulip_csrptr_t csr_reserved;		/* CSR10 */
217    tulip_csrptr_t csr_full_duplex;		/* CSR11 */
218
219    /* DC21040/DC21041 common registers */
220
221    tulip_csrptr_t csr_sia_status;		/* CSR12 */
222    tulip_csrptr_t csr_sia_connectivity;	/* CSR13 */
223    tulip_csrptr_t csr_sia_tx_rx;		/* CSR14 */
224    tulip_csrptr_t csr_sia_general;		/* CSR15 */
225
226    /* DC21140/DC21041 common registers */
227
228    tulip_csrptr_t csr_srom_mii;		/* CSR9 */
229    tulip_csrptr_t csr_gp_timer;		/* CSR11 */
230
231    /* DC21140 specific registers */
232
233    tulip_csrptr_t csr_gp;			/* CSR12 */
234    tulip_csrptr_t csr_watchdog;		/* CSR15 */
235
236    /* DC21041 specific registers */
237
238    tulip_csrptr_t csr_bootrom;			/* CSR10 */
239} tulip_regfile_t;
240
241/*
242 * While 21x4x allows chaining of its descriptors, this driver
243 * doesn't take advantage of it.  We keep the descriptors in a
244 * traditional FIFO ring.
245 */
246typedef struct {
247    tulip_desc_t *ri_first;	/* first entry in ring */
248    tulip_desc_t *ri_last;	/* one after last entry */
249    tulip_desc_t *ri_nextin;	/* next to processed by host */
250    tulip_desc_t *ri_nextout;	/* next to processed by adapter */
251    int ri_max;
252    int ri_free;
253} tulip_ringinfo_t;
254
255/*
256 * The DC21040 has a stupid restriction in that the receive
257 * buffers must be longword aligned.  But since Ethernet
258 * headers are not a multiple of longwords in size this forces
259 * the data to non-longword aligned.  Since IP requires the
260 * data to be longword aligned, we need to copy it after it has
261 * been DMA'ed in our memory.
262 *
263 * Since we have to copy it anyways, we might as well as allocate
264 * dedicated receive space for the input.  This allows to use a
265 * small receive buffer size and more ring entries to be able to
266 * better keep with a flood of tiny Ethernet packets.
267 *
268 * The receive space MUST ALWAYS be a multiple of the page size.
269 * And the number of receive descriptors multiplied by the size
270 * of the receive buffers must equal the recevive space.  This
271 * is so that we can manipulate the page tables so that even if a
272 * packet wraps around the end of the receive space, we can
273 * treat it as virtually contiguous.
274 *
275 * The above used to be true (the stupid restriction is still true)
276 * but we gone to directly DMA'ing into MBUFs (unless it's on an
277 * architecture which can't handle unaligned accesses) because with
278 * 100Mb/s cards the copying is just too much of a hit.
279 */
280#if defined(__alpha__)
281#define	TULIP_COPY_RXDATA	1
282#endif
283
284#define	TULIP_RXDESCS		48
285#define	TULIP_TXDESCS		128
286#define	TULIP_RXQ_TARGET	32
287#if TULIP_RXQ_TARGET >= TULIP_RXDESCS
288#error TULIP_RXQ_TARGET must be less than TULIP_RXDESCS
289#endif
290#define	TULIP_RX_BUFLEN		((MCLBYTES < 2048 ? MCLBYTES : 2048) - 16)
291
292/*
293 * Forward reference to make C happy.
294 */
295typedef struct _tulip_softc_t tulip_softc_t;
296
297/*
298 * Some boards need to treated specially.  The following enumeration
299 * identifies the cards with quirks (or those we just want to single
300 * out for special merit or scorn).
301 */
302typedef enum {
303    TULIP_DC21040_GENERIC,		/* Generic DC21040 (works with most any board) */
304    TULIP_DC21040_ZX314_MASTER,		/* ZNYX ZX314 Master 21040 (it has the interrupt line) */
305    TULIP_DC21040_ZX314_SLAVE,		/* ZNYX ZX314 Slave 21040 (its interrupt is tied to the master's */
306    TULIP_DC21140_DEC_EB,		/* Digital Semicondutor 21140 Evaluation Board */
307    TULIP_DC21140_DEC_DE500,		/* Digital DE500-?? 10/100 */
308    TULIP_DC21140_SMC_9332,		/* SMC 9332 */
309    TULIP_DC21140_COGENT_EM100,		/* Cogent EM100 100 only */
310    TULIP_DC21140_ZNYX_ZX34X,		/* ZNYX ZX342 10/100 */
311    TULIP_DC21041_GENERIC,		/* Generic DC21041 card */
312    TULIP_DC21041_DEC_DE450		/* Digital DE450 */
313} tulip_board_t;
314
315/*
316 * This data structure is used to abstract out the quirks.
317 * media_probe  = tries to determine the media type.
318 * media_select = enables the current media (or autosenses)
319 * media_preset = 21140, etal requires bit to set before the
320 *		  the software reset; hence pre-set.  Should be
321 *		  pre-reset but that's ugly.
322 * mii_probe	= probe for PHY devices connected via the MII interface
323 *		  on 21140, etal.
324 */
325
326typedef struct {
327    tulip_board_t bd_type;
328    const char *bd_description;
329    int (*bd_media_probe)(tulip_softc_t *sc);
330    void (*bd_media_select)(tulip_softc_t *sc);
331    void (*bd_media_preset)(tulip_softc_t *sc);
332    void (*bd_mii_probe)(tulip_softc_t *sc);
333} tulip_boardsw_t;
334
335/*
336 * The next few declarations are for MII/PHY based board.
337 *
338 *    The first enumeration identifies a superset of various datums
339 * that can be obtained from various PHY chips.  Not all PHYs will
340 * support all datums.
341 *    The modedata structure indicates what register contains
342 * a datum, what mask is applied the register contents, and what the
343 * result should be.
344 *    The attr structure records information about a supported PHY.
345 *    The phy structure records information about a PHY instance.
346 */
347
348typedef enum {
349    PHY_MODE_10T,
350    PHY_MODE_100TX,
351    PHY_MODE_100T4,
352    PHY_MODE_FULLDUPLEX,
353    PHY_MODE_MAX
354} phy_mode_t;
355
356typedef struct {
357    unsigned short pm_regno;
358    unsigned short pm_mask;
359    unsigned short pm_value;
360} phy_modedata_t;
361
362typedef struct {
363    const char *attr_name;
364    unsigned attr_id;
365    unsigned short attr_flags;
366#define	PHY_NEED_HARD_RESET	0x0001
367#define	PHY_DUAL_CYCLE_TA	0x0002
368    phy_modedata_t attr_modes[PHY_MODE_MAX];
369} phy_attr_t;
370
371typedef struct _tulip_phy_t {
372    const struct _tulip_phy_t *phy_next;
373    const phy_attr_t *phy_attr;
374    unsigned phy_devaddr;
375    unsigned phy_status;
376} tulip_phy_t;
377
378/*
379 * The various controllers support.  Technically the DE425 is just
380 * a 21040 on EISA.  But since it remarkable difference from normal
381 * 21040s, we give it its own chip id.
382 */
383
384typedef enum {
385    TULIP_DC21040, TULIP_DE425,
386    TULIP_DC21041,
387    TULIP_DC21140, TULIP_DC21140A, TULIP_DC21142,
388    TULIP_CHIPID_UNKNOWN
389} tulip_chipid_t;
390
391/*
392 * Various probe states used when trying to autosense the media.
393 * While we could try to autosense on the 21040, it a pain and so
394 * until someone complain we won't.  However, the 21041 and MII
395 * 2114x do support autosense.
396 */
397
398typedef enum {
399    TULIP_PROBE_INACTIVE, TULIP_PROBE_10BASET, TULIP_PROBE_AUI,
400    TULIP_PROBE_BNC, TULIP_PROBE_PHYRESET, TULIP_PROBE_PHYAUTONEG,
401    TULIP_PROBE_MEDIATEST, TULIP_PROBE_FAILED
402} tulip_probe_state_t;
403
404/*
405 * Various physical media types supported.
406 * BNCAUI is BNC or AUI since on the 21040 you can't really tell
407 * which is in use.
408 */
409typedef enum {
410    TULIP_MEDIA_UNKNOWN,
411    TULIP_MEDIA_10BASET,
412    TULIP_MEDIA_BNC,
413    TULIP_MEDIA_AUI,
414    TULIP_MEDIA_BNCAUI,
415    TULIP_MEDIA_10BASET_FD,
416    TULIP_MEDIA_100BASETX,
417    TULIP_MEDIA_100BASETX_FD,
418    TULIP_MEDIA_100BASET4
419} tulip_media_t;
420
421typedef struct {
422    /*
423     * Transmit Statistics
424     */
425    tulip_uint32_t dot3StatsSingleCollisionFrames;
426    tulip_uint32_t dot3StatsMultipleCollisionFrames;
427    tulip_uint32_t dot3StatsSQETestErrors;
428    tulip_uint32_t dot3StatsDeferredTransmissions;
429    tulip_uint32_t dot3StatsLateCollisions;
430    tulip_uint32_t dot3StatsExcessiveCollisions;
431    tulip_uint32_t dot3StatsInternalMacTransmitErrors;
432    tulip_uint32_t dot3StatsCarrierSenseErrors;
433    /*
434     * Receive Statistics
435     */
436    tulip_uint32_t dot3StatsMissedFrames;	/* not in rfc1650! */
437    tulip_uint32_t dot3StatsAlignmentErrors;
438    tulip_uint32_t dot3StatsFCSErrors;
439    tulip_uint32_t dot3StatsFrameTooLongs;
440    tulip_uint32_t dot3StatsInternalMacReceiveErrors;
441} tulip_dot3_stats_t;
442
443/*
444 * Now to important stuff.  This is softc structure (where does softc
445 * come from??? No idea) for the tulip device.
446 *
447 */
448struct _tulip_softc_t {
449#if defined(__bsdi__)
450    struct device tulip_dev;		/* base device */
451    struct isadev tulip_id;		/* ISA device */
452    struct intrhand tulip_ih;		/* intrrupt vectoring */
453    struct atshutdown tulip_ats;	/* shutdown hook */
454#if _BSDI_VERSION < 199401
455    caddr_t tulip_bpf;			/* for BPF */
456#else
457    prf_t tulip_pf;			/* printf function */
458#endif
459#endif
460#if defined(__NetBSD__)
461    struct device tulip_dev;		/* base device */
462    void *tulip_ih;			/* intrrupt vectoring */
463    void *tulip_ats;			/* shutdown hook */
464    bus_chipset_tag_t tulip_bc;
465    pci_chipset_tag_t tulip_pc;
466#ifdef TULIP_IOMAPPED
467    bus_io_handle_t tulip_ioh;		/* I/O region handle */
468#else
469    bus_io_handle_t tulip_memh;		/* memory region handle */
470#endif
471#endif
472    struct arpcom tulip_ac;
473    tulip_regfile_t tulip_csrs;
474    unsigned tulip_flags;
475#define	TULIP_WANTSETUP		0x00000001
476#define	TULIP_WANTHASH		0x00000002
477#define	TULIP_DOINGSETUP	0x00000004
478#define	TULIP_ALTPHYS		0x00000008
479#define	TULIP_PRINTMEDIA	0x00000010
480#define	TULIP_TXPROBE_ACTIVE	0x00000020
481#define	TULIP_TXPROBE_OK	0x00000040
482#define	TULIP_WANTRXACT		0x00000080
483#define	TULIP_RXACT		0x00000100
484#define	TULIP_INRESET		0x00000200
485#define	TULIP_NEEDRESET		0x00000400
486#define	TULIP_SQETEST		0x00000800
487#define	TULIP_ROMOK		0x00001000
488#define	TULIP_SLAVEDROM		0x00002000
489#define	TULIP_SLAVEDINTR	0x00004000
490#define	TULIP_LINKSUSPECT	0x00008000
491#define	TULIP_LINKUP		0x00010000
492#define	TULIP_RXBUFSLOW		0x00020000
493#define	TULIP_NOMESSAGES	0x00040000
494#define	TULIP_SYSTEMERROR	0x00080000
495#define	TULIP_DEVICEPROBE	0x00100000
496#define	TULIP_FAKEGPTIMEOUT	0x00200000
497    unsigned char tulip_rombuf[128];
498    tulip_uint32_t tulip_setupbuf[192/sizeof(tulip_uint32_t)];
499    tulip_uint32_t tulip_setupdata[192/sizeof(tulip_uint32_t)];
500    tulip_uint32_t tulip_intrmask;
501    tulip_uint32_t tulip_cmdmode;
502    tulip_uint32_t tulip_revinfo;
503    tulip_uint32_t tulip_gpticks;
504    tulip_uint32_t tulip_gpunits;
505    tulip_uint32_t tulip_last_system_error : 3;
506    tulip_uint32_t tulip_txtimer : 2;
507    tulip_uint32_t tulip_system_errors;
508    tulip_uint32_t tulip_statusbits;
509    tulip_uint32_t tulip_abilities;
510    /* tulip_uint32_t tulip_bus; XXX */
511    tulip_media_t tulip_media;
512    tulip_probe_state_t tulip_probe_state;
513    tulip_chipid_t tulip_chipid;
514    const char *tulip_boardid;
515    char tulip_boardidbuf[16];
516    const tulip_boardsw_t *tulip_boardsw;
517    tulip_softc_t *tulip_slaves;
518    tulip_phy_t *tulip_phys;
519#ifdef TULIP_DEBUG
520    struct {
521	tulip_uint32_t dbg_intrs;
522	tulip_uint32_t dbg_msdelay;
523	tulip_uint32_t dbg_gpticks;
524	enum {
525	    TULIP_GPTMR_10MB,
526	    TULIP_GPTMR_10MB_MII,
527	    TULIP_GPTMR_100MB_MII
528	} dbg_gprate;
529	tulip_uint32_t dbg_gpintrs;
530	tulip_uint32_t dbg_gpintrs_hz;
531	tulip_uint32_t dbg_link_downed;
532	tulip_uint32_t dbg_link_suspected;
533	u_int16_t dbg_phyregs[32][4];
534	tulip_uint32_t dbg_rxlowbufs;
535	tulip_uint32_t dbg_rxintrs;
536	tulip_uint32_t dbg_last_rxintrs;
537	tulip_uint32_t dbg_high_rxintrs_hz;
538	tulip_uint32_t dbg_rxpktsperintr[TULIP_RXDESCS];
539    } tulip_dbg;
540#endif
541    struct ifqueue tulip_txq;
542    struct ifqueue tulip_rxq;
543    tulip_dot3_stats_t tulip_dot3stats;
544    tulip_ringinfo_t tulip_rxinfo;
545    tulip_ringinfo_t tulip_txinfo;
546    tulip_desc_t tulip_rxdescs[TULIP_RXDESCS];
547    tulip_desc_t tulip_txdescs[TULIP_TXDESCS];
548};
549
550static const char * const tulip_chipdescs[] = {
551    "DC21040 [10Mb/s]",
552#if defined(TULIP_EISA)
553    "DE425 [10Mb/s]",
554#else
555    NULL,
556#endif
557    "DC21041 [10Mb/s]",
558    "DC21140 [10-100Mb/s]",
559    "DC21140A [10-100Mb/s]",
560    "DC21142 [10-100Mb/s]",
561};
562
563static const char * const tulip_mediums[] = {
564    "unknown",			/* TULIP_MEDIA_UNKNOWN */
565    "10baseT",			/* TULIP_MEDIA_10BASET */
566    "BNC",			/* TULIP_MEDIA_BNC */
567    "AUI",			/* TULIP_MEDIA_AUI */
568    "BNC/AUI",			/* TULIP_MEDIA_BNCAUI */
569    "Full Duplex 10baseT",	/* TULIP_MEDIA_10BASET_FD */
570    "100baseTX",		/* TULIP_MEDIA_100BASET */
571    "Full Duplex 100baseTX",	/* TULIP_MEDIA_100BASET_FD */
572    "100baseT4",		/* TULIP_MEDIA_100BASET4 */
573};
574
575static const tulip_media_t tulip_phy_statuses[] = {
576    TULIP_MEDIA_10BASET, TULIP_MEDIA_10BASET_FD,
577    TULIP_MEDIA_100BASETX, TULIP_MEDIA_100BASETX_FD,
578    TULIP_MEDIA_100BASET4
579};
580
581static const char * const tulip_system_errors[] = {
582    "parity error",
583    "master abort",
584    "target abort",
585    "reserved #3",
586    "reserved #4",
587    "reserved #5",
588    "reserved #6",
589    "reserved #7",
590};
591
592static const char * const tulip_status_bits[] = {
593    NULL,
594    "transmit process stopped",
595    NULL,
596    "transmit jabber timeout",
597
598    NULL,
599    "transmit underflow",
600    NULL,
601    "receive underflow",
602
603    "receive process stopped",
604    "receive watchdog timeout",
605    NULL,
606    NULL,
607
608    "link failure",
609    NULL,
610    NULL,
611};
612
613#ifndef IFF_ALTPHYS
614#define	IFF_ALTPHYS	IFF_LINK2		/* In case it isn't defined */
615#endif
616
617#ifndef IFF_FULLDUPLEX
618#define	IFF_FULLDUPLEX	IFF_LINK1
619#endif
620
621#ifndef	IFF_NOAUTONEG
622#if IFF_ALTPHYS == IFF_LINK2
623#define	IFF_NOAUTONEG	IFF_LINK0
624#else
625#define	IFF_NOAUTONEG	IFF_LINK2
626#endif
627#endif
628
629#if (IFF_ALTPHYS&IFF_FULLDUPLEX&IFF_NOAUTONEG) != 0
630#error IFF_ALTPHYS, IFF_FULLDUPLEX, IFF_NOAUTONEG overlap
631#endif
632
633
634#if defined(__FreeBSD__)
635typedef void ifnet_ret_t;
636typedef int ioctl_cmd_t;
637#define	TULIP_COUNTINCR		4
638tulip_softc_t **tulips;
639int tulip_count;
640#if BSD >= 199506
641#define TULIP_IFP_TO_SOFTC(ifp) ((tulip_softc_t *)((ifp)->if_softc))
642#if NBPFILTER > 0
643#define	TULIP_BPF_MTAP(sc, m)	bpf_mtap(&(sc)->tulip_if, m)
644#define	TULIP_BPF_TAP(sc, p, l)	bpf_tap(&(sc)->tulip_if, p, l)
645#define	TULIP_BPF_ATTACH(sc)	bpfattach(&(sc)->tulip_if, DLT_EN10MB, sizeof(struct ether_header))
646#endif
647#define	tulip_intrfunc_t	void
648#define	TULIP_VOID_INTRFUNC
649#define	IFF_NOTRAILERS		0
650#define	CLBYTES			PAGE_SIZE
651#if 0
652#define	TULIP_KVATOPHYS(sc, va)	kvtop(va)
653#endif
654#define	TULIP_EADDR_FMT		"%6D"
655#define	TULIP_EADDR_ARGS(addr)	addr, ":"
656#else
657extern int bootverbose;
658#define TULIP_IFP_TO_SOFTC(ifp)         (TULIP_UNIT_TO_SOFTC((ifp)->if_unit))
659#endif
660#define	TULIP_UNIT_TO_SOFTC(unit)	(tulips[unit])
661#define	TULIP_BURSTSIZE(unit)		pci_max_burst_len
662#define	loudprintf			if (bootverbose) printf
663#endif
664
665#if defined(__bsdi__)
666typedef int ifnet_ret_t;
667typedef int ioctl_cmd_t;
668extern struct cfdriver decd;
669#define	TULIP_UNIT_TO_SOFTC(unit)	((tulip_softc_t *) decd.cd_devs[unit])
670#define TULIP_IFP_TO_SOFTC(ifp)		(TULIP_UNIT_TO_SOFTC((ifp)->if_unit))
671#if _BSDI_VERSION >= 199510
672#if 0
673#define	TULIP_BURSTSIZE(unit)		log2_burst_size
674#endif
675#define	loudprintf			aprint_verbose
676#define	printf				(*sc->tulip_pf)
677#elif _BSDI_VERSION <= 199401
678#define	DRQNONE				0
679#define	loudprintf			printf
680static void
681arp_ifinit(
682    struct arpcom *ac,
683    struct ifaddr *ifa)
684{
685    ac->ac_ipaddr = IA_SIN(ifa)->sin_addr;
686    arpwhohas(ac, &ac->ac_ipaddr);
687}
688#endif
689#endif	/* __bsdi__ */
690
691#if defined(__NetBSD__)
692typedef void ifnet_ret_t;
693typedef u_long ioctl_cmd_t;
694extern struct cfattach de_ca;
695extern struct cfdriver de_cd;
696#define	TULIP_UNIT_TO_SOFTC(unit)	((tulip_softc_t *) de_cd.cd_devs[unit])
697#define TULIP_IFP_TO_SOFTC(ifp)         ((tulip_softc_t *)((ifp)->if_softc))
698#define	tulip_xname			tulip_ac.ac_if.if_xname
699#define	tulip_unit			tulip_dev.dv_unit
700#define	loudprintf			printf
701#define	TULIP_PRINTF_FMT		"%s"
702#define	TULIP_PRINTF_ARGS		sc->tulip_xname
703#if defined(__alpha__)
704/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */
705#define TULIP_KVATOPHYS(va)		(vtophys(va) | 0x40000000)
706#endif
707#endif	/* __NetBSD__ */
708
709#ifndef TULIP_PRINTF_FMT
710#define	TULIP_PRINTF_FMT		"%s%d"
711#endif
712#ifndef TULIP_PRINTF_ARGS
713#define	TULIP_PRINTF_ARGS		sc->tulip_name, sc->tulip_unit
714#endif
715
716#ifndef TULIP_BURSTSIZE
717#define	TULIP_BURSTSIZE(unit)		3
718#endif
719
720#define	tulip_if	tulip_ac.ac_if
721#ifndef tulip_unit
722#define	tulip_unit	tulip_ac.ac_if.if_unit
723#endif
724#define	tulip_name	tulip_ac.ac_if.if_name
725#define	tulip_hwaddr	tulip_ac.ac_enaddr
726
727#if !defined(tulip_bpf) && (!defined(__bsdi__) || _BSDI_VERSION >= 199401)
728#define	tulip_bpf	tulip_ac.ac_if.if_bpf
729#endif
730
731#if !defined(tulip_intrfunc_t)
732#define	tulip_intrfunc_t	int
733#endif
734
735#if !defined(TULIP_KVATOPHYS)
736#define	TULIP_KVATOPHYS(sc, va)	vtophys(va)
737#endif
738
739/*
740 * While I think FreeBSD's 2.2 change to the bpf is a nice simplification,
741 * it does add yet more conditional code to this driver.  Sigh.
742 */
743#if !defined(TULIP_BPF_MTAP) && NBPFILTER > 0
744#define	TULIP_BPF_MTAP(sc, m)	bpf_mtap((sc)->tulip_bpf, m)
745#define	TULIP_BPF_TAP(sc, p, l)	bpf_tap((sc)->tulip_bpf, p, l)
746#define	TULIP_BPF_ATTACH(sc)	bpfattach(&(sc)->tulip_bpf, &(sc)->tulip_if, DLT_EN10MB, sizeof(struct ether_header))
747#endif
748
749/*
750 * However, this change to FreeBSD I am much less enamored with.
751 */
752#if !defined(TULIP_EADDR_FMT)
753#define	TULIP_EADDR_FMT		"%s"
754#define	TULIP_EADDR_ARGS(addr)	ether_sprintf(addr)
755#endif
756
757#define	TULIP_CRC32_POLY	0xEDB88320UL	/* CRC-32 Poly -- Little Endian */
758#define	TULIP_MAX_TXSEG		30
759
760#define	TULIP_ADDREQUAL(a1, a2) \
761	(((u_int16_t *)a1)[0] == ((u_int16_t *)a2)[0] \
762	 && ((u_int16_t *)a1)[1] == ((u_int16_t *)a2)[1] \
763	 && ((u_int16_t *)a1)[2] == ((u_int16_t *)a2)[2])
764#define	TULIP_ADDRBRDCST(a1) \
765	(((u_int16_t *)a1)[0] == 0xFFFFU \
766	 && ((u_int16_t *)a1)[1] == 0xFFFFU \
767	 && ((u_int16_t *)a1)[2] == 0xFFFFU)
768
769static tulip_intrfunc_t tulip_intr(void *arg);
770static void tulip_reset(tulip_softc_t * const sc);
771static ifnet_ret_t tulip_ifstart(struct ifnet *ifp);
772static void tulip_rx_intr(tulip_softc_t * const sc);
773static void tulip_addr_filter(tulip_softc_t * const sc);
774static unsigned tulip_mii_readreg(tulip_softc_t * const sc, unsigned devaddr, unsigned regno);
775static void tulip_mii_writereg(tulip_softc_t * const sc, unsigned devaddr, unsigned regno, unsigned data);
776
777static int
778tulip_dc21040_media_probe(
779    tulip_softc_t * const sc)
780{
781    int cnt;
782
783    TULIP_CSR_WRITE(sc, csr_sia_connectivity, 0);
784    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_10BASET);
785    for (cnt = 0; cnt < 2400; cnt++) {
786	if ((TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_LINKFAIL) == 0)
787	    break;
788	DELAY(1000);
789    }
790    sc->tulip_if.if_baudrate = 10000000;
791    return (TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_LINKFAIL) != 0;
792}
793
794static void
795tulip_dc21040_media_select(
796    tulip_softc_t * const sc)
797{
798    sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_THRSHLD160
799	|TULIP_CMD_BACKOFFCTR;
800    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
801    sc->tulip_flags |= TULIP_SQETEST|TULIP_LINKUP;
802    if (sc->tulip_if.if_flags & IFF_ALTPHYS) {
803	TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_AUI);
804	sc->tulip_media = TULIP_MEDIA_BNCAUI;
805	sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
806	if ((sc->tulip_flags & TULIP_ALTPHYS) == 0)
807	    sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_ALTPHYS;
808    } else {
809	if (sc->tulip_if.if_flags & IFF_FULLDUPLEX) {
810	    sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
811	    sc->tulip_media = TULIP_MEDIA_10BASET_FD;
812	    sc->tulip_flags &= ~TULIP_SQETEST;
813	} else {
814	    sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
815	    sc->tulip_media = TULIP_MEDIA_10BASET;
816	}
817	if (sc->tulip_flags & TULIP_ALTPHYS)
818	    sc->tulip_flags ^= TULIP_PRINTMEDIA|TULIP_ALTPHYS;
819	TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_10BASET);
820    }
821}
822
823static int
824tulip_dc21040_10baset_only_media_probe(
825    tulip_softc_t * const sc)
826{
827    TULIP_CSR_WRITE(sc, csr_sia_connectivity, 0);
828    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_10BASET);
829    sc->tulip_if.if_baudrate = 10000000;
830    return 0;
831}
832
833static void
834tulip_dc21040_10baset_only_media_select(
835    tulip_softc_t * const sc)
836{
837    sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_THRSHLD160
838	|TULIP_CMD_BACKOFFCTR;
839    sc->tulip_flags |= TULIP_LINKUP;
840    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
841    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_10BASET);
842    if (sc->tulip_if.if_flags & IFF_FULLDUPLEX) {
843	sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
844	sc->tulip_media = TULIP_MEDIA_10BASET_FD;
845	sc->tulip_flags &= ~TULIP_SQETEST;
846    } else {
847	sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
848	sc->tulip_media = TULIP_MEDIA_10BASET;
849	sc->tulip_flags |= TULIP_SQETEST;
850    }
851    if (sc->tulip_flags & TULIP_ALTPHYS)
852	sc->tulip_flags ^= TULIP_PRINTMEDIA|TULIP_ALTPHYS;
853    sc->tulip_flags &= ~TULIP_ALTPHYS;
854}
855
856static int
857tulip_dc21040_auibnc_only_media_probe(
858    tulip_softc_t * const sc)
859{
860    TULIP_CSR_WRITE(sc, csr_sia_connectivity, 0);
861    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_AUI);
862    sc->tulip_if.if_baudrate = 10000000;
863    sc->tulip_flags |= TULIP_SQETEST|TULIP_LINKUP;
864    return 0;
865}
866
867static void
868tulip_dc21040_auibnc_only_media_select(
869    tulip_softc_t * const sc)
870{
871    sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_THRSHLD160
872	|TULIP_CMD_BACKOFFCTR;
873    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
874    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_AUI);
875    if (sc->tulip_if.if_flags & IFF_FULLDUPLEX)
876	sc->tulip_if.if_flags &= ~IFF_FULLDUPLEX;
877    sc->tulip_media = TULIP_MEDIA_BNCAUI;
878    sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
879    if ((sc->tulip_flags & TULIP_ALTPHYS) == 0)
880	sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_ALTPHYS;
881    sc->tulip_flags &= ~TULIP_ALTPHYS;
882}
883
884static const tulip_boardsw_t tulip_dc21040_boardsw = {
885    TULIP_DC21040_GENERIC,
886    "",
887    tulip_dc21040_media_probe,
888    tulip_dc21040_media_select,
889    NULL,
890    NULL
891};
892
893static const tulip_boardsw_t tulip_dc21040_10baset_only_boardsw = {
894    TULIP_DC21040_GENERIC,
895    "",
896    tulip_dc21040_10baset_only_media_probe,
897    tulip_dc21040_10baset_only_media_select,
898    NULL,
899    NULL
900};
901
902static const tulip_boardsw_t tulip_dc21040_auibnc_only_boardsw = {
903    TULIP_DC21040_GENERIC,
904    "",
905    tulip_dc21040_auibnc_only_media_probe,
906    tulip_dc21040_auibnc_only_media_select,
907    NULL,
908    NULL
909};
910
911static const tulip_boardsw_t tulip_dc21040_zx314_master_boardsw = {
912    TULIP_DC21040_ZX314_MASTER,
913    "ZNYX ZX314 ",
914    tulip_dc21040_10baset_only_media_probe,
915    tulip_dc21040_10baset_only_media_select
916};
917
918static const tulip_boardsw_t tulip_dc21040_zx314_slave_boardsw = {
919    TULIP_DC21040_ZX314_SLAVE,
920    "ZNYX ZX314 ",
921    tulip_dc21040_10baset_only_media_probe,
922    tulip_dc21040_10baset_only_media_select
923};
924
925static const phy_attr_t tulip_phy_attrlist[] = {
926    { "NS DP83840", 0x20005c00, 0,	/* 08-00-17 */
927      {
928	{ 0x19, 0x40, 0x40 },	/* 10TX */
929	{ 0x19, 0x40, 0x00 },	/* 100TX */
930      }
931    },
932    { "Seeq 80C240", 0x0281F400, 0,	/* 00-A0-7D */
933      {
934	{ 0x12, 0x10, 0x00 },	/* 10T */
935	{ },			/* 100TX */
936	{ 0x12, 0x10, 0x10 },	/* 100T4 */
937	{ 0x12, 0x08, 0x08 },	/* FULL_DUPLEX */
938      }
939    },
940    { NULL }
941};
942
943static void
944tulip_dc21140_mii_probe(
945    tulip_softc_t * const sc)
946{
947    unsigned devaddr;
948
949    for (devaddr = 31; devaddr > 0; devaddr--) {
950	unsigned status = tulip_mii_readreg(sc, devaddr, PHYREG_STATUS);
951	unsigned media;
952	unsigned id;
953	const phy_attr_t *attr;
954	tulip_phy_t *phy;
955	const char *sep;
956	if (status == 0 || status == 0xFFFF || status < PHYSTS_10BASET)
957	    continue;
958	if ((status & PHYSTS_EXTENDED_REGS) == 0) {
959	    loudprintf(TULIP_PRINTF_FMT "(phy%d): skipping (no extended register set)\n",
960		   TULIP_PRINTF_ARGS, devaddr);
961	    continue;
962	}
963	id = (tulip_mii_readreg(sc, devaddr, PHYREG_IDLOW) << 16) |
964	    tulip_mii_readreg(sc, devaddr, PHYREG_IDHIGH);
965	for (attr = tulip_phy_attrlist; attr->attr_name != NULL; attr++) {
966	    if ((id & ~0x0F) == attr->attr_id)
967		break;
968	}
969	if (attr->attr_name == NULL) {
970	    loudprintf(TULIP_PRINTF_FMT "(phy%d): skipping (unrecogized id 0x%08x)\n",
971		   TULIP_PRINTF_ARGS, devaddr, id & ~0x0F);
972	    continue;
973	}
974
975	MALLOC(phy, tulip_phy_t *, sizeof(tulip_phy_t), M_DEVBUF, M_NOWAIT);
976	if (phy == NULL) {
977	    loudprintf(TULIP_PRINTF_FMT "(phy%d): skipping (memory allocation failed)\n",
978		   TULIP_PRINTF_ARGS, devaddr);
979	    continue;
980	}
981	phy->phy_attr = attr;
982	phy->phy_devaddr = devaddr;
983	phy->phy_status = status;
984	phy->phy_next = sc->tulip_phys;
985	sc->tulip_phys = phy;
986
987	loudprintf(TULIP_PRINTF_FMT "(phy%d): model = %s%s\n",
988	       TULIP_PRINTF_ARGS,
989	       phy->phy_devaddr, phy->phy_attr->attr_name,
990	       (phy->phy_status & PHYSTS_CAN_AUTONEG)
991	           ? " (supports media autonegotiation)"
992	           : "");
993	loudprintf(TULIP_PRINTF_FMT "(phy%d): media = ",
994	       TULIP_PRINTF_ARGS, phy->phy_devaddr);
995	for (media = 11, sep = ""; media < 16; media++) {
996	    if (status & (1 << media)) {
997		loudprintf("%s%s", sep, tulip_mediums[tulip_phy_statuses[media-11]]);
998		sep = ", ";
999	    }
1000	}
1001	loudprintf("\n");
1002    }
1003}
1004
1005/*
1006 * The general purpose timer of the 21140/21140a/21142 is kind
1007 * of strange.  It can run on one of 3 speeds depending on the mode
1008 * of the chip.
1009 *
1010 *	10Mb/s port	204.8  microseconds (also speed of DC21041 timer)
1011 *	100Mb/s MII	 81.92 microseconds
1012 *	10Mb/s MII	819.2  microseconds
1013 *
1014 * So we use a tick of a 819.2 microseconds and bias the number of ticks
1015 * required based on the mode in which we are running.  2560/3125 = .8192
1016 * so we use the reciprocal to scale the ms delay to 21140 ticks.
1017 */
1018static void
1019tulip_dc21140_gp_timer_set(
1020    tulip_softc_t * const sc,
1021    unsigned msdelay)
1022{
1023    tulip_uint32_t cmdmode = TULIP_CSR_READ(sc, csr_command);
1024#ifdef TULIP_DEBUG
1025    sc->tulip_dbg.dbg_msdelay = msdelay;
1026#endif
1027    if ((cmdmode & TULIP_CMD_PORTSELECT) == 0) {
1028	msdelay *= 4;
1029#ifdef TULIP_DEBUG
1030	sc->tulip_dbg.dbg_gprate = TULIP_GPTMR_10MB_MII;
1031#endif
1032    } else if ((cmdmode & TULIP_CMD_TXTHRSHLDCTL) == 0) {
1033	msdelay *= 10;
1034#ifdef TULIP_DEBUG
1035	sc->tulip_dbg.dbg_gprate = TULIP_GPTMR_100MB_MII;
1036    } else {
1037	sc->tulip_dbg.dbg_gprate = TULIP_GPTMR_10MB;
1038#endif
1039    }
1040#if 0
1041    if (sc->tulip_chipid == TULIP_DC21140A)
1042	msdelay *= 10;
1043#endif
1044    TULIP_CSR_WRITE(sc, csr_status, TULIP_STS_GPTIMEOUT);
1045    TULIP_CSR_WRITE(sc, csr_gp_timer, (msdelay * 313 + 128) / 256);
1046    if (sc->tulip_flags & TULIP_DEVICEPROBE) {
1047	sc->tulip_flags |= TULIP_FAKEGPTIMEOUT;
1048    } else {
1049	TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
1050	sc->tulip_flags &= ~TULIP_FAKEGPTIMEOUT;
1051    }
1052#ifdef TULIP_DEBUG
1053    sc->tulip_dbg.dbg_gpticks = (msdelay * 313 + 128) / 256;
1054#endif
1055}
1056
1057static int
1058tulip_dc21140_map_abilities(
1059    tulip_softc_t * const sc,
1060    const tulip_phy_t * const phy,
1061    unsigned abilities)
1062{
1063    sc->tulip_abilities = abilities;
1064    if (abilities & PHYSTS_100BASETX_FD) {
1065	sc->tulip_media = TULIP_MEDIA_100BASETX_FD;
1066    } else if (abilities & PHYSTS_100BASETX) {
1067	sc->tulip_media = TULIP_MEDIA_100BASETX;
1068    } else if (abilities & PHYSTS_100BASET4) {
1069	sc->tulip_media = TULIP_MEDIA_100BASET4;
1070    } else if (abilities & PHYSTS_10BASET_FD) {
1071	sc->tulip_media = TULIP_MEDIA_10BASET_FD;
1072    } else if (abilities & PHYSTS_10BASET) {
1073	sc->tulip_media = TULIP_MEDIA_10BASET;
1074    } else {
1075	sc->tulip_media = TULIP_MEDIA_UNKNOWN;
1076	sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
1077	return 1;
1078    }
1079    sc->tulip_intrmask &= ~TULIP_STS_GPTIMEOUT;
1080    sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
1081    sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_NEEDRESET;
1082    sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
1083    return 0;
1084}
1085
1086static void
1087tulip_dc21140_autonegotiate(
1088    tulip_softc_t * const sc,
1089    const tulip_phy_t * const phy)
1090{
1091    tulip_uint32_t data;
1092
1093    if (sc->tulip_flags & TULIP_INRESET) {
1094	sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
1095    }
1096    if (sc->tulip_if.if_flags & IFF_NOAUTONEG) {
1097	sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
1098	data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_CONTROL);
1099	if (data & PHYCTL_AUTONEG_ENABLE) {
1100	    data &= ~PHYCTL_AUTONEG_ENABLE;
1101	    tulip_mii_writereg(sc, phy->phy_devaddr, PHYREG_CONTROL, data);
1102	}
1103	return;
1104    }
1105
1106  again:
1107    switch (sc->tulip_probe_state) {
1108        case TULIP_PROBE_INACTIVE: {
1109	    sc->tulip_flags |= TULIP_TXPROBE_ACTIVE;
1110	    tulip_mii_writereg(sc, phy->phy_devaddr, PHYREG_CONTROL, PHYCTL_RESET);
1111	    sc->tulip_gpticks = 10;
1112	    sc->tulip_intrmask |= TULIP_STS_ABNRMLINTR|TULIP_STS_GPTIMEOUT|TULIP_STS_NORMALINTR;
1113	    sc->tulip_probe_state = TULIP_PROBE_PHYRESET;
1114	    goto again;
1115	}
1116        case TULIP_PROBE_PHYRESET: {
1117	    data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_CONTROL);
1118	    if (data & PHYCTL_RESET) {
1119		if (--sc->tulip_gpticks > 0) {
1120		    tulip_dc21140_gp_timer_set(sc, 100);
1121		    return;
1122		}
1123		printf(TULIP_PRINTF_FMT "(phy%d): error: reset of PHY never completed!\n",
1124			   TULIP_PRINTF_ARGS, phy->phy_devaddr);
1125		sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
1126		sc->tulip_probe_state = TULIP_PROBE_FAILED;
1127		sc->tulip_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
1128		sc->tulip_intrmask &= ~TULIP_STS_GPTIMEOUT;
1129		return;
1130	    }
1131	    if ((phy->phy_status & PHYSTS_CAN_AUTONEG) == 0
1132		    && (sc->tulip_if.if_flags & IFF_NOAUTONEG)) {
1133#ifdef TULIP_DEBUG
1134		loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation disabled\n",
1135			   TULIP_PRINTF_ARGS, phy->phy_devaddr);
1136#endif
1137		sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
1138		return;
1139	    }
1140	    if (tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_AUTONEG_ADVERTISEMENT) != ((phy->phy_status >> 6) | 0x01))
1141		tulip_mii_writereg(sc, phy->phy_devaddr, PHYREG_AUTONEG_ADVERTISEMENT, (phy->phy_status >> 6) | 0x01);
1142	    tulip_mii_writereg(sc, phy->phy_devaddr, PHYREG_CONTROL, data|PHYCTL_AUTONEG_RESTART|PHYCTL_AUTONEG_ENABLE);
1143	    data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_CONTROL);
1144#ifdef TULIP_DEBUG
1145	    if ((data & PHYCTL_AUTONEG_ENABLE) == 0)
1146		loudprintf(TULIP_PRINTF_FMT "(phy%d): oops: enable autonegotiation failed: 0x%04x\n",
1147			   TULIP_PRINTF_ARGS, phy->phy_devaddr, data);
1148	    else
1149		loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation restarted: 0x%04x\n",
1150			   TULIP_PRINTF_ARGS, phy->phy_devaddr, data);
1151#endif
1152	    sc->tulip_probe_state = TULIP_PROBE_PHYAUTONEG;
1153	    sc->tulip_gpticks = 60;
1154	    goto again;
1155	}
1156        case TULIP_PROBE_PHYAUTONEG: {
1157	    data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_STATUS);
1158	    if ((data & PHYSTS_AUTONEG_DONE) == 0) {
1159		if (--sc->tulip_gpticks > 0) {
1160		    tulip_dc21140_gp_timer_set(sc, 100);
1161		    return;
1162		}
1163#ifdef TULIP_DEBUG
1164		loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation timeout: sts=0x%04x, ctl=0x%04x\n",
1165			   TULIP_PRINTF_ARGS, phy->phy_devaddr, data,
1166			   tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_CONTROL));
1167#endif
1168		sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
1169		return;
1170	    }
1171	    data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_AUTONEG_ABILITIES);
1172#ifdef TULIP_DEBUG
1173	    loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation complete: 0x%04x\n",
1174		       TULIP_PRINTF_ARGS, phy->phy_devaddr, data);
1175#endif
1176	    data = (data << 6) & phy->phy_status;
1177	    tulip_dc21140_map_abilities(sc, phy, data);
1178	    return;
1179	}
1180    }
1181#ifdef TULIP_DEBUG
1182    loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation failure: state = %d\n",
1183	       TULIP_PRINTF_ARGS, phy->phy_devaddr, sc->tulip_probe_state);
1184#endif
1185}
1186
1187static tulip_media_t
1188tulip_dc21140_phy_readspecific(
1189    tulip_softc_t * const sc,
1190    const tulip_phy_t * const phy)
1191{
1192    const phy_attr_t * const attr = phy->phy_attr;
1193    unsigned data;
1194    unsigned idx = 0;
1195    static const tulip_media_t table[] = {
1196	TULIP_MEDIA_UNKNOWN,
1197	TULIP_MEDIA_10BASET,
1198	TULIP_MEDIA_100BASETX,
1199	TULIP_MEDIA_100BASET4,
1200	TULIP_MEDIA_UNKNOWN,
1201	TULIP_MEDIA_10BASET_FD,
1202	TULIP_MEDIA_100BASETX_FD,
1203	TULIP_MEDIA_UNKNOWN
1204    };
1205
1206    /*
1207     * Don't read phy specific registers if link is not up.
1208     */
1209    data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_STATUS);
1210    if ((data & PHYSTS_LINK_UP) == 0)
1211	return TULIP_MEDIA_UNKNOWN;
1212
1213    if (attr->attr_modes[PHY_MODE_100TX].pm_regno) {
1214	const phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_100TX];
1215	data = tulip_mii_readreg(sc, phy->phy_devaddr, pm->pm_regno);
1216	if ((data & pm->pm_mask) == pm->pm_value)
1217	    idx = 2;
1218    }
1219    if (idx == 0 && attr->attr_modes[PHY_MODE_100T4].pm_regno) {
1220	const phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_100T4];
1221	data = tulip_mii_readreg(sc, phy->phy_devaddr, pm->pm_regno);
1222	if ((data & pm->pm_mask) == pm->pm_value)
1223	    idx = 3;
1224    }
1225    if (idx == 0 && attr->attr_modes[PHY_MODE_10T].pm_regno) {
1226	const phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_10T];
1227	data = tulip_mii_readreg(sc, phy->phy_devaddr, pm->pm_regno);
1228	if ((data & pm->pm_mask) == pm->pm_value)
1229	    idx = 1;
1230    }
1231    if (idx != 0 && attr->attr_modes[PHY_MODE_FULLDUPLEX].pm_regno) {
1232	const phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_FULLDUPLEX];
1233	data = tulip_mii_readreg(sc, phy->phy_devaddr, pm->pm_regno);
1234	idx += ((data & pm->pm_mask) == pm->pm_value ? 4 : 0);
1235    }
1236    return table[idx];
1237}
1238
1239static void
1240tulip_dc21140_mii_link_monitor(
1241    tulip_softc_t * const sc,
1242    const tulip_phy_t * const phy)
1243{
1244    tulip_uint32_t data;
1245
1246    tulip_dc21140_gp_timer_set(sc, 425);
1247    /*
1248     * Have we seen some packets?  If so, the link must be good.
1249     */
1250    if ((sc->tulip_flags & (TULIP_RXACT|TULIP_LINKSUSPECT|TULIP_LINKUP)) == (TULIP_RXACT|TULIP_LINKUP)) {
1251	sc->tulip_flags &= ~TULIP_RXACT;
1252	return;
1253    }
1254
1255    /*
1256     * Read the PHY status register.
1257     */
1258    data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_STATUS);
1259    if ((sc->tulip_if.if_flags & IFF_NOAUTONEG) == 0 && (data & PHYSTS_AUTONEG_DONE)) {
1260	/*
1261	 * If autonegotiation hasn't been disabled and the PHY has complete
1262	 * autonegotiation, see the if the remote systems abilities have changed.
1263	 * If so, upgrade or downgrade as appropriate.
1264	 */
1265	unsigned abilities = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_AUTONEG_ABILITIES);
1266	abilities = (abilities << 6) & phy->phy_status;
1267	if (abilities != sc->tulip_abilities) {
1268	    sc->tulip_flags |= TULIP_PRINTMEDIA;
1269#ifdef TULIP_DEBUG
1270	    loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation changed: 0x%04x -> 0x%04x\n",
1271		       TULIP_PRINTF_ARGS, phy->phy_devaddr,
1272		       sc->tulip_abilities, abilities);
1273#endif
1274	    tulip_dc21140_map_abilities(sc, phy, abilities);
1275	    return;
1276	}
1277    }
1278    /*
1279     * The link is now up.  If was down, say its back up.
1280     */
1281    if ((data & (PHYSTS_LINK_UP|PHYSTS_REMOTE_FAULT)) == PHYSTS_LINK_UP) {
1282	if ((sc->tulip_if.if_flags & IFF_NOAUTONEG) == 0) {
1283	    tulip_media_t media = tulip_dc21140_phy_readspecific(sc, phy);
1284	    if (media != sc->tulip_media && media != TULIP_MEDIA_UNKNOWN) {
1285		sc->tulip_media = media;
1286		sc->tulip_flags |= TULIP_PRINTMEDIA;
1287	    }
1288	}
1289	sc->tulip_gpticks = 0;
1290	if (sc->tulip_flags & TULIP_PRINTMEDIA) {
1291	    printf(TULIP_PRINTF_FMT ": %senabling %s port\n",
1292		   TULIP_PRINTF_ARGS,
1293		   (sc->tulip_flags & TULIP_LINKUP) ? "" : "link up: ",
1294		   tulip_mediums[sc->tulip_media]);
1295	} else if ((sc->tulip_flags & TULIP_LINKUP) == 0) {
1296	    printf(TULIP_PRINTF_FMT ": link up\n", TULIP_PRINTF_ARGS);
1297	}
1298	sc->tulip_flags &= ~(TULIP_PRINTMEDIA|TULIP_LINKSUSPECT|TULIP_RXACT);
1299	sc->tulip_flags |= TULIP_LINKUP;
1300	return;
1301    }
1302    /*
1303     * The link may be down.  Mark it as suspect.  If suspect for 12 ticks,
1304     * mark it down.  If autonegotiation is not disabled, restart the media
1305     * probe to see if the media has changed.
1306     */
1307    if ((sc->tulip_flags & TULIP_LINKSUSPECT) == 0) {
1308	sc->tulip_flags |= TULIP_LINKSUSPECT;
1309	sc->tulip_flags &= ~TULIP_LINKUP;
1310	sc->tulip_gpticks = 12;
1311#ifdef TULIP_DEBUG
1312	sc->tulip_dbg.dbg_link_suspected++;
1313#endif
1314	return;
1315    }
1316    if (--sc->tulip_gpticks > 0)
1317	return;
1318    if (sc->tulip_flags & TULIP_LINKSUSPECT) {
1319	printf(TULIP_PRINTF_FMT ": link down: cable problem?\n", TULIP_PRINTF_ARGS);
1320	sc->tulip_flags &= ~TULIP_LINKSUSPECT;
1321#ifdef TULIP_DEBUG
1322	sc->tulip_dbg.dbg_link_downed++;
1323#endif
1324    }
1325    if (sc->tulip_if.if_flags & IFF_NOAUTONEG)
1326	return;
1327    sc->tulip_media = TULIP_MEDIA_UNKNOWN;
1328    sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
1329    tulip_dc21140_autonegotiate(sc, phy);
1330}
1331
1332static void
1333tulip_dc21140_nomii_media_preset(
1334    tulip_softc_t * const sc)
1335{
1336    sc->tulip_flags &= ~TULIP_SQETEST;
1337    if (sc->tulip_if.if_flags & IFF_ALTPHYS) {
1338	sc->tulip_cmdmode |= TULIP_CMD_PORTSELECT
1339	    |TULIP_CMD_PCSFUNCTION|TULIP_CMD_SCRAMBLER;
1340	sc->tulip_if.if_baudrate = 100000000;
1341    } else {
1342	sc->tulip_cmdmode &= ~(TULIP_CMD_PORTSELECT
1343			       |TULIP_CMD_PCSFUNCTION|TULIP_CMD_SCRAMBLER);
1344	sc->tulip_if.if_baudrate = 10000000;
1345	if ((sc->tulip_cmdmode & TULIP_CMD_FULLDUPLEX) == 0)
1346	    sc->tulip_flags |= TULIP_SQETEST;
1347    }
1348    TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
1349}
1350
1351static void
1352tulip_dc21140_mii_media_preset(
1353    tulip_softc_t * const sc)
1354{
1355    sc->tulip_cmdmode |= TULIP_CMD_PORTSELECT;
1356    sc->tulip_flags &= ~TULIP_SQETEST;
1357    if (sc->tulip_media != TULIP_MEDIA_UNKNOWN) {
1358	switch (sc->tulip_media) {
1359	    case TULIP_MEDIA_10BASET: {
1360		sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
1361		sc->tulip_cmdmode |= TULIP_CMD_TXTHRSHLDCTL;
1362		sc->tulip_if.if_baudrate = 10000000;
1363		sc->tulip_flags |= TULIP_SQETEST;
1364		break;
1365	    }
1366	    case TULIP_MEDIA_10BASET_FD: {
1367		sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX|TULIP_CMD_TXTHRSHLDCTL;
1368		sc->tulip_if.if_baudrate = 10000000;
1369		break;
1370	    }
1371	    case TULIP_MEDIA_100BASET4:
1372	    case TULIP_MEDIA_100BASETX: {
1373		sc->tulip_cmdmode &= ~(TULIP_CMD_FULLDUPLEX|TULIP_CMD_TXTHRSHLDCTL);
1374		sc->tulip_if.if_baudrate = 100000000;
1375		break;
1376	    }
1377	    case TULIP_MEDIA_100BASETX_FD: {
1378		sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
1379		sc->tulip_cmdmode &= ~TULIP_CMD_TXTHRSHLDCTL;
1380		sc->tulip_if.if_baudrate = 100000000;
1381		break;
1382	    }
1383	}
1384    }
1385    TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
1386}
1387
1388static void
1389tulip_dc21140_nomii_100only_media_preset(
1390    tulip_softc_t * const sc)
1391{
1392    sc->tulip_cmdmode |= TULIP_CMD_PORTSELECT
1393	|TULIP_CMD_PCSFUNCTION|TULIP_CMD_SCRAMBLER;
1394    TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
1395}
1396
1397
1398static int
1399tulip_dc21140_evalboard_media_probe(
1400    tulip_softc_t * const sc)
1401{
1402    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS);
1403    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_INIT);
1404    TULIP_CSR_WRITE(sc, csr_command,
1405	TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT |
1406	TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
1407    TULIP_CSR_WRITE(sc, csr_command,
1408	TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
1409    DELAY(1000000);
1410    return (TULIP_CSR_READ(sc, csr_gp) & TULIP_GP_EB_OK100) != 0;
1411}
1412
1413static void
1414tulip_dc21140_evalboard_media_select(
1415    tulip_softc_t * const sc)
1416{
1417    sc->tulip_cmdmode |= TULIP_CMD_STOREFWD|TULIP_CMD_MUSTBEONE
1418	|TULIP_CMD_BACKOFFCTR;
1419    sc->tulip_flags |= TULIP_LINKUP;
1420    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS);
1421    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_INIT);
1422    if (sc->tulip_if.if_flags & IFF_ALTPHYS) {
1423	if ((sc->tulip_flags & TULIP_ALTPHYS) == 0)
1424	    sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_ALTPHYS;
1425	sc->tulip_cmdmode &= ~TULIP_CMD_TXTHRSHLDCTL;
1426	sc->tulip_media = TULIP_MEDIA_100BASETX;
1427	sc->tulip_flags &= ~TULIP_SQETEST;
1428    } else {
1429	if (sc->tulip_flags & TULIP_ALTPHYS)
1430	    sc->tulip_flags ^= TULIP_PRINTMEDIA|TULIP_ALTPHYS;
1431	sc->tulip_cmdmode |= TULIP_CMD_TXTHRSHLDCTL;
1432	sc->tulip_media = TULIP_MEDIA_10BASET;
1433	sc->tulip_flags |= TULIP_SQETEST;
1434    }
1435#ifdef BIG_PACKET
1436    if (sc->tulip_if.if_mtu > ETHERMTU) {
1437	TULIP_CSR_WRITE(sc, csr_watchdog, TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE);
1438    }
1439#endif
1440}
1441
1442static const tulip_boardsw_t tulip_dc21140_eb_boardsw = {
1443    TULIP_DC21140_DEC_EB,
1444    "",
1445    tulip_dc21140_evalboard_media_probe,
1446    tulip_dc21140_evalboard_media_select,
1447    tulip_dc21140_nomii_media_preset,
1448};
1449
1450static int
1451tulip_dc21140_smc9332_media_probe(
1452    tulip_softc_t * const sc)
1453{
1454    int idx;
1455    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_SMC_9332_PINS);
1456    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_SMC_9332_INIT);
1457    TULIP_CSR_WRITE(sc, csr_command,
1458	TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT |
1459	TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
1460    TULIP_CSR_WRITE(sc, csr_command,
1461	TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
1462    DELAY(200000);
1463    for (idx = 1000; idx > 0; idx--) {
1464	tulip_uint32_t csr = TULIP_CSR_READ(sc, csr_gp);
1465	if ((csr & (TULIP_GP_SMC_9332_OK100|TULIP_GP_SMC_9332_OK10)) == TULIP_GP_SMC_9332_OK100)
1466	    return 1;
1467	if ((csr & (TULIP_GP_SMC_9332_OK100|TULIP_GP_SMC_9332_OK10)) == TULIP_GP_SMC_9332_OK10)
1468	    return 0;
1469	DELAY(1000);
1470    }
1471    return 0;
1472}
1473
1474static void
1475tulip_dc21140_smc9332_media_select(
1476    tulip_softc_t * const sc)
1477{
1478    sc->tulip_cmdmode |= TULIP_CMD_STOREFWD|TULIP_CMD_MUSTBEONE
1479	|TULIP_CMD_BACKOFFCTR;
1480    sc->tulip_flags |= TULIP_LINKUP;
1481    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_SMC_9332_PINS);
1482    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_SMC_9332_INIT);
1483    if (sc->tulip_if.if_flags & IFF_ALTPHYS) {
1484	if ((sc->tulip_flags & TULIP_ALTPHYS) == 0)
1485	    sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_ALTPHYS;
1486	sc->tulip_cmdmode &= ~TULIP_CMD_TXTHRSHLDCTL;
1487	sc->tulip_media = TULIP_MEDIA_100BASETX;
1488	sc->tulip_flags &= ~TULIP_SQETEST;
1489    } else {
1490	if (sc->tulip_flags & TULIP_ALTPHYS)
1491	    sc->tulip_flags ^= TULIP_PRINTMEDIA|TULIP_ALTPHYS;
1492	sc->tulip_cmdmode |= TULIP_CMD_TXTHRSHLDCTL;
1493	sc->tulip_media = TULIP_MEDIA_10BASET;
1494	sc->tulip_flags |= TULIP_SQETEST;
1495    }
1496#ifdef BIG_PACKET
1497    if (sc->tulip_if.if_mtu > ETHERMTU) {
1498	TULIP_CSR_WRITE(sc, csr_watchdog, TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE);
1499    }
1500#endif
1501}
1502
1503static const tulip_boardsw_t tulip_dc21140_smc9332_boardsw = {
1504    TULIP_DC21140_SMC_9332,
1505    "SMC 9332 ",
1506    tulip_dc21140_smc9332_media_probe,
1507    tulip_dc21140_smc9332_media_select,
1508    tulip_dc21140_nomii_media_preset,
1509};
1510
1511static int
1512tulip_dc21140_cogent_em100_media_probe(
1513    tulip_softc_t * const sc)
1514{
1515    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_PINS);
1516    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_INIT);
1517    TULIP_CSR_WRITE(sc, csr_command,
1518	TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT |
1519	TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
1520    TULIP_CSR_WRITE(sc, csr_command,
1521	TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
1522    return 1;
1523}
1524
1525static void
1526tulip_dc21140_cogent_em100_media_select(
1527    tulip_softc_t * const sc)
1528{
1529    sc->tulip_cmdmode |= TULIP_CMD_STOREFWD|TULIP_CMD_MUSTBEONE
1530	|TULIP_CMD_BACKOFFCTR;
1531    sc->tulip_flags |= TULIP_LINKUP;
1532    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_PINS);
1533    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_INIT);
1534    if ((sc->tulip_flags & TULIP_ALTPHYS) == 0)
1535	sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_ALTPHYS;
1536    sc->tulip_cmdmode &= ~TULIP_CMD_TXTHRSHLDCTL;
1537    sc->tulip_media = TULIP_MEDIA_100BASETX;
1538#ifdef BIG_PACKET
1539    if (sc->tulip_if.if_mtu > ETHERMTU) {
1540	TULIP_CSR_WRITE(sc, csr_watchdog, TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE);
1541    }
1542#endif
1543}
1544
1545static const tulip_boardsw_t tulip_dc21140_cogent_em100_boardsw = {
1546    TULIP_DC21140_COGENT_EM100,
1547    "Cogent EM100 ",
1548    tulip_dc21140_cogent_em100_media_probe,
1549    tulip_dc21140_cogent_em100_media_select,
1550    tulip_dc21140_nomii_100only_media_preset
1551};
1552
1553
1554static int
1555tulip_dc21140_znyx_zx34x_media_probe(
1556    tulip_softc_t * const sc)
1557{
1558    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_PINS);
1559    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_INIT);
1560    TULIP_CSR_WRITE(sc, csr_command,
1561	TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT |
1562	TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
1563    TULIP_CSR_WRITE(sc, csr_command,
1564	TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
1565    DELAY(1000000);
1566
1567    return (TULIP_CSR_READ(sc, csr_gp) & TULIP_GP_ZX34X_OK10);
1568}
1569
1570static void
1571tulip_dc21140_znyx_zx34x_media_select(
1572    tulip_softc_t * const sc)
1573{
1574    sc->tulip_cmdmode |= TULIP_CMD_STOREFWD|TULIP_CMD_MUSTBEONE
1575	|TULIP_CMD_BACKOFFCTR;
1576    sc->tulip_flags |= TULIP_LINKUP;
1577    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_PINS);
1578    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_INIT);
1579    if (sc->tulip_if.if_flags & IFF_ALTPHYS) {
1580	if ((sc->tulip_flags & TULIP_ALTPHYS) == 0)
1581	    sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_ALTPHYS;
1582	sc->tulip_cmdmode &= ~TULIP_CMD_TXTHRSHLDCTL;
1583	sc->tulip_media = TULIP_MEDIA_100BASETX;
1584    } else {
1585	if (sc->tulip_flags & TULIP_ALTPHYS)
1586	    sc->tulip_flags ^= TULIP_PRINTMEDIA|TULIP_ALTPHYS;
1587	sc->tulip_cmdmode |= TULIP_CMD_TXTHRSHLDCTL;
1588	sc->tulip_media = TULIP_MEDIA_10BASET;
1589    }
1590#ifdef BIG_PACKET
1591    if (sc->tulip_if.if_mtu > ETHERMTU) {
1592	TULIP_CSR_WRITE(sc, csr_watchdog, TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE);
1593    }
1594#endif
1595}
1596
1597static const tulip_boardsw_t tulip_dc21140_znyx_zx34x_boardsw = {
1598    TULIP_DC21140_ZNYX_ZX34X,
1599    "ZNYX ZX34X ",
1600    tulip_dc21140_znyx_zx34x_media_probe,
1601    tulip_dc21140_znyx_zx34x_media_select,
1602    tulip_dc21140_nomii_media_preset,
1603};
1604
1605static const struct {
1606    unsigned short value_gp;
1607    unsigned short value_phyctl;
1608} tulip_dc21140_de500_csrvalues[] = {
1609    { TULIP_GP_DE500_HALFDUPLEX, 0 },	/* TULIP_MEDIA_UNKNOWN */
1610    { TULIP_GP_DE500_HALFDUPLEX, 0 },	/* TULIP_MEDIA_10BASET */
1611    { /* n/a */ },			/* TULIP_MEDIA_BNC */
1612    { /* n/a */ },			/* TULIP_MEDIA_AUI */
1613    { /* n/a */ },			/* TULIP_MEDIA_BNCAUI */
1614    { 0, PHYCTL_FULL_DUPLEX },		/* TULIP_MEDIA_10BASET_FD */
1615    { TULIP_GP_DE500_HALFDUPLEX|	/* TULIP_MEDIA_100BASET */
1616      TULIP_GP_DE500_FORCE_100, PHYCTL_SELECT_100MB },
1617    { TULIP_GP_DE500_FORCE_100,		/* TULIP_MEDIA_100BASET_FD */
1618      PHYCTL_SELECT_100MB|PHYCTL_FULL_DUPLEX },
1619    { TULIP_GP_DE500_HALFDUPLEX|	/* TULIP_MEDIA_100BASET4 */
1620      TULIP_GP_DE500_FORCE_100, PHYCTL_SELECT_100MB },
1621};
1622
1623static void
1624tulip_dc21140_de500_media_select(
1625    tulip_softc_t * const sc)
1626{
1627    if (sc->tulip_if.if_flags & IFF_ALTPHYS) {
1628	if (sc->tulip_if.if_flags & IFF_FULLDUPLEX) {
1629	    sc->tulip_media = TULIP_MEDIA_100BASETX_FD;
1630	    sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
1631	} else {
1632	    sc->tulip_media = TULIP_MEDIA_100BASETX;
1633	    sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
1634	}
1635	if ((sc->tulip_flags & TULIP_ALTPHYS) == 0)
1636	    sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_ALTPHYS;
1637    } else {
1638	if (sc->tulip_if.if_flags & IFF_FULLDUPLEX) {
1639	    sc->tulip_media = TULIP_MEDIA_10BASET_FD;
1640	    sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
1641	} else {
1642	    sc->tulip_media = TULIP_MEDIA_10BASET;
1643	    sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
1644	}
1645	if (sc->tulip_flags & TULIP_ALTPHYS)
1646	    sc->tulip_flags ^= TULIP_PRINTMEDIA|TULIP_ALTPHYS;
1647    }
1648}
1649
1650static int
1651tulip_dc21140_de500xa_media_probe(
1652    tulip_softc_t * const sc)
1653{
1654    int idx;
1655
1656    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_DE500_PINS);
1657    DELAY(500);
1658    TULIP_CSR_WRITE(sc, csr_gp,
1659		    TULIP_GP_DE500_HALFDUPLEX|TULIP_GP_DE500_FORCE_100);
1660    DELAY(1000);
1661    TULIP_CSR_WRITE(sc, csr_command,
1662		    TULIP_CSR_READ(sc, csr_command)
1663		    |TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1664		    |TULIP_CMD_SCRAMBLER|TULIP_CMD_MUSTBEONE);
1665    TULIP_CSR_WRITE(sc, csr_command,
1666		    TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
1667    for (idx = 2400; idx > 0; idx--) {
1668	tulip_uint32_t data;
1669	DELAY(1000);
1670	data = ~TULIP_CSR_READ(sc, csr_gp);
1671	if ((data & (TULIP_GP_DE500_LINK_PASS|TULIP_GP_DE500_SYM_LINK)) == (TULIP_GP_DE500_SYM_LINK|TULIP_GP_DE500_LINK_PASS))
1672	    return 1;
1673    }
1674    return 0;
1675}
1676
1677static void
1678tulip_dc21140_de500xa_media_select(
1679    tulip_softc_t * const sc)
1680{
1681    sc->tulip_cmdmode |= TULIP_CMD_STOREFWD|TULIP_CMD_MUSTBEONE
1682	|TULIP_CMD_BACKOFFCTR;
1683    sc->tulip_flags |= TULIP_LINKUP;
1684    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_DE500_PINS);
1685    tulip_dc21140_de500_media_select(sc);
1686    TULIP_CSR_WRITE(sc, csr_gp, tulip_dc21140_de500_csrvalues[sc->tulip_media].value_gp);
1687#ifdef BIG_PACKET
1688    if (sc->tulip_if.if_mtu > ETHERMTU) {
1689	TULIP_CSR_WRITE(sc, csr_watchdog, TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE);
1690    }
1691#endif
1692}
1693
1694static const tulip_boardsw_t tulip_dc21140_de500xa_boardsw = {
1695    TULIP_DC21140_DEC_DE500, "Digital DE500-XA ",
1696    tulip_dc21140_de500xa_media_probe,
1697    tulip_dc21140_de500xa_media_select,
1698    tulip_dc21140_nomii_media_preset,
1699};
1700
1701static int
1702tulip_dc21140_de500aa_media_probe(
1703    tulip_softc_t * const sc)
1704{
1705    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_DE500_PINS);
1706    TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_DE500_PHY_RESET);
1707    DELAY(1000);
1708    TULIP_CSR_WRITE(sc, csr_gp, 0);
1709
1710    TULIP_CSR_WRITE(sc, csr_command, TULIP_CMD_PORTSELECT);
1711    return 0;
1712}
1713
1714static void
1715tulip_dc21140_de500aa_media_select(
1716    tulip_softc_t * const sc)
1717{
1718    const tulip_phy_t *phy = sc->tulip_phys;
1719    tulip_uint32_t data;
1720
1721    if (phy == NULL)
1722	return;
1723
1724    /*
1725     * Defer autosensing until out of device probe (will be
1726     * triggered by ifwatchdog or ifioctl).
1727     */
1728
1729    if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) {
1730	tulip_media_t old_media;
1731	if (sc->tulip_probe_state != TULIP_PROBE_MEDIATEST)
1732	    tulip_dc21140_autonegotiate(sc, phy);
1733	if (sc->tulip_probe_state != TULIP_PROBE_MEDIATEST)
1734	    return;
1735	old_media = sc->tulip_media;
1736	if (sc->tulip_if.if_flags & IFF_NOAUTONEG) {
1737	    tulip_dc21140_de500_media_select(sc);
1738	} else {
1739	    sc->tulip_media = tulip_dc21140_phy_readspecific(sc, phy);
1740	    if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) {
1741		sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
1742		tulip_dc21140_autonegotiate(sc, phy);
1743		return;
1744	    }
1745	    sc->tulip_flags |= TULIP_PRINTMEDIA;
1746	}
1747	sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
1748	sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
1749	sc->tulip_intrmask &= ~TULIP_STS_GPTIMEOUT;
1750	if (sc->tulip_flags & TULIP_INRESET)
1751	    goto in_reset;
1752	if (sc->tulip_media != old_media)
1753	    sc->tulip_flags |= TULIP_NEEDRESET;
1754	return;
1755    }
1756    if ((sc->tulip_flags & TULIP_INRESET) == 0) {
1757	tulip_dc21140_mii_link_monitor(sc, phy);
1758	return;
1759    }
1760  in_reset:
1761    if (sc->tulip_if.if_flags & IFF_ALTPHYS) {
1762	sc->tulip_flags |= TULIP_ALTPHYS;
1763    } else {
1764	sc->tulip_flags &= ~TULIP_ALTPHYS;
1765    }
1766    sc->tulip_gpticks = 8;
1767    sc->tulip_intrmask |= TULIP_STS_ABNRMLINTR|TULIP_STS_GPTIMEOUT|TULIP_STS_NORMALINTR;
1768    tulip_dc21140_gp_timer_set(sc, 425);
1769    data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_CONTROL);
1770    if ((data & PHYCTL_AUTONEG_ENABLE) == 0) {
1771	data &= ~(PHYCTL_SELECT_100MB|PHYCTL_FULL_DUPLEX);
1772	data |= tulip_dc21140_de500_csrvalues[sc->tulip_media].value_phyctl;
1773	tulip_mii_writereg(sc, phy->phy_devaddr, PHYREG_CONTROL, data);
1774    }
1775}
1776
1777static const tulip_boardsw_t tulip_dc21140_de500aa_boardsw = {
1778    TULIP_DC21140_DEC_DE500, "Digital DE500-AA ",
1779    tulip_dc21140_de500aa_media_probe,
1780    tulip_dc21140_de500aa_media_select,
1781    tulip_dc21140_mii_media_preset,
1782    tulip_dc21140_mii_probe,
1783};
1784
1785static int
1786tulip_dc21041_media_probe(
1787    tulip_softc_t * const sc)
1788{
1789    sc->tulip_if.if_baudrate = 10000000;
1790    return 0;
1791}
1792
1793#ifdef BIG_PACKET
1794#define TULIP_DC21041_SIAGEN_WATCHDOG	(sc->tulip_if.if_mtu > ETHERMTU ? TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE : 0)
1795#else
1796#define	TULIP_DC21041_SIAGEN_WATCHDOG	0
1797#endif
1798
1799static void
1800tulip_dc21041_media_select(
1801    tulip_softc_t * const sc)
1802{
1803    sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_ENHCAPTEFFCT
1804	|TULIP_CMD_THRSHLD160|TULIP_CMD_BACKOFFCTR;
1805    sc->tulip_intrmask |= TULIP_STS_NORMALINTR|TULIP_STS_GPTIMEOUT|TULIP_STS_TXINTR
1806	|TULIP_STS_ABNRMLINTR|TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL;
1807    if (sc->tulip_if.if_flags & IFF_ALTPHYS) {
1808	if ((sc->tulip_flags & TULIP_ALTPHYS) == 0) {
1809	    sc->tulip_media = TULIP_MEDIA_UNKNOWN;
1810	    sc->tulip_flags &= ~(TULIP_TXPROBE_OK|TULIP_TXPROBE_ACTIVE);
1811	    sc->tulip_flags |= TULIP_ALTPHYS|TULIP_WANTRXACT;
1812	    sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
1813	}
1814    } else {
1815	if (sc->tulip_flags & TULIP_ALTPHYS) {
1816	    sc->tulip_media = TULIP_MEDIA_UNKNOWN;
1817	    sc->tulip_flags &= ~(TULIP_TXPROBE_OK|TULIP_TXPROBE_ACTIVE|TULIP_ALTPHYS);
1818	    sc->tulip_flags |= TULIP_WANTRXACT;
1819	    sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
1820	}
1821    }
1822
1823    if (TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_LINKFAIL) {
1824	if (sc->tulip_media == TULIP_MEDIA_10BASET) {
1825	    sc->tulip_media = TULIP_MEDIA_UNKNOWN;
1826	} else if (sc->tulip_media == TULIP_MEDIA_BNC) {
1827	    sc->tulip_intrmask &= ~TULIP_STS_GPTIMEOUT;
1828	    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
1829	    DELAY(50);
1830	    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_BNC);
1831	    TULIP_CSR_WRITE(sc, csr_sia_tx_rx,        TULIP_DC21041_SIATXRX_BNC);
1832	    TULIP_CSR_WRITE(sc, csr_sia_general,      TULIP_DC21041_SIAGEN_BNC|TULIP_DC21041_SIAGEN_WATCHDOG);
1833	    DELAY(50);
1834	    return;
1835	} else if (sc->tulip_media == TULIP_MEDIA_AUI) {
1836	    sc->tulip_intrmask &= ~TULIP_STS_GPTIMEOUT;
1837	    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
1838	    DELAY(50);
1839	    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_AUI);
1840	    TULIP_CSR_WRITE(sc, csr_sia_tx_rx,        TULIP_DC21041_SIATXRX_AUI);
1841	    TULIP_CSR_WRITE(sc, csr_sia_general,      TULIP_DC21041_SIAGEN_AUI|TULIP_DC21041_SIAGEN_WATCHDOG);
1842	    DELAY(50);
1843	    return;
1844	}
1845
1846	switch (sc->tulip_probe_state) {
1847	    case TULIP_PROBE_INACTIVE: {
1848		sc->tulip_if.if_flags |= IFF_OACTIVE;
1849		sc->tulip_gpticks = 200;
1850		sc->tulip_probe_state = TULIP_PROBE_10BASET;
1851		sc->tulip_flags |= TULIP_TXPROBE_ACTIVE;
1852		sc->tulip_flags &= ~(TULIP_TXPROBE_OK|TULIP_LINKUP);
1853		sc->tulip_cmdmode |= TULIP_CMD_TXRUN;
1854		TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode & ~TULIP_CMD_RXRUN);
1855
1856		TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
1857		DELAY(50);
1858		TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_10BASET);
1859		if (sc->tulip_cmdmode & TULIP_CMD_FULLDUPLEX)
1860		    TULIP_CSR_WRITE(sc, csr_sia_tx_rx,        TULIP_DC21041_SIATXRX_10BASET_FD);
1861		else
1862		    TULIP_CSR_WRITE(sc, csr_sia_tx_rx,        TULIP_DC21041_SIATXRX_10BASET);
1863		TULIP_CSR_WRITE(sc, csr_sia_general,      TULIP_DC21041_SIAGEN_10BASET|TULIP_DC21041_SIAGEN_WATCHDOG);
1864		DELAY(50);
1865		TULIP_CSR_WRITE(sc, csr_gp_timer, 12000000 / 204800); /* 120 ms */
1866		TULIP_CSR_WRITE(sc, csr_status, TULIP_STS_GPTIMEOUT);
1867		tulip_ifstart(&sc->tulip_if);
1868		break;
1869	    }
1870	    case TULIP_PROBE_10BASET: {
1871		if (--sc->tulip_gpticks > 0) {
1872		    if ((TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_OTHERRXACTIVITY) == 0) {
1873			TULIP_CSR_WRITE(sc, csr_gp_timer, 12000000 / 204800); /* 120 ms */
1874		 /* TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask); */
1875			break;
1876		    }
1877		}
1878		sc->tulip_gpticks = 4;
1879		if (TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_OTHERRXACTIVITY) {
1880		    sc->tulip_probe_state = TULIP_PROBE_BNC;
1881		    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
1882		    DELAY(50);
1883		    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_BNC);
1884		    TULIP_CSR_WRITE(sc, csr_sia_tx_rx,        TULIP_DC21041_SIATXRX_BNC);
1885		    TULIP_CSR_WRITE(sc, csr_sia_general,      TULIP_DC21041_SIAGEN_BNC|TULIP_DC21041_SIAGEN_WATCHDOG);
1886		    TULIP_CSR_WRITE(sc, csr_sia_status, TULIP_SIASTS_OTHERRXACTIVITY);
1887		    DELAY(50);
1888		    TULIP_CSR_WRITE(sc, csr_gp_timer, 100000000 / 204800); /* 100 ms */
1889		} else {
1890		    sc->tulip_probe_state = TULIP_PROBE_AUI;
1891		    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
1892		    DELAY(50);
1893		    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_AUI);
1894		    TULIP_CSR_WRITE(sc, csr_sia_tx_rx,        TULIP_DC21041_SIATXRX_AUI);
1895		    TULIP_CSR_WRITE(sc, csr_sia_general,      TULIP_DC21041_SIAGEN_AUI|TULIP_DC21041_SIAGEN_WATCHDOG);
1896		    DELAY(50);
1897		    TULIP_CSR_WRITE(sc, csr_gp_timer, 100000000 / 204800); /* 100 ms */
1898		}
1899		break;
1900	    }
1901	    case TULIP_PROBE_BNC:
1902	    case TULIP_PROBE_AUI: {
1903		if (sc->tulip_flags & TULIP_TXPROBE_OK) {
1904		    sc->tulip_intrmask &= ~TULIP_STS_GPTIMEOUT;
1905		    sc->tulip_flags &= ~(TULIP_TXPROBE_OK|TULIP_TXPROBE_ACTIVE);
1906		    sc->tulip_flags |= TULIP_LINKUP;
1907		    TULIP_CSR_WRITE(sc, csr_gp_timer, 0); /* disable */
1908		    if (sc->tulip_probe_state == TULIP_PROBE_AUI) {
1909			if (sc->tulip_media != TULIP_MEDIA_AUI) {
1910			    sc->tulip_media = TULIP_MEDIA_AUI;
1911			    sc->tulip_flags |= TULIP_PRINTMEDIA;
1912			}
1913		    } else if (sc->tulip_probe_state == TULIP_PROBE_BNC) {
1914			if (sc->tulip_media != TULIP_MEDIA_BNC) {
1915			    sc->tulip_media = TULIP_MEDIA_BNC;
1916			    sc->tulip_flags |= TULIP_PRINTMEDIA;
1917			}
1918		    }
1919		    TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
1920		    sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
1921		    break;
1922		}
1923		if ((sc->tulip_flags & TULIP_WANTRXACT) == 0
1924		    || (TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_RXACTIVITY)) {
1925		    if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0) {
1926			struct mbuf *m;
1927			/*
1928			 * Before we are sure this is the right media we need
1929			 * to send a small packet to make sure there's carrier.
1930			 * Strangely, BNC and AUI will 'see" receive data if
1931			 * either is connected so the transmit is the only way
1932			 * to verify the connectivity.
1933			 */
1934			MGETHDR(m, M_DONTWAIT, MT_DATA);
1935			if (m == NULL) {
1936			    TULIP_CSR_WRITE(sc, csr_gp_timer, 100000000 / 204800); /* 100 ms */
1937			    break;
1938			}
1939			/*
1940			 * Construct a LLC TEST message which will point to ourselves.
1941			 */
1942			bcopy(sc->tulip_hwaddr, mtod(m, struct ether_header *)->ether_dhost, 6);
1943			bcopy(sc->tulip_hwaddr, mtod(m, struct ether_header *)->ether_shost, 6);
1944			mtod(m, struct ether_header *)->ether_type = htons(3);
1945			mtod(m, unsigned char *)[14] = 0;
1946			mtod(m, unsigned char *)[15] = 0;
1947			mtod(m, unsigned char *)[16] = 0xE3;	/* LLC Class1 TEST (no poll) */
1948			m->m_len = m->m_pkthdr.len = sizeof(struct ether_header) + 3;
1949			/*
1950			 * send it!
1951			 */
1952			sc->tulip_flags &= ~TULIP_TXPROBE_OK;
1953			IF_PREPEND(&sc->tulip_if.if_snd, m);
1954			tulip_ifstart(&sc->tulip_if);
1955			break;
1956		    }
1957		    sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
1958		}
1959		/*
1960		 * Take 2 passes through before deciding to not
1961		 * wait for receive activity.  Then take another
1962		 * two passes before spitting out a warning.
1963		 */
1964		if (sc->tulip_gpticks > 0 && --sc->tulip_gpticks == 0) {
1965		    if (sc->tulip_flags & TULIP_WANTRXACT) {
1966			sc->tulip_flags &= ~TULIP_WANTRXACT;
1967			sc->tulip_gpticks = 4;
1968		    } else {
1969			printf(TULIP_PRINTF_FMT ": autosense failed: cable problem?\n",
1970			       TULIP_PRINTF_ARGS);
1971		    }
1972		}
1973		/*
1974		 * Since this media failed to probe, try the other one.
1975		 */
1976		if (sc->tulip_probe_state == TULIP_PROBE_AUI) {
1977		    sc->tulip_probe_state = TULIP_PROBE_BNC;
1978		    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
1979		    DELAY(50);
1980		    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_BNC);
1981		    TULIP_CSR_WRITE(sc, csr_sia_tx_rx,        TULIP_DC21041_SIATXRX_BNC);
1982		    TULIP_CSR_WRITE(sc, csr_sia_general,      TULIP_DC21041_SIAGEN_BNC|TULIP_DC21041_SIAGEN_WATCHDOG);
1983		    DELAY(50);
1984		    TULIP_CSR_WRITE(sc, csr_gp_timer, 100000000 / 204800); /* 100 ms */
1985		} else {
1986		    sc->tulip_probe_state = TULIP_PROBE_AUI;
1987		    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
1988		    DELAY(50);
1989		    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_AUI);
1990		    TULIP_CSR_WRITE(sc, csr_sia_tx_rx,        TULIP_DC21041_SIATXRX_AUI);
1991		    TULIP_CSR_WRITE(sc, csr_sia_general,      TULIP_DC21041_SIAGEN_AUI|TULIP_DC21041_SIAGEN_WATCHDOG);
1992		    DELAY(50);
1993		    TULIP_CSR_WRITE(sc, csr_gp_timer, 100000000 / 204800); /* 100 ms */
1994		}
1995		break;
1996	    }
1997	}
1998    } else {
1999	/*
2000	 * If the link has passed LinkPass, 10baseT is the
2001	 * proper media to use.
2002	 */
2003	if (sc->tulip_if.if_flags & IFF_FULLDUPLEX) {
2004	    if (sc->tulip_media != TULIP_MEDIA_10BASET_FD) {
2005		sc->tulip_media = TULIP_MEDIA_10BASET_FD;
2006		sc->tulip_flags |= TULIP_PRINTMEDIA;
2007		sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
2008	    }
2009	} else {
2010	    if (sc->tulip_media != TULIP_MEDIA_10BASET) {
2011		sc->tulip_media = TULIP_MEDIA_10BASET;
2012		sc->tulip_flags |= TULIP_PRINTMEDIA;
2013		sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
2014	    }
2015	}
2016	if (sc->tulip_media != TULIP_MEDIA_10BASET
2017		|| (sc->tulip_flags & TULIP_INRESET)) {
2018	    sc->tulip_media = TULIP_MEDIA_10BASET;
2019	    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
2020	    DELAY(50);
2021	    TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_10BASET);
2022	    if (sc->tulip_cmdmode & TULIP_CMD_FULLDUPLEX)
2023		TULIP_CSR_WRITE(sc, csr_sia_tx_rx,    TULIP_DC21041_SIATXRX_10BASET_FD);
2024	    else
2025		TULIP_CSR_WRITE(sc, csr_sia_tx_rx,    TULIP_DC21041_SIATXRX_10BASET);
2026	    TULIP_CSR_WRITE(sc, csr_sia_general,      TULIP_DC21041_SIAGEN_10BASET|TULIP_DC21041_SIAGEN_WATCHDOG);
2027	    DELAY(50);
2028	}
2029	TULIP_CSR_WRITE(sc, csr_gp_timer, 0); /* disable */
2030	sc->tulip_gpticks = 1;
2031	sc->tulip_probe_state = TULIP_PROBE_10BASET;
2032	sc->tulip_intrmask &= ~TULIP_STS_GPTIMEOUT;
2033	sc->tulip_flags |= TULIP_LINKUP;
2034	sc->tulip_flags &= ~(TULIP_TXPROBE_OK|TULIP_TXPROBE_ACTIVE);
2035	sc->tulip_if.if_flags &= ~IFF_OACTIVE;
2036	TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
2037    }
2038    if (sc->tulip_flags & TULIP_DEVICEPROBE) {
2039	sc->tulip_flags |= TULIP_FAKEGPTIMEOUT;
2040    } else {
2041	TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
2042	sc->tulip_flags &= ~TULIP_FAKEGPTIMEOUT;
2043    }
2044}
2045
2046static const tulip_boardsw_t tulip_dc21041_boardsw = {
2047    TULIP_DC21041_GENERIC,
2048    "",
2049    tulip_dc21041_media_probe,
2050    tulip_dc21041_media_select
2051};
2052
2053static void
2054tulip_reset(
2055    tulip_softc_t * const sc)
2056{
2057    tulip_ringinfo_t *ri;
2058    tulip_desc_t *di;
2059
2060    /*
2061     * Brilliant.  Simply brilliant.  When switching modes/speeds
2062     * on a DC2114*, you need to set the appriopriate MII/PCS/SCL/PS
2063     * bits in CSR6 and then do a software reset to get the DC21140
2064     * to properly reset its internal pathways to the right places.
2065     *   Grrrr.
2066     */
2067    if (sc->tulip_boardsw->bd_media_preset != NULL)
2068	(*sc->tulip_boardsw->bd_media_preset)(sc);
2069
2070    TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
2071    DELAY(10);	/* Wait 10 microseconds (actually 50 PCI cycles but at
2072		   33MHz that comes to two microseconds but wait a
2073		   bit longer anyways) */
2074
2075    sc->tulip_flags |= TULIP_INRESET;
2076    sc->tulip_flags &= ~(TULIP_NEEDRESET|TULIP_RXBUFSLOW);
2077    sc->tulip_intrmask = 0;
2078    TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
2079
2080    TULIP_CSR_WRITE(sc, csr_txlist, TULIP_KVATOPHYS(sc, &sc->tulip_txinfo.ri_first[0]));
2081    TULIP_CSR_WRITE(sc, csr_rxlist, TULIP_KVATOPHYS(sc, &sc->tulip_rxinfo.ri_first[0]));
2082    TULIP_CSR_WRITE(sc, csr_busmode,
2083	(1 << (TULIP_BURSTSIZE(sc->tulip_unit) + 8))
2084	|TULIP_BUSMODE_CACHE_ALIGN8
2085	|(BYTE_ORDER != LITTLE_ENDIAN ? TULIP_BUSMODE_BIGENDIAN : 0));
2086
2087    sc->tulip_gpticks = 0;
2088    sc->tulip_txtimer = 0;
2089    sc->tulip_txq.ifq_maxlen = TULIP_TXDESCS;
2090    sc->tulip_if.if_flags &= ~IFF_OACTIVE;
2091    /*
2092     * Free all the mbufs that were on the transmit ring.
2093     */
2094    for (;;) {
2095	struct mbuf *m;
2096	IF_DEQUEUE(&sc->tulip_txq, m);
2097	if (m == NULL)
2098	    break;
2099	m_freem(m);
2100    }
2101
2102    ri = &sc->tulip_txinfo;
2103    ri->ri_nextin = ri->ri_nextout = ri->ri_first;
2104    ri->ri_free = ri->ri_max;
2105    for (di = ri->ri_first; di < ri->ri_last; di++)
2106	di->d_status = 0;
2107
2108    /*
2109     * We need to collect all the mbufs were on the
2110     * receive ring before we reinit it either to put
2111     * them back on or to know if we have to allocate
2112     * more.
2113     */
2114    ri = &sc->tulip_rxinfo;
2115    ri->ri_nextin = ri->ri_nextout = ri->ri_first;
2116    ri->ri_free = ri->ri_max;
2117    for (di = ri->ri_first; di < ri->ri_last; di++) {
2118	di->d_status = 0;
2119	di->d_length1 = 0; di->d_addr1 = 0;
2120	di->d_length2 = 0; di->d_addr2 = 0;
2121    }
2122    for (;;) {
2123	struct mbuf *m;
2124	IF_DEQUEUE(&sc->tulip_rxq, m);
2125	if (m == NULL)
2126	    break;
2127	m_freem(m);
2128    }
2129
2130    (*sc->tulip_boardsw->bd_media_select)(sc);
2131#ifdef TULIP_DEBUG
2132    if ((sc->tulip_flags & (TULIP_DEVICEPROBE|TULIP_NEEDRESET)) == TULIP_NEEDRESET)
2133	printf(TULIP_PRINTF_FMT ": tulip_reset: additional reset needed?!?\n",
2134	       TULIP_PRINTF_ARGS);
2135#endif
2136    if ((sc->tulip_flags & (TULIP_LINKUP|TULIP_PRINTMEDIA)) == (TULIP_LINKUP|TULIP_PRINTMEDIA)) {
2137	printf(TULIP_PRINTF_FMT ": enabling %s port\n",
2138	       TULIP_PRINTF_ARGS,
2139	       tulip_mediums[sc->tulip_media]);
2140	sc->tulip_flags &= ~TULIP_PRINTMEDIA;
2141    }
2142    if (sc->tulip_chipid == TULIP_DC21041)
2143	TULIP_CSR_WRITE(sc, csr_sia_status, TULIP_CSR_READ(sc, csr_sia_status));
2144
2145    sc->tulip_intrmask |= TULIP_STS_NORMALINTR|TULIP_STS_RXINTR|TULIP_STS_TXINTR
2146	|TULIP_STS_ABNRMLINTR|TULIP_STS_SYSERROR|TULIP_STS_TXSTOPPED
2147	    |TULIP_STS_TXBABBLE|TULIP_STS_LINKFAIL|TULIP_STS_RXSTOPPED;
2148    sc->tulip_flags &= ~(TULIP_DOINGSETUP|TULIP_WANTSETUP|TULIP_INRESET
2149			 |TULIP_RXACT);
2150    tulip_addr_filter(sc);
2151}
2152
2153static void
2154tulip_init(
2155    tulip_softc_t * const sc)
2156{
2157    if (sc->tulip_if.if_flags & IFF_UP) {
2158	sc->tulip_if.if_flags |= IFF_RUNNING;
2159	if (sc->tulip_if.if_flags & IFF_PROMISC) {
2160	    sc->tulip_cmdmode |= TULIP_CMD_PROMISCUOUS;
2161	} else {
2162	    sc->tulip_cmdmode &= ~TULIP_CMD_PROMISCUOUS;
2163	    if (sc->tulip_if.if_flags & IFF_ALLMULTI) {
2164		sc->tulip_cmdmode |= TULIP_CMD_ALLMULTI;
2165	    } else {
2166		sc->tulip_cmdmode &= ~TULIP_CMD_ALLMULTI;
2167	    }
2168	}
2169	sc->tulip_cmdmode |= TULIP_CMD_TXRUN;
2170	if ((sc->tulip_flags & TULIP_WANTSETUP) == 0) {
2171	    tulip_rx_intr(sc);
2172	    sc->tulip_cmdmode |= TULIP_CMD_RXRUN;
2173	    sc->tulip_intrmask |= TULIP_STS_RXSTOPPED;
2174	} else {
2175	    sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED;
2176	    tulip_ifstart(&sc->tulip_if);
2177	}
2178	TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
2179	TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
2180    } else {
2181	tulip_reset(sc);
2182	sc->tulip_if.if_flags &= ~IFF_RUNNING;
2183    }
2184}
2185
2186static void
2187tulip_rx_intr(
2188    tulip_softc_t * const sc)
2189{
2190    tulip_ringinfo_t * const ri = &sc->tulip_rxinfo;
2191    struct ifnet * const ifp = &sc->tulip_if;
2192    int fillok = 1;
2193#ifdef TULIP_DEBUG
2194    int cnt = 0;
2195#endif
2196
2197    for (;;) {
2198	struct ether_header eh;
2199	tulip_desc_t *eop = ri->ri_nextin;
2200	int total_len = 0, last_offset = 0;
2201	struct mbuf *ms = NULL, *me = NULL;
2202	int accept = 0;
2203
2204	if (fillok && sc->tulip_rxq.ifq_len < TULIP_RXQ_TARGET)
2205	    goto queue_mbuf;
2206
2207#ifdef TULIP_DEBUG
2208	if (cnt == ri->ri_max) {
2209	    sc->tulip_dbg.dbg_rxintrs++;
2210	    sc->tulip_dbg.dbg_rxpktsperintr[cnt]++;
2211	    return;
2212	}
2213#endif
2214
2215	if (((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER) {
2216#ifdef TULIP_DEBUG
2217	    sc->tulip_dbg.dbg_rxintrs++;
2218	    sc->tulip_dbg.dbg_rxpktsperintr[cnt]++;
2219#endif
2220	    return;
2221	}
2222	/*
2223	 * It is possible (though improbable unless the BIG_PACKET support
2224	 * is enabled or MCLBYTES < 1518) for a received packet to cross
2225	 * more than one receive descriptor.
2226	 */
2227	while ((((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_RxLASTDESC) == 0) {
2228	    if (++eop == ri->ri_last)
2229		eop = ri->ri_first;
2230	    if (((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER) {
2231#ifdef TULIP_DEBUG
2232		sc->tulip_dbg.dbg_rxintrs++;
2233		sc->tulip_dbg.dbg_rxpktsperintr[cnt]++;
2234#endif
2235		return;
2236	    }
2237	    total_len++;
2238	}
2239
2240	/*
2241	 * Dequeue the first buffer for the start of the packet.  Hopefully this
2242	 * will be the only one we need to dequeue.  However, if the packet consumed
2243	 * multiple descriptors, then we need to dequeue those buffers and chain to
2244	 * the starting mbuf.  All buffers but the last buffer have the same length
2245	 * so we can set that now.  (we add to last_offset instead of multiplying
2246	 * since we normally won't go into the loop and thereby saving a ourselves
2247	 * from doing a multiplication by 0 in the normal case).
2248	 */
2249	IF_DEQUEUE(&sc->tulip_rxq, ms);
2250	for (me = ms; total_len > 0; total_len--) {
2251	    me->m_len = TULIP_RX_BUFLEN;
2252	    last_offset += TULIP_RX_BUFLEN;
2253	    IF_DEQUEUE(&sc->tulip_rxq, me->m_next);
2254	    me = me->m_next;
2255	}
2256
2257	/*
2258	 *  Now get the size of received packet (minus the CRC).
2259	 */
2260	total_len = ((eop->d_status >> 16) & 0x7FFF) - 4;
2261	if ((eop->d_status & TULIP_DSTS_ERRSUM) == 0
2262#ifdef BIG_PACKET
2263	     || (total_len <= sc->tulip_if.if_mtu + sizeof(struct ether_header) &&
2264		 (eop->d_status & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxRUNT|
2265				  TULIP_DSTS_RxCOLLSEEN|TULIP_DSTS_RxBADCRC|
2266				  TULIP_DSTS_RxOVERFLOW)) == 0)
2267#endif
2268		) {
2269	    me->m_len = total_len - last_offset;
2270	    eh = *mtod(ms, struct ether_header *);
2271#if NBPFILTER > 0
2272	    if (sc->tulip_bpf != NULL)
2273		if (me == ms)
2274		    TULIP_BPF_TAP(sc, mtod(ms, caddr_t), total_len);
2275		else
2276		    TULIP_BPF_MTAP(sc, ms);
2277#endif
2278	    if ((sc->tulip_if.if_flags & IFF_PROMISC)
2279		    && (eh.ether_dhost[0] & 1) == 0
2280		    && !TULIP_ADDREQUAL(eh.ether_dhost, sc->tulip_ac.ac_enaddr))
2281		    goto next;
2282	    accept = 1;
2283	    sc->tulip_flags |= TULIP_RXACT;
2284	    total_len -= sizeof(struct ether_header);
2285	} else {
2286	    ifp->if_ierrors++;
2287	    if (eop->d_status & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxOVERFLOW|TULIP_DSTS_RxWATCHDOG)) {
2288		sc->tulip_dot3stats.dot3StatsInternalMacReceiveErrors++;
2289	    } else {
2290		const char *error = NULL;
2291		if (eop->d_status & TULIP_DSTS_RxTOOLONG) {
2292		    sc->tulip_dot3stats.dot3StatsFrameTooLongs++;
2293		    error = "frame too long";
2294		}
2295		if (eop->d_status & TULIP_DSTS_RxBADCRC) {
2296		    if (eop->d_status & TULIP_DSTS_RxDRBBLBIT) {
2297			sc->tulip_dot3stats.dot3StatsAlignmentErrors++;
2298			error = "alignment error";
2299		    } else {
2300			sc->tulip_dot3stats.dot3StatsFCSErrors++;
2301			error = "bad crc";
2302		    }
2303		}
2304		if (error != NULL && (sc->tulip_flags & TULIP_NOMESSAGES) == 0) {
2305		    printf(TULIP_PRINTF_FMT ": receive: " TULIP_EADDR_FMT ": %s\n",
2306			   TULIP_PRINTF_ARGS,
2307			   TULIP_EADDR_ARGS(mtod(ms, u_char *) + 6),
2308			   error);
2309		    sc->tulip_flags |= TULIP_NOMESSAGES;
2310		}
2311	    }
2312	}
2313      next:
2314#ifdef TULIP_DEBUG
2315	cnt++;
2316#endif
2317	ifp->if_ipackets++;
2318	if (++eop == ri->ri_last)
2319	    eop = ri->ri_first;
2320	ri->ri_nextin = eop;
2321      queue_mbuf:
2322	/*
2323	 * Either we are priming the TULIP with mbufs (m == NULL)
2324	 * or we are about to accept an mbuf for the upper layers
2325	 * so we need to allocate an mbuf to replace it.  If we
2326	 * can't replace it, send up it anyways.  This may cause
2327	 * us to drop packets in the future but that's better than
2328	 * being caught in livelock.
2329	 *
2330	 * Note that if this packet crossed multiple descriptors
2331	 * we don't even try to reallocate all the mbufs here.
2332	 * Instead we rely on the test of the beginning of
2333	 * the loop to refill for the extra consumed mbufs.
2334	 */
2335	if (accept || ms == NULL) {
2336	    struct mbuf *m0;
2337	    MGETHDR(m0, M_DONTWAIT, MT_DATA);
2338	    if (m0 != NULL) {
2339#if defined(TULIP_COPY_RXDATA)
2340		if (!accept || total_len >= MHLEN) {
2341#endif
2342		    MCLGET(m0, M_DONTWAIT);
2343		    if ((m0->m_flags & M_EXT) == 0) {
2344			m_freem(m0);
2345			m0 = NULL;
2346		    }
2347#if defined(TULIP_COPY_RXDATA)
2348		}
2349#endif
2350	    }
2351	    if (accept) {
2352#if defined(__bsdi__)
2353		eh.ether_type = ntohs(eh.ether_type);
2354#endif
2355#if !defined(TULIP_COPY_RXDATA)
2356		ms->m_data += sizeof(struct ether_header);
2357		ms->m_len -= sizeof(struct ether_header);
2358		ms->m_pkthdr.len = total_len;
2359		ms->m_pkthdr.rcvif = ifp;
2360		ether_input(ifp, &eh, ms);
2361#else
2362#ifdef BIG_PACKET
2363#error BIG_PACKET is incompatible with TULIP_COPY_RXDATA
2364#endif
2365		if (ms == me)
2366		    bcopy(mtod(ms, caddr_t) + sizeof(struct ether_header),
2367			  mtod(m0, caddr_t), total_len);
2368		else
2369		    m_copydata(ms, 0, total_len, mtod(m0, caddr_t));
2370		m0->m_len = m0->m_pkthdr.len = total_len;
2371		m0->m_pkthdr.rcvif = ifp;
2372		ether_input(ifp, &eh, m0);
2373		m0 = ms;
2374#endif
2375	    }
2376	    ms = m0;
2377	}
2378	if (ms == NULL) {
2379	    /*
2380	     * Couldn't allocate a new buffer.  Don't bother
2381	     * trying to replenish the receive queue.
2382	     */
2383	    fillok = 0;
2384	    sc->tulip_flags |= TULIP_RXBUFSLOW;
2385#ifdef TULIP_DEBUG
2386	    sc->tulip_dbg.dbg_rxlowbufs++;
2387#endif
2388	    continue;
2389	}
2390	/*
2391	 * Now give the buffer(s) to the TULIP and save in our
2392	 * receive queue.
2393	 */
2394	do {
2395	    ri->ri_nextout->d_length1 = TULIP_RX_BUFLEN;
2396	    ri->ri_nextout->d_addr1 = TULIP_KVATOPHYS(sc, mtod(ms, caddr_t));
2397	    ri->ri_nextout->d_status = TULIP_DSTS_OWNER;
2398	    if (++ri->ri_nextout == ri->ri_last)
2399		ri->ri_nextout = ri->ri_first;
2400	    me = ms->m_next;
2401	    ms->m_next = NULL;
2402	    IF_ENQUEUE(&sc->tulip_rxq, ms);
2403	} while ((ms = me) != NULL);
2404
2405	if (sc->tulip_rxq.ifq_len == TULIP_RXQ_TARGET)
2406	    sc->tulip_flags &= ~TULIP_RXBUFSLOW;
2407    }
2408}
2409
2410static int
2411tulip_tx_intr(
2412    tulip_softc_t * const sc)
2413{
2414    tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
2415    struct mbuf *m;
2416    int xmits = 0;
2417
2418    while (ri->ri_free < ri->ri_max) {
2419	if (((volatile tulip_desc_t *) ri->ri_nextin)->d_status & TULIP_DSTS_OWNER)
2420	    break;
2421
2422	if (ri->ri_nextin->d_flag & TULIP_DFLAG_TxLASTSEG) {
2423	    if (ri->ri_nextin->d_flag & TULIP_DFLAG_TxSETUPPKT) {
2424		/*
2425		 * We've just finished processing a setup packet.
2426		 * Mark that we can finished it.  If there's not
2427		 * another pending, startup the TULIP receiver.
2428		 * Make sure we ack the RXSTOPPED so we won't get
2429		 * an abormal interrupt indication.
2430		 */
2431		sc->tulip_flags &= ~TULIP_DOINGSETUP;
2432		if ((sc->tulip_flags & TULIP_WANTSETUP) == 0
2433		        && (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0) {
2434		    tulip_rx_intr(sc);
2435		    sc->tulip_cmdmode |= TULIP_CMD_RXRUN;
2436		    sc->tulip_intrmask |= TULIP_STS_RXSTOPPED;
2437		    TULIP_CSR_WRITE(sc, csr_status, TULIP_STS_RXSTOPPED);
2438		    TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
2439		    TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
2440		}
2441	    } else {
2442		tulip_desc_t * eop = ri->ri_nextin;
2443		IF_DEQUEUE(&sc->tulip_txq, m);
2444		m_freem(m);
2445		xmits++;
2446		if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) {
2447		    if ((eop->d_status & (TULIP_DSTS_TxNOCARR|TULIP_DSTS_TxEXCCOLL)) == 0)
2448			sc->tulip_flags |= TULIP_TXPROBE_OK;
2449		    (*sc->tulip_boardsw->bd_media_select)(sc);
2450		    if (sc->tulip_chipid == TULIP_DC21041)
2451			TULIP_CSR_WRITE(sc, csr_sia_status, TULIP_CSR_READ(sc, csr_sia_status));
2452		} else {
2453		    if (eop->d_status & TULIP_DSTS_ERRSUM) {
2454			sc->tulip_if.if_oerrors++;
2455			if (eop->d_status & TULIP_DSTS_TxEXCCOLL)
2456			    sc->tulip_dot3stats.dot3StatsExcessiveCollisions++;
2457			if (eop->d_status & TULIP_DSTS_TxLATECOLL)
2458			    sc->tulip_dot3stats.dot3StatsLateCollisions++;
2459			if (eop->d_status & (TULIP_DSTS_TxNOCARR|TULIP_DSTS_TxCARRLOSS))
2460			    sc->tulip_dot3stats.dot3StatsCarrierSenseErrors++;
2461			if (eop->d_status & (TULIP_DSTS_TxUNDERFLOW|TULIP_DSTS_TxBABBLE))
2462			    sc->tulip_dot3stats.dot3StatsInternalMacTransmitErrors++;
2463		    } else {
2464			tulip_uint32_t collisions =
2465			    (eop->d_status & TULIP_DSTS_TxCOLLMASK)
2466				>> TULIP_DSTS_V_TxCOLLCNT;
2467			sc->tulip_if.if_collisions += collisions;
2468			if (collisions == 1)
2469			    sc->tulip_dot3stats.dot3StatsSingleCollisionFrames++;
2470			else if (collisions > 1)
2471			    sc->tulip_dot3stats.dot3StatsMultipleCollisionFrames++;
2472			else if (eop->d_status & TULIP_DSTS_TxDEFERRED)
2473			    sc->tulip_dot3stats.dot3StatsDeferredTransmissions++;
2474			/*
2475			 * SQE is only valid for 10baseT/BNC/AUI when not
2476			 * running in full-duplex.  In order to speed up the
2477			 * test, the corresponding bit in tulip_flags needs to
2478			 * set as well to get us to count SQE Test Errors.
2479			 */
2480			if (eop->d_status & TULIP_DSTS_TxNOHRTBT & sc->tulip_flags)
2481			    sc->tulip_dot3stats.dot3StatsSQETestErrors++;
2482		    }
2483		}
2484	    }
2485	}
2486
2487	if (++ri->ri_nextin == ri->ri_last)
2488	    ri->ri_nextin = ri->ri_first;
2489	ri->ri_free++;
2490	sc->tulip_if.if_flags &= ~IFF_OACTIVE;
2491    }
2492    /*
2493     * If nothing left to transmit, disable the timer.
2494     * Else if progress, reset the timer back to 2 ticks.
2495     */
2496    if (ri->ri_free == ri->ri_max)
2497	sc->tulip_txtimer = 0;
2498    else if (xmits > 0)
2499	sc->tulip_txtimer = 2;
2500    sc->tulip_if.if_opackets += xmits;
2501    return xmits;
2502}
2503
2504static ifnet_ret_t
2505tulip_ifstart(
2506    struct ifnet * const ifp)
2507{
2508    tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
2509    struct ifqueue * const ifq = &ifp->if_snd;
2510    tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
2511    struct mbuf *m, *m0, *next_m0;
2512
2513    if ((ifp->if_flags & IFF_RUNNING) == 0
2514	    && (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0)
2515	return;
2516
2517    for (;;) {
2518	tulip_desc_t *eop, *nextout;
2519	int segcnt, free, recopy;
2520	tulip_uint32_t d_status;
2521
2522	if (sc->tulip_flags & TULIP_WANTSETUP) {
2523	    if ((sc->tulip_flags & TULIP_DOINGSETUP) || ri->ri_free == 1) {
2524		ifp->if_flags |= IFF_OACTIVE;
2525		return;
2526	    }
2527	    bcopy(sc->tulip_setupdata, sc->tulip_setupbuf,
2528		   sizeof(sc->tulip_setupbuf));
2529	    sc->tulip_flags &= ~TULIP_WANTSETUP;
2530	    sc->tulip_flags |= TULIP_DOINGSETUP;
2531	    ri->ri_free--;
2532	    ri->ri_nextout->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
2533	    ri->ri_nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG|TULIP_DFLAG_TxLASTSEG
2534		    |TULIP_DFLAG_TxSETUPPKT|TULIP_DFLAG_TxWANTINTR;
2535	    if (sc->tulip_flags & TULIP_WANTHASH)
2536		ri->ri_nextout->d_flag |= TULIP_DFLAG_TxHASHFILT;
2537	    ri->ri_nextout->d_length1 = sizeof(sc->tulip_setupbuf);
2538	    ri->ri_nextout->d_addr1 = TULIP_KVATOPHYS(sc, sc->tulip_setupbuf);
2539	    ri->ri_nextout->d_length2 = 0;
2540	    ri->ri_nextout->d_addr2 = 0;
2541	    ri->ri_nextout->d_status = TULIP_DSTS_OWNER;
2542	    TULIP_CSR_WRITE(sc, csr_txpoll, 1);
2543	    /*
2544	     * Advance the ring for the next transmit packet.
2545	     */
2546	    if (++ri->ri_nextout == ri->ri_last)
2547		ri->ri_nextout = ri->ri_first;
2548	    /*
2549	     * Make sure the next descriptor is owned by us since it
2550	     * may have been set up above if we ran out of room in the
2551	     * ring.
2552	     */
2553	    ri->ri_nextout->d_status = 0;
2554	}
2555
2556	IF_DEQUEUE(ifq, m);
2557	if (m == NULL)
2558	    break;
2559
2560	/*
2561	 * Now we try to fill in our transmit descriptors.  This is
2562	 * a bit reminiscent of going on the Ark two by two
2563	 * since each descriptor for the TULIP can describe
2564	 * two buffers.  So we advance through packet filling
2565	 * each of the two entries at a time to to fill each
2566	 * descriptor.  Clear the first and last segment bits
2567	 * in each descriptor (actually just clear everything
2568	 * but the end-of-ring or chain bits) to make sure
2569	 * we don't get messed up by previously sent packets.
2570	 *
2571	 * We may fail to put the entire packet on the ring if
2572	 * there is either not enough ring entries free or if the
2573	 * packet has more than MAX_TXSEG segments.  In the former
2574	 * case we will just wait for the ring to empty.  In the
2575	 * latter case we have to recopy.
2576	 */
2577	d_status = 0;
2578	recopy = 0;
2579	eop = nextout = ri->ri_nextout;
2580	m0 = m;
2581	segcnt = 0;
2582	free = ri->ri_free;
2583	do {
2584	    int len = m0->m_len;
2585	    caddr_t addr = mtod(m0, caddr_t);
2586	    unsigned clsize = CLBYTES - (((u_long) addr) & (CLBYTES-1));
2587
2588	    next_m0 = m0->m_next;
2589	    while (len > 0) {
2590		unsigned slen = min(len, clsize);
2591#ifdef BIG_PACKET
2592		int partial = 0;
2593		if (slen >= 2048)
2594		    slen = 2040, partial = 1;
2595#endif
2596		segcnt++;
2597		if (segcnt > TULIP_MAX_TXSEG) {
2598		    recopy = 1;
2599		    next_m0 = NULL; /* to break out of outside loop */
2600		    break;
2601		}
2602		if (segcnt & 1) {
2603		    if (--free == 0) {
2604			/*
2605			 * There's no more room but since nothing
2606			 * has been committed at this point, just
2607			 * show output is active, put back the
2608			 * mbuf and return.
2609			 */
2610			ifp->if_flags |= IFF_OACTIVE;
2611			IF_PREPEND(ifq, m);
2612			return;
2613		    }
2614		    eop = nextout;
2615		    if (++nextout == ri->ri_last)
2616			nextout = ri->ri_first;
2617		    eop->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
2618		    eop->d_status = d_status;
2619		    eop->d_addr1 = TULIP_KVATOPHYS(sc, addr);
2620		    eop->d_length1 = slen;
2621		} else {
2622		    /*
2623		     *  Fill in second half of descriptor
2624		     */
2625		    eop->d_addr2 = TULIP_KVATOPHYS(sc, addr);
2626		    eop->d_length2 = slen;
2627		}
2628		d_status = TULIP_DSTS_OWNER;
2629		len -= slen;
2630		addr += slen;
2631#ifdef BIG_PACKET
2632		if (partial)
2633		    continue;
2634#endif
2635		clsize = CLBYTES;
2636	    }
2637	} while ((m0 = next_m0) != NULL);
2638
2639	/*
2640	 * The packet exceeds the number of transmit buffer
2641	 * entries that we can use for one packet, so we have
2642	 * recopy it into one mbuf and then try again.
2643	 */
2644	if (recopy) {
2645	    MGETHDR(m0, M_DONTWAIT, MT_DATA);
2646	    if (m0 != NULL) {
2647		if (m->m_pkthdr.len > MHLEN) {
2648		    MCLGET(m0, M_DONTWAIT);
2649		    if ((m0->m_flags & M_EXT) == 0) {
2650			m_freem(m);
2651			m_freem(m0);
2652			continue;
2653		    }
2654		}
2655		m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t));
2656		m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len;
2657		IF_PREPEND(ifq, m0);
2658	    }
2659	    m_freem(m);
2660	    continue;
2661	}
2662
2663	/*
2664	 * The descriptors have been filled in.  Now get ready
2665	 * to transmit.
2666	 */
2667#if NBPFILTER > 0
2668	if (sc->tulip_bpf != NULL)
2669	    TULIP_BPF_MTAP(sc, m);
2670#endif
2671	IF_ENQUEUE(&sc->tulip_txq, m);
2672
2673	/*
2674	 * Make sure the next descriptor after this packet is owned
2675	 * by us since it may have been set up above if we ran out
2676	 * of room in the ring.
2677	 */
2678	nextout->d_status = 0;
2679
2680	/*
2681	 * If we only used the first segment of the last descriptor,
2682	 * make sure the second segment will not be used.
2683	 */
2684	if (segcnt & 1) {
2685	    eop->d_addr2 = 0;
2686	    eop->d_length2 = 0;
2687	}
2688
2689	/*
2690	 * Mark the last and first segments, indicate we want a transmit
2691	 * complete interrupt, give the descriptors to the TULIP, and tell
2692	 * it to transmit!
2693	 */
2694	eop->d_flag |= TULIP_DFLAG_TxLASTSEG|TULIP_DFLAG_TxWANTINTR;
2695
2696	/*
2697	 * Note that ri->ri_nextout is still the start of the packet
2698	 * and until we set the OWNER bit, we can still back out of
2699	 * everything we have done.
2700	 */
2701	ri->ri_nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG;
2702	ri->ri_nextout->d_status = TULIP_DSTS_OWNER;
2703
2704	/*
2705	 * This advances the ring for us.
2706	 */
2707	ri->ri_nextout = nextout;
2708	ri->ri_free = free;
2709
2710	TULIP_CSR_WRITE(sc, csr_txpoll, 1);
2711
2712	if (sc->tulip_txtimer == 0)
2713	    sc->tulip_txtimer = 2;
2714    }
2715    if (m != NULL) {
2716	ifp->if_flags |= IFF_OACTIVE;
2717	IF_PREPEND(ifq, m);
2718    }
2719}
2720
2721static void
2722tulip_print_abnormal_interrupt(
2723    tulip_softc_t * const sc,
2724    tulip_uint32_t csr)
2725{
2726    const char * const *msgp = tulip_status_bits;
2727    const char *sep;
2728
2729    csr &= (1 << (sizeof(tulip_status_bits)/sizeof(tulip_status_bits[0]))) - 1;
2730    printf(TULIP_PRINTF_FMT ": abnormal interrupt:", TULIP_PRINTF_ARGS);
2731    for (sep = " "; csr != 0; csr >>= 1, msgp++) {
2732	if ((csr & 1) && *msgp != NULL) {
2733	    printf("%s%s", sep, *msgp);
2734	    sep = ", ";
2735	}
2736    }
2737    printf("\n");
2738}
2739
2740static tulip_intrfunc_t
2741tulip_intr(
2742    void *arg)
2743{
2744    tulip_softc_t * sc = (tulip_softc_t *) arg;
2745    tulip_uint32_t csr;
2746#if !defined(TULIP_VOID_INTRFUNC)
2747    int progress = 0;
2748#endif
2749
2750    do {
2751#if defined(TULIP_DEBUG)
2752	sc->tulip_dbg.dbg_intrs++;
2753#endif
2754	while ((csr = TULIP_CSR_READ(sc, csr_status)) & (TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR)) {
2755#if !defined(TULIP_VOID_INTRFUNC)
2756	    progress = 1;
2757#endif
2758	    TULIP_CSR_WRITE(sc, csr_status, csr);
2759
2760	    if (csr & TULIP_STS_SYSERROR) {
2761		sc->tulip_last_system_error = (csr & TULIP_STS_ERRORMASK) >> TULIP_STS_ERR_SHIFT;
2762		if (sc->tulip_flags & TULIP_NOMESSAGES) {
2763		    sc->tulip_flags |= TULIP_SYSTEMERROR;
2764		} else {
2765		    printf(TULIP_PRINTF_FMT ": system error: %s\n",
2766			   TULIP_PRINTF_ARGS,
2767			   tulip_system_errors[sc->tulip_last_system_error]);
2768		}
2769		sc->tulip_flags |= TULIP_NEEDRESET;
2770		sc->tulip_system_errors++;
2771		break;
2772	    }
2773	    if (csr & (TULIP_STS_GPTIMEOUT|TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL)) {
2774#if defined(TULIP_DEBUG)
2775		sc->tulip_dbg.dbg_gpintrs++;
2776#endif
2777		if (sc->tulip_chipid == TULIP_DC21041) {
2778		    (*sc->tulip_boardsw->bd_media_select)(sc);
2779		    if (csr & (TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL))
2780			csr &= ~TULIP_STS_ABNRMLINTR;
2781		    TULIP_CSR_WRITE(sc, csr_sia_status, TULIP_CSR_READ(sc, csr_sia_status));
2782		} else if (sc->tulip_chipid == TULIP_DC21140 || sc->tulip_chipid == TULIP_DC21140A) {
2783		    (*sc->tulip_boardsw->bd_media_select)(sc);
2784		    csr &= ~(TULIP_STS_ABNRMLINTR|TULIP_STS_GPTIMEOUT);
2785		}
2786		if ((sc->tulip_flags & (TULIP_LINKUP|TULIP_PRINTMEDIA)) == (TULIP_LINKUP|TULIP_PRINTMEDIA)) {
2787		    printf(TULIP_PRINTF_FMT ": enabling %s port\n",
2788			   TULIP_PRINTF_ARGS,
2789			   tulip_mediums[sc->tulip_media]);
2790		    sc->tulip_flags &= ~TULIP_PRINTMEDIA;
2791		}
2792	    }
2793	    if (csr & TULIP_STS_ABNRMLINTR) {
2794		tulip_uint32_t tmp = csr & sc->tulip_intrmask
2795			& ~(TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR);
2796		if (sc->tulip_flags & TULIP_NOMESSAGES) {
2797		    sc->tulip_statusbits |= tmp;
2798		} else {
2799		    tulip_print_abnormal_interrupt(sc, tmp);
2800		    sc->tulip_flags |= TULIP_NOMESSAGES;
2801		}
2802		TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
2803	    }
2804	    if (csr & (TULIP_STS_RXINTR|TULIP_STS_RXNOBUF)) {
2805		tulip_rx_intr(sc);
2806		if (csr & TULIP_STS_RXNOBUF)
2807		    sc->tulip_dot3stats.dot3StatsMissedFrames +=
2808			TULIP_CSR_READ(sc, csr_missed_frames) & 0xFFFF;
2809	    }
2810	    if (sc->tulip_txinfo.ri_free < sc->tulip_txinfo.ri_max) {
2811		tulip_tx_intr(sc);
2812		tulip_ifstart(&sc->tulip_if);
2813	    }
2814	}
2815	if (sc->tulip_flags & TULIP_NEEDRESET) {
2816	    tulip_reset(sc);
2817	    tulip_init(sc);
2818	}
2819    } while ((sc = sc->tulip_slaves) != NULL);
2820#if !defined(TULIP_VOID_INTRFUNC)
2821    return progress;
2822#endif
2823}
2824
2825/*
2826 *
2827 */
2828
2829static void
2830tulip_delay_300ns(
2831    tulip_softc_t * const sc)
2832{
2833    int idx;
2834    for (idx = (300 / 33) + 1; idx > 0; idx--)
2835	TULIP_CSR_READ(sc, csr_busmode);
2836}
2837
2838#define EMIT    do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); tulip_delay_300ns(sc); } while (0)
2839
2840static void
2841tulip_idle_srom(
2842    tulip_softc_t * const sc)
2843{
2844    unsigned bit, csr;
2845
2846    csr  = SROMSEL ; EMIT;
2847    csr  = SROMSEL | SROMRD; EMIT;
2848    csr ^= SROMCS; EMIT;
2849    csr ^= SROMCLKON; EMIT;
2850
2851    /*
2852     * Write 25 cycles of 0 which will force the SROM to be idle.
2853     */
2854    for (bit = 3 + SROM_BITWIDTH + 16; bit > 0; bit--) {
2855        csr ^= SROMCLKOFF; EMIT;    /* clock low; data not valid */
2856        csr ^= SROMCLKON; EMIT;     /* clock high; data valid */
2857    }
2858    csr ^= SROMCLKOFF; EMIT;
2859    csr ^= SROMCS; EMIT;
2860    csr  = 0; EMIT;
2861}
2862
2863
2864static void
2865tulip_read_srom(
2866    tulip_softc_t * const sc)
2867{
2868    int idx;
2869    const unsigned bitwidth = SROM_BITWIDTH;
2870    const unsigned cmdmask = (SROMCMD_RD << bitwidth);
2871    const unsigned msb = 1 << (bitwidth + 3 - 1);
2872    unsigned lastidx = (1 << bitwidth) - 1;
2873
2874    tulip_idle_srom(sc);
2875
2876    for (idx = 0; idx <= lastidx; idx++) {
2877        unsigned lastbit, data, bits, bit, csr;
2878	csr  = SROMSEL ;	        EMIT;
2879        csr  = SROMSEL | SROMRD;        EMIT;
2880        csr ^= SROMCSON;                EMIT;
2881        csr ^=            SROMCLKON;    EMIT;
2882
2883        lastbit = 0;
2884        for (bits = idx|cmdmask, bit = bitwidth + 3; bit > 0; bit--, bits <<= 1) {
2885            const unsigned thisbit = bits & msb;
2886            csr ^= SROMCLKOFF; EMIT;    /* clock low; data not valid */
2887            if (thisbit != lastbit) {
2888                csr ^= SROMDOUT; EMIT;  /* clock low; invert data */
2889            } else {
2890		EMIT;
2891	    }
2892            csr ^= SROMCLKON; EMIT;     /* clock high; data valid */
2893            lastbit = thisbit;
2894        }
2895        csr ^= SROMCLKOFF; EMIT;
2896
2897        for (data = 0, bits = 0; bits < 16; bits++) {
2898            data <<= 1;
2899            csr ^= SROMCLKON; EMIT;     /* clock high; data valid */
2900            data |= TULIP_CSR_READ(sc, csr_srom_mii) & SROMDIN ? 1 : 0;
2901            csr ^= SROMCLKOFF; EMIT;    /* clock low; data not valid */
2902        }
2903	sc->tulip_rombuf[idx*2] = data & 0xFF;
2904	sc->tulip_rombuf[idx*2+1] = data >> 8;
2905	csr  = SROMSEL | SROMRD; EMIT;
2906	csr  = 0; EMIT;
2907    }
2908    tulip_idle_srom(sc);
2909}
2910
2911#define MII_EMIT    do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); tulip_delay_300ns(sc); } while (0)
2912
2913static void
2914tulip_mii_sendbits(
2915    tulip_softc_t * const sc,
2916    unsigned data,
2917    unsigned bits)
2918{
2919    unsigned msb = 1 << (bits - 1);
2920    unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
2921    unsigned lastbit = (csr & MII_DOUT) ? msb : 0;
2922
2923    csr |= MII_WR; MII_EMIT;  		/* clock low; assert write */
2924
2925    for (; bits > 0; bits--, data <<= 1) {
2926	const unsigned thisbit = data & msb;
2927	if (thisbit != lastbit) {
2928	    csr ^= MII_DOUT; MII_EMIT;  /* clock low; invert data */
2929	}
2930	csr ^= MII_CLKON; MII_EMIT;     /* clock high; data valid */
2931	lastbit = thisbit;
2932	csr ^= MII_CLKOFF; MII_EMIT;    /* clock low; data not valid */
2933    }
2934}
2935
2936static void
2937tulip_mii_turnaround(
2938    tulip_softc_t * const sc,
2939    unsigned cmd)
2940{
2941    unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
2942
2943    if (cmd == MII_WRCMD) {
2944	csr |= MII_DOUT; MII_EMIT;	/* clock low; change data */
2945	csr ^= MII_CLKON; MII_EMIT;	/* clock high; data valid */
2946	csr ^= MII_CLKOFF; MII_EMIT;	/* clock low; data not valid */
2947	csr ^= MII_DOUT; MII_EMIT;	/* clock low; change data */
2948    } else {
2949	csr |= MII_RD; MII_EMIT;	/* clock low; switch to read */
2950    }
2951    csr ^= MII_CLKON; MII_EMIT;		/* clock high; data valid */
2952    csr ^= MII_CLKOFF; MII_EMIT;	/* clock low; data not valid */
2953}
2954
2955static unsigned
2956tulip_mii_readbits(
2957    tulip_softc_t * const sc)
2958{
2959    unsigned data;
2960    unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
2961    int idx;
2962
2963    for (idx = 0, data = 0; idx < 16; idx++) {
2964	data <<= 1;	/* this is NOOP on the first pass through */
2965	csr ^= MII_CLKON; MII_EMIT;	/* clock high; data valid */
2966	if (TULIP_CSR_READ(sc, csr_srom_mii) & MII_DIN)
2967	    data |= 1;
2968	csr ^= MII_CLKOFF; MII_EMIT;	/* clock low; data not valid */
2969    }
2970    csr ^= MII_RD; MII_EMIT;		/* clock low; turn off read */
2971
2972    return data;
2973}
2974
2975static unsigned
2976tulip_mii_readreg(
2977    tulip_softc_t * const sc,
2978    unsigned devaddr,
2979    unsigned regno)
2980{
2981    unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
2982    unsigned data;
2983
2984    csr &= ~(MII_RD|MII_CLK); MII_EMIT;
2985    tulip_mii_sendbits(sc, MII_PREAMBLE, 32);
2986    tulip_mii_sendbits(sc, MII_RDCMD, 8);
2987    tulip_mii_sendbits(sc, devaddr, 5);
2988    tulip_mii_sendbits(sc, regno, 5);
2989    tulip_mii_turnaround(sc, MII_RDCMD);
2990
2991    data = tulip_mii_readbits(sc);
2992#ifdef TULIP_DEBUG
2993    sc->tulip_dbg.dbg_phyregs[regno][0] = data;
2994    sc->tulip_dbg.dbg_phyregs[regno][1]++;
2995#endif
2996    return data;
2997}
2998
2999static void
3000tulip_mii_writereg(
3001    tulip_softc_t * const sc,
3002    unsigned devaddr,
3003    unsigned regno,
3004    unsigned data)
3005{
3006    unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
3007    csr &= ~(MII_RD|MII_CLK); MII_EMIT;
3008    tulip_mii_sendbits(sc, MII_PREAMBLE, 32);
3009    tulip_mii_sendbits(sc, MII_WRCMD, 8);
3010    tulip_mii_sendbits(sc, devaddr, 5);
3011    tulip_mii_sendbits(sc, regno, 5);
3012    tulip_mii_turnaround(sc, MII_WRCMD);
3013    tulip_mii_sendbits(sc, data, 16);
3014#ifdef TULIP_DEBUG
3015    sc->tulip_dbg.dbg_phyregs[regno][2] = data;
3016    sc->tulip_dbg.dbg_phyregs[regno][3]++;
3017#endif
3018}
3019
3020#define	tulip_mchash(mca)	(tulip_crc32(mca, 6) & 0x1FF)
3021#define	tulip_srom_crcok(databuf)	( \
3022    ((tulip_crc32(databuf, 126) & 0xFFFF) ^ 0xFFFF)== \
3023     ((databuf)[126] | ((databuf)[127] << 8)))
3024
3025static unsigned
3026tulip_crc32(
3027    const unsigned char *databuf,
3028    size_t datalen)
3029{
3030    u_int idx, bit, data, crc = 0xFFFFFFFFUL;
3031
3032    for (idx = 0; idx < datalen; idx++)
3033        for (data = *databuf++, bit = 0; bit < 8; bit++, data >>= 1)
3034            crc = (crc >> 1) ^ (((crc ^ data) & 1) ? TULIP_CRC32_POLY : 0);
3035    return crc;
3036}
3037
3038static void
3039tulip_identify_smc_nic(
3040    tulip_softc_t *sc)
3041{
3042    tulip_uint32_t id1, id2, ei;
3043    int auibnc = 0, utp = 0;
3044    char *cp;
3045
3046    if (sc->tulip_chipid == TULIP_DC21041)
3047	return;
3048    if (sc->tulip_chipid == TULIP_DC21140) {
3049	sc->tulip_boardsw = &tulip_dc21140_smc9332_boardsw;
3050	return;
3051    }
3052    id1 = sc->tulip_rombuf[0x60] | (sc->tulip_rombuf[0x61] << 8);
3053    id2 = sc->tulip_rombuf[0x62] | (sc->tulip_rombuf[0x63] << 8);
3054    ei  = sc->tulip_rombuf[0x66] | (sc->tulip_rombuf[0x67] << 8);
3055
3056    strcpy(sc->tulip_boardidbuf, "SMC 8432");
3057    cp = &sc->tulip_boardidbuf[8];
3058    if ((id1 & 1) == 0)
3059	*cp++ = 'B', auibnc = 1;
3060    if ((id1 & 0xFF) > 0x32)
3061	*cp++ = 'T', utp = 1;
3062    if ((id1 & 0x4000) == 0)
3063	*cp++ = 'A', auibnc = 1;
3064    if (id2 == 0x15) {
3065	sc->tulip_boardidbuf[7] = '4';
3066	*cp++ = '-';
3067	*cp++ = 'C';
3068	*cp++ = 'H';
3069	*cp++ = (ei ? '2' : '1');
3070    }
3071    *cp++ = ' ';
3072    *cp = '\0';
3073    if (utp && !auibnc)
3074	sc->tulip_boardsw = &tulip_dc21040_10baset_only_boardsw;
3075    else if (!utp && auibnc)
3076	sc->tulip_boardsw = &tulip_dc21040_auibnc_only_boardsw;
3077}
3078
3079/*
3080 * This deals with the vagaries of the address roms and the
3081 * brain-deadness that various vendors commit in using them.
3082 */
3083static int
3084tulip_read_macaddr(
3085    tulip_softc_t *sc)
3086{
3087    int cksum, rom_cksum, idx;
3088    tulip_uint32_t csr;
3089    unsigned char tmpbuf[8];
3090    static const u_char testpat[] = { 0xFF, 0, 0x55, 0xAA, 0xFF, 0, 0x55, 0xAA };
3091
3092    if (sc->tulip_chipid == TULIP_DC21040) {
3093	TULIP_CSR_WRITE(sc, csr_enetrom, 1);
3094	for (idx = 0; idx < sizeof(sc->tulip_rombuf); idx++) {
3095	    int cnt = 0;
3096	    while (((csr = TULIP_CSR_READ(sc, csr_enetrom)) & 0x80000000L) && cnt < 10000)
3097		cnt++;
3098	    sc->tulip_rombuf[idx] = csr & 0xFF;
3099	}
3100	sc->tulip_boardsw = &tulip_dc21040_boardsw;
3101#if defined(TULIP_EISA)
3102    } else if (sc->tulip_chipid == TULIP_DE425) {
3103	int cnt;
3104	for (idx = 0, cnt = 0; idx < sizeof(testpat) && cnt < 32; cnt++) {
3105	    tmpbuf[idx] = TULIP_CSR_READBYTE(sc, csr_enetrom);
3106	    if (tmpbuf[idx] == testpat[idx])
3107		++idx;
3108	    else
3109		idx = 0;
3110	}
3111	for (idx = 0; idx < 32; idx++)
3112	    sc->tulip_rombuf[idx] = TULIP_CSR_READBYTE(sc, csr_enetrom);
3113	sc->tulip_boardsw = &tulip_dc21040_boardsw;
3114#endif /* TULIP_EISA */
3115    } else {
3116	int new_srom_fmt = 0;
3117	/*
3118	 * Thankfully all DC21041's act the same.
3119	 * Assume all DC21140 board are compatible with the
3120	 * DEC 10/100 evaluation board.  Not really valid but
3121	 * it's the best we can do until every one switches to
3122	 * the new SROM format.
3123	 */
3124	if (sc->tulip_chipid == TULIP_DC21041)
3125	    sc->tulip_boardsw = &tulip_dc21041_boardsw;
3126	else
3127	    sc->tulip_boardsw = &tulip_dc21140_eb_boardsw;
3128	tulip_read_srom(sc);
3129	if (tulip_srom_crcok(sc->tulip_rombuf)) {
3130	    /*
3131	     * SROM CRC is valid therefore it must be in the
3132	     * new format.
3133	     */
3134	    new_srom_fmt = 1;
3135	} else if (sc->tulip_rombuf[126] == 0xff && sc->tulip_rombuf[127] == 0xFF) {
3136	    /*
3137	     * No checksum is present.  See if the SROM id checks out;
3138	     * the first 18 bytes should be 0 followed by a 1 followed
3139	     * by the number of adapters (which we don't deal with yet).
3140	     */
3141	    for (idx = 0; idx < 18; idx++) {
3142		if (sc->tulip_rombuf[idx] != 0)
3143		    break;
3144	    }
3145	    if (idx == 18 && sc->tulip_rombuf[18] == 1 && sc->tulip_rombuf[19] != 0)
3146		new_srom_fmt = 2;
3147	}
3148	if (new_srom_fmt) {
3149	    int copy_name = 0;
3150	    /*
3151	     * New SROM format.  Copy out the Ethernet address.
3152	     * If it contains a DE500-XA string, then it must be
3153	     * a DE500-XA.
3154	     */
3155	    bcopy(sc->tulip_rombuf + 20, sc->tulip_hwaddr, 6);
3156	    if (bcmp(sc->tulip_rombuf + 29, "DE500-XA", 8) == 0) {
3157		sc->tulip_boardsw = &tulip_dc21140_de500xa_boardsw;
3158		copy_name = 1;
3159	    } else if (bcmp(sc->tulip_rombuf + 29, "DE500-AA", 8) == 0) {
3160		sc->tulip_boardsw = &tulip_dc21140_de500aa_boardsw;
3161		copy_name = 1;
3162	    } else if (bcmp(sc->tulip_rombuf + 29, "DE450", 5) == 0) {
3163		copy_name = 1;
3164	    }
3165	    if (copy_name) {
3166		bcopy(sc->tulip_rombuf + 29, sc->tulip_boardidbuf, 8);
3167		sc->tulip_boardidbuf[8] = ' ';
3168		sc->tulip_boardid = sc->tulip_boardidbuf;
3169	    }
3170	    if (sc->tulip_boardsw == NULL)
3171		return -6;
3172	    goto check_oui;
3173	}
3174    }
3175
3176
3177    if (bcmp(&sc->tulip_rombuf[0], &sc->tulip_rombuf[16], 8) != 0) {
3178	/*
3179	 * Some folks don't use the standard ethernet rom format
3180	 * but instead just put the address in the first 6 bytes
3181	 * of the rom and let the rest be all 0xffs.  (Can we say
3182	 * ZNYX???) (well sometimes they put in a checksum so we'll
3183	 * start at 8).
3184	 */
3185	for (idx = 8; idx < 32; idx++) {
3186	    if (sc->tulip_rombuf[idx] != 0xFF)
3187		return -4;
3188	}
3189	/*
3190	 * Make sure the address is not multicast or locally assigned
3191	 * that the OUI is not 00-00-00.
3192	 */
3193	if ((sc->tulip_rombuf[0] & 3) != 0)
3194	    return -4;
3195	if (sc->tulip_rombuf[0] == 0 && sc->tulip_rombuf[1] == 0
3196		&& sc->tulip_rombuf[2] == 0)
3197	    return -4;
3198	bcopy(sc->tulip_rombuf, sc->tulip_hwaddr, 6);
3199	sc->tulip_flags |= TULIP_ROMOK;
3200	goto check_oui;
3201    } else {
3202	/*
3203	 * A number of makers of multiport boards (ZNYX and Cogent)
3204	 * only put on one address ROM on their DC21040 boards.  So
3205	 * if the ROM is all zeros and this is a DC21040, look at the
3206	 * previous configured boards (as long as they are on the same
3207	 * PCI bus and the bus number is non-zero) until we find the
3208	 * master board with address ROM.  We then use its address ROM
3209	 * as the base for this board.  (we add our relative board
3210	 * to the last byte of its address).
3211	 */
3212	if (sc->tulip_chipid == TULIP_DC21040 /* && sc->tulip_bus != 0 XXX */) {
3213	    for (idx = 0; idx < 32; idx++) {
3214		if (sc->tulip_rombuf[idx] != 0)
3215		    break;
3216	    }
3217	    if (idx == 32) {
3218		int root_unit;
3219		tulip_softc_t *root_sc = NULL;
3220		for (root_unit = sc->tulip_unit - 1; root_unit >= 0; root_unit--) {
3221		    root_sc = TULIP_UNIT_TO_SOFTC(root_unit);
3222		    if (root_sc == NULL || (root_sc->tulip_flags & (TULIP_ROMOK|TULIP_SLAVEDROM)) == TULIP_ROMOK)
3223			break;
3224		    root_sc = NULL;
3225		}
3226		if (root_sc != NULL
3227			/* && root_sc->tulip_bus == sc->tulip_bus XXX */) {
3228		    bcopy(root_sc->tulip_hwaddr, sc->tulip_hwaddr, 6);
3229		    sc->tulip_hwaddr[5] += sc->tulip_unit - root_sc->tulip_unit;
3230		    sc->tulip_flags |= TULIP_SLAVEDROM;
3231		    if (root_sc->tulip_boardsw->bd_type == TULIP_DC21040_ZX314_MASTER) {
3232			sc->tulip_boardsw = &tulip_dc21040_zx314_slave_boardsw;
3233			/*
3234			 * Now for a truly disgusting kludge: all 4 DC21040s on
3235			 * the ZX314 share the same INTA line so the mapping
3236			 * setup by the BIOS on the PCI bridge is worthless.
3237			 * Rather than reprogramming the value in the config
3238			 * register, we will handle this internally.
3239			 */
3240			sc->tulip_slaves = root_sc->tulip_slaves;
3241			root_sc->tulip_slaves = sc;
3242			sc->tulip_flags |= TULIP_SLAVEDINTR;
3243		    }
3244		    return 0;
3245		}
3246	    }
3247	}
3248    }
3249
3250    /*
3251     * This is the standard DEC address ROM test.
3252     */
3253
3254    if (bcmp(&sc->tulip_rombuf[24], testpat, 8) != 0)
3255	return -3;
3256
3257    tmpbuf[0] = sc->tulip_rombuf[15]; tmpbuf[1] = sc->tulip_rombuf[14];
3258    tmpbuf[2] = sc->tulip_rombuf[13]; tmpbuf[3] = sc->tulip_rombuf[12];
3259    tmpbuf[4] = sc->tulip_rombuf[11]; tmpbuf[5] = sc->tulip_rombuf[10];
3260    tmpbuf[6] = sc->tulip_rombuf[9];  tmpbuf[7] = sc->tulip_rombuf[8];
3261    if (bcmp(&sc->tulip_rombuf[0], tmpbuf, 8) != 0)
3262	return -2;
3263
3264    bcopy(sc->tulip_rombuf, sc->tulip_hwaddr, 6);
3265
3266    cksum = *(u_int16_t *) &sc->tulip_hwaddr[0];
3267    cksum *= 2;
3268    if (cksum > 65535) cksum -= 65535;
3269    cksum += *(u_int16_t *) &sc->tulip_hwaddr[2];
3270    if (cksum > 65535) cksum -= 65535;
3271    cksum *= 2;
3272    if (cksum > 65535) cksum -= 65535;
3273    cksum += *(u_int16_t *) &sc->tulip_hwaddr[4];
3274    if (cksum >= 65535) cksum -= 65535;
3275
3276    rom_cksum = *(u_int16_t *) &sc->tulip_rombuf[6];
3277
3278    if (cksum != rom_cksum)
3279	return -1;
3280
3281  check_oui:
3282    /*
3283     * Check for various boards based on OUI.  Did I say braindead?
3284     */
3285   if (sc->tulip_hwaddr[0] == TULIP_OUI_COGENT_0
3286	    && sc->tulip_hwaddr[1] == TULIP_OUI_COGENT_1
3287	    && sc->tulip_hwaddr[2] == TULIP_OUI_COGENT_2) {
3288	if (sc->tulip_chipid == TULIP_DC21140 || sc->tulip_chipid == TULIP_DC21140A) {
3289	    if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100_ID)
3290		sc->tulip_boardsw = &tulip_dc21140_cogent_em100_boardsw;
3291	}
3292    } else if (sc->tulip_hwaddr[0] == TULIP_OUI_ZNYX_0
3293	    && sc->tulip_hwaddr[1] == TULIP_OUI_ZNYX_1
3294	    && sc->tulip_hwaddr[2] == TULIP_OUI_ZNYX_2) {
3295	if (sc->tulip_chipid == TULIP_DC21140 || sc->tulip_chipid == TULIP_DC21140A) {
3296	    /* this at least works for the zx342 from Znyx */
3297	    sc->tulip_boardsw = &tulip_dc21140_znyx_zx34x_boardsw;
3298	} else if (sc->tulip_chipid == TULIP_DC21040
3299	        && (sc->tulip_hwaddr[3] & ~3) == 0xF0
3300	        && (sc->tulip_hwaddr[5] & 3) == 0) {
3301	    sc->tulip_boardsw = &tulip_dc21040_zx314_master_boardsw;
3302	}
3303    } else if (sc->tulip_hwaddr[0] == TULIP_OUI_SMC_0
3304	       && sc->tulip_hwaddr[1] == TULIP_OUI_SMC_1
3305	       && sc->tulip_hwaddr[2] == TULIP_OUI_SMC_2) {
3306	tulip_identify_smc_nic(sc);
3307    }
3308
3309    if (sc->tulip_boardidbuf[0] != '\0')
3310	sc->tulip_boardid = sc->tulip_boardidbuf;
3311    else
3312	sc->tulip_boardid = sc->tulip_boardsw->bd_description;
3313    sc->tulip_flags |= TULIP_ROMOK;
3314    return 0;
3315}
3316
3317static void
3318tulip_addr_filter(
3319    tulip_softc_t * const sc)
3320{
3321    tulip_uint32_t *sp = sc->tulip_setupdata;
3322    struct ether_multistep step;
3323    struct ether_multi *enm;
3324    int i = 0;
3325
3326    sc->tulip_flags &= ~TULIP_WANTHASH;
3327    sc->tulip_flags |= TULIP_WANTSETUP;
3328    sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
3329    sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED;
3330    if (sc->tulip_ac.ac_multicnt > 14) {
3331	unsigned hash;
3332	/*
3333	 * If we have more than 14 multicasts, we have
3334	 * go into hash perfect mode (512 bit multicast
3335	 * hash and one perfect hardware).
3336	 */
3337
3338	bzero(sc->tulip_setupdata, sizeof(sc->tulip_setupdata));
3339	hash = tulip_mchash(etherbroadcastaddr);
3340	sp[hash >> 4] |= 1 << (hash & 0xF);
3341	ETHER_FIRST_MULTI(step, &sc->tulip_ac, enm);
3342	while (enm != NULL) {
3343	    hash = tulip_mchash(enm->enm_addrlo);
3344	    sp[hash >> 4] |= 1 << (hash & 0xF);
3345	    ETHER_NEXT_MULTI(step, enm);
3346	}
3347	sc->tulip_flags |= TULIP_WANTHASH;
3348	sp[39] = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[0];
3349	sp[40] = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[1];
3350	sp[41] = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[2];
3351    } else {
3352	/*
3353	 * Else can get perfect filtering for 16 addresses.
3354	 */
3355	ETHER_FIRST_MULTI(step, &sc->tulip_ac, enm);
3356	for (; enm != NULL; i++) {
3357	    *sp++ = ((u_int16_t *) enm->enm_addrlo)[0];
3358	    *sp++ = ((u_int16_t *) enm->enm_addrlo)[1];
3359	    *sp++ = ((u_int16_t *) enm->enm_addrlo)[2];
3360	    ETHER_NEXT_MULTI(step, enm);
3361	}
3362	/*
3363	 * Add the broadcast address.
3364	 */
3365	i++;
3366	*sp++ = 0xFFFF;
3367	*sp++ = 0xFFFF;
3368	*sp++ = 0xFFFF;
3369	/*
3370	 * Pad the rest with our hardware address
3371	 */
3372	for (; i < 16; i++) {
3373	    *sp++ = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[0];
3374	    *sp++ = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[1];
3375	    *sp++ = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[2];
3376	}
3377    }
3378}
3379
3380static int
3381tulip_ifioctl(
3382    struct ifnet * const ifp,
3383    ioctl_cmd_t cmd,
3384    caddr_t data)
3385{
3386    tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
3387    struct ifaddr *ifa = (struct ifaddr *)data;
3388    struct ifreq *ifr = (struct ifreq *) data;
3389    int s, error = 0;
3390
3391    s = splimp();
3392
3393    switch (cmd) {
3394	case SIOCSIFADDR: {
3395	    ifp->if_flags |= IFF_UP;
3396	    switch(ifa->ifa_addr->sa_family) {
3397#ifdef INET
3398		case AF_INET: {
3399		    tulip_init(sc);
3400		    arp_ifinit(&sc->tulip_ac, ifa);
3401		    break;
3402		}
3403#endif /* INET */
3404
3405#ifdef NS
3406		/*
3407		 * This magic copied from if_is.c; I don't use XNS,
3408		 * so I have no way of telling if this actually
3409		 * works or not.
3410		 */
3411		case AF_NS: {
3412		    struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
3413		    if (ns_nullhost(*ina)) {
3414			ina->x_host = *(union ns_host *)(sc->tulip_ac.ac_enaddr);
3415		    } else {
3416			ifp->if_flags &= ~IFF_RUNNING;
3417			bcopy((caddr_t)ina->x_host.c_host,
3418			      (caddr_t)sc->tulip_ac.ac_enaddr,
3419			      sizeof sc->tulip_ac.ac_enaddr);
3420		    }
3421		    tulip_init(sc);
3422		    break;
3423		}
3424#endif /* NS */
3425
3426		default: {
3427		    tulip_init(sc);
3428		    break;
3429		}
3430	    }
3431	    break;
3432	}
3433	case SIOCGIFADDR: {
3434	    bcopy((caddr_t) sc->tulip_ac.ac_enaddr,
3435		  (caddr_t) ((struct sockaddr *)&ifr->ifr_data)->sa_data,
3436		  6);
3437	    break;
3438	}
3439
3440	case SIOCSIFFLAGS: {
3441	    /*
3442	     * Changing the connection forces a reset.
3443	     */
3444	    if (sc->tulip_flags & TULIP_ALTPHYS) {
3445		if ((ifp->if_flags & IFF_ALTPHYS) == 0) {
3446		    sc->tulip_flags |= TULIP_NEEDRESET;
3447		}
3448	    } else {
3449		if (ifp->if_flags & IFF_ALTPHYS) {
3450		    sc->tulip_flags |= TULIP_NEEDRESET;
3451		}
3452	    }
3453	    if (sc->tulip_flags & TULIP_NEEDRESET) {
3454		sc->tulip_media = TULIP_MEDIA_UNKNOWN;
3455		sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
3456		sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_TXPROBE_OK|TULIP_WANTRXACT);
3457		tulip_reset(sc);
3458	    }
3459	    tulip_init(sc);
3460	    break;
3461	}
3462
3463	case SIOCADDMULTI:
3464	case SIOCDELMULTI: {
3465	    /*
3466	     * Update multicast listeners
3467	     */
3468	    if (cmd == SIOCADDMULTI)
3469		error = ether_addmulti(ifr, &sc->tulip_ac);
3470	    else
3471		error = ether_delmulti(ifr, &sc->tulip_ac);
3472
3473	    if (error == ENETRESET) {
3474		tulip_addr_filter(sc);		/* reset multicast filtering */
3475		tulip_init(sc);
3476		error = 0;
3477	    }
3478	    break;
3479	}
3480#if defined(SIOCSIFMTU)
3481#if !defined(ifr_mtu)
3482#define ifr_mtu ifr_metric
3483#endif
3484	case SIOCSIFMTU:
3485	    /*
3486	     * Set the interface MTU.
3487	     */
3488	    if (ifr->ifr_mtu > ETHERMTU
3489#ifdef BIG_PACKET
3490		    && sc->tulip_chipid != TULIP_DC21140
3491		    && sc->tulip_chipid != TULIP_DC21140A
3492		    && sc->tulip_chipid != TULIP_DC21041
3493#endif
3494		) {
3495		error = EINVAL;
3496		break;
3497	    }
3498	    ifp->if_mtu = ifr->ifr_mtu;
3499#ifdef BIG_PACKET
3500	    tulip_reset(sc);
3501	    tulip_init(sc);
3502#endif
3503	    break;
3504#endif /* SIOCSIFMTU */
3505
3506	default: {
3507	    error = EINVAL;
3508	    break;
3509	}
3510    }
3511
3512    splx(s);
3513    return error;
3514}
3515
3516static void
3517tulip_ifwatchdog(
3518    struct ifnet *ifp)
3519{
3520    tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
3521
3522#if defined(TULIP_DEBUG)
3523    tulip_uint32_t rxintrs = sc->tulip_dbg.dbg_rxintrs - sc->tulip_dbg.dbg_last_rxintrs;
3524    if (rxintrs > sc->tulip_dbg.dbg_high_rxintrs_hz)
3525	sc->tulip_dbg.dbg_high_rxintrs_hz = rxintrs;
3526    sc->tulip_dbg.dbg_last_rxintrs = sc->tulip_dbg.dbg_rxintrs;
3527    sc->tulip_dbg.dbg_gpintrs_hz = sc->tulip_dbg.dbg_gpintrs;
3528    sc->tulip_dbg.dbg_gpintrs = 0;
3529#endif /* TULIP_DEBUG */
3530
3531    sc->tulip_if.if_timer = 1;
3532    /*
3533     * These should be rare so do a bulk test up front so we can just skip
3534     * them if needed.
3535     */
3536    if (sc->tulip_flags & (TULIP_SYSTEMERROR|TULIP_RXBUFSLOW|TULIP_FAKEGPTIMEOUT|TULIP_NOMESSAGES)) {
3537	/*
3538	 * This for those devices that need to autosense.  Interrupts are not
3539	 * allowed during device probe so we fake one here to start the
3540	 * autosense.  Do this before the others since it can effect their
3541	 * state.
3542	 */
3543	if (sc->tulip_flags & TULIP_FAKEGPTIMEOUT)
3544	    (*sc->tulip_boardsw->bd_media_select)(sc);
3545
3546	/*
3547	 * If the number of receive buffer is low, try to refill
3548	 */
3549	if (sc->tulip_flags & TULIP_RXBUFSLOW)
3550	    tulip_rx_intr(sc);
3551
3552	if (sc->tulip_flags & TULIP_SYSTEMERROR) {
3553	    printf(TULIP_PRINTF_FMT ": %d system errors: last was %s\n",
3554		   TULIP_PRINTF_ARGS, sc->tulip_system_errors,
3555		   tulip_system_errors[sc->tulip_last_system_error]);
3556	}
3557	if (sc->tulip_statusbits) {
3558	    tulip_print_abnormal_interrupt(sc, sc->tulip_statusbits);
3559	    sc->tulip_statusbits = 0;
3560	}
3561
3562	sc->tulip_flags &= ~(TULIP_NOMESSAGES|TULIP_SYSTEMERROR);
3563    }
3564
3565    if (sc->tulip_txtimer && --sc->tulip_txtimer == 0) {
3566	printf(TULIP_PRINTF_FMT ": transmission timeout\n", TULIP_PRINTF_ARGS);
3567	sc->tulip_media = TULIP_MEDIA_UNKNOWN;
3568	sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
3569	sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_TXPROBE_OK|TULIP_WANTRXACT|TULIP_LINKUP|TULIP_LINKSUSPECT);
3570	tulip_reset(sc);
3571	tulip_init(sc);
3572    }
3573}
3574#if defined(__bsdi__) || (defined(__FreeBSD__) && BSD < 199506)
3575static ifnet_ret_t
3576tulip_ifwatchdog_wrapper(
3577    int unit)
3578{
3579    tulip_ifwatchdog(&TULIP_UNIT_TO_SOFTC(unit)->tulip_if);
3580}
3581#define	tulip_ifwatchdog	tulip_ifwatchdog_wrapper
3582#endif
3583
3584/*
3585 * All printf's are real as of now!
3586 */
3587#ifdef printf
3588#undef printf
3589#endif
3590#if !defined(IFF_NOTRAILERS)
3591#define IFF_NOTRAILERS		0
3592#endif
3593
3594static void
3595tulip_attach(
3596    tulip_softc_t * const sc)
3597{
3598    struct ifnet * const ifp = &sc->tulip_if;
3599
3600    ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST;
3601    ifp->if_ioctl = tulip_ifioctl;
3602    ifp->if_start = tulip_ifstart;
3603    ifp->if_watchdog = tulip_ifwatchdog;
3604    ifp->if_timer = 1;
3605#if !defined(__bsdi__) || _BSDI_VERSION < 199401
3606    ifp->if_output = ether_output;
3607#endif
3608#if defined(__bsdi__) && _BSDI_VERSION < 199401
3609    ifp->if_mtu = ETHERMTU;
3610#endif
3611
3612#if defined(__bsdi__) && _BSDI_VERSION >= 199510
3613    aprint_naive(": DEC Ethernet");
3614    aprint_normal(": %s%s", sc->tulip_boardid,
3615        tulip_chipdescs[sc->tulip_chipid]);
3616    aprint_verbose(" pass %d.%d", (sc->tulip_revinfo & 0xF0) >> 4,
3617        sc->tulip_revinfo & 0x0F);
3618    printf("\n");
3619    sc->tulip_pf = aprint_normal;
3620    aprint_normal(TULIP_PRINTF_FMT ": address " TULIP_EADDR_FMT "\n",
3621		  TULIP_PRINTF_ARGS,
3622		  TULIP_EADDR_ARGS(sc->tulip_hwaddr));
3623#else
3624    printf(
3625#if defined(__bsdi__)
3626	   "\n"
3627#endif
3628	   TULIP_PRINTF_FMT ": %s%s pass %d.%d\n",
3629	   TULIP_PRINTF_ARGS,
3630	   sc->tulip_boardid,
3631	   tulip_chipdescs[sc->tulip_chipid],
3632	   (sc->tulip_revinfo & 0xF0) >> 4,
3633	   sc->tulip_revinfo & 0x0F);
3634    printf(TULIP_PRINTF_FMT ": address " TULIP_EADDR_FMT "\n",
3635	   TULIP_PRINTF_ARGS,
3636	   TULIP_EADDR_ARGS(sc->tulip_hwaddr));
3637#endif
3638
3639
3640    if (sc->tulip_boardsw->bd_mii_probe != NULL)
3641	(*sc->tulip_boardsw->bd_mii_probe)(sc);
3642
3643    if ((*sc->tulip_boardsw->bd_media_probe)(sc)) {
3644	ifp->if_flags |= IFF_ALTPHYS;
3645    } else {
3646	sc->tulip_flags |= TULIP_ALTPHYS;
3647    }
3648
3649    sc->tulip_flags |= TULIP_DEVICEPROBE;
3650    tulip_reset(sc);
3651    sc->tulip_flags &= ~TULIP_DEVICEPROBE;
3652
3653#if defined(__bsdi__) && _BSDI_VERSION >= 199510
3654    sc->tulip_pf = printf;
3655    ether_attach(ifp);
3656#else
3657    if_attach(ifp);
3658#if defined(__NetBSD__) || (defined(__FreeBSD__) && BSD >= 199506)
3659    ether_ifattach(ifp);
3660#endif
3661#endif /* __bsdi__ */
3662
3663#if NBPFILTER > 0
3664    TULIP_BPF_ATTACH(sc);
3665#endif
3666}
3667
3668static void
3669tulip_initcsrs(
3670    tulip_softc_t * const sc,
3671    tulip_csrptr_t csr_base,
3672    size_t csr_size)
3673{
3674    sc->tulip_csrs.csr_busmode		= csr_base +  0 * csr_size;
3675    sc->tulip_csrs.csr_txpoll		= csr_base +  1 * csr_size;
3676    sc->tulip_csrs.csr_rxpoll		= csr_base +  2 * csr_size;
3677    sc->tulip_csrs.csr_rxlist		= csr_base +  3 * csr_size;
3678    sc->tulip_csrs.csr_txlist		= csr_base +  4 * csr_size;
3679    sc->tulip_csrs.csr_status		= csr_base +  5 * csr_size;
3680    sc->tulip_csrs.csr_command		= csr_base +  6 * csr_size;
3681    sc->tulip_csrs.csr_intr		= csr_base +  7 * csr_size;
3682    sc->tulip_csrs.csr_missed_frames	= csr_base +  8 * csr_size;
3683    if (sc->tulip_chipid == TULIP_DC21040) {
3684	sc->tulip_csrs.csr_enetrom		= csr_base +  9 * csr_size;
3685	sc->tulip_csrs.csr_reserved		= csr_base + 10 * csr_size;
3686	sc->tulip_csrs.csr_full_duplex		= csr_base + 11 * csr_size;
3687	sc->tulip_csrs.csr_sia_status		= csr_base + 12 * csr_size;
3688	sc->tulip_csrs.csr_sia_connectivity	= csr_base + 13 * csr_size;
3689	sc->tulip_csrs.csr_sia_tx_rx 		= csr_base + 14 * csr_size;
3690	sc->tulip_csrs.csr_sia_general		= csr_base + 15 * csr_size;
3691#if defined(TULIP_EISA)
3692    } else if (sc->tulip_chipid == TULIP_DE425) {
3693	sc->tulip_csrs.csr_enetrom		= csr_base + DE425_ENETROM_OFFSET;
3694	sc->tulip_csrs.csr_reserved		= csr_base + 10 * csr_size;
3695	sc->tulip_csrs.csr_full_duplex		= csr_base + 11 * csr_size;
3696	sc->tulip_csrs.csr_sia_status		= csr_base + 12 * csr_size;
3697	sc->tulip_csrs.csr_sia_connectivity	= csr_base + 13 * csr_size;
3698	sc->tulip_csrs.csr_sia_tx_rx 		= csr_base + 14 * csr_size;
3699	sc->tulip_csrs.csr_sia_general		= csr_base + 15 * csr_size;
3700#endif /* TULIP_EISA */
3701    } else if (sc->tulip_chipid == TULIP_DC21140 || sc->tulip_chipid == TULIP_DC21140A) {
3702	sc->tulip_csrs.csr_srom_mii		= csr_base +  9 * csr_size;
3703	sc->tulip_csrs.csr_gp_timer		= csr_base + 11 * csr_size;
3704	sc->tulip_csrs.csr_gp			= csr_base + 12 * csr_size;
3705	sc->tulip_csrs.csr_watchdog		= csr_base + 15 * csr_size;
3706    } else if (sc->tulip_chipid == TULIP_DC21041) {
3707	sc->tulip_csrs.csr_srom_mii		= csr_base +  9 * csr_size;
3708	sc->tulip_csrs.csr_bootrom		= csr_base + 10 * csr_size;
3709	sc->tulip_csrs.csr_gp_timer		= csr_base + 11 * csr_size;
3710	sc->tulip_csrs.csr_sia_status		= csr_base + 12 * csr_size;
3711	sc->tulip_csrs.csr_sia_connectivity	= csr_base + 13 * csr_size;
3712	sc->tulip_csrs.csr_sia_tx_rx 		= csr_base + 14 * csr_size;
3713	sc->tulip_csrs.csr_sia_general		= csr_base + 15 * csr_size;
3714    }
3715}
3716
3717static void
3718tulip_initring(
3719    tulip_softc_t * const sc,
3720    tulip_ringinfo_t * const ri,
3721    tulip_desc_t *descs,
3722    int ndescs)
3723{
3724    ri->ri_max = ndescs;
3725    ri->ri_first = descs;
3726    ri->ri_last = ri->ri_first + ri->ri_max;
3727    bzero((caddr_t) ri->ri_first, sizeof(ri->ri_first[0]) * ri->ri_max);
3728    ri->ri_last[-1].d_flag = TULIP_DFLAG_ENDRING;
3729}
3730
3731/*
3732 * This is the PCI configuration support.  Since the DC21040 is available
3733 * on both EISA and PCI boards, one must be careful in how defines the
3734 * DC21040 in the config file.
3735 */
3736
3737#define	PCI_CFID	0x00	/* Configuration ID */
3738#define	PCI_CFCS	0x04	/* Configurtion Command/Status */
3739#define	PCI_CFRV	0x08	/* Configuration Revision */
3740#define	PCI_CFLT	0x0c	/* Configuration Latency Timer */
3741#define	PCI_CBIO	0x10	/* Configuration Base IO Address */
3742#define	PCI_CBMA	0x14	/* Configuration Base Memory Address */
3743#define	PCI_CFIT	0x3c	/* Configuration Interrupt */
3744#define	PCI_CFDA	0x40	/* Configuration Driver Area */
3745
3746#if defined(TULIP_EISA)
3747static const int tulip_eisa_irqs[4] = { IRQ5, IRQ9, IRQ10, IRQ11 };
3748#endif
3749
3750#if defined(__FreeBSD__)
3751
3752#define	TULIP_PCI_ATTACH_ARGS	pcici_t config_id, int unit
3753
3754static int
3755tulip_pci_shutdown(
3756    struct kern_devconf * const kdc,
3757    int force)
3758{
3759    if (kdc->kdc_unit < tulip_count) {
3760	tulip_softc_t * const sc = TULIP_UNIT_TO_SOFTC(kdc->kdc_unit);
3761	TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
3762	DELAY(10);	/* Wait 10 microseconds (actually 50 PCI cycles but at
3763			   33MHz that comes to two microseconds but wait a
3764			   bit longer anyways) */
3765    }
3766    (void) dev_detach(kdc);
3767    return 0;
3768}
3769
3770static char*
3771tulip_pci_probe(
3772    pcici_t config_id,
3773    pcidi_t device_id)
3774{
3775    if (PCI_VENDORID(device_id) != DEC_VENDORID)
3776	return NULL;
3777    if (PCI_CHIPID(device_id) == DC21040_CHIPID)
3778	return "Digital DC21040 Ethernet";
3779    if (PCI_CHIPID(device_id) == DC21041_CHIPID)
3780	return "Digital DC21041 Ethernet";
3781    if (PCI_CHIPID(device_id) == DC21140_CHIPID) {
3782	tulip_uint32_t revinfo = pci_conf_read(config_id, PCI_CFRV) & 0xFF;
3783	if (revinfo >= 0x20)
3784	    return "Digital DC21140A Fast Ethernet";
3785	else
3786	    return "Digital DC21140 Fast Ethernet";
3787
3788    }
3789    return NULL;
3790}
3791
3792static void  tulip_pci_attach(TULIP_PCI_ATTACH_ARGS);
3793static u_long tulip_pci_count;
3794
3795struct pci_device dedevice = {
3796    "de",
3797    tulip_pci_probe,
3798    tulip_pci_attach,
3799   &tulip_pci_count,
3800    tulip_pci_shutdown,
3801};
3802
3803DATA_SET (pcidevice_set, dedevice);
3804#endif /* __FreeBSD__ */
3805
3806#if defined(__bsdi__)
3807#define	TULIP_PCI_ATTACH_ARGS	struct device * const parent, struct device * const self, void * const aux
3808
3809static void
3810tulip_shutdown(
3811    void *arg)
3812{
3813    tulip_softc_t * const sc = (tulip_softc_t *) arg;
3814    TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
3815    DELAY(10);	/* Wait 10 microseconds (actually 50 PCI cycles but at
3816			   33MHz that comes to two microseconds but wait a
3817			   bit longer anyways) */
3818}
3819
3820static int
3821tulip_pci_match(
3822    pci_devaddr_t *pa)
3823{
3824    int irq;
3825    unsigned id;
3826
3827    id = pci_inl(pa, PCI_VENDOR_ID);
3828    if (PCI_VENDORID(id) != DEC_VENDORID)
3829	return 0;
3830    id = PCI_CHIPID(id);
3831    if (id != DC21040_CHIPID && id != DC21041_CHIPID && id != DC21140_CHIPID)
3832	return 0;
3833    irq = pci_inl(pa, PCI_I_LINE) & 0xFF;
3834    if (irq == 0 || irq >= 16) {
3835	printf("de?: invalid IRQ %d; skipping\n", irq);
3836	return 0;
3837    }
3838    return 1;
3839}
3840
3841static int
3842tulip_probe(
3843    struct device *parent,
3844    struct cfdata *cf,
3845    void *aux)
3846{
3847    struct isa_attach_args * const ia = (struct isa_attach_args *) aux;
3848    unsigned irq, slot;
3849    pci_devaddr_t *pa;
3850
3851#if _BSDI_VERSION >= 199401
3852    switch (ia->ia_bustype) {
3853    case BUS_PCI:
3854#endif
3855	pa = pci_scan(tulip_pci_match);
3856	if (pa == NULL)
3857	    return 0;
3858
3859	irq = (1 << (pci_inl(pa, PCI_I_LINE) & 0xFF));
3860
3861	/* Get the base address; assume the BIOS set it up correctly */
3862#if defined(TULIP_IOMAPPED)
3863	ia->ia_maddr = NULL;
3864	ia->ia_msize = 0;
3865	ia->ia_iobase = pci_inl(pa, PCI_CBIO) & ~7;
3866	pci_outl(pa, PCI_CBIO, 0xFFFFFFFF);
3867	ia->ia_iosize = ((~pci_inl(pa, PCI_CBIO)) | 7) + 1;
3868	pci_outl(pa, PCI_CBIO, (int) ia->ia_iobase);
3869
3870	/* Disable memory space access */
3871	pci_outl(pa, PCI_COMMAND, pci_inl(pa, PCI_COMMAND) & ~2);
3872#else
3873	ia->ia_maddr = (caddr_t) (pci_inl(pa, PCI_CBMA) & ~7);
3874	pci_outl(pa, PCI_CBMA, 0xFFFFFFFF);
3875	ia->ia_msize = ((~pci_inl(pa, PCI_CBMA)) | 7) + 1;
3876	pci_outl(pa, PCI_CBMA, (int) ia->ia_maddr);
3877	ia->ia_iobase = 0;
3878	ia->ia_iosize = 0;
3879
3880	/* Disable I/O space access */
3881	pci_outl(pa, PCI_COMMAND, pci_inl(pa, PCI_COMMAND) & ~1);
3882#endif /* TULIP_IOMAPPED */
3883
3884	ia->ia_aux = (void *) pa;
3885#if _BSDI_VERSION >= 199401
3886	break;
3887
3888#if defined(TULIP_EISA)
3889    case BUS_EISA: {
3890	unsigned tmp;
3891
3892	if ((slot = eisa_match(cf, ia)) == 0)
3893	    return 0;
3894	ia->ia_iobase = slot << 12;
3895	ia->ia_iosize = EISA_NPORT;
3896	eisa_slotalloc(slot);
3897	tmp = inb(ia->ia_iobase + DE425_CFG0);
3898	irq = tulip_eisa_irqs[(tmp >> 1) & 0x03];
3899	/*
3900	 * Until BSD/OS likes level interrupts, force
3901	 * the DE425 into edge-triggered mode.
3902	 */
3903	if ((tmp & 1) == 0)
3904	    outb(ia->ia_iobase + DE425_CFG0, tmp | 1);
3905	/*
3906	 * CBIO needs to map to the EISA slot
3907	 * enable I/O access and Master
3908	 */
3909	outl(ia->ia_iobase + DE425_CBIO, ia->ia_iobase);
3910	outl(ia->ia_iobase + DE425_CFCS, 5 | inl(ia->ia_iobase + DE425_CFCS));
3911	ia->ia_aux = NULL;
3912	break;
3913    }
3914#endif /* TULIP_EISA */
3915    default:
3916	return 0;
3917    }
3918#endif
3919
3920    /* PCI bus masters don't use host DMA channels */
3921    ia->ia_drq = DRQNONE;
3922
3923    if (ia->ia_irq != IRQUNK && irq != ia->ia_irq) {
3924	printf("de%d: error: desired IRQ of %d does not match device's "
3925	    "actual IRQ of %d,\n",
3926	       cf->cf_unit,
3927	       ffs(ia->ia_irq) - 1, ffs(irq) - 1);
3928	return 0;
3929    }
3930    if (ia->ia_irq == IRQUNK)
3931	ia->ia_irq = irq;
3932#ifdef IRQSHARE
3933    ia->ia_irq |= IRQSHARE;
3934#endif
3935    return 1;
3936}
3937
3938static void tulip_pci_attach(TULIP_PCI_ATTACH_ARGS);
3939
3940#if defined(TULIP_EISA)
3941static char *tulip_eisa_ids[] = {
3942    "DEC4250",
3943    NULL
3944};
3945#endif
3946
3947struct cfdriver decd = {
3948    0, "de", tulip_probe, tulip_pci_attach,
3949#if _BSDI_VERSION >= 199401
3950    DV_IFNET,
3951#endif
3952    sizeof(tulip_softc_t),
3953#if defined(TULIP_EISA)
3954    tulip_eisa_ids
3955#endif
3956};
3957
3958#endif /* __bsdi__ */
3959
3960#if defined(__NetBSD__)
3961#define	TULIP_PCI_ATTACH_ARGS	struct device * const parent, struct device * const self, void * const aux
3962
3963static void
3964tulip_pci_shutdown(
3965    void *arg)
3966{
3967    tulip_softc_t * const sc = (tulip_softc_t *) arg;
3968    TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
3969    DELAY(10);	/* Wait 10 microseconds (actually 50 PCI cycles but at
3970			   33MHz that comes to two microseconds but wait a
3971			   bit longer anyways) */
3972}
3973
3974static int
3975tulip_pci_probe(
3976    struct device *parent,
3977    void *match,
3978    void *aux)
3979{
3980    struct pci_attach_args *pa = (struct pci_attach_args *) aux;
3981
3982    if (PCI_VENDORID(pa->pa_id) != DEC_VENDORID)
3983	return 0;
3984    if (PCI_CHIPID(pa->pa_id) == DC21040_CHIPID
3985	    || PCI_CHIPID(pa->pa_id) == DC21041_CHIPID
3986	    || PCI_CHIPID(pa->pa_id) == DC21140_CHIPID)
3987	return 1;
3988
3989    return 0;
3990}
3991
3992static void tulip_pci_attach(TULIP_PCI_ATTACH_ARGS);
3993
3994struct cfattach de_ca = {
3995    sizeof(tulip_softc_t), tulip_pci_probe, tulip_pci_attach
3996};
3997
3998struct cfdriver de_cd = {
3999    0, "de", DV_IFNET
4000};
4001
4002#endif /* __NetBSD__ */
4003
4004static void
4005tulip_pci_attach(
4006    TULIP_PCI_ATTACH_ARGS)
4007{
4008#if defined(__FreeBSD__)
4009    tulip_softc_t *sc;
4010#define	PCI_CONF_WRITE(r, v)	pci_conf_write(config_id, (r), (v))
4011#define	PCI_CONF_READ(r)	pci_conf_read(config_id, (r))
4012#endif
4013#if defined(__bsdi__)
4014    tulip_softc_t * const sc = (tulip_softc_t *) self;
4015    struct isa_attach_args * const ia = (struct isa_attach_args *) aux;
4016    pci_devaddr_t *pa = (pci_devaddr_t *) ia->ia_aux;
4017    const int unit = sc->tulip_dev.dv_unit;
4018#define	PCI_CONF_WRITE(r, v)	pci_outl(pa, (r), (v))
4019#define	PCI_CONF_READ(r)	pci_inl(pa, (r))
4020#endif
4021#if defined(__NetBSD__)
4022    tulip_softc_t * const sc = (tulip_softc_t *) self;
4023    struct pci_attach_args * const pa = (struct pci_attach_args *) aux;
4024    const int unit = sc->tulip_dev.dv_unit;
4025#if defined(TULIP_IOMAPPED)
4026    bus_io_addr_t iobase;
4027    bus_io_size_t iosize;
4028#else
4029    bus_mem_addr_t membase;
4030    bus_mem_size_t memsize;
4031#endif
4032#define	PCI_CONF_WRITE(r, v)	pci_conf_write(pa->pa_pc, pa->pa_tag, (r), (v))
4033#define	PCI_CONF_READ(r)	pci_conf_read(pa->pa_pc, pa->pa_tag, (r))
4034#endif /* __NetBSD__ */
4035    int retval, idx;
4036    tulip_uint32_t revinfo, cfdainfo, id;
4037#if !defined(TULIP_IOMAPPED) && defined(__FreeBSD__)
4038    vm_offset_t pa_csrs;
4039#endif
4040    unsigned csroffset = TULIP_PCI_CSROFFSET;
4041    unsigned csrsize = TULIP_PCI_CSRSIZE;
4042    tulip_csrptr_t csr_base;
4043    tulip_chipid_t chipid = TULIP_CHIPID_UNKNOWN;
4044
4045#if defined(__FreeBSD__)
4046    if (unit >= tulip_count) {
4047	tulip_softc_t **new_tulips =
4048	    (tulip_softc_t **) malloc((tulip_count + TULIP_COUNTINCR) * sizeof(tulip_softc_t *), M_DEVBUF, M_WAITOK);
4049	if (new_tulips == NULL) {
4050	    printf("de%d: not configured; can't allocate memory\n", unit);
4051	    return;
4052	}
4053	if (tulips != NULL) {
4054	    bcopy(tulips, new_tulips, tulip_count * sizeof(tulips[0]));
4055	    free(tulips, M_DEVBUF);
4056	}
4057	bzero(&new_tulips[tulip_count], TULIP_COUNTINCR * sizeof(new_tulips[0]));
4058	tulip_count += TULIP_COUNTINCR;
4059	tulips = new_tulips;
4060    }
4061#endif
4062
4063#if defined(__bsdi__)
4064    if (pa != NULL) {
4065	revinfo = pci_inl(pa, PCI_CFRV) & 0xFF;
4066	id = pci_inl(pa, PCI_CFID);
4067	cfdainfo = pci_inl(pa, PCI_CFDA);
4068#if defined(TULIP_EISA)
4069    } else {
4070	revinfo = inl(ia->ia_iobase + DE425_CFRV) & 0xFF;
4071	csroffset = TULIP_EISA_CSROFFSET;
4072	csrsize = TULIP_EISA_CSRSIZE;
4073	chipid = TULIP_DE425;
4074	cfdainfo = 0;
4075#endif
4076    }
4077#else /* __bsdi__ */
4078    revinfo  = PCI_CONF_READ(PCI_CFRV) & 0xFF;
4079    id       = PCI_CONF_READ(PCI_CFID);
4080    cfdainfo = PCI_CONF_READ(PCI_CFDA);
4081#endif
4082
4083    if (PCI_VENDORID(id) == DEC_VENDORID) {
4084	if (PCI_CHIPID(id) == DC21040_CHIPID) chipid = TULIP_DC21040;
4085	else if (PCI_CHIPID(id) == DC21140_CHIPID) {
4086	    chipid = (revinfo >= 0x20) ? TULIP_DC21140A : TULIP_DC21140;
4087	}
4088	else if (PCI_CHIPID(id) == DC21041_CHIPID) chipid = TULIP_DC21041;
4089    }
4090    if (chipid == TULIP_CHIPID_UNKNOWN)
4091	return;
4092
4093    if ((chipid == TULIP_DC21040 || chipid == TULIP_DE425) && revinfo < 0x20) {
4094#ifdef __FreeBSD__
4095	printf("de%d", unit);
4096#endif
4097	printf(": not configured; DC21040 pass 2.0 required (%d.%d found)\n",
4098	       revinfo >> 4, revinfo & 0x0f);
4099	return;
4100    } else if (chipid == TULIP_DC21140 && revinfo < 0x11) {
4101#ifndef __FreeBSD__
4102	printf("\n");
4103#endif
4104	printf("de%d: not configured; DC21140 pass 1.1 required (%d.%d found)\n",
4105	       unit, revinfo >> 4, revinfo & 0x0f);
4106	return;
4107    }
4108
4109    if ((chipid == TULIP_DC21041 || chipid == TULIP_DC21140A)
4110	&& (cfdainfo & (TULIP_CFDA_SLEEP|TULIP_CFDA_SNOOZE))) {
4111	cfdainfo &= ~(TULIP_CFDA_SLEEP|TULIP_CFDA_SNOOZE);
4112	PCI_CONF_WRITE(PCI_CFDA, cfdainfo);
4113	printf("de%d: waking device from sleep/snooze mode\n", unit);
4114	DELAY(11*1000);
4115    }
4116
4117
4118#if defined(__FreeBSD__)
4119    sc = (tulip_softc_t *) malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
4120    if (sc == NULL)
4121	return;
4122    bzero(sc, sizeof(*sc));				/* Zero out the softc*/
4123#endif
4124
4125    sc->tulip_chipid = chipid;
4126#if defined(__NetBSD__)
4127    bcopy(self->dv_xname, sc->tulip_if.if_xname, IFNAMSIZ);
4128    sc->tulip_if.if_softc = sc;
4129    sc->tulip_bc = pa->pa_bc;
4130    sc->tulip_pc = pa->pa_pc;
4131#else
4132    sc->tulip_unit = unit;
4133    sc->tulip_name = "de";
4134#endif
4135    sc->tulip_revinfo = revinfo;
4136#if defined(__FreeBSD__)
4137#if BSD >= 199506
4138    sc->tulip_if.if_softc = sc;
4139#endif
4140#if defined(TULIP_IOMAPPED)
4141    retval = pci_map_port(config_id, PCI_CBIO, &csr_base);
4142#else
4143    retval = pci_map_mem(config_id, PCI_CBMA, (vm_offset_t *) &csr_base, &pa_csrs);
4144#endif
4145    if (!retval) {
4146	free((caddr_t) sc, M_DEVBUF);
4147	return;
4148    }
4149    tulips[unit] = sc;
4150#endif /* __FreeBSD__ */
4151
4152#if defined(__bsdi__)
4153#if defined(TULIP_IOMAPPED)
4154    csr_base = ia->ia_iobase;
4155#else
4156    csr_base = (vm_offset_t) mapphys((vm_offset_t) ia->ia_maddr, ia->ia_msize);
4157#endif
4158#endif /* __bsdi__ */
4159
4160#if defined(__NetBSD__)
4161    csr_base = 0;
4162#if defined(TULIP_IOMAPPED)
4163    if (pci_io_find(pa->pa_pc, pa->pa_tag, PCI_CBIO, &iobase, &iosize)
4164	|| bus_io_map(pa->pa_bc, iobase, iosize, &sc->tulip_ioh))
4165	return;
4166#else
4167    if (pci_mem_find(pa->pa_pc, pa->pa_tag, PCI_CBMA, &membase, &memsize, NULL)
4168	|| bus_mem_map(pa->pa_bc, membase, memsize, 0, &sc->tulip_memh))
4169	return;
4170#endif
4171#endif /* __NetBSD__ */
4172
4173    tulip_initcsrs(sc, csr_base + csroffset, csrsize);
4174    tulip_initring(sc, &sc->tulip_rxinfo, sc->tulip_rxdescs, TULIP_RXDESCS);
4175    tulip_initring(sc, &sc->tulip_txinfo, sc->tulip_txdescs, TULIP_TXDESCS);
4176    if ((retval = tulip_read_macaddr(sc)) < 0) {
4177#ifdef __FreeBSD__
4178	printf(TULIP_PRINTF_FMT, TULIP_PRINTF_ARGS);
4179#endif
4180	printf(": can't read ENET ROM (why=%d) (", retval);
4181	for (idx = 0; idx < 32; idx++)
4182	    printf("%02x", sc->tulip_rombuf[idx]);
4183	printf("\n");
4184	printf(TULIP_PRINTF_FMT ": %s%s pass %d.%d\n",
4185	       TULIP_PRINTF_ARGS,
4186	       (sc->tulip_boardid != NULL ? sc->tulip_boardid : ""),
4187	       tulip_chipdescs[sc->tulip_chipid],
4188	       (sc->tulip_revinfo & 0xF0) >> 4, sc->tulip_revinfo & 0x0F);
4189	printf(TULIP_PRINTF_FMT ": address unknown\n", TULIP_PRINTF_ARGS);
4190    } else {
4191	int s;
4192	/*
4193	 * Make sure there won't be any interrupts or such...
4194	 */
4195	TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
4196	DELAY(10);	/* Wait 10 microseconds (actually 50 PCI cycles but at
4197			   33MHz that comes to two microseconds but wait a
4198			   bit longer anyways) */
4199#if defined(__NetBSD__)
4200	if ((sc->tulip_flags & TULIP_SLAVEDINTR) == 0) {
4201	    pci_intr_handle_t intrhandle;
4202	    const char *intrstr;
4203
4204	    if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
4205			     pa->pa_intrline, &intrhandle)) {
4206		printf(": couldn't map interrupt\n");
4207		return;
4208	    }
4209	    intrstr = pci_intr_string(pa->pa_pc, intrhandle);
4210	    sc->tulip_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_NET,
4211					     tulip_intr, sc);
4212	    if (sc->tulip_ih == NULL)
4213		printf(": couldn't establish interrupt");
4214	    if (intrstr != NULL)
4215		printf(" at %s", intrstr);
4216	    printf("\n");
4217	    if (sc->tulip_ih == NULL)
4218		return;
4219	}
4220	sc->tulip_ats = shutdownhook_establish(tulip_pci_shutdown, sc);
4221	if (sc->tulip_ats == NULL)
4222	    printf("\n%s: warning: couldn't establish shutdown hook\n",
4223		   sc->tulip_xname);
4224#endif
4225#if defined(__FreeBSD__)
4226	if ((sc->tulip_flags & TULIP_SLAVEDINTR) == 0) {
4227	    if (!pci_map_int (config_id, tulip_intr, (void*) sc, &net_imask)) {
4228		printf(TULIP_PRINTF_FMT ": couldn't map interrupt\n",
4229		       TULIP_PRINTF_ARGS);
4230		return;
4231	    }
4232	}
4233#endif
4234#if defined(__bsdi__)
4235	if ((sc->tulip_flags & TULIP_SLAVEDINTR) == 0) {
4236	    isa_establish(&sc->tulip_id, &sc->tulip_dev);
4237
4238	    sc->tulip_ih.ih_fun = tulip_intr;
4239	    sc->tulip_ih.ih_arg = (void *)sc;
4240	    intr_establish(ia->ia_irq, &sc->tulip_ih, DV_NET);
4241	}
4242
4243	sc->tulip_ats.func = tulip_shutdown;
4244	sc->tulip_ats.arg = (void *) sc;
4245	atshutdown(&sc->tulip_ats, ATSH_ADD);
4246#endif
4247	s = splimp();
4248	tulip_reset(sc);
4249	tulip_attach(sc);
4250	splx(s);
4251    }
4252}
4253
4254