1 /* $NetBSD: if_tlp_cardbus.c,v 1.38 2002/11/11 12:51:38 onoe Exp $ */ 2 3 /*- 4 * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * CardBus bus front-end for the Digital Semiconductor ``Tulip'' (21x4x) 42 * Ethernet controller family driver. 43 */ 44 45 #include <sys/cdefs.h> 46 __KERNEL_RCSID(0, "$NetBSD: if_tlp_cardbus.c,v 1.38 2002/11/11 12:51:38 onoe Exp $"); 47 48 #include "opt_inet.h" 49 #include "opt_ns.h" 50 #include "bpfilter.h" 51 52 #include <sys/param.h> 53 #include <sys/systm.h> 54 #include <sys/mbuf.h> 55 #include <sys/malloc.h> 56 #include <sys/kernel.h> 57 #include <sys/socket.h> 58 #include <sys/ioctl.h> 59 #include <sys/errno.h> 60 #include <sys/device.h> 61 62 #include <machine/endian.h> 63 64 #include <net/if.h> 65 #include <net/if_dl.h> 66 #include <net/if_media.h> 67 #include <net/if_ether.h> 68 69 #if NBPFILTER > 0 70 #include <net/bpf.h> 71 #endif 72 73 #ifdef INET 74 #include <netinet/in.h> 75 #include <netinet/if_inarp.h> 76 #endif 77 78 #ifdef NS 79 #include <netns/ns.h> 80 #include <netns/ns_if.h> 81 #endif 82 83 #include <machine/bus.h> 84 #include <machine/intr.h> 85 86 #include <dev/mii/miivar.h> 87 #include <dev/mii/mii_bitbang.h> 88 89 #include <dev/ic/tulipreg.h> 90 #include <dev/ic/tulipvar.h> 91 92 #include <dev/pci/pcivar.h> 93 #include <dev/pci/pcireg.h> 94 #include <dev/pci/pcidevs.h> 95 96 #include <dev/cardbus/cardbusvar.h> 97 #include <dev/cardbus/cardbusdevs.h> 98 99 /* 100 * PCI configuration space registers used by the Tulip. 101 */ 102 #define TULIP_PCI_IOBA 0x10 /* i/o mapped base */ 103 #define TULIP_PCI_MMBA 0x14 /* memory mapped base */ 104 #define TULIP_PCI_CFDA 0x40 /* configuration driver area */ 105 106 #define CFDA_SLEEP 0x80000000 /* sleep mode */ 107 #define CFDA_SNOOZE 0x40000000 /* snooze mode */ 108 109 struct tulip_cardbus_softc { 110 struct tulip_softc sc_tulip; /* real Tulip softc */ 111 112 /* CardBus-specific goo. */ 113 void *sc_ih; /* interrupt handle */ 114 cardbus_devfunc_t sc_ct; /* our CardBus devfuncs */ 115 cardbustag_t sc_tag; /* our CardBus tag */ 116 int sc_csr; /* CSR bits */ 117 bus_size_t sc_mapsize; /* the size of mapped bus space 118 region */ 119 120 int sc_cben; /* CardBus enables */ 121 int sc_bar_reg; /* which BAR to use */ 122 pcireg_t sc_bar_val; /* value of the BAR */ 123 124 int sc_intrline; /* interrupt line */ 125 }; 126 127 int tlp_cardbus_match __P((struct device *, struct cfdata *, void *)); 128 void tlp_cardbus_attach __P((struct device *, struct device *, void *)); 129 int tlp_cardbus_detach __P((struct device *, int)); 130 131 CFATTACH_DECL(tlp_cardbus, sizeof(struct tulip_cardbus_softc), 132 tlp_cardbus_match, tlp_cardbus_attach, tlp_cardbus_detach, tlp_activate); 133 134 const struct tulip_cardbus_product { 135 u_int32_t tcp_vendor; /* PCI vendor ID */ 136 u_int32_t tcp_product; /* PCI product ID */ 137 tulip_chip_t tcp_chip; /* base Tulip chip type */ 138 } tlp_cardbus_products[] = { 139 { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_21142, 140 TULIP_CHIP_21142 }, 141 142 { PCI_VENDOR_XIRCOM, PCI_PRODUCT_XIRCOM_X3201_3_21143, 143 TULIP_CHIP_X3201_3 }, 144 145 { PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_AN985, 146 TULIP_CHIP_AN985 }, 147 148 { CARDBUS_VENDOR_ACCTON, CARDBUS_PRODUCT_ACCTON_EN2242, 149 TULIP_CHIP_AN985 }, 150 151 { CARDBUS_VENDOR_ABOCOM, CARDBUS_PRODUCT_ABOCOM_FE2500, 152 TULIP_CHIP_AN985 }, 153 154 { CARDBUS_VENDOR_ABOCOM, CARDBUS_PRODUCT_ABOCOM_PCM200, 155 TULIP_CHIP_AN985 }, 156 157 { CARDBUS_VENDOR_ABOCOM, CARDBUS_PRODUCT_ABOCOM_FE2500MX, 158 TULIP_CHIP_AN985 }, 159 160 { CARDBUS_VENDOR_HAWKING, CARDBUS_PRODUCT_HAWKING_PN672TX, 161 TULIP_CHIP_AN985 }, 162 163 { 0, 0, 164 TULIP_CHIP_INVALID }, 165 }; 166 167 struct tlp_cardbus_quirks { 168 void (*tpq_func) __P((struct tulip_cardbus_softc *, 169 const u_int8_t *)); 170 u_int8_t tpq_oui[3]; 171 }; 172 173 void tlp_cardbus_lxt_quirks __P((struct tulip_cardbus_softc *, 174 const u_int8_t *)); 175 176 const struct tlp_cardbus_quirks tlp_cardbus_21142_quirks[] = { 177 { tlp_cardbus_lxt_quirks, { 0x00, 0x40, 0x05 } }, 178 { NULL, { 0, 0, 0 } } 179 }; 180 181 void tlp_cardbus_setup __P((struct tulip_cardbus_softc *)); 182 183 int tlp_cardbus_enable __P((struct tulip_softc *)); 184 void tlp_cardbus_disable __P((struct tulip_softc *)); 185 void tlp_cardbus_power __P((struct tulip_softc *, int)); 186 187 void tlp_cardbus_x3201_reset __P((struct tulip_softc *)); 188 189 const struct tulip_cardbus_product *tlp_cardbus_lookup 190 __P((const struct cardbus_attach_args *)); 191 void tlp_cardbus_get_quirks __P((struct tulip_cardbus_softc *, 192 const u_int8_t *, const struct tlp_cardbus_quirks *)); 193 194 const struct tulip_cardbus_product * 195 tlp_cardbus_lookup(ca) 196 const struct cardbus_attach_args *ca; 197 { 198 const struct tulip_cardbus_product *tcp; 199 200 for (tcp = tlp_cardbus_products; 201 tlp_chip_names[tcp->tcp_chip] != NULL; 202 tcp++) { 203 if (PCI_VENDOR(ca->ca_id) == tcp->tcp_vendor && 204 PCI_PRODUCT(ca->ca_id) == tcp->tcp_product) 205 return (tcp); 206 } 207 return (NULL); 208 } 209 210 void 211 tlp_cardbus_get_quirks(csc, enaddr, tpq) 212 struct tulip_cardbus_softc *csc; 213 const u_int8_t *enaddr; 214 const struct tlp_cardbus_quirks *tpq; 215 { 216 217 for (; tpq->tpq_func != NULL; tpq++) { 218 if (tpq->tpq_oui[0] == enaddr[0] && 219 tpq->tpq_oui[1] == enaddr[1] && 220 tpq->tpq_oui[2] == enaddr[2]) { 221 (*tpq->tpq_func)(csc, enaddr); 222 return; 223 } 224 } 225 } 226 227 int 228 tlp_cardbus_match(parent, match, aux) 229 struct device *parent; 230 struct cfdata *match; 231 void *aux; 232 { 233 struct cardbus_attach_args *ca = aux; 234 235 if (tlp_cardbus_lookup(ca) != NULL) 236 return (1); 237 238 return (0); 239 } 240 241 void 242 tlp_cardbus_attach(parent, self, aux) 243 struct device *parent, *self; 244 void *aux; 245 { 246 struct tulip_cardbus_softc *csc = (void *)self; 247 struct tulip_softc *sc = &csc->sc_tulip; 248 struct cardbus_attach_args *ca = aux; 249 cardbus_devfunc_t ct = ca->ca_ct; 250 const struct tulip_cardbus_product *tcp; 251 u_int8_t enaddr[ETHER_ADDR_LEN]; 252 bus_addr_t adr; 253 pcireg_t reg; 254 255 sc->sc_devno = ca->ca_device; 256 sc->sc_dmat = ca->ca_dmat; 257 csc->sc_ct = ct; 258 csc->sc_tag = ca->ca_tag; 259 260 tcp = tlp_cardbus_lookup(ca); 261 if (tcp == NULL) { 262 printf("\n"); 263 panic("tlp_cardbus_attach: impossible"); 264 } 265 sc->sc_chip = tcp->tcp_chip; 266 267 /* 268 * By default, Tulip registers are 8 bytes long (4 bytes 269 * followed by a 4 byte pad). 270 */ 271 sc->sc_regshift = 3; 272 273 /* 274 * Power management hooks. 275 */ 276 sc->sc_enable = tlp_cardbus_enable; 277 sc->sc_disable = tlp_cardbus_disable; 278 sc->sc_power = tlp_cardbus_power; 279 280 /* 281 * Get revision info, and set some chip-specific variables. 282 */ 283 sc->sc_rev = PCI_REVISION(ca->ca_class); 284 switch (sc->sc_chip) { 285 case TULIP_CHIP_21142: 286 if (sc->sc_rev >= 0x20) 287 sc->sc_chip = TULIP_CHIP_21143; 288 break; 289 290 case TULIP_CHIP_AN985: 291 /* 292 * The AN983 and AN985 are very similar, and are 293 * differentiated by a "signature" register that 294 * is like, but not identical, to a PCI ID register. 295 */ 296 reg = cardbus_conf_read(ct->ct_cc, ct->ct_cf, csc->sc_tag, 297 0x80); 298 switch (reg) { 299 case 0x09811317: 300 sc->sc_chip = TULIP_CHIP_AN985; 301 break; 302 303 case 0x09851317: 304 sc->sc_chip = TULIP_CHIP_AN983; 305 break; 306 307 } 308 break; 309 310 default: 311 /* Nothing. -- to make gcc happy */ 312 break; 313 } 314 315 printf(": %s Ethernet, pass %d.%d\n", 316 tlp_chip_names[sc->sc_chip], 317 (sc->sc_rev >> 4) & 0xf, sc->sc_rev & 0xf); 318 319 /* 320 * Map the device. 321 */ 322 csc->sc_csr = CARDBUS_COMMAND_MASTER_ENABLE; 323 if (Cardbus_mapreg_map(ct, TULIP_PCI_MMBA, 324 CARDBUS_MAPREG_TYPE_MEM, 0, &sc->sc_st, &sc->sc_sh, &adr, 325 &csc->sc_mapsize) == 0) { 326 #if rbus 327 #else 328 (*ct->ct_cf->cardbus_mem_open)(cc, 0, adr, adr+csc->sc_mapsize); 329 #endif 330 csc->sc_cben = CARDBUS_MEM_ENABLE; 331 csc->sc_csr |= CARDBUS_COMMAND_MEM_ENABLE; 332 csc->sc_bar_reg = TULIP_PCI_MMBA; 333 csc->sc_bar_val = adr | CARDBUS_MAPREG_TYPE_MEM; 334 } else if (Cardbus_mapreg_map(ct, TULIP_PCI_IOBA, 335 CARDBUS_MAPREG_TYPE_IO, 0, &sc->sc_st, &sc->sc_sh, &adr, 336 &csc->sc_mapsize) == 0) { 337 #if rbus 338 #else 339 (*ct->ct_cf->cardbus_io_open)(cc, 0, adr, adr+csc->sc_mapsize); 340 #endif 341 csc->sc_cben = CARDBUS_IO_ENABLE; 342 csc->sc_csr |= CARDBUS_COMMAND_IO_ENABLE; 343 csc->sc_bar_reg = TULIP_PCI_IOBA; 344 csc->sc_bar_val = adr | CARDBUS_MAPREG_TYPE_IO; 345 } else { 346 printf("%s: unable to map device registers\n", 347 sc->sc_dev.dv_xname); 348 return; 349 } 350 351 /* 352 * Bring the chip out of powersave mode and initialize the 353 * configuration registers. 354 */ 355 tlp_cardbus_setup(csc); 356 357 /* 358 * Read the contents of the Ethernet Address ROM/SROM. 359 */ 360 switch (sc->sc_chip) { 361 case TULIP_CHIP_X3201_3: 362 /* 363 * No SROM on this chip. 364 */ 365 break; 366 367 default: 368 if (tlp_read_srom(sc) == 0) 369 goto cant_cope; 370 break; 371 } 372 373 /* 374 * Deal with chip/board quirks. This includes setting up 375 * the mediasw, and extracting the Ethernet address from 376 * the rombuf. 377 */ 378 switch (sc->sc_chip) { 379 case TULIP_CHIP_21142: 380 case TULIP_CHIP_21143: 381 /* Check for new format SROM. */ 382 if (tlp_isv_srom_enaddr(sc, enaddr) != 0) { 383 /* 384 * We start out with the 2114x ISV media switch. 385 * When we search for quirks, we may change to 386 * a different switch. 387 */ 388 sc->sc_mediasw = &tlp_2114x_isv_mediasw; 389 } else if (tlp_parse_old_srom(sc, enaddr) == 0) { 390 /* 391 * Not an ISV SROM, and not in old DEC Address 392 * ROM format. Try to snarf it out of the CIS. 393 */ 394 if (ca->ca_cis.funce.network.netid_present == 0) 395 goto cant_cope; 396 397 /* Grab the MAC address from the CIS. */ 398 memcpy(enaddr, ca->ca_cis.funce.network.netid, 399 sizeof(enaddr)); 400 } 401 402 /* 403 * Deal with any quirks this board might have. 404 */ 405 tlp_cardbus_get_quirks(csc, enaddr, tlp_cardbus_21142_quirks); 406 407 /* 408 * If we don't already have a media switch, default to 409 * MII-over-SIO, with no special reset routine. 410 */ 411 if (sc->sc_mediasw == NULL) { 412 printf("%s: defaulting to MII-over-SIO; no bets...\n", 413 sc->sc_dev.dv_xname); 414 sc->sc_mediasw = &tlp_sio_mii_mediasw; 415 } 416 break; 417 418 case TULIP_CHIP_AN983: 419 case TULIP_CHIP_AN985: 420 /* 421 * The ADMtek AN985's Ethernet address is located 422 * at offset 8 of its EEPROM. 423 */ 424 memcpy(enaddr, &sc->sc_srom[8], ETHER_ADDR_LEN); 425 426 /* 427 * The ADMtek AN985 can be configured in Single-Chip 428 * mode or MAC-only mode. Single-Chip uses the built-in 429 * PHY, MAC-only has an external PHY (usually HomePNA). 430 * The selection is based on an EEPROM setting, and both 431 * PHYs are access via MII attached to SIO. 432 * 433 * The AN985 "ghosts" the internal PHY onto all 434 * MII addresses, so we have to use a media init 435 * routine that limits the search. 436 * XXX How does this work with MAC-only mode? 437 */ 438 sc->sc_mediasw = &tlp_an985_mediasw; 439 break; 440 441 case TULIP_CHIP_X3201_3: 442 /* 443 * The X3201 doesn't have an SROM. Lift the MAC address 444 * from the CIS. Also, we have a special media switch: 445 * MII-on-SIO, plus some special GPIO setup. 446 */ 447 memcpy(enaddr, ca->ca_cis.funce.network.netid, sizeof(enaddr)); 448 sc->sc_reset = tlp_cardbus_x3201_reset; 449 sc->sc_mediasw = &tlp_sio_mii_mediasw; 450 break; 451 452 default: 453 cant_cope: 454 printf("%s: sorry, unable to handle your board\n", 455 sc->sc_dev.dv_xname); 456 return; 457 } 458 459 /* Remember which interrupt line. */ 460 csc->sc_intrline = ca->ca_intrline; 461 462 /* 463 * The CardBus cards will make it to store-and-forward mode as 464 * soon as you put them under any kind of load, so just start 465 * out there. 466 */ 467 sc->sc_txthresh = TXTH_SF; 468 469 /* 470 * Finish off the attach. 471 */ 472 tlp_attach(sc, enaddr); 473 474 /* 475 * Power down the socket. 476 */ 477 Cardbus_function_disable(csc->sc_ct); 478 } 479 480 int 481 tlp_cardbus_detach(self, flags) 482 struct device *self; 483 int flags; 484 { 485 struct tulip_cardbus_softc *csc = (void *)self; 486 struct tulip_softc *sc = &csc->sc_tulip; 487 struct cardbus_devfunc *ct = csc->sc_ct; 488 int rv; 489 490 #if defined(DIAGNOSTIC) 491 if (ct == NULL) 492 panic("%s: data structure lacks", sc->sc_dev.dv_xname); 493 #endif 494 495 rv = tlp_detach(sc); 496 if (rv) 497 return (rv); 498 499 /* 500 * Unhook the interrupt handler. 501 */ 502 if (csc->sc_ih != NULL) 503 cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, csc->sc_ih); 504 505 /* 506 * Release bus space and close window. 507 */ 508 if (csc->sc_bar_reg != 0) 509 Cardbus_mapreg_unmap(ct, csc->sc_bar_reg, 510 sc->sc_st, sc->sc_sh, csc->sc_mapsize); 511 512 return (0); 513 } 514 515 int 516 tlp_cardbus_enable(sc) 517 struct tulip_softc *sc; 518 { 519 struct tulip_cardbus_softc *csc = (void *) sc; 520 cardbus_devfunc_t ct = csc->sc_ct; 521 cardbus_chipset_tag_t cc = ct->ct_cc; 522 cardbus_function_tag_t cf = ct->ct_cf; 523 524 /* 525 * Power on the socket. 526 */ 527 Cardbus_function_enable(ct); 528 529 /* 530 * Set up the PCI configuration registers. 531 */ 532 tlp_cardbus_setup(csc); 533 534 /* 535 * Map and establish the interrupt. 536 */ 537 csc->sc_ih = cardbus_intr_establish(cc, cf, csc->sc_intrline, IPL_NET, 538 tlp_intr, sc); 539 if (csc->sc_ih == NULL) { 540 printf("%s: unable to establish interrupt at %d\n", 541 sc->sc_dev.dv_xname, csc->sc_intrline); 542 Cardbus_function_disable(csc->sc_ct); 543 return (1); 544 } 545 printf("%s: interrupting at %d\n", sc->sc_dev.dv_xname, 546 csc->sc_intrline); 547 548 return (0); 549 } 550 551 void 552 tlp_cardbus_disable(sc) 553 struct tulip_softc *sc; 554 { 555 struct tulip_cardbus_softc *csc = (void *) sc; 556 cardbus_devfunc_t ct = csc->sc_ct; 557 cardbus_chipset_tag_t cc = ct->ct_cc; 558 cardbus_function_tag_t cf = ct->ct_cf; 559 560 /* Unhook the interrupt handler. */ 561 cardbus_intr_disestablish(cc, cf, csc->sc_ih); 562 csc->sc_ih = NULL; 563 564 /* Power down the socket. */ 565 Cardbus_function_disable(ct); 566 } 567 568 void 569 tlp_cardbus_power(sc, why) 570 struct tulip_softc *sc; 571 int why; 572 { 573 struct tulip_cardbus_softc *csc = (void *) sc; 574 575 if (why == PWR_RESUME) { 576 /* 577 * Give the PCI configuration registers a kick 578 * in the head. 579 */ 580 #ifdef DIAGNOSTIC 581 if (TULIP_IS_ENABLED(sc) == 0) 582 panic("tlp_cardbus_power"); 583 #endif 584 tlp_cardbus_setup(csc); 585 } 586 } 587 588 void 589 tlp_cardbus_setup(csc) 590 struct tulip_cardbus_softc *csc; 591 { 592 struct tulip_softc *sc = &csc->sc_tulip; 593 cardbus_devfunc_t ct = csc->sc_ct; 594 cardbus_chipset_tag_t cc = ct->ct_cc; 595 cardbus_function_tag_t cf = ct->ct_cf; 596 pcireg_t reg; 597 int pmreg; 598 599 /* 600 * Check to see if the device is in power-save mode, and 601 * bring it out if necessary. 602 */ 603 switch (sc->sc_chip) { 604 case TULIP_CHIP_21142: 605 case TULIP_CHIP_21143: 606 case TULIP_CHIP_X3201_3: 607 /* 608 * Clear the "sleep mode" bit in the CFDA register. 609 */ 610 reg = cardbus_conf_read(cc, cf, csc->sc_tag, TULIP_PCI_CFDA); 611 if (reg & (CFDA_SLEEP|CFDA_SNOOZE)) 612 cardbus_conf_write(cc, cf, csc->sc_tag, TULIP_PCI_CFDA, 613 reg & ~(CFDA_SLEEP|CFDA_SNOOZE)); 614 break; 615 616 default: 617 /* Nothing. -- to make gcc happy */ 618 break; 619 } 620 621 if (cardbus_get_capability(cc, cf, csc->sc_tag, 622 PCI_CAP_PWRMGMT, &pmreg, 0)) { 623 reg = cardbus_conf_read(cc, cf, csc->sc_tag, pmreg + 4) & 0x03; 624 #if 1 /* XXX Probably not right for CardBus. */ 625 if (reg == 3) { 626 /* 627 * The card has lost all configuration data in 628 * this state, so punt. 629 */ 630 printf("%s: unable to wake up from power state D3\n", 631 sc->sc_dev.dv_xname); 632 return; 633 } 634 #endif 635 if (reg != 0) { 636 printf("%s: waking up from power state D%d\n", 637 sc->sc_dev.dv_xname, reg); 638 cardbus_conf_write(cc, cf, csc->sc_tag, 639 pmreg + 4, 0); 640 } 641 } 642 643 /* Make sure the right access type is on the CardBus bridge. */ 644 (*ct->ct_cf->cardbus_ctrl)(cc, csc->sc_cben); 645 (*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE); 646 647 /* Program the BAR. */ 648 cardbus_conf_write(cc, cf, csc->sc_tag, csc->sc_bar_reg, 649 csc->sc_bar_val); 650 651 /* Enable the appropriate bits in the PCI CSR. */ 652 reg = cardbus_conf_read(cc, cf, csc->sc_tag, PCI_COMMAND_STATUS_REG); 653 reg &= ~(PCI_COMMAND_IO_ENABLE|PCI_COMMAND_MEM_ENABLE); 654 reg |= csc->sc_csr; 655 cardbus_conf_write(cc, cf, csc->sc_tag, PCI_COMMAND_STATUS_REG, reg); 656 657 /* 658 * Make sure the latency timer is set to some reasonable 659 * value. 660 */ 661 reg = cardbus_conf_read(cc, cf, csc->sc_tag, PCI_BHLC_REG); 662 if (PCI_LATTIMER(reg) < 0x20) { 663 reg &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT); 664 reg |= (0x20 << PCI_LATTIMER_SHIFT); 665 cardbus_conf_write(cc, cf, csc->sc_tag, PCI_BHLC_REG, reg); 666 } 667 } 668 669 void 670 tlp_cardbus_x3201_reset(sc) 671 struct tulip_softc *sc; 672 { 673 u_int32_t reg; 674 675 reg = TULIP_READ(sc, CSR_SIAGEN); 676 677 /* make GP[2,0] outputs */ 678 TULIP_WRITE(sc, CSR_SIAGEN, (reg & ~SIAGEN_MD) | SIAGEN_CWE | 679 0x00050000); 680 TULIP_WRITE(sc, CSR_SIAGEN, (reg & ~SIAGEN_CWE) | SIAGEN_MD); 681 } 682 683 void 684 tlp_cardbus_lxt_quirks(csc, enaddr) 685 struct tulip_cardbus_softc *csc; 686 const u_int8_t *enaddr; 687 { 688 struct tulip_softc *sc = &csc->sc_tulip; 689 690 sc->sc_mediasw = &tlp_sio_mii_mediasw; 691 } 692