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