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