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