1 /* 2 * Copyright (c) 2000 Berkeley Software Design, Inc. 3 * Copyright (c) 1997, 1998, 1999, 2000 4 * Bill Paul <wpaul@osd.bsdi.com>. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Bill Paul. 17 * 4. Neither the name of the author nor the names of any co-contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 * THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 * $FreeBSD: src/sys/pci/if_pcn.c,v 1.5.2.10 2003/03/05 18:42:33 njl Exp $ 34 * $DragonFly: src/sys/dev/netif/pcn/if_pcn.c,v 1.3 2003/07/26 21:56:10 rob Exp $ 35 * 36 * $FreeBSD: src/sys/pci/if_pcn.c,v 1.5.2.10 2003/03/05 18:42:33 njl Exp $ 37 */ 38 39 /* 40 * AMD Am79c972 fast ethernet PCI NIC driver. Datatheets are available 41 * from http://www.amd.com. 42 * 43 * Written by Bill Paul <wpaul@osd.bsdi.com> 44 */ 45 46 /* 47 * The AMD PCnet/PCI controllers are more advanced and functional 48 * versions of the venerable 7990 LANCE. The PCnet/PCI chips retain 49 * backwards compatibility with the LANCE and thus can be made 50 * to work with older LANCE drivers. This is in fact how the 51 * PCnet/PCI chips were supported in FreeBSD originally. The trouble 52 * is that the PCnet/PCI devices offer several performance enhancements 53 * which can't be exploited in LANCE compatibility mode. Chief among 54 * these enhancements is the ability to perform PCI DMA operations 55 * using 32-bit addressing (which eliminates the need for ISA 56 * bounce-buffering), and special receive buffer alignment (which 57 * allows the receive handler to pass packets to the upper protocol 58 * layers without copying on both the x86 and alpha platforms). 59 */ 60 61 #include <sys/param.h> 62 #include <sys/systm.h> 63 #include <sys/sockio.h> 64 #include <sys/mbuf.h> 65 #include <sys/malloc.h> 66 #include <sys/kernel.h> 67 #include <sys/socket.h> 68 69 #include <net/if.h> 70 #include <net/if_arp.h> 71 #include <net/ethernet.h> 72 #include <net/if_dl.h> 73 #include <net/if_media.h> 74 75 #include <net/bpf.h> 76 77 #include <vm/vm.h> /* for vtophys */ 78 #include <vm/pmap.h> /* for vtophys */ 79 #include <machine/clock.h> /* for DELAY */ 80 #include <machine/bus_pio.h> 81 #include <machine/bus_memio.h> 82 #include <machine/bus.h> 83 #include <machine/resource.h> 84 #include <sys/bus.h> 85 #include <sys/rman.h> 86 87 #include <dev/mii/mii.h> 88 #include <dev/mii/miivar.h> 89 90 #include <pci/pcireg.h> 91 #include <pci/pcivar.h> 92 93 #define PCN_USEIOSPACE 94 95 #include <pci/if_pcnreg.h> 96 97 /* "controller miibus0" required. See GENERIC if you get errors here. */ 98 #include "miibus_if.h" 99 100 /* 101 * Various supported device vendors/types and their names. 102 */ 103 static struct pcn_type pcn_devs[] = { 104 { PCN_VENDORID, PCN_DEVICEID_PCNET, "AMD PCnet/PCI 10/100BaseTX" }, 105 { PCN_VENDORID, PCN_DEVICEID_HOME, "AMD PCnet/Home HomePNA" }, 106 { 0, 0, NULL } 107 }; 108 109 static u_int32_t pcn_csr_read __P((struct pcn_softc *, int)); 110 static u_int16_t pcn_csr_read16 __P((struct pcn_softc *, int)); 111 static u_int16_t pcn_bcr_read16 __P((struct pcn_softc *, int)); 112 static void pcn_csr_write __P((struct pcn_softc *, int, int)); 113 static u_int32_t pcn_bcr_read __P((struct pcn_softc *, int)); 114 static void pcn_bcr_write __P((struct pcn_softc *, int, int)); 115 116 static int pcn_probe __P((device_t)); 117 static int pcn_attach __P((device_t)); 118 static int pcn_detach __P((device_t)); 119 120 static int pcn_newbuf __P((struct pcn_softc *, int, struct mbuf *)); 121 static int pcn_encap __P((struct pcn_softc *, 122 struct mbuf *, u_int32_t *)); 123 static void pcn_rxeof __P((struct pcn_softc *)); 124 static void pcn_txeof __P((struct pcn_softc *)); 125 static void pcn_intr __P((void *)); 126 static void pcn_tick __P((void *)); 127 static void pcn_start __P((struct ifnet *)); 128 static int pcn_ioctl __P((struct ifnet *, u_long, caddr_t)); 129 static void pcn_init __P((void *)); 130 static void pcn_stop __P((struct pcn_softc *)); 131 static void pcn_watchdog __P((struct ifnet *)); 132 static void pcn_shutdown __P((device_t)); 133 static int pcn_ifmedia_upd __P((struct ifnet *)); 134 static void pcn_ifmedia_sts __P((struct ifnet *, struct ifmediareq *)); 135 136 static int pcn_miibus_readreg __P((device_t, int, int)); 137 static int pcn_miibus_writereg __P((device_t, int, int, int)); 138 static void pcn_miibus_statchg __P((device_t)); 139 140 static void pcn_setfilt __P((struct ifnet *)); 141 static void pcn_setmulti __P((struct pcn_softc *)); 142 static u_int32_t pcn_crc __P((caddr_t)); 143 static void pcn_reset __P((struct pcn_softc *)); 144 static int pcn_list_rx_init __P((struct pcn_softc *)); 145 static int pcn_list_tx_init __P((struct pcn_softc *)); 146 147 #ifdef PCN_USEIOSPACE 148 #define PCN_RES SYS_RES_IOPORT 149 #define PCN_RID PCN_PCI_LOIO 150 #else 151 #define PCN_RES SYS_RES_MEMORY 152 #define PCN_RID PCN_PCI_LOMEM 153 #endif 154 155 static device_method_t pcn_methods[] = { 156 /* Device interface */ 157 DEVMETHOD(device_probe, pcn_probe), 158 DEVMETHOD(device_attach, pcn_attach), 159 DEVMETHOD(device_detach, pcn_detach), 160 DEVMETHOD(device_shutdown, pcn_shutdown), 161 162 /* bus interface */ 163 DEVMETHOD(bus_print_child, bus_generic_print_child), 164 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 165 166 /* MII interface */ 167 DEVMETHOD(miibus_readreg, pcn_miibus_readreg), 168 DEVMETHOD(miibus_writereg, pcn_miibus_writereg), 169 DEVMETHOD(miibus_statchg, pcn_miibus_statchg), 170 171 { 0, 0 } 172 }; 173 174 static driver_t pcn_driver = { 175 "pcn", 176 pcn_methods, 177 sizeof(struct pcn_softc) 178 }; 179 180 static devclass_t pcn_devclass; 181 182 DRIVER_MODULE(if_pcn, pci, pcn_driver, pcn_devclass, 0, 0); 183 DRIVER_MODULE(miibus, pcn, miibus_driver, miibus_devclass, 0, 0); 184 185 #define PCN_CSR_SETBIT(sc, reg, x) \ 186 pcn_csr_write(sc, reg, pcn_csr_read(sc, reg) | (x)) 187 188 #define PCN_CSR_CLRBIT(sc, reg, x) \ 189 pcn_csr_write(sc, reg, pcn_csr_read(sc, reg) & ~(x)) 190 191 #define PCN_BCR_SETBIT(sc, reg, x) \ 192 pcn_bcr_write(sc, reg, pcn_bcr_read(sc, reg) | (x)) 193 194 #define PCN_BCR_CLRBIT(sc, reg, x) \ 195 pcn_bcr_write(sc, reg, pcn_bcr_read(sc, reg) & ~(x)) 196 197 static u_int32_t pcn_csr_read(sc, reg) 198 struct pcn_softc *sc; 199 int reg; 200 { 201 CSR_WRITE_4(sc, PCN_IO32_RAP, reg); 202 return(CSR_READ_4(sc, PCN_IO32_RDP)); 203 } 204 205 static u_int16_t pcn_csr_read16(sc, reg) 206 struct pcn_softc *sc; 207 int reg; 208 { 209 CSR_WRITE_2(sc, PCN_IO16_RAP, reg); 210 return(CSR_READ_2(sc, PCN_IO16_RDP)); 211 } 212 213 static void pcn_csr_write(sc, reg, val) 214 struct pcn_softc *sc; 215 int reg; 216 { 217 CSR_WRITE_4(sc, PCN_IO32_RAP, reg); 218 CSR_WRITE_4(sc, PCN_IO32_RDP, val); 219 return; 220 } 221 222 static u_int32_t pcn_bcr_read(sc, reg) 223 struct pcn_softc *sc; 224 int reg; 225 { 226 CSR_WRITE_4(sc, PCN_IO32_RAP, reg); 227 return(CSR_READ_4(sc, PCN_IO32_BDP)); 228 } 229 230 static u_int16_t pcn_bcr_read16(sc, reg) 231 struct pcn_softc *sc; 232 int reg; 233 { 234 CSR_WRITE_2(sc, PCN_IO16_RAP, reg); 235 return(CSR_READ_2(sc, PCN_IO16_BDP)); 236 } 237 238 static void pcn_bcr_write(sc, reg, val) 239 struct pcn_softc *sc; 240 int reg; 241 { 242 CSR_WRITE_4(sc, PCN_IO32_RAP, reg); 243 CSR_WRITE_4(sc, PCN_IO32_BDP, val); 244 return; 245 } 246 247 static int pcn_miibus_readreg(dev, phy, reg) 248 device_t dev; 249 int phy, reg; 250 { 251 struct pcn_softc *sc; 252 int val; 253 254 sc = device_get_softc(dev); 255 256 if (sc->pcn_phyaddr && phy > sc->pcn_phyaddr) 257 return(0); 258 259 pcn_bcr_write(sc, PCN_BCR_MIIADDR, reg | (phy << 5)); 260 val = pcn_bcr_read(sc, PCN_BCR_MIIDATA) & 0xFFFF; 261 if (val == 0xFFFF) 262 return(0); 263 264 sc->pcn_phyaddr = phy; 265 266 return(val); 267 } 268 269 static int pcn_miibus_writereg(dev, phy, reg, data) 270 device_t dev; 271 int phy, reg, data; 272 { 273 struct pcn_softc *sc; 274 275 sc = device_get_softc(dev); 276 277 pcn_bcr_write(sc, PCN_BCR_MIIADDR, reg | (phy << 5)); 278 pcn_bcr_write(sc, PCN_BCR_MIIDATA, data); 279 280 return(0); 281 } 282 283 static void pcn_miibus_statchg(dev) 284 device_t dev; 285 { 286 struct pcn_softc *sc; 287 struct mii_data *mii; 288 289 sc = device_get_softc(dev); 290 mii = device_get_softc(sc->pcn_miibus); 291 292 if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) { 293 PCN_BCR_SETBIT(sc, PCN_BCR_DUPLEX, PCN_DUPLEX_FDEN); 294 } else { 295 PCN_BCR_CLRBIT(sc, PCN_BCR_DUPLEX, PCN_DUPLEX_FDEN); 296 } 297 298 return; 299 } 300 301 #define DC_POLY 0xEDB88320 302 303 static u_int32_t pcn_crc(addr) 304 caddr_t addr; 305 { 306 u_int32_t idx, bit, data, crc; 307 308 /* Compute CRC for the address value. */ 309 crc = 0xFFFFFFFF; /* initial value */ 310 311 for (idx = 0; idx < 6; idx++) { 312 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) 313 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? DC_POLY : 0); 314 } 315 316 return ((crc >> 26) & 0x3F); 317 } 318 319 static void pcn_setmulti(sc) 320 struct pcn_softc *sc; 321 { 322 struct ifnet *ifp; 323 struct ifmultiaddr *ifma; 324 u_int32_t h, i; 325 u_int16_t hashes[4] = { 0, 0, 0, 0 }; 326 327 ifp = &sc->arpcom.ac_if; 328 329 PCN_CSR_SETBIT(sc, PCN_CSR_EXTCTL1, PCN_EXTCTL1_SPND); 330 331 if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { 332 for (i = 0; i < 4; i++) 333 pcn_csr_write(sc, PCN_CSR_MAR0 + i, 0xFFFF); 334 PCN_CSR_CLRBIT(sc, PCN_CSR_EXTCTL1, PCN_EXTCTL1_SPND); 335 return; 336 } 337 338 /* first, zot all the existing hash bits */ 339 for (i = 0; i < 4; i++) 340 pcn_csr_write(sc, PCN_CSR_MAR0 + i, 0); 341 342 /* now program new ones */ 343 for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL; 344 ifma = ifma->ifma_link.le_next) { 345 if (ifma->ifma_addr->sa_family != AF_LINK) 346 continue; 347 h = pcn_crc(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); 348 hashes[h >> 4] |= 1 << (h & 0xF); 349 } 350 351 for (i = 0; i < 4; i++) 352 pcn_csr_write(sc, PCN_CSR_MAR0 + i, hashes[i]); 353 354 PCN_CSR_CLRBIT(sc, PCN_CSR_EXTCTL1, PCN_EXTCTL1_SPND); 355 356 return; 357 } 358 359 static void pcn_reset(sc) 360 struct pcn_softc *sc; 361 { 362 /* 363 * Issue a reset by reading from the RESET register. 364 * Note that we don't know if the chip is operating in 365 * 16-bit or 32-bit mode at this point, so we attempt 366 * to reset the chip both ways. If one fails, the other 367 * will succeed. 368 */ 369 CSR_READ_2(sc, PCN_IO16_RESET); 370 CSR_READ_4(sc, PCN_IO32_RESET); 371 372 /* Wait a little while for the chip to get its brains in order. */ 373 DELAY(1000); 374 375 /* Select 32-bit (DWIO) mode */ 376 CSR_WRITE_4(sc, PCN_IO32_RDP, 0); 377 378 /* Select software style 3. */ 379 pcn_bcr_write(sc, PCN_BCR_SSTYLE, PCN_SWSTYLE_PCNETPCI_BURST); 380 381 return; 382 } 383 384 /* 385 * Probe for an AMD chip. Check the PCI vendor and device 386 * IDs against our list and return a device name if we find a match. 387 */ 388 static int pcn_probe(dev) 389 device_t dev; 390 { 391 struct pcn_type *t; 392 struct pcn_softc *sc; 393 int rid; 394 u_int32_t chip_id; 395 396 t = pcn_devs; 397 sc = device_get_softc(dev); 398 399 while(t->pcn_name != NULL) { 400 if ((pci_get_vendor(dev) == t->pcn_vid) && 401 (pci_get_device(dev) == t->pcn_did)) { 402 /* 403 * Temporarily map the I/O space 404 * so we can read the chip ID register. 405 */ 406 rid = PCN_RID; 407 sc->pcn_res = bus_alloc_resource(dev, PCN_RES, &rid, 408 0, ~0, 1, RF_ACTIVE); 409 if (sc->pcn_res == NULL) { 410 device_printf(dev, 411 "couldn't map ports/memory\n"); 412 return(ENXIO); 413 } 414 sc->pcn_btag = rman_get_bustag(sc->pcn_res); 415 sc->pcn_bhandle = rman_get_bushandle(sc->pcn_res); 416 /* 417 * Note: we can *NOT* put the chip into 418 * 32-bit mode yet. The lnc driver will only 419 * work in 16-bit mode, and once the chip 420 * goes into 32-bit mode, the only way to 421 * get it out again is with a hardware reset. 422 * So if pcn_probe() is called before the 423 * lnc driver's probe routine, the chip will 424 * be locked into 32-bit operation and the lnc 425 * driver will be unable to attach to it. 426 * Note II: if the chip happens to already 427 * be in 32-bit mode, we still need to check 428 * the chip ID, but first we have to detect 429 * 32-bit mode using only 16-bit operations. 430 * The safest way to do this is to read the 431 * PCI subsystem ID from BCR23/24 and compare 432 * that with the value read from PCI config 433 * space. 434 */ 435 chip_id = pcn_bcr_read16(sc, PCN_BCR_PCISUBSYSID); 436 chip_id <<= 16; 437 chip_id |= pcn_bcr_read16(sc, PCN_BCR_PCISUBVENID); 438 /* 439 * Note III: the test for 0x10001000 is a hack to 440 * pacify VMware, who's pseudo-PCnet interface is 441 * broken. Reading the subsystem register from PCI 442 * config space yeilds 0x00000000 while reading the 443 * same value from I/O space yeilds 0x10001000. It's 444 * not supposed to be that way. 445 */ 446 if (chip_id == pci_read_config(dev, 447 PCIR_SUBVEND_0, 4) || chip_id == 0x10001000) { 448 /* We're in 16-bit mode. */ 449 chip_id = pcn_csr_read16(sc, PCN_CSR_CHIPID1); 450 chip_id <<= 16; 451 chip_id |= pcn_csr_read16(sc, PCN_CSR_CHIPID0); 452 } else { 453 /* We're in 32-bit mode. */ 454 chip_id = pcn_csr_read(sc, PCN_CSR_CHIPID1); 455 chip_id <<= 16; 456 chip_id |= pcn_csr_read(sc, PCN_CSR_CHIPID0); 457 } 458 bus_release_resource(dev, PCN_RES, 459 PCN_RID, sc->pcn_res); 460 chip_id >>= 12; 461 sc->pcn_type = chip_id & PART_MASK; 462 switch(sc->pcn_type) { 463 case Am79C971: 464 case Am79C972: 465 case Am79C973: 466 case Am79C975: 467 case Am79C976: 468 case Am79C978: 469 break; 470 default: 471 return(ENXIO); 472 break; 473 } 474 device_set_desc(dev, t->pcn_name); 475 return(0); 476 } 477 t++; 478 } 479 480 return(ENXIO); 481 } 482 483 /* 484 * Attach the interface. Allocate softc structures, do ifmedia 485 * setup and ethernet/BPF attach. 486 */ 487 static int pcn_attach(dev) 488 device_t dev; 489 { 490 int s; 491 u_int32_t eaddr[2]; 492 u_int32_t command; 493 struct pcn_softc *sc; 494 struct ifnet *ifp; 495 int unit, error = 0, rid; 496 497 s = splimp(); 498 499 sc = device_get_softc(dev); 500 unit = device_get_unit(dev); 501 502 /* 503 * Handle power management nonsense. 504 */ 505 506 command = pci_read_config(dev, PCN_PCI_CAPID, 4) & 0x000000FF; 507 if (command == 0x01) { 508 509 command = pci_read_config(dev, PCN_PCI_PWRMGMTCTRL, 4); 510 if (command & PCN_PSTATE_MASK) { 511 u_int32_t iobase, membase, irq; 512 513 /* Save important PCI config data. */ 514 iobase = pci_read_config(dev, PCN_PCI_LOIO, 4); 515 membase = pci_read_config(dev, PCN_PCI_LOMEM, 4); 516 irq = pci_read_config(dev, PCN_PCI_INTLINE, 4); 517 518 /* Reset the power state. */ 519 printf("pcn%d: chip is in D%d power mode " 520 "-- setting to D0\n", unit, command & PCN_PSTATE_MASK); 521 command &= 0xFFFFFFFC; 522 pci_write_config(dev, PCN_PCI_PWRMGMTCTRL, command, 4); 523 524 /* Restore PCI config data. */ 525 pci_write_config(dev, PCN_PCI_LOIO, iobase, 4); 526 pci_write_config(dev, PCN_PCI_LOMEM, membase, 4); 527 pci_write_config(dev, PCN_PCI_INTLINE, irq, 4); 528 } 529 } 530 531 /* 532 * Map control/status registers. 533 */ 534 command = pci_read_config(dev, PCIR_COMMAND, 4); 535 command |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); 536 pci_write_config(dev, PCIR_COMMAND, command, 4); 537 command = pci_read_config(dev, PCIR_COMMAND, 4); 538 539 #ifdef PCN_USEIOSPACE 540 if (!(command & PCIM_CMD_PORTEN)) { 541 printf("pcn%d: failed to enable I/O ports!\n", unit); 542 error = ENXIO;; 543 goto fail; 544 } 545 #else 546 if (!(command & PCIM_CMD_MEMEN)) { 547 printf("pcn%d: failed to enable memory mapping!\n", unit); 548 error = ENXIO;; 549 goto fail; 550 } 551 #endif 552 553 rid = PCN_RID; 554 sc->pcn_res = bus_alloc_resource(dev, PCN_RES, &rid, 555 0, ~0, 1, RF_ACTIVE); 556 557 if (sc->pcn_res == NULL) { 558 printf("pcn%d: couldn't map ports/memory\n", unit); 559 error = ENXIO; 560 goto fail; 561 } 562 563 sc->pcn_btag = rman_get_bustag(sc->pcn_res); 564 sc->pcn_bhandle = rman_get_bushandle(sc->pcn_res); 565 566 /* Allocate interrupt */ 567 rid = 0; 568 sc->pcn_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 569 RF_SHAREABLE | RF_ACTIVE); 570 571 if (sc->pcn_irq == NULL) { 572 printf("pcn%d: couldn't map interrupt\n", unit); 573 bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res); 574 error = ENXIO; 575 goto fail; 576 } 577 578 error = bus_setup_intr(dev, sc->pcn_irq, INTR_TYPE_NET, 579 pcn_intr, sc, &sc->pcn_intrhand); 580 581 if (error) { 582 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->pcn_res); 583 bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res); 584 printf("pcn%d: couldn't set up irq\n", unit); 585 goto fail; 586 } 587 588 /* Reset the adapter. */ 589 pcn_reset(sc); 590 591 /* 592 * Get station address from the EEPROM. 593 */ 594 eaddr[0] = CSR_READ_4(sc, PCN_IO32_APROM00); 595 eaddr[1] = CSR_READ_4(sc, PCN_IO32_APROM01); 596 bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 597 598 /* 599 * An AMD chip was detected. Inform the world. 600 */ 601 printf("pcn%d: Ethernet address: %6D\n", unit, 602 sc->arpcom.ac_enaddr, ":"); 603 604 sc->pcn_unit = unit; 605 callout_handle_init(&sc->pcn_stat_ch); 606 607 sc->pcn_ldata = contigmalloc(sizeof(struct pcn_list_data), M_DEVBUF, 608 M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0); 609 610 if (sc->pcn_ldata == NULL) { 611 printf("pcn%d: no memory for list buffers!\n", unit); 612 bus_teardown_intr(dev, sc->pcn_irq, sc->pcn_intrhand); 613 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->pcn_irq); 614 bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res); 615 error = ENXIO; 616 goto fail; 617 } 618 bzero(sc->pcn_ldata, sizeof(struct pcn_list_data)); 619 620 ifp = &sc->arpcom.ac_if; 621 ifp->if_softc = sc; 622 ifp->if_unit = unit; 623 ifp->if_name = "pcn"; 624 ifp->if_mtu = ETHERMTU; 625 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 626 ifp->if_ioctl = pcn_ioctl; 627 ifp->if_output = ether_output; 628 ifp->if_start = pcn_start; 629 ifp->if_watchdog = pcn_watchdog; 630 ifp->if_init = pcn_init; 631 ifp->if_baudrate = 10000000; 632 ifp->if_snd.ifq_maxlen = PCN_TX_LIST_CNT - 1; 633 634 /* 635 * Do MII setup. 636 */ 637 if (mii_phy_probe(dev, &sc->pcn_miibus, 638 pcn_ifmedia_upd, pcn_ifmedia_sts)) { 639 printf("pcn%d: MII without any PHY!\n", sc->pcn_unit); 640 contigfree(sc->pcn_ldata, sizeof(struct pcn_list_data), 641 M_DEVBUF); 642 bus_teardown_intr(dev, sc->pcn_irq, sc->pcn_intrhand); 643 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->pcn_irq); 644 bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res); 645 error = ENXIO; 646 goto fail; 647 } 648 649 /* 650 * Call MI attach routine. 651 */ 652 ether_ifattach(ifp, ETHER_BPF_SUPPORTED); 653 callout_handle_init(&sc->pcn_stat_ch); 654 655 fail: 656 splx(s); 657 return(error); 658 } 659 660 static int pcn_detach(dev) 661 device_t dev; 662 { 663 struct pcn_softc *sc; 664 struct ifnet *ifp; 665 int s; 666 667 s = splimp(); 668 669 sc = device_get_softc(dev); 670 ifp = &sc->arpcom.ac_if; 671 672 pcn_reset(sc); 673 pcn_stop(sc); 674 ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); 675 676 if (sc->pcn_miibus != NULL) { 677 bus_generic_detach(dev); 678 device_delete_child(dev, sc->pcn_miibus); 679 } 680 681 bus_teardown_intr(dev, sc->pcn_irq, sc->pcn_intrhand); 682 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->pcn_irq); 683 bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res); 684 685 contigfree(sc->pcn_ldata, sizeof(struct pcn_list_data), M_DEVBUF); 686 687 splx(s); 688 689 return(0); 690 } 691 692 /* 693 * Initialize the transmit descriptors. 694 */ 695 static int pcn_list_tx_init(sc) 696 struct pcn_softc *sc; 697 { 698 struct pcn_list_data *ld; 699 struct pcn_ring_data *cd; 700 int i; 701 702 cd = &sc->pcn_cdata; 703 ld = sc->pcn_ldata; 704 705 for (i = 0; i < PCN_TX_LIST_CNT; i++) { 706 cd->pcn_tx_chain[i] = NULL; 707 ld->pcn_tx_list[i].pcn_tbaddr = 0; 708 ld->pcn_tx_list[i].pcn_txctl = 0; 709 ld->pcn_tx_list[i].pcn_txstat = 0; 710 } 711 712 cd->pcn_tx_prod = cd->pcn_tx_cons = cd->pcn_tx_cnt = 0; 713 714 return(0); 715 } 716 717 718 /* 719 * Initialize the RX descriptors and allocate mbufs for them. 720 */ 721 static int pcn_list_rx_init(sc) 722 struct pcn_softc *sc; 723 { 724 struct pcn_list_data *ld; 725 struct pcn_ring_data *cd; 726 int i; 727 728 ld = sc->pcn_ldata; 729 cd = &sc->pcn_cdata; 730 731 for (i = 0; i < PCN_RX_LIST_CNT; i++) { 732 if (pcn_newbuf(sc, i, NULL) == ENOBUFS) 733 return(ENOBUFS); 734 } 735 736 cd->pcn_rx_prod = 0; 737 738 return(0); 739 } 740 741 /* 742 * Initialize an RX descriptor and attach an MBUF cluster. 743 */ 744 static int pcn_newbuf(sc, idx, m) 745 struct pcn_softc *sc; 746 int idx; 747 struct mbuf *m; 748 { 749 struct mbuf *m_new = NULL; 750 struct pcn_rx_desc *c; 751 752 c = &sc->pcn_ldata->pcn_rx_list[idx]; 753 754 if (m == NULL) { 755 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 756 if (m_new == NULL) 757 return(ENOBUFS); 758 759 MCLGET(m_new, M_DONTWAIT); 760 if (!(m_new->m_flags & M_EXT)) { 761 m_freem(m_new); 762 return(ENOBUFS); 763 } 764 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 765 } else { 766 m_new = m; 767 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 768 m_new->m_data = m_new->m_ext.ext_buf; 769 } 770 771 m_adj(m_new, ETHER_ALIGN); 772 773 sc->pcn_cdata.pcn_rx_chain[idx] = m_new; 774 c->pcn_rbaddr = vtophys(mtod(m_new, caddr_t)); 775 c->pcn_bufsz = (~(PCN_RXLEN) + 1) & PCN_RXLEN_BUFSZ; 776 c->pcn_bufsz |= PCN_RXLEN_MBO; 777 c->pcn_rxstat = PCN_RXSTAT_STP|PCN_RXSTAT_ENP|PCN_RXSTAT_OWN; 778 779 return(0); 780 } 781 782 /* 783 * A frame has been uploaded: pass the resulting mbuf chain up to 784 * the higher level protocols. 785 */ 786 static void pcn_rxeof(sc) 787 struct pcn_softc *sc; 788 { 789 struct ether_header *eh; 790 struct mbuf *m; 791 struct ifnet *ifp; 792 struct pcn_rx_desc *cur_rx; 793 int i; 794 795 ifp = &sc->arpcom.ac_if; 796 i = sc->pcn_cdata.pcn_rx_prod; 797 798 while(PCN_OWN_RXDESC(&sc->pcn_ldata->pcn_rx_list[i])) { 799 cur_rx = &sc->pcn_ldata->pcn_rx_list[i]; 800 m = sc->pcn_cdata.pcn_rx_chain[i]; 801 sc->pcn_cdata.pcn_rx_chain[i] = NULL; 802 803 /* 804 * If an error occurs, update stats, clear the 805 * status word and leave the mbuf cluster in place: 806 * it should simply get re-used next time this descriptor 807 * comes up in the ring. 808 */ 809 if (cur_rx->pcn_rxstat & PCN_RXSTAT_ERR) { 810 ifp->if_ierrors++; 811 pcn_newbuf(sc, i, m); 812 PCN_INC(i, PCN_RX_LIST_CNT); 813 continue; 814 } 815 816 if (pcn_newbuf(sc, i, NULL)) { 817 /* Ran out of mbufs; recycle this one. */ 818 pcn_newbuf(sc, i, m); 819 ifp->if_ierrors++; 820 PCN_INC(i, PCN_RX_LIST_CNT); 821 continue; 822 } 823 824 PCN_INC(i, PCN_RX_LIST_CNT); 825 826 /* No errors; receive the packet. */ 827 ifp->if_ipackets++; 828 eh = mtod(m, struct ether_header *); 829 m->m_len = m->m_pkthdr.len = 830 cur_rx->pcn_rxlen - ETHER_CRC_LEN; 831 m->m_pkthdr.rcvif = ifp; 832 833 /* Remove header from mbuf and pass it on. */ 834 m_adj(m, sizeof(struct ether_header)); 835 ether_input(ifp, eh, m); 836 } 837 838 sc->pcn_cdata.pcn_rx_prod = i; 839 840 return; 841 } 842 843 /* 844 * A frame was downloaded to the chip. It's safe for us to clean up 845 * the list buffers. 846 */ 847 848 static void pcn_txeof(sc) 849 struct pcn_softc *sc; 850 { 851 struct pcn_tx_desc *cur_tx = NULL; 852 struct ifnet *ifp; 853 u_int32_t idx; 854 855 ifp = &sc->arpcom.ac_if; 856 857 /* 858 * Go through our tx list and free mbufs for those 859 * frames that have been transmitted. 860 */ 861 idx = sc->pcn_cdata.pcn_tx_cons; 862 while (idx != sc->pcn_cdata.pcn_tx_prod) { 863 cur_tx = &sc->pcn_ldata->pcn_tx_list[idx]; 864 865 if (!PCN_OWN_TXDESC(cur_tx)) 866 break; 867 868 if (!(cur_tx->pcn_txctl & PCN_TXCTL_ENP)) { 869 sc->pcn_cdata.pcn_tx_cnt--; 870 PCN_INC(idx, PCN_TX_LIST_CNT); 871 continue; 872 } 873 874 if (cur_tx->pcn_txctl & PCN_TXCTL_ERR) { 875 ifp->if_oerrors++; 876 if (cur_tx->pcn_txstat & PCN_TXSTAT_EXDEF) 877 ifp->if_collisions++; 878 if (cur_tx->pcn_txstat & PCN_TXSTAT_RTRY) 879 ifp->if_collisions++; 880 } 881 882 ifp->if_collisions += 883 cur_tx->pcn_txstat & PCN_TXSTAT_TRC; 884 885 ifp->if_opackets++; 886 if (sc->pcn_cdata.pcn_tx_chain[idx] != NULL) { 887 m_freem(sc->pcn_cdata.pcn_tx_chain[idx]); 888 sc->pcn_cdata.pcn_tx_chain[idx] = NULL; 889 } 890 891 sc->pcn_cdata.pcn_tx_cnt--; 892 PCN_INC(idx, PCN_TX_LIST_CNT); 893 } 894 895 if (idx != sc->pcn_cdata.pcn_tx_cons) { 896 /* Some buffers have been freed. */ 897 sc->pcn_cdata.pcn_tx_cons = idx; 898 ifp->if_flags &= ~IFF_OACTIVE; 899 } 900 ifp->if_timer = (sc->pcn_cdata.pcn_tx_cnt == 0) ? 0 : 5; 901 902 return; 903 } 904 905 static void pcn_tick(xsc) 906 void *xsc; 907 { 908 struct pcn_softc *sc; 909 struct mii_data *mii; 910 struct ifnet *ifp; 911 int s; 912 913 s = splimp(); 914 915 sc = xsc; 916 ifp = &sc->arpcom.ac_if; 917 918 mii = device_get_softc(sc->pcn_miibus); 919 mii_tick(mii); 920 921 if (sc->pcn_link & !(mii->mii_media_status & IFM_ACTIVE)) 922 sc->pcn_link = 0; 923 924 if (!sc->pcn_link) { 925 mii_pollstat(mii); 926 if (mii->mii_media_status & IFM_ACTIVE && 927 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) 928 sc->pcn_link++; 929 if (ifp->if_snd.ifq_head != NULL) 930 pcn_start(ifp); 931 } 932 933 sc->pcn_stat_ch = timeout(pcn_tick, sc, hz); 934 935 splx(s); 936 937 return; 938 } 939 940 static void pcn_intr(arg) 941 void *arg; 942 { 943 struct pcn_softc *sc; 944 struct ifnet *ifp; 945 u_int32_t status; 946 947 sc = arg; 948 ifp = &sc->arpcom.ac_if; 949 950 /* Supress unwanted interrupts */ 951 if (!(ifp->if_flags & IFF_UP)) { 952 pcn_stop(sc); 953 return; 954 } 955 956 CSR_WRITE_4(sc, PCN_IO32_RAP, PCN_CSR_CSR); 957 958 while ((status = CSR_READ_4(sc, PCN_IO32_RDP)) & PCN_CSR_INTR) { 959 CSR_WRITE_4(sc, PCN_IO32_RDP, status); 960 961 if (status & PCN_CSR_RINT) 962 pcn_rxeof(sc); 963 964 if (status & PCN_CSR_TINT) 965 pcn_txeof(sc); 966 967 if (status & PCN_CSR_ERR) { 968 pcn_init(sc); 969 break; 970 } 971 } 972 973 if (ifp->if_snd.ifq_head != NULL) 974 pcn_start(ifp); 975 976 return; 977 } 978 979 /* 980 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data 981 * pointers to the fragment pointers. 982 */ 983 static int pcn_encap(sc, m_head, txidx) 984 struct pcn_softc *sc; 985 struct mbuf *m_head; 986 u_int32_t *txidx; 987 { 988 struct pcn_tx_desc *f = NULL; 989 struct mbuf *m; 990 int frag, cur, cnt = 0; 991 992 /* 993 * Start packing the mbufs in this chain into 994 * the fragment pointers. Stop when we run out 995 * of fragments or hit the end of the mbuf chain. 996 */ 997 m = m_head; 998 cur = frag = *txidx; 999 1000 for (m = m_head; m != NULL; m = m->m_next) { 1001 if (m->m_len != 0) { 1002 if ((PCN_TX_LIST_CNT - 1003 (sc->pcn_cdata.pcn_tx_cnt + cnt)) < 2) 1004 return(ENOBUFS); 1005 f = &sc->pcn_ldata->pcn_tx_list[frag]; 1006 f->pcn_txctl = (~(m->m_len) + 1) & PCN_TXCTL_BUFSZ; 1007 f->pcn_txctl |= PCN_TXCTL_MBO; 1008 f->pcn_tbaddr = vtophys(mtod(m, vm_offset_t)); 1009 if (cnt == 0) 1010 f->pcn_txctl |= PCN_TXCTL_STP; 1011 else 1012 f->pcn_txctl |= PCN_TXCTL_OWN; 1013 cur = frag; 1014 PCN_INC(frag, PCN_TX_LIST_CNT); 1015 cnt++; 1016 } 1017 } 1018 1019 if (m != NULL) 1020 return(ENOBUFS); 1021 1022 sc->pcn_cdata.pcn_tx_chain[cur] = m_head; 1023 sc->pcn_ldata->pcn_tx_list[cur].pcn_txctl |= 1024 PCN_TXCTL_ENP|PCN_TXCTL_ADD_FCS|PCN_TXCTL_MORE_LTINT; 1025 sc->pcn_ldata->pcn_tx_list[*txidx].pcn_txctl |= PCN_TXCTL_OWN; 1026 sc->pcn_cdata.pcn_tx_cnt += cnt; 1027 *txidx = frag; 1028 1029 return(0); 1030 } 1031 1032 /* 1033 * Main transmit routine. To avoid having to do mbuf copies, we put pointers 1034 * to the mbuf data regions directly in the transmit lists. We also save a 1035 * copy of the pointers since the transmit list fragment pointers are 1036 * physical addresses. 1037 */ 1038 static void pcn_start(ifp) 1039 struct ifnet *ifp; 1040 { 1041 struct pcn_softc *sc; 1042 struct mbuf *m_head = NULL; 1043 u_int32_t idx; 1044 1045 sc = ifp->if_softc; 1046 1047 if (!sc->pcn_link) 1048 return; 1049 1050 idx = sc->pcn_cdata.pcn_tx_prod; 1051 1052 if (ifp->if_flags & IFF_OACTIVE) 1053 return; 1054 1055 while(sc->pcn_cdata.pcn_tx_chain[idx] == NULL) { 1056 IF_DEQUEUE(&ifp->if_snd, m_head); 1057 if (m_head == NULL) 1058 break; 1059 1060 if (pcn_encap(sc, m_head, &idx)) { 1061 IF_PREPEND(&ifp->if_snd, m_head); 1062 ifp->if_flags |= IFF_OACTIVE; 1063 break; 1064 } 1065 1066 /* 1067 * If there's a BPF listener, bounce a copy of this frame 1068 * to him. 1069 */ 1070 if (ifp->if_bpf) 1071 bpf_mtap(ifp, m_head); 1072 1073 } 1074 1075 /* Transmit */ 1076 sc->pcn_cdata.pcn_tx_prod = idx; 1077 pcn_csr_write(sc, PCN_CSR_CSR, PCN_CSR_TX|PCN_CSR_INTEN); 1078 1079 /* 1080 * Set a timeout in case the chip goes out to lunch. 1081 */ 1082 ifp->if_timer = 5; 1083 1084 return; 1085 } 1086 1087 void pcn_setfilt(ifp) 1088 struct ifnet *ifp; 1089 { 1090 struct pcn_softc *sc; 1091 1092 sc = ifp->if_softc; 1093 1094 /* If we want promiscuous mode, set the allframes bit. */ 1095 if (ifp->if_flags & IFF_PROMISC) { 1096 PCN_CSR_SETBIT(sc, PCN_CSR_MODE, PCN_MODE_PROMISC); 1097 } else { 1098 PCN_CSR_CLRBIT(sc, PCN_CSR_MODE, PCN_MODE_PROMISC); 1099 } 1100 1101 /* Set the capture broadcast bit to capture broadcast frames. */ 1102 if (ifp->if_flags & IFF_BROADCAST) { 1103 PCN_CSR_CLRBIT(sc, PCN_CSR_MODE, PCN_MODE_RXNOBROAD); 1104 } else { 1105 PCN_CSR_SETBIT(sc, PCN_CSR_MODE, PCN_MODE_RXNOBROAD); 1106 } 1107 1108 return; 1109 } 1110 1111 static void pcn_init(xsc) 1112 void *xsc; 1113 { 1114 struct pcn_softc *sc = xsc; 1115 struct ifnet *ifp = &sc->arpcom.ac_if; 1116 struct mii_data *mii = NULL; 1117 int s; 1118 1119 s = splimp(); 1120 1121 /* 1122 * Cancel pending I/O and free all RX/TX buffers. 1123 */ 1124 pcn_stop(sc); 1125 pcn_reset(sc); 1126 1127 mii = device_get_softc(sc->pcn_miibus); 1128 1129 /* Set MAC address */ 1130 pcn_csr_write(sc, PCN_CSR_PAR0, 1131 ((u_int16_t *)sc->arpcom.ac_enaddr)[0]); 1132 pcn_csr_write(sc, PCN_CSR_PAR1, 1133 ((u_int16_t *)sc->arpcom.ac_enaddr)[1]); 1134 pcn_csr_write(sc, PCN_CSR_PAR2, 1135 ((u_int16_t *)sc->arpcom.ac_enaddr)[2]); 1136 1137 /* Init circular RX list. */ 1138 if (pcn_list_rx_init(sc) == ENOBUFS) { 1139 printf("pcn%d: initialization failed: no " 1140 "memory for rx buffers\n", sc->pcn_unit); 1141 pcn_stop(sc); 1142 (void)splx(s); 1143 return; 1144 } 1145 1146 /* Set up RX filter. */ 1147 pcn_setfilt(ifp); 1148 1149 /* 1150 * Init tx descriptors. 1151 */ 1152 pcn_list_tx_init(sc); 1153 1154 /* Set up the mode register. */ 1155 pcn_csr_write(sc, PCN_CSR_MODE, PCN_PORT_MII); 1156 1157 /* 1158 * Load the multicast filter. 1159 */ 1160 pcn_setmulti(sc); 1161 1162 /* 1163 * Load the addresses of the RX and TX lists. 1164 */ 1165 pcn_csr_write(sc, PCN_CSR_RXADDR0, 1166 vtophys(&sc->pcn_ldata->pcn_rx_list[0]) & 0xFFFF); 1167 pcn_csr_write(sc, PCN_CSR_RXADDR1, 1168 (vtophys(&sc->pcn_ldata->pcn_rx_list[0]) >> 16) & 0xFFFF); 1169 pcn_csr_write(sc, PCN_CSR_TXADDR0, 1170 vtophys(&sc->pcn_ldata->pcn_tx_list[0]) & 0xFFFF); 1171 pcn_csr_write(sc, PCN_CSR_TXADDR1, 1172 (vtophys(&sc->pcn_ldata->pcn_tx_list[0]) >> 16) & 0xFFFF); 1173 1174 /* Set the RX and TX ring sizes. */ 1175 pcn_csr_write(sc, PCN_CSR_RXRINGLEN, (~PCN_RX_LIST_CNT) + 1); 1176 pcn_csr_write(sc, PCN_CSR_TXRINGLEN, (~PCN_TX_LIST_CNT) + 1); 1177 1178 /* We're not using the initialization block. */ 1179 pcn_csr_write(sc, PCN_CSR_IAB1, 0); 1180 1181 /* Enable fast suspend mode. */ 1182 PCN_CSR_SETBIT(sc, PCN_CSR_EXTCTL2, PCN_EXTCTL2_FASTSPNDE); 1183 1184 /* 1185 * Enable burst read and write. Also set the no underflow 1186 * bit. This will avoid transmit underruns in certain 1187 * conditions while still providing decent performance. 1188 */ 1189 PCN_BCR_SETBIT(sc, PCN_BCR_BUSCTL, PCN_BUSCTL_NOUFLOW| 1190 PCN_BUSCTL_BREAD|PCN_BUSCTL_BWRITE); 1191 1192 /* Enable graceful recovery from underflow. */ 1193 PCN_CSR_SETBIT(sc, PCN_CSR_IMR, PCN_IMR_DXSUFLO); 1194 1195 /* Enable auto-padding of short TX frames. */ 1196 PCN_CSR_SETBIT(sc, PCN_CSR_TFEAT, PCN_TFEAT_PAD_TX); 1197 1198 /* Disable MII autoneg (we handle this ourselves). */ 1199 PCN_BCR_SETBIT(sc, PCN_BCR_MIICTL, PCN_MIICTL_DANAS); 1200 1201 if (sc->pcn_type == Am79C978) 1202 pcn_bcr_write(sc, PCN_BCR_PHYSEL, 1203 PCN_PHYSEL_PCNET|PCN_PHY_HOMEPNA); 1204 1205 /* Enable interrupts and start the controller running. */ 1206 pcn_csr_write(sc, PCN_CSR_CSR, PCN_CSR_INTEN|PCN_CSR_START); 1207 1208 mii_mediachg(mii); 1209 1210 ifp->if_flags |= IFF_RUNNING; 1211 ifp->if_flags &= ~IFF_OACTIVE; 1212 1213 (void)splx(s); 1214 sc->pcn_stat_ch = timeout(pcn_tick, sc, hz); 1215 1216 return; 1217 } 1218 1219 /* 1220 * Set media options. 1221 */ 1222 static int pcn_ifmedia_upd(ifp) 1223 struct ifnet *ifp; 1224 { 1225 struct pcn_softc *sc; 1226 struct mii_data *mii; 1227 1228 sc = ifp->if_softc; 1229 mii = device_get_softc(sc->pcn_miibus); 1230 1231 sc->pcn_link = 0; 1232 if (mii->mii_instance) { 1233 struct mii_softc *miisc; 1234 for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL; 1235 miisc = LIST_NEXT(miisc, mii_list)) 1236 mii_phy_reset(miisc); 1237 } 1238 mii_mediachg(mii); 1239 1240 return(0); 1241 } 1242 1243 /* 1244 * Report current media status. 1245 */ 1246 static void pcn_ifmedia_sts(ifp, ifmr) 1247 struct ifnet *ifp; 1248 struct ifmediareq *ifmr; 1249 { 1250 struct pcn_softc *sc; 1251 struct mii_data *mii; 1252 1253 sc = ifp->if_softc; 1254 1255 mii = device_get_softc(sc->pcn_miibus); 1256 mii_pollstat(mii); 1257 ifmr->ifm_active = mii->mii_media_active; 1258 ifmr->ifm_status = mii->mii_media_status; 1259 1260 return; 1261 } 1262 1263 static int pcn_ioctl(ifp, command, data) 1264 struct ifnet *ifp; 1265 u_long command; 1266 caddr_t data; 1267 { 1268 struct pcn_softc *sc = ifp->if_softc; 1269 struct ifreq *ifr = (struct ifreq *) data; 1270 struct mii_data *mii = NULL; 1271 int s, error = 0; 1272 1273 s = splimp(); 1274 1275 switch(command) { 1276 case SIOCSIFADDR: 1277 case SIOCGIFADDR: 1278 case SIOCSIFMTU: 1279 error = ether_ioctl(ifp, command, data); 1280 break; 1281 case SIOCSIFFLAGS: 1282 if (ifp->if_flags & IFF_UP) { 1283 if (ifp->if_flags & IFF_RUNNING && 1284 ifp->if_flags & IFF_PROMISC && 1285 !(sc->pcn_if_flags & IFF_PROMISC)) { 1286 PCN_CSR_SETBIT(sc, PCN_CSR_EXTCTL1, 1287 PCN_EXTCTL1_SPND); 1288 pcn_setfilt(ifp); 1289 PCN_CSR_CLRBIT(sc, PCN_CSR_EXTCTL1, 1290 PCN_EXTCTL1_SPND); 1291 pcn_csr_write(sc, PCN_CSR_CSR, 1292 PCN_CSR_INTEN|PCN_CSR_START); 1293 } else if (ifp->if_flags & IFF_RUNNING && 1294 !(ifp->if_flags & IFF_PROMISC) && 1295 sc->pcn_if_flags & IFF_PROMISC) { 1296 PCN_CSR_SETBIT(sc, PCN_CSR_EXTCTL1, 1297 PCN_EXTCTL1_SPND); 1298 pcn_setfilt(ifp); 1299 PCN_CSR_CLRBIT(sc, PCN_CSR_EXTCTL1, 1300 PCN_EXTCTL1_SPND); 1301 pcn_csr_write(sc, PCN_CSR_CSR, 1302 PCN_CSR_INTEN|PCN_CSR_START); 1303 } else if (!(ifp->if_flags & IFF_RUNNING)) 1304 pcn_init(sc); 1305 } else { 1306 if (ifp->if_flags & IFF_RUNNING) 1307 pcn_stop(sc); 1308 } 1309 sc->pcn_if_flags = ifp->if_flags; 1310 error = 0; 1311 break; 1312 case SIOCADDMULTI: 1313 case SIOCDELMULTI: 1314 pcn_setmulti(sc); 1315 error = 0; 1316 break; 1317 case SIOCGIFMEDIA: 1318 case SIOCSIFMEDIA: 1319 mii = device_get_softc(sc->pcn_miibus); 1320 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); 1321 break; 1322 default: 1323 error = EINVAL; 1324 break; 1325 } 1326 1327 (void)splx(s); 1328 1329 return(error); 1330 } 1331 1332 static void pcn_watchdog(ifp) 1333 struct ifnet *ifp; 1334 { 1335 struct pcn_softc *sc; 1336 1337 sc = ifp->if_softc; 1338 1339 ifp->if_oerrors++; 1340 printf("pcn%d: watchdog timeout\n", sc->pcn_unit); 1341 1342 pcn_stop(sc); 1343 pcn_reset(sc); 1344 pcn_init(sc); 1345 1346 if (ifp->if_snd.ifq_head != NULL) 1347 pcn_start(ifp); 1348 1349 return; 1350 } 1351 1352 /* 1353 * Stop the adapter and free any mbufs allocated to the 1354 * RX and TX lists. 1355 */ 1356 static void pcn_stop(sc) 1357 struct pcn_softc *sc; 1358 { 1359 int i; 1360 struct ifnet *ifp; 1361 1362 ifp = &sc->arpcom.ac_if; 1363 ifp->if_timer = 0; 1364 1365 untimeout(pcn_tick, sc, sc->pcn_stat_ch); 1366 PCN_CSR_SETBIT(sc, PCN_CSR_CSR, PCN_CSR_STOP); 1367 sc->pcn_link = 0; 1368 1369 /* 1370 * Free data in the RX lists. 1371 */ 1372 for (i = 0; i < PCN_RX_LIST_CNT; i++) { 1373 if (sc->pcn_cdata.pcn_rx_chain[i] != NULL) { 1374 m_freem(sc->pcn_cdata.pcn_rx_chain[i]); 1375 sc->pcn_cdata.pcn_rx_chain[i] = NULL; 1376 } 1377 } 1378 bzero((char *)&sc->pcn_ldata->pcn_rx_list, 1379 sizeof(sc->pcn_ldata->pcn_rx_list)); 1380 1381 /* 1382 * Free the TX list buffers. 1383 */ 1384 for (i = 0; i < PCN_TX_LIST_CNT; i++) { 1385 if (sc->pcn_cdata.pcn_tx_chain[i] != NULL) { 1386 m_freem(sc->pcn_cdata.pcn_tx_chain[i]); 1387 sc->pcn_cdata.pcn_tx_chain[i] = NULL; 1388 } 1389 } 1390 1391 bzero((char *)&sc->pcn_ldata->pcn_tx_list, 1392 sizeof(sc->pcn_ldata->pcn_tx_list)); 1393 1394 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1395 1396 return; 1397 } 1398 1399 /* 1400 * Stop all chip I/O so that the kernel's probe routines don't 1401 * get confused by errant DMAs when rebooting. 1402 */ 1403 static void pcn_shutdown(dev) 1404 device_t dev; 1405 { 1406 struct pcn_softc *sc; 1407 1408 sc = device_get_softc(dev); 1409 1410 pcn_reset(sc); 1411 pcn_stop(sc); 1412 1413 return; 1414 } 1415