xref: /openbsd/sys/dev/pci/if_dc_pci.c (revision 4cfece93)
1 /*	$OpenBSD: if_dc_pci.c,v 1.76 2017/04/11 14:43:49 dhill Exp $	*/
2 
3 /*
4  * Copyright (c) 1997, 1998, 1999
5  *	Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Bill Paul.
18  * 4. Neither the name of the author nor the names of any co-contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32  * THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * $FreeBSD: src/sys/pci/if_dc.c,v 1.5 2000/01/12 22:24:05 wpaul Exp $
35  */
36 
37 #include "bpfilter.h"
38 
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/mbuf.h>
42 #include <sys/protosw.h>
43 #include <sys/socket.h>
44 #include <sys/ioctl.h>
45 #include <sys/errno.h>
46 #include <sys/timeout.h>
47 #include <sys/malloc.h>
48 #include <sys/kernel.h>
49 #include <sys/device.h>
50 
51 #include <net/if.h>
52 
53 #include <netinet/in.h>
54 #include <netinet/if_ether.h>
55 
56 #include <net/if_media.h>
57 
58 #if NBPFILTER > 0
59 #include <net/bpf.h>
60 #endif
61 
62 #include <dev/mii/miivar.h>
63 
64 #include <dev/pci/pcireg.h>
65 #include <dev/pci/pcivar.h>
66 #include <dev/pci/pcidevs.h>
67 
68 #ifdef __sparc64__
69 #include <dev/ofw/openfirm.h>
70 #endif
71 
72 #ifndef __hppa__
73 #define DC_USEIOSPACE
74 #endif
75 
76 #include <dev/ic/dcreg.h>
77 
78 /*
79  * Various supported device vendors/types and their names.
80  */
81 struct dc_type dc_devs[] = {
82 	{ PCI_VENDOR_DEC, PCI_PRODUCT_DEC_21140 },
83 	{ PCI_VENDOR_DEC, PCI_PRODUCT_DEC_21142 },
84 	{ PCI_VENDOR_DAVICOM, PCI_PRODUCT_DAVICOM_DM9009 },
85 	{ PCI_VENDOR_DAVICOM, PCI_PRODUCT_DAVICOM_DM9100 },
86 	{ PCI_VENDOR_DAVICOM, PCI_PRODUCT_DAVICOM_DM9102 },
87 	{ PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_ADM9511 },
88 	{ PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_ADM9513 },
89 	{ PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_AL981 },
90 	{ PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_AN983 },
91 	{ PCI_VENDOR_ASIX, PCI_PRODUCT_ASIX_AX88140A },
92 	{ PCI_VENDOR_MACRONIX, PCI_PRODUCT_MACRONIX_MX98713 },
93 	{ PCI_VENDOR_MACRONIX, PCI_PRODUCT_MACRONIX_MX98715 },
94 	{ PCI_VENDOR_MACRONIX, PCI_PRODUCT_MACRONIX_MX98727 },
95 	{ PCI_VENDOR_COMPEX, PCI_PRODUCT_COMPEX_98713 },
96 	{ PCI_VENDOR_LITEON, PCI_PRODUCT_LITEON_PNIC },
97 	{ PCI_VENDOR_LITEON, PCI_PRODUCT_LITEON_PNICII },
98 	{ PCI_VENDOR_ACCTON, PCI_PRODUCT_ACCTON_EN1217 },
99 	{ PCI_VENDOR_ACCTON, PCI_PRODUCT_ACCTON_EN2242 },
100 	{ PCI_VENDOR_CONEXANT, PCI_PRODUCT_CONEXANT_RS7112 },
101 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_21145 },
102 	{ PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CSHO100BTX },
103 	{ PCI_VENDOR_MICROSOFT, PCI_PRODUCT_MICROSOFT_MN130 },
104 	{ PCI_VENDOR_XIRCOM, PCI_PRODUCT_XIRCOM_X3201_3_21143 },
105 	{ PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_AN985 },
106 	{ PCI_VENDOR_ABOCOM, PCI_PRODUCT_ABOCOM_FE2500 },
107 	{ PCI_VENDOR_ABOCOM, PCI_PRODUCT_ABOCOM_FE2500MX },
108 	{ PCI_VENDOR_ABOCOM, PCI_PRODUCT_ABOCOM_PCM200 },
109 	{ PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DRP32TXD },
110 	{ PCI_VENDOR_LINKSYS, PCI_PRODUCT_LINKSYS_PCMPC200 },
111 	{ PCI_VENDOR_LINKSYS, PCI_PRODUCT_LINKSYS_PCM200 },
112 	{ PCI_VENDOR_HAWKING, PCI_PRODUCT_HAWKING_PN672TX },
113 	{ PCI_VENDOR_MICROSOFT, PCI_PRODUCT_MICROSOFT_MN120 },
114 	{ 0, 0 }
115 };
116 
117 int dc_pci_match(struct device *, void *, void *);
118 void dc_pci_attach(struct device *, struct device *, void *);
119 int dc_pci_detach(struct device *, int);
120 
121 struct dc_pci_softc {
122 	struct dc_softc		psc_softc;
123 	pci_chipset_tag_t	psc_pc;
124 	bus_size_t		psc_mapsize;
125 };
126 
127 /*
128  * Probe for a 21143 or clone chip. Check the PCI vendor and device
129  * IDs against our list and return a device name if we find a match.
130  */
131 int
132 dc_pci_match(struct device *parent, void *match, void *aux)
133 {
134 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
135 	struct dc_type *t;
136 
137 	/*
138 	 * Support for the 21140 chip is experimental.  If it works for you,
139 	 * that's great.  By default, this chip will use de.
140 	 */
141         if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_DEC &&
142 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21140)
143 		return (1);
144 
145 	/*
146 	 * The following chip revision doesn't seem to work so well with dc,
147 	 * so let's have de handle it.  (de will return a match of 2)
148 	 */
149         if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_DEC &&
150 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21142 &&
151 	    PCI_REVISION(pa->pa_class) == 0x21)
152 		return (1);
153 
154 	for (t = dc_devs; t->dc_vid != 0; t++) {
155 		if ((PCI_VENDOR(pa->pa_id) == t->dc_vid) &&
156 		    (PCI_PRODUCT(pa->pa_id) == t->dc_did)) {
157 			return (3);
158 		}
159 	}
160 
161 	return (0);
162 }
163 
164 /*
165  * Attach the interface. Allocate softc structures, do ifmedia
166  * setup and ethernet/BPF attach.
167  */
168 void
169 dc_pci_attach(struct device *parent, struct device *self, void *aux)
170 {
171 	const char		*intrstr = NULL;
172 	pcireg_t		command;
173 	struct dc_pci_softc	*psc = (struct dc_pci_softc *)self;
174 	struct dc_softc		*sc = &psc->psc_softc;
175 	struct pci_attach_args	*pa = aux;
176 	pci_chipset_tag_t	pc = pa->pa_pc;
177 	pci_intr_handle_t	ih;
178 	int			found = 0;
179 
180 	psc->psc_pc = pa->pa_pc;
181 	sc->sc_dmat = pa->pa_dmat;
182 
183 	pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
184 
185 	sc->dc_csid = pci_conf_read(pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
186 
187 	/*
188 	 * Map control/status registers.
189 	 */
190 #ifdef DC_USEIOSPACE
191 	if (pci_mapreg_map(pa, DC_PCI_CFBIO,
192 	    PCI_MAPREG_TYPE_IO, 0,
193 	    &sc->dc_btag, &sc->dc_bhandle, NULL, &psc->psc_mapsize, 0)) {
194 		printf(": can't map i/o space\n");
195 		return;
196 	}
197 #else
198 	if (pci_mapreg_map(pa, DC_PCI_CFBMA,
199 	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
200 	    &sc->dc_btag, &sc->dc_bhandle, NULL, &psc->psc_mapsize, 0)) {
201 		printf(": can't map mem space\n");
202 		return;
203 	}
204 #endif
205 
206 	/* Allocate interrupt */
207 	if (pci_intr_map(pa, &ih)) {
208 		printf(": couldn't map interrupt\n");
209 		goto fail_1;
210 	}
211 	intrstr = pci_intr_string(pc, ih);
212 	sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, dc_intr, sc,
213 	    self->dv_xname);
214 	if (sc->sc_ih == NULL) {
215 		printf(": couldn't establish interrupt");
216 		if (intrstr != NULL)
217 			printf(" at %s", intrstr);
218 		printf("\n");
219 		goto fail_1;
220 	}
221 	printf(": %s", intrstr);
222 
223 	/* Need this info to decide on a chip type. */
224 	sc->dc_revision = PCI_REVISION(pa->pa_class);
225 
226 	/* Get the eeprom width, if possible */
227 	if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_LITEON &&
228 	      PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LITEON_PNIC))
229 		;	/* PNIC has non-standard eeprom */
230 	else if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_XIRCOM &&
231 	      PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_XIRCOM_X3201_3_21143))
232 		;	/* XIRCOM has non-standard eeprom */
233 	else
234 		dc_eeprom_width(sc);
235 
236 	switch (PCI_VENDOR(pa->pa_id)) {
237 	case PCI_VENDOR_DEC:
238 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21140 ||
239 		    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21142) {
240 			found = 1;
241 			sc->dc_type = DC_TYPE_21143;
242 			sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
243 			sc->dc_flags |= DC_REDUCED_MII_POLL;
244 			dc_read_srom(sc, sc->dc_romwidth);
245 		}
246 		break;
247 	case PCI_VENDOR_INTEL:
248 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_21145) {
249 			found = 1;
250 			sc->dc_type = DC_TYPE_21145;
251 			sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
252 			sc->dc_flags |= DC_REDUCED_MII_POLL;
253 			dc_read_srom(sc, sc->dc_romwidth);
254 		}
255 		break;
256 	case PCI_VENDOR_DAVICOM:
257 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DAVICOM_DM9100 ||
258 		    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DAVICOM_DM9102 ||
259 		    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DAVICOM_DM9009) {
260 			found = 1;
261 			sc->dc_type = DC_TYPE_DM9102;
262 			sc->dc_flags |= DC_TX_COALESCE|DC_TX_INTR_ALWAYS;
263 			sc->dc_flags |= DC_REDUCED_MII_POLL|DC_TX_STORENFWD;
264 			sc->dc_flags |= DC_TX_ALIGN;
265 			sc->dc_pmode = DC_PMODE_MII;
266 
267 			/* Increase the latency timer value. */
268 			command = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFLT);
269 			command &= 0xFFFF00FF;
270 			command |= 0x00008000;
271 			pci_conf_write(pc, pa->pa_tag, DC_PCI_CFLT, command);
272 		}
273 		break;
274 	case PCI_VENDOR_ADMTEK:
275 	case PCI_VENDOR_3COM:
276 	case PCI_VENDOR_MICROSOFT:
277 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_AL981) {
278 			found = 1;
279 			sc->dc_type = DC_TYPE_AL981;
280 			sc->dc_flags |= DC_TX_USE_TX_INTR;
281 			sc->dc_flags |= DC_TX_ADMTEK_WAR;
282 			sc->dc_pmode = DC_PMODE_MII;
283 			dc_read_srom(sc, sc->dc_romwidth);
284 		}
285 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_ADM9511 ||
286 		    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_ADM9513 ||
287 		    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_AN983 ||
288 		    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3COM_3CSHO100BTX ||
289 		    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MICROSOFT_MN130) {
290 			found = 1;
291 			sc->dc_type = DC_TYPE_AN983;
292 			sc->dc_flags |= DC_TX_USE_TX_INTR;
293 			sc->dc_flags |= DC_TX_ADMTEK_WAR;
294 			sc->dc_flags |= DC_64BIT_HASH;
295 			sc->dc_pmode = DC_PMODE_MII;
296 			/* Don't read SROM for - auto-loaded on reset */
297 		}
298 		break;
299 	case PCI_VENDOR_MACRONIX:
300 	case PCI_VENDOR_ACCTON:
301 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ACCTON_EN2242) {
302 			found = 1;
303 			sc->dc_type = DC_TYPE_AN983;
304 			sc->dc_flags |= DC_TX_USE_TX_INTR;
305 			sc->dc_flags |= DC_TX_ADMTEK_WAR;
306 			sc->dc_flags |= DC_64BIT_HASH;
307 			sc->dc_pmode = DC_PMODE_MII;
308 			/* Don't read SROM for - auto-loaded on reset */
309 		}
310 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98713) {
311 			found = 1;
312 			if (sc->dc_revision < DC_REVISION_98713A)
313 				sc->dc_type = DC_TYPE_98713;
314 			if (sc->dc_revision >= DC_REVISION_98713A) {
315 				sc->dc_type = DC_TYPE_98713A;
316 				sc->dc_flags |= DC_21143_NWAY;
317 			}
318 			sc->dc_flags |= DC_REDUCED_MII_POLL;
319 			sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
320 		}
321 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98715 ||
322 		    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ACCTON_EN1217) {
323 			found = 1;
324 			if (sc->dc_revision >= DC_REVISION_98715AEC_C &&
325 			    sc->dc_revision < DC_REVISION_98725)
326 				sc->dc_flags |= DC_128BIT_HASH;
327 			sc->dc_type = DC_TYPE_987x5;
328 			sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
329 			sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY;
330 		}
331 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98727) {
332 			found = 1;
333 			sc->dc_type = DC_TYPE_987x5;
334 			sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
335 			sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY;
336 		}
337 		break;
338 	case PCI_VENDOR_COMPEX:
339 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_COMPEX_98713) {
340 			found = 1;
341 			if (sc->dc_revision < DC_REVISION_98713A) {
342 				sc->dc_type = DC_TYPE_98713;
343 				sc->dc_flags |= DC_REDUCED_MII_POLL;
344 			}
345 			if (sc->dc_revision >= DC_REVISION_98713A)
346 				sc->dc_type = DC_TYPE_98713A;
347 			sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
348 		}
349 		break;
350 	case PCI_VENDOR_LITEON:
351 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LITEON_PNICII) {
352 			found = 1;
353 			sc->dc_type = DC_TYPE_PNICII;
354 			sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
355 			sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY;
356 			sc->dc_flags |= DC_128BIT_HASH;
357 		}
358 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LITEON_PNIC) {
359 			found = 1;
360 			sc->dc_type = DC_TYPE_PNIC;
361 			sc->dc_flags |= DC_TX_STORENFWD|DC_TX_INTR_ALWAYS;
362 			sc->dc_flags |= DC_PNIC_RX_BUG_WAR;
363 			sc->dc_pnic_rx_buf = malloc(ETHER_MAX_DIX_LEN * 5,
364 			    M_DEVBUF, M_NOWAIT);
365 			if (sc->dc_pnic_rx_buf == NULL)
366 				panic("dc_pci_attach");
367 			if (sc->dc_revision < DC_REVISION_82C169)
368 				sc->dc_pmode = DC_PMODE_SYM;
369 		}
370 		break;
371 	case PCI_VENDOR_ASIX:
372 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ASIX_AX88140A) {
373 			found = 1;
374 			sc->dc_type = DC_TYPE_ASIX;
375 			sc->dc_flags |= DC_TX_USE_TX_INTR|DC_TX_INTR_FIRSTFRAG;
376 			sc->dc_flags |= DC_REDUCED_MII_POLL;
377 			sc->dc_pmode = DC_PMODE_MII;
378 		}
379 		break;
380 	case PCI_VENDOR_CONEXANT:
381 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CONEXANT_RS7112) {
382 			found = 1;
383 			sc->dc_type = DC_TYPE_CONEXANT;
384 			sc->dc_flags |= DC_TX_INTR_ALWAYS;
385 			sc->dc_flags |= DC_REDUCED_MII_POLL;
386 			sc->dc_pmode = DC_PMODE_MII;
387 			dc_read_srom(sc, sc->dc_romwidth);
388 		}
389 		break;
390 	case PCI_VENDOR_XIRCOM:
391 		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_XIRCOM_X3201_3_21143) {
392 			found = 1;
393 			sc->dc_type = DC_TYPE_XIRCOM;
394 			sc->dc_flags |= DC_TX_INTR_ALWAYS;
395 			sc->dc_flags |= DC_TX_COALESCE;
396 			sc->dc_flags |= DC_TX_ALIGN;
397 			sc->dc_pmode = DC_PMODE_MII;
398 		}
399 		break;
400 	}
401 	if (found == 0) {
402 		/* This shouldn't happen if probe has done its job... */
403 		printf(": unknown device: %x:%x\n",
404 		    PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id));
405 		goto fail_2;
406 	}
407 
408 	/* Save the cache line size. */
409 	if (DC_IS_DAVICOM(sc))
410 		sc->dc_cachesize = 0;
411 	else
412 		sc->dc_cachesize = pci_conf_read(pc, pa->pa_tag,
413 		    DC_PCI_CFLT) & 0xFF;
414 
415 	/* Reset the adapter. */
416 	dc_reset(sc);
417 
418 	/* Take 21143 out of snooze mode */
419 	if (DC_IS_INTEL(sc) || DC_IS_XIRCOM(sc)) {
420 		command = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFDD);
421 		command &= ~(DC_CFDD_SNOOZE_MODE|DC_CFDD_SLEEP_MODE);
422 		pci_conf_write(pc, pa->pa_tag, DC_PCI_CFDD, command);
423 	}
424 
425 	/*
426 	 * If we discover later (in dc_attach) that we have an
427 	 * MII with no PHY, we need to have the 21143 drive the LEDs.
428 	 * Except there are some systems like the NEC VersaPro NoteBook PC
429 	 * which have no LEDs, and twiddling these bits has adverse effects
430 	 * on them. (I.e. you suddenly can't get a link.)
431 	 *
432 	 * If mii_attach() returns an error, we leave the DC_TULIP_LEDS
433 	 * bit set, else we clear it. Since our dc(4) driver is split into
434 	 * bus-dependent and bus-independent parts, we must do set this bit
435 	 * here while we are able to do PCI configuration reads.
436 	 */
437 	if (DC_IS_INTEL(sc)) {
438 		if (pci_conf_read(pc, pa->pa_tag, DC_PCI_CSID) != 0x80281033)
439 			sc->dc_flags |= DC_TULIP_LEDS;
440 	}
441 
442 	/*
443 	 * Try to learn something about the supported media.
444 	 * We know that ASIX and ADMtek and Davicom devices
445 	 * will *always* be using MII media, so that's a no-brainer.
446 	 * The tricky ones are the Macronix/PNIC II and the
447 	 * Intel 21143.
448 	 */
449 	if (DC_IS_INTEL(sc))
450 		dc_parse_21143_srom(sc);
451 	else if (DC_IS_MACRONIX(sc) || DC_IS_PNICII(sc)) {
452 		if (sc->dc_type == DC_TYPE_98713)
453 			sc->dc_pmode = DC_PMODE_MII;
454 		else
455 			sc->dc_pmode = DC_PMODE_SYM;
456 	} else if (!sc->dc_pmode)
457 		sc->dc_pmode = DC_PMODE_MII;
458 
459 #ifdef __sparc64__
460 	{
461 		extern void myetheraddr(u_char *);
462 
463 		if (OF_getprop(PCITAG_NODE(pa->pa_tag), "local-mac-address",
464 		    sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0)
465 			myetheraddr(sc->sc_arpcom.ac_enaddr);
466 		if (sc->sc_arpcom.ac_enaddr[0] == 0x00 &&
467 		    sc->sc_arpcom.ac_enaddr[1] == 0x03 &&
468 		    sc->sc_arpcom.ac_enaddr[2] == 0xcc)
469 			sc->dc_flags |= DC_MOMENCO_BOTCH;
470 		sc->sc_hasmac = 1;
471 	}
472 #endif
473 
474 #ifdef SRM_MEDIA
475 	sc->dc_srm_media = 0;
476 
477 	/* Remember the SRM console media setting */
478 	if (DC_IS_INTEL(sc)) {
479 		command = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFDD);
480 		command &= ~(DC_CFDD_SNOOZE_MODE|DC_CFDD_SLEEP_MODE);
481 		switch ((command >> 8) & 0xff) {
482 		case 3:
483 			sc->dc_srm_media = IFM_10_T;
484 			break;
485 		case 4:
486 			sc->dc_srm_media = IFM_10_T | IFM_FDX;
487 			break;
488 		case 5:
489 			sc->dc_srm_media = IFM_100_TX;
490 			break;
491 		case 6:
492 			sc->dc_srm_media = IFM_100_TX | IFM_FDX;
493 			break;
494 		}
495 		if (sc->dc_srm_media)
496 			sc->dc_srm_media |= IFM_ACTIVE | IFM_ETHER;
497 	}
498 #endif
499 	dc_attach(sc);
500 
501 	return;
502 
503 fail_2:
504 	pci_intr_disestablish(pc, sc->sc_ih);
505 
506 fail_1:
507 	bus_space_unmap(sc->dc_btag, sc->dc_bhandle, psc->psc_mapsize);
508 }
509 
510 int
511 dc_pci_detach(struct device *self, int flags)
512 {
513 	struct dc_pci_softc *psc = (void *)self;
514 	struct dc_softc *sc = &psc->psc_softc;
515 
516 	if (sc->sc_ih != NULL)
517 		pci_intr_disestablish(psc->psc_pc, sc->sc_ih);
518 	dc_detach(sc);
519 	bus_space_unmap(sc->dc_btag, sc->dc_bhandle, psc->psc_mapsize);
520 
521 	return (0);
522 }
523 
524 struct cfattach dc_pci_ca = {
525 	sizeof(struct dc_softc), dc_pci_match, dc_pci_attach, dc_pci_detach,
526 	dc_activate
527 };
528