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