1/*- 2 * Copyright (c) 2003 3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4 * 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 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * Author: Hartmut Brandt <harti@freebsd.org> 28 * 29 * Driver for IDT77252 based cards like ProSum's. 30 */ 31 32#include <sys/cdefs.h> 33__FBSDID("$FreeBSD$"); 34 35#include "opt_inet.h" 36#include "opt_natm.h" 37 38#include <sys/types.h> 39#include <sys/param.h> 40#include <sys/systm.h> 41#include <sys/malloc.h> 42#include <sys/kernel.h> 43#include <sys/bus.h> 44#include <sys/errno.h> 45#include <sys/conf.h> 46#include <sys/module.h> 47#include <sys/lock.h> 48#include <sys/mutex.h> 49#include <sys/sysctl.h> 50#include <sys/queue.h> 51#include <sys/condvar.h> 52#include <vm/uma.h> 53 54#include <sys/sockio.h> 55#include <sys/mbuf.h> 56#include <sys/socket.h> 57 58#include <net/if.h> 59#include <net/if_media.h> 60#include <net/if_types.h> 61#include <net/if_atm.h> 62#include <net/route.h> 63#ifdef ENABLE_BPF 64#include <net/bpf.h> 65#endif 66#include <netinet/in.h> 67#include <netinet/if_atm.h> 68 69#include <machine/bus.h> 70#include <machine/resource.h> 71#include <sys/bus.h> 72#include <sys/rman.h> 73#include <sys/mbpool.h> 74#include <dev/pci/pcireg.h> 75#include <dev/pci/pcivar.h> 76 77#include <dev/utopia/utopia.h> 78#include <dev/patm/idt77252reg.h> 79#include <dev/patm/if_patmvar.h> 80 81MODULE_DEPEND(patm, utopia, 1, 1, 1); 82MODULE_DEPEND(patm, pci, 1, 1, 1); 83MODULE_DEPEND(patm, atm, 1, 1, 1); 84MODULE_DEPEND(patm, libmbpool, 1, 1, 1); 85 86devclass_t patm_devclass; 87 88static int patm_probe(device_t dev); 89static int patm_attach(device_t dev); 90static int patm_detach(device_t dev); 91static device_method_t patm_methods[] = { 92 DEVMETHOD(device_probe, patm_probe), 93 DEVMETHOD(device_attach, patm_attach), 94 DEVMETHOD(device_detach, patm_detach), 95 {0,0} 96}; 97static driver_t patm_driver = { 98 "patm", 99 patm_methods, 100 sizeof(struct patm_softc), 101}; 102DRIVER_MODULE(patm, pci, patm_driver, patm_devclass, NULL, 0); 103 104static const struct { 105 u_int devid; 106 const char *desc; 107} devs[] = { 108 { PCI_DEVICE_IDT77252, "NICStAR (77222/77252) ATM adapter" }, 109 { PCI_DEVICE_IDT77v252, "NICStAR (77v252) ATM adapter" }, 110 { PCI_DEVICE_IDT77v222, "NICStAR (77v222) ATM adapter" }, 111 { 0, NULL } 112}; 113 114SYSCTL_DECL(_hw_atm); 115 116static int patm_phy_readregs(struct ifatm *, u_int, uint8_t *, u_int *); 117static int patm_phy_writereg(struct ifatm *, u_int, u_int, u_int); 118static const struct utopia_methods patm_utopia_methods = { 119 patm_phy_readregs, 120 patm_phy_writereg 121}; 122 123static void patm_destroy(struct patm_softc *sc); 124 125static int patm_sysctl_istats(SYSCTL_HANDLER_ARGS); 126static int patm_sysctl_eeprom(SYSCTL_HANDLER_ARGS); 127 128static void patm_read_eeprom(struct patm_softc *sc); 129static int patm_sq_init(struct patm_softc *sc); 130static int patm_rbuf_init(struct patm_softc *sc); 131static int patm_txmap_init(struct patm_softc *sc); 132 133static void patm_env_getuint(struct patm_softc *, u_int *, const char *); 134 135#ifdef PATM_DEBUG 136static int patm_sysctl_regs(SYSCTL_HANDLER_ARGS); 137static int patm_sysctl_tsq(SYSCTL_HANDLER_ARGS); 138int patm_dump_vc(u_int unit, u_int vc) __unused; 139int patm_dump_regs(u_int unit) __unused; 140int patm_dump_sram(u_int unit, u_int from, u_int words) __unused; 141#endif 142 143/* 144 * Probe for a IDT77252 controller 145 */ 146static int 147patm_probe(device_t dev) 148{ 149 u_int i; 150 151 if (pci_get_vendor(dev) == PCI_VENDOR_IDT) { 152 for (i = 0; devs[i].desc != NULL; i++) 153 if (pci_get_device(dev) == devs[i].devid) { 154 device_set_desc(dev, devs[i].desc); 155 return (BUS_PROBE_DEFAULT); 156 } 157 } 158 return (ENXIO); 159} 160 161/* 162 * Attach 163 */ 164static int 165patm_attach(device_t dev) 166{ 167 struct patm_softc *sc; 168 int error; 169 struct ifnet *ifp; 170 int rid; 171 u_int a; 172 173 static const struct idt_mmap idt_mmap[4] = IDT_MMAP; 174 175 sc = device_get_softc(dev); 176 177 sc->dev = dev; 178#ifdef IATM_DEBUG 179 sc->debug = IATM_DEBUG; 180#endif 181 ifp = sc->ifp = if_alloc(IFT_ATM); 182 if (ifp == NULL) { 183 return (ENOSPC); 184 } 185 186 IFP2IFATM(sc->ifp)->mib.device = ATM_DEVICE_IDTABR25; 187 IFP2IFATM(sc->ifp)->mib.serial = 0; 188 IFP2IFATM(sc->ifp)->mib.hw_version = 0; 189 IFP2IFATM(sc->ifp)->mib.sw_version = 0; 190 IFP2IFATM(sc->ifp)->mib.vpi_bits = PATM_VPI_BITS; 191 IFP2IFATM(sc->ifp)->mib.vci_bits = 0; /* set below */; 192 IFP2IFATM(sc->ifp)->mib.max_vpcs = 0; 193 IFP2IFATM(sc->ifp)->mib.max_vccs = 0; /* set below */ 194 IFP2IFATM(sc->ifp)->mib.media = IFM_ATM_UNKNOWN; 195 IFP2IFATM(sc->ifp)->phy = &sc->utopia; 196 197 ifp->if_softc = sc; 198 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 199 ifp->if_flags = IFF_SIMPLEX; 200 ifp->if_init = patm_init; 201 ifp->if_ioctl = patm_ioctl; 202 ifp->if_start = patm_start; 203 204 /* do this early so we can destroy unconditionally */ 205 mtx_init(&sc->mtx, device_get_nameunit(dev), 206 MTX_NETWORK_LOCK, MTX_DEF); 207 mtx_init(&sc->tst_lock, "tst lock", NULL, MTX_DEF); 208 cv_init(&sc->vcc_cv, "vcc_close"); 209 210 callout_init(&sc->tst_callout, CALLOUT_MPSAFE); 211 212 sysctl_ctx_init(&sc->sysctl_ctx); 213 214 /* 215 * Get revision 216 */ 217 sc->revision = pci_read_config(dev, PCIR_REVID, 4) & 0xf; 218 219 /* 220 * Enable PCI bus master and memory 221 */ 222 pci_enable_busmaster(dev); 223 224 rid = IDT_PCI_REG_MEMBASE; 225 sc->memres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 226 RF_ACTIVE); 227 if (sc->memres == NULL) { 228 patm_printf(sc, "could not map memory\n"); 229 error = ENXIO; 230 goto fail; 231 } 232 sc->memh = rman_get_bushandle(sc->memres); 233 sc->memt = rman_get_bustag(sc->memres); 234 235 /* 236 * Allocate the interrupt (enable it later) 237 */ 238 sc->irqid = 0; 239 sc->irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid, 240 RF_SHAREABLE | RF_ACTIVE); 241 if (sc->irqres == 0) { 242 patm_printf(sc, "could not allocate irq\n"); 243 error = ENXIO; 244 goto fail; 245 } 246 247 /* 248 * Construct the sysctl tree 249 */ 250 error = ENOMEM; 251 if ((sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx, 252 SYSCTL_STATIC_CHILDREN(_hw_atm), OID_AUTO, 253 device_get_nameunit(dev), CTLFLAG_RD, 0, "")) == NULL) 254 goto fail; 255 256 if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), 257 OID_AUTO, "istats", CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, 258 patm_sysctl_istats, "S", "internal statistics") == NULL) 259 goto fail; 260 261 if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), 262 OID_AUTO, "eeprom", CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, 263 patm_sysctl_eeprom, "S", "EEPROM contents") == NULL) 264 goto fail; 265 266 if (SYSCTL_ADD_UINT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), 267 OID_AUTO, "lbuf_max", CTLFLAG_RD, &sc->lbuf_max, 268 0, "maximum number of large receive buffers") == NULL) 269 goto fail; 270 patm_env_getuint(sc, &sc->lbuf_max, "lbuf_max"); 271 272 if (SYSCTL_ADD_UINT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), 273 OID_AUTO, "max_txmaps", CTLFLAG_RW, &sc->tx_maxmaps, 274 0, "maximum number of TX DMA maps") == NULL) 275 goto fail; 276 patm_env_getuint(sc, &sc->tx_maxmaps, "tx_maxmaps"); 277 278#ifdef PATM_DEBUG 279 if (SYSCTL_ADD_UINT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), 280 OID_AUTO, "debug", CTLFLAG_RW, &sc->debug, 281 0, "debug flags") == NULL) 282 goto fail; 283 sc->debug = PATM_DEBUG; 284 patm_env_getuint(sc, &sc->debug, "debug"); 285 286 if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), 287 OID_AUTO, "regs", CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, 288 patm_sysctl_regs, "S", "registers") == NULL) 289 goto fail; 290 291 if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), 292 OID_AUTO, "tsq", CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, 293 patm_sysctl_tsq, "S", "TSQ") == NULL) 294 goto fail; 295#endif 296 297 patm_reset(sc); 298 299 /* 300 * Detect and attach the phy. 301 */ 302 patm_debug(sc, ATTACH, "attaching utopia"); 303 IFP2IFATM(sc->ifp)->phy = &sc->utopia; 304 utopia_attach(&sc->utopia, IFP2IFATM(sc->ifp), &sc->media, &sc->mtx, 305 &sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), 306 &patm_utopia_methods); 307 308 /* 309 * Start the PHY because we need the autodetection 310 */ 311 patm_debug(sc, ATTACH, "starting utopia"); 312 mtx_lock(&sc->mtx); 313 utopia_start(&sc->utopia); 314 utopia_reset(&sc->utopia); 315 mtx_unlock(&sc->mtx); 316 317 /* Read EEPROM */ 318 patm_read_eeprom(sc); 319 320 /* analyze it */ 321 if (strncmp(sc->eeprom + PATM_PROATM_NAME_OFFSET, PATM_PROATM_NAME, 322 strlen(PATM_PROATM_NAME)) == 0) { 323 if (sc->utopia.chip->type == UTP_TYPE_IDT77105) { 324 IFP2IFATM(sc->ifp)->mib.device = ATM_DEVICE_PROATM25; 325 IFP2IFATM(sc->ifp)->mib.pcr = ATM_RATE_25_6M; 326 IFP2IFATM(sc->ifp)->mib.media = IFM_ATM_UTP_25; 327 sc->flags |= PATM_25M; 328 patm_printf(sc, "ProATM 25 interface; "); 329 330 } else { 331 /* cannot really know which media */ 332 IFP2IFATM(sc->ifp)->mib.device = ATM_DEVICE_PROATM155; 333 IFP2IFATM(sc->ifp)->mib.pcr = ATM_RATE_155M; 334 IFP2IFATM(sc->ifp)->mib.media = IFM_ATM_MM_155; 335 patm_printf(sc, "ProATM 155 interface; "); 336 } 337 338 bcopy(sc->eeprom + PATM_PROATM_MAC_OFFSET, IFP2IFATM(sc->ifp)->mib.esi, 339 sizeof(IFP2IFATM(sc->ifp)->mib.esi)); 340 341 } else { 342 if (sc->utopia.chip->type == UTP_TYPE_IDT77105) { 343 IFP2IFATM(sc->ifp)->mib.device = ATM_DEVICE_IDTABR25; 344 IFP2IFATM(sc->ifp)->mib.pcr = ATM_RATE_25_6M; 345 IFP2IFATM(sc->ifp)->mib.media = IFM_ATM_UTP_25; 346 sc->flags |= PATM_25M; 347 patm_printf(sc, "IDT77252 25MBit interface; "); 348 349 } else { 350 /* cannot really know which media */ 351 IFP2IFATM(sc->ifp)->mib.device = ATM_DEVICE_IDTABR155; 352 IFP2IFATM(sc->ifp)->mib.pcr = ATM_RATE_155M; 353 IFP2IFATM(sc->ifp)->mib.media = IFM_ATM_MM_155; 354 patm_printf(sc, "IDT77252 155MBit interface; "); 355 } 356 357 bcopy(sc->eeprom + PATM_IDT_MAC_OFFSET, IFP2IFATM(sc->ifp)->mib.esi, 358 sizeof(IFP2IFATM(sc->ifp)->mib.esi)); 359 } 360 printf("idt77252 Rev. %c; %s PHY\n", 'A' + sc->revision, 361 sc->utopia.chip->name); 362 363 utopia_reset_media(&sc->utopia); 364 utopia_init_media(&sc->utopia); 365 366 /* 367 * Determine RAM size 368 */ 369 for (a = 0; a < 0x20000; a++) 370 patm_sram_write(sc, a, 0); 371 patm_sram_write(sc, 0, 0xdeadbeef); 372 if (patm_sram_read(sc, 0x4004) == 0xdeadbeef) 373 sc->mmap = &idt_mmap[0]; 374 else if (patm_sram_read(sc, 0x8000) == 0xdeadbeef) 375 sc->mmap = &idt_mmap[1]; 376 else if (patm_sram_read(sc, 0x20000) == 0xdeadbeef) 377 sc->mmap = &idt_mmap[2]; 378 else 379 sc->mmap = &idt_mmap[3]; 380 381 IFP2IFATM(sc->ifp)->mib.vci_bits = sc->mmap->vcbits - IFP2IFATM(sc->ifp)->mib.vpi_bits; 382 IFP2IFATM(sc->ifp)->mib.max_vccs = sc->mmap->max_conn; 383 patm_sram_write(sc, 0, 0); 384 patm_printf(sc, "%uK x 32 SRAM; %u connections\n", sc->mmap->sram, 385 sc->mmap->max_conn); 386 387 /* initialize status queues */ 388 error = patm_sq_init(sc); 389 if (error != 0) 390 goto fail; 391 392 /* get TST */ 393 sc->tst_soft = malloc(sizeof(uint32_t) * sc->mmap->tst_size, 394 M_DEVBUF, M_WAITOK); 395 396 /* allocate all the receive buffer stuff */ 397 error = patm_rbuf_init(sc); 398 if (error != 0) 399 goto fail; 400 401 /* 402 * Allocate SCD tag 403 * 404 * Don't use BUS_DMA_ALLOCNOW, because we never need bouncing with 405 * bus_dmamem_alloc() 406 */ 407 error = bus_dma_tag_create(bus_get_dma_tag(dev), PAGE_SIZE, 0, 408 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, 409 NULL, NULL, sizeof(struct patm_scd), 1, 410 sizeof(struct patm_scd), 0, NULL, NULL, &sc->scd_tag); 411 if (error) { 412 patm_printf(sc, "SCD DMA tag create %d\n", error); 413 goto fail; 414 } 415 LIST_INIT(&sc->scd_list); 416 417 /* allocate VCC zone and pointers */ 418 if ((sc->vcc_zone = uma_zcreate("PATM vccs", sizeof(struct patm_vcc), 419 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0)) == NULL) { 420 patm_printf(sc, "cannot allocate zone for vccs\n"); 421 goto fail; 422 } 423 sc->vccs = malloc(sizeof(sc->vccs[0]) * sc->mmap->max_conn, 424 M_DEVBUF, M_WAITOK | M_ZERO); 425 426 /* allocate transmission resources */ 427 error = patm_txmap_init(sc); 428 if (error != 0) 429 goto fail; 430 431 /* poll while we are not running */ 432 sc->utopia.flags |= UTP_FL_POLL_CARRIER; 433 434 patm_debug(sc, ATTACH, "attaching interface"); 435 atm_ifattach(ifp); 436 437#ifdef ENABLE_BPF 438 bpfattach(ifp, DLT_ATM_RFC1483, sizeof(struct atmllc)); 439#endif 440 441 patm_debug(sc, ATTACH, "attaching interrupt handler"); 442 error = bus_setup_intr(dev, sc->irqres, INTR_TYPE_NET | INTR_MPSAFE, 443 NULL, patm_intr, sc, &sc->ih); 444 if (error != 0) { 445 patm_printf(sc, "could not setup interrupt\n"); 446 atm_ifdetach(sc->ifp); 447 if_free(sc->ifp); 448 goto fail; 449 } 450 451 return (0); 452 453 fail: 454 patm_destroy(sc); 455 return (error); 456} 457 458/* 459 * Detach 460 */ 461static int 462patm_detach(device_t dev) 463{ 464 struct patm_softc *sc; 465 466 sc = device_get_softc(dev); 467 468 mtx_lock(&sc->mtx); 469 patm_stop(sc); 470 if (sc->utopia.state & UTP_ST_ATTACHED) { 471 patm_debug(sc, ATTACH, "detaching utopia"); 472 utopia_stop(&sc->utopia); 473 utopia_detach(&sc->utopia); 474 } 475 mtx_unlock(&sc->mtx); 476 477 atm_ifdetach(sc->ifp); 478 479 patm_destroy(sc); 480 481 return (0); 482} 483 484/* 485 * Destroy everything. Assume we are stopped. 486 */ 487static void 488patm_destroy(struct patm_softc *sc) 489{ 490 u_int i; 491 struct patm_txmap *map; 492 493 if (sc->ih != NULL) 494 bus_teardown_intr(sc->dev, sc->irqres, sc->ih); 495 496 if (sc->tx_mapzone != NULL) { 497 /* all maps must be free */ 498 while ((map = SLIST_FIRST(&sc->tx_maps_free)) != NULL) { 499 bus_dmamap_destroy(sc->tx_tag, map->map); 500 SLIST_REMOVE_HEAD(&sc->tx_maps_free, link); 501 uma_zfree(sc->tx_mapzone, map); 502 } 503 uma_zdestroy(sc->tx_mapzone); 504 } 505 506 if (sc->scd_tag != NULL) 507 bus_dma_tag_destroy(sc->scd_tag); 508 509 if (sc->tx_tag != NULL) 510 bus_dma_tag_destroy(sc->scd_tag); 511 512 if (sc->vccs != NULL) { 513 for (i = 0; i < sc->mmap->max_conn; i++) 514 if (sc->vccs[i] != NULL) 515 uma_zfree(sc->vcc_zone, sc->vccs[i]); 516 free(sc->vccs, M_DEVBUF); 517 } 518 if (sc->vcc_zone != NULL) 519 uma_zdestroy(sc->vcc_zone); 520 521 if (sc->lbufs != NULL) { 522 for (i = 0; i < sc->lbuf_max; i++) 523 bus_dmamap_destroy(sc->lbuf_tag, sc->lbufs[i].map); 524 free(sc->lbufs, M_DEVBUF); 525 } 526 527 if (sc->lbuf_tag != NULL) 528 bus_dma_tag_destroy(sc->lbuf_tag); 529 530 if (sc->sbuf_pool != NULL) 531 mbp_destroy(sc->sbuf_pool); 532 if (sc->vbuf_pool != NULL) 533 mbp_destroy(sc->vbuf_pool); 534 535 if (sc->sbuf_tag != NULL) 536 bus_dma_tag_destroy(sc->sbuf_tag); 537 538 if (sc->tst_soft != NULL) 539 free(sc->tst_soft, M_DEVBUF); 540 541 /* 542 * Free all status queue memory resources 543 */ 544 if (sc->tsq != NULL) { 545 bus_dmamap_unload(sc->sq_tag, sc->sq_map); 546 bus_dmamem_free(sc->sq_tag, sc->tsq, sc->sq_map); 547 bus_dma_tag_destroy(sc->sq_tag); 548 } 549 550 if (sc->irqres != NULL) 551 bus_release_resource(sc->dev, SYS_RES_IRQ, 552 sc->irqid, sc->irqres); 553 if (sc->memres != NULL) 554 bus_release_resource(sc->dev, SYS_RES_MEMORY, 555 IDT_PCI_REG_MEMBASE, sc->memres); 556 557 /* this was initialize unconditionally */ 558 sysctl_ctx_free(&sc->sysctl_ctx); 559 cv_destroy(&sc->vcc_cv); 560 mtx_destroy(&sc->tst_lock); 561 mtx_destroy(&sc->mtx); 562 563 if (sc->ifp != NULL) 564 if_free(sc->ifp); 565} 566 567/* 568 * Try to find a variable in the environment and parse it as an unsigned 569 * integer. 570 */ 571static void 572patm_env_getuint(struct patm_softc *sc, u_int *var, const char *name) 573{ 574 char full[IFNAMSIZ + 3 + 20]; 575 char *val, *end; 576 u_long u; 577 578 snprintf(full, sizeof(full), "hw.%s.%s", 579 device_get_nameunit(sc->dev), name); 580 581 if ((val = getenv(full)) != NULL) { 582 u = strtoul(val, &end, 0); 583 if (end > val && *end == '\0') { 584 if (bootverbose) 585 patm_printf(sc, "%s=%lu\n", full, u); 586 *var = u; 587 } 588 freeenv(val); 589 } 590} 591 592/* 593 * Sysctl handler for internal statistics 594 * 595 * LOCK: unlocked, needed 596 */ 597static int 598patm_sysctl_istats(SYSCTL_HANDLER_ARGS) 599{ 600 struct patm_softc *sc = arg1; 601 uint32_t *ret; 602 int error; 603 604 ret = malloc(sizeof(sc->stats), M_TEMP, M_WAITOK); 605 606 mtx_lock(&sc->mtx); 607 bcopy(&sc->stats, ret, sizeof(sc->stats)); 608 mtx_unlock(&sc->mtx); 609 610 error = SYSCTL_OUT(req, ret, sizeof(sc->stats)); 611 free(ret, M_TEMP); 612 613 return (error); 614} 615 616/* 617 * Sysctl handler for EEPROM 618 * 619 * LOCK: unlocked, needed 620 */ 621static int 622patm_sysctl_eeprom(SYSCTL_HANDLER_ARGS) 623{ 624 struct patm_softc *sc = arg1; 625 void *ret; 626 int error; 627 628 ret = malloc(sizeof(sc->eeprom), M_TEMP, M_WAITOK); 629 630 mtx_lock(&sc->mtx); 631 bcopy(sc->eeprom, ret, sizeof(sc->eeprom)); 632 mtx_unlock(&sc->mtx); 633 634 error = SYSCTL_OUT(req, ret, sizeof(sc->eeprom)); 635 free(ret, M_TEMP); 636 637 return (error); 638} 639 640/* 641 * Read the EEPROM. We assume that this is a XIRCOM 25020 642 */ 643static void 644patm_read_eeprom(struct patm_softc *sc) 645{ 646 u_int gp; 647 uint8_t byte; 648 int i, addr; 649 650 static const uint32_t tab[] = { 651 /* CS transition to reset the chip */ 652 IDT_GP_EECS | IDT_GP_EESCLK, 0, 653 /* read command 0x03 */ 654 IDT_GP_EESCLK, 0, 655 IDT_GP_EESCLK, 0, 656 IDT_GP_EESCLK, 0, 657 IDT_GP_EESCLK, 0, 658 IDT_GP_EESCLK, 0, 659 IDT_GP_EESCLK, IDT_GP_EEDO, 660 IDT_GP_EESCLK | IDT_GP_EEDO, IDT_GP_EEDO, 661 IDT_GP_EESCLK | IDT_GP_EEDO, 0, 662 /* address 0x00 */ 663 IDT_GP_EESCLK, 0, 664 IDT_GP_EESCLK, 0, 665 IDT_GP_EESCLK, 0, 666 IDT_GP_EESCLK, 0, 667 IDT_GP_EESCLK, 0, 668 IDT_GP_EESCLK, 0, 669 IDT_GP_EESCLK, 0, 670 IDT_GP_EESCLK, 0, 671 }; 672 673 /* go to a known state (chip enabled) */ 674 gp = patm_nor_read(sc, IDT_NOR_GP); 675 gp &= ~(IDT_GP_EESCLK | IDT_GP_EECS | IDT_GP_EEDO); 676 677 for (i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) { 678 patm_nor_write(sc, IDT_NOR_GP, gp | tab[i]); 679 DELAY(40); 680 } 681 682 /* read out the prom */ 683 for (addr = 0; addr < 256; addr++) { 684 byte = 0; 685 for (i = 0; i < 8; i++) { 686 byte <<= 1; 687 if (patm_nor_read(sc, IDT_NOR_GP) & IDT_GP_EEDI) 688 byte |= 1; 689 /* rising CLK */ 690 patm_nor_write(sc, IDT_NOR_GP, gp | IDT_GP_EESCLK); 691 DELAY(40); 692 /* falling clock */ 693 patm_nor_write(sc, IDT_NOR_GP, gp); 694 DELAY(40); 695 } 696 sc->eeprom[addr] = byte; 697 } 698} 699 700/* 701 * PHY access read 702 */ 703static int 704patm_phy_readregs(struct ifatm *ifatm, u_int reg, uint8_t *val, u_int *n) 705{ 706 struct patm_softc *sc = ifatm->ifp->if_softc; 707 u_int cnt = *n; 708 709 if (reg >= 0x100) 710 return (EINVAL); 711 712 patm_cmd_wait(sc); 713 while (reg < 0x100 && cnt > 0) { 714 patm_nor_write(sc, IDT_NOR_CMD, IDT_MKCMD_RUTIL(1, 0, reg)); 715 patm_cmd_wait(sc); 716 *val = patm_nor_read(sc, IDT_NOR_D0); 717 patm_debug(sc, PHY, "phy(%02x)=%02x", reg, *val); 718 val++; 719 reg++; 720 cnt--; 721 } 722 *n = *n - cnt; 723 return (0); 724} 725 726/* 727 * Write PHY reg 728 */ 729static int 730patm_phy_writereg(struct ifatm *ifatm, u_int reg, u_int mask, u_int val) 731{ 732 struct patm_softc *sc = ifatm->ifp->if_softc; 733 u_int old, new; 734 735 if (reg >= 0x100) 736 return (EINVAL); 737 738 patm_cmd_wait(sc); 739 patm_nor_write(sc, IDT_NOR_CMD, IDT_MKCMD_RUTIL(1, 0, reg)); 740 patm_cmd_wait(sc); 741 742 old = patm_nor_read(sc, IDT_NOR_D0); 743 new = (old & ~mask) | (val & mask); 744 patm_debug(sc, PHY, "phy(%02x) %02x -> %02x", reg, old, new); 745 746 patm_nor_write(sc, IDT_NOR_D0, new); 747 patm_nor_write(sc, IDT_NOR_CMD, IDT_MKCMD_WUTIL(1, 0, reg)); 748 patm_cmd_wait(sc); 749 750 return (0); 751} 752 753/* 754 * Allocate a large chunk of DMA able memory for the transmit 755 * and receive status queues. We align this to a page boundary 756 * to ensure the alignment. 757 */ 758static int 759patm_sq_init(struct patm_softc *sc) 760{ 761 int error; 762 void *p; 763 764 /* compute size of the two queues */ 765 sc->sq_size = IDT_TSQ_SIZE * IDT_TSQE_SIZE + 766 PATM_RSQ_SIZE * IDT_RSQE_SIZE + 767 IDT_RAWHND_SIZE; 768 769 patm_debug(sc, ATTACH, 770 "allocating status queues (%zu) ...", sc->sq_size); 771 772 /* 773 * allocate tag 774 * Don't use BUS_DMA_ALLOCNOW, because we never need bouncing with 775 * bus_dmamem_alloc() 776 */ 777 error = bus_dma_tag_create(bus_get_dma_tag(sc->dev), 778 PATM_SQ_ALIGNMENT, 0, 779 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, 780 NULL, NULL, sc->sq_size, 1, sc->sq_size, 781 0, NULL, NULL, &sc->sq_tag); 782 if (error) { 783 patm_printf(sc, "memory DMA tag create %d\n", error); 784 return (error); 785 } 786 787 /* allocate memory */ 788 error = bus_dmamem_alloc(sc->sq_tag, &p, 0, &sc->sq_map); 789 if (error) { 790 patm_printf(sc, "memory DMA alloc %d\n", error); 791 bus_dma_tag_destroy(sc->sq_tag); 792 return (error); 793 } 794 795 /* map it */ 796 sc->tsq_phy = 0x1fff; 797 error = bus_dmamap_load(sc->sq_tag, sc->sq_map, p, 798 sc->sq_size, patm_load_callback, &sc->tsq_phy, BUS_DMA_NOWAIT); 799 if (error) { 800 patm_printf(sc, "memory DMA map load %d\n", error); 801 bus_dmamem_free(sc->sq_tag, p, sc->sq_map); 802 bus_dma_tag_destroy(sc->sq_tag); 803 return (error); 804 } 805 806 /* set queue start */ 807 sc->tsq = p; 808 sc->rsq = (void *)((char *)p + IDT_TSQ_SIZE * IDT_TSQE_SIZE); 809 sc->rsq_phy = sc->tsq_phy + IDT_TSQ_SIZE * IDT_TSQE_SIZE; 810 sc->rawhnd = (void *)((char *)sc->rsq + PATM_RSQ_SIZE * IDT_RSQE_SIZE); 811 sc->rawhnd_phy = sc->rsq_phy + PATM_RSQ_SIZE * IDT_RSQE_SIZE; 812 813 return (0); 814} 815 816/* 817 * Initialize all receive buffer stuff 818 */ 819static int 820patm_rbuf_init(struct patm_softc *sc) 821{ 822 u_int i; 823 int error; 824 825 patm_debug(sc, ATTACH, "allocating Rx buffer resources ..."); 826 /* 827 * Create a tag for small buffers. We allocate these page wise. 828 * Don't use BUS_DMA_ALLOCNOW, because we never need bouncing with 829 * bus_dmamem_alloc() 830 */ 831 if ((error = bus_dma_tag_create(bus_get_dma_tag(sc->dev), PAGE_SIZE, 0, 832 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 833 SMBUF_PAGE_SIZE, 1, SMBUF_PAGE_SIZE, 0, 834 NULL, NULL, &sc->sbuf_tag)) != 0) { 835 patm_printf(sc, "sbuf DMA tag create %d\n", error); 836 return (error); 837 } 838 839 error = mbp_create(&sc->sbuf_pool, "patm sbufs", sc->sbuf_tag, 840 SMBUF_MAX_PAGES, SMBUF_PAGE_SIZE, SMBUF_CHUNK_SIZE); 841 if (error != 0) { 842 patm_printf(sc, "smbuf pool create %d\n", error); 843 return (error); 844 } 845 846 error = mbp_create(&sc->vbuf_pool, "patm vbufs", sc->sbuf_tag, 847 VMBUF_MAX_PAGES, SMBUF_PAGE_SIZE, VMBUF_CHUNK_SIZE); 848 if (error != 0) { 849 patm_printf(sc, "vmbuf pool create %d\n", error); 850 return (error); 851 } 852 853 /* 854 * Create a tag for large buffers. 855 * Don't use BUS_DMA_ALLOCNOW, because it makes no sense with multiple 856 * maps using one tag. Rather use BUS_DMA_NOWAIT when loading the map 857 * to prevent EINPROGRESS. 858 */ 859 if ((error = bus_dma_tag_create(bus_get_dma_tag(sc->dev), 4, 0, 860 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 861 MCLBYTES, 1, MCLBYTES, 0, 862 NULL, NULL, &sc->lbuf_tag)) != 0) { 863 patm_printf(sc, "lbuf DMA tag create %d\n", error); 864 return (error); 865 } 866 867 if (sc->lbuf_max < IDT_FBQ_SIZE) 868 sc->lbuf_max = LMBUF_MAX; 869 sc->lbufs = malloc(sizeof(sc->lbufs[0]) * sc->lbuf_max, 870 M_DEVBUF, M_ZERO | M_WAITOK); 871 872 SLIST_INIT(&sc->lbuf_free_list); 873 for (i = 0; i < sc->lbuf_max; i++) { 874 struct lmbuf *b = &sc->lbufs[i]; 875 876 error = bus_dmamap_create(sc->lbuf_tag, 0, &b->map); 877 if (error) { 878 /* must deallocate here, because a test for NULL 879 * does not work on most archs */ 880 while (i-- > 0) 881 bus_dmamap_destroy(sc->lbuf_tag, 882 sc->lbufs[i].map); 883 free(sc->lbufs, M_DEVBUF); 884 sc->lbufs = NULL; 885 return (error); 886 } 887 b->handle = i; 888 SLIST_INSERT_HEAD(&sc->lbuf_free_list, b, link); 889 } 890 891 return (0); 892} 893 894/* 895 * Allocate everything needed for the transmission maps. 896 */ 897static int 898patm_txmap_init(struct patm_softc *sc) 899{ 900 int error; 901 struct patm_txmap *map; 902 903 /* get transmission tag */ 904 error = bus_dma_tag_create(bus_get_dma_tag(sc->dev), 1, 0, 905 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, 906 NULL, NULL, 65536, IDT_SCQ_SIZE - 1, 65536, 907 0, NULL, NULL, &sc->tx_tag); 908 if (error) { 909 patm_printf(sc, "cannot allocate TX tag %d\n", error); 910 return (error); 911 } 912 913 if ((sc->tx_mapzone = uma_zcreate("PATM tx maps", 914 sizeof(struct patm_txmap), NULL, NULL, NULL, NULL, 915 UMA_ALIGN_PTR, 0)) == NULL) 916 return (ENOMEM); 917 918 if (sc->tx_maxmaps < PATM_CFG_TXMAPS_MAX) 919 sc->tx_maxmaps = PATM_CFG_TXMAPS_MAX; 920 sc->tx_nmaps = PATM_CFG_TXMAPS_INIT; 921 922 for (sc->tx_nmaps = 0; sc->tx_nmaps < PATM_CFG_TXMAPS_INIT; 923 sc->tx_nmaps++) { 924 map = uma_zalloc(sc->tx_mapzone, M_WAITOK); 925 error = bus_dmamap_create(sc->tx_tag, 0, &map->map); 926 if (error) { 927 uma_zfree(sc->tx_mapzone, map); 928 return (ENOMEM); 929 } 930 SLIST_INSERT_HEAD(&sc->tx_maps_free, map, link); 931 } 932 933 return (0); 934} 935 936#ifdef PATM_DEBUG 937 938/* 939 * Sysctl handler for REGS 940 * 941 * LOCK: unlocked, needed 942 */ 943static int 944patm_sysctl_regs(SYSCTL_HANDLER_ARGS) 945{ 946 struct patm_softc *sc = arg1; 947 uint32_t *ret; 948 int error, i; 949 950 ret = malloc(IDT_NOR_END, M_TEMP, M_WAITOK); 951 952 mtx_lock(&sc->mtx); 953 for (i = 0; i < IDT_NOR_END; i += 4) 954 ret[i / 4] = patm_nor_read(sc, i); 955 mtx_unlock(&sc->mtx); 956 957 error = SYSCTL_OUT(req, ret, IDT_NOR_END); 958 free(ret, M_TEMP); 959 960 return (error); 961} 962 963/* 964 * Sysctl handler for TSQ 965 * 966 * LOCK: unlocked, needed 967 */ 968static int 969patm_sysctl_tsq(SYSCTL_HANDLER_ARGS) 970{ 971 struct patm_softc *sc = arg1; 972 void *ret; 973 int error; 974 975 ret = malloc(IDT_TSQ_SIZE * IDT_TSQE_SIZE, M_TEMP, M_WAITOK); 976 977 mtx_lock(&sc->mtx); 978 memcpy(ret, sc->tsq, IDT_TSQ_SIZE * IDT_TSQE_SIZE); 979 mtx_unlock(&sc->mtx); 980 981 error = SYSCTL_OUT(req, ret, IDT_TSQ_SIZE * IDT_TSQE_SIZE); 982 free(ret, M_TEMP); 983 984 return (error); 985} 986 987/* 988 * debugging 989 */ 990static struct patm_softc * 991patm_dump_unit(u_int unit) 992{ 993 devclass_t dc; 994 struct patm_softc *sc; 995 996 dc = devclass_find("patm"); 997 if (dc == NULL) { 998 printf("%s: can't find devclass\n", __func__); 999 return (NULL); 1000 } 1001 sc = devclass_get_softc(dc, unit); 1002 if (sc == NULL) { 1003 printf("%s: invalid unit number: %d\n", __func__, unit); 1004 return (NULL); 1005 } 1006 return (sc); 1007} 1008 1009int 1010patm_dump_vc(u_int unit, u_int vc) 1011{ 1012 struct patm_softc *sc; 1013 uint32_t tct[8]; 1014 uint32_t rct[4]; 1015 uint32_t scd[12]; 1016 u_int i; 1017 1018 if ((sc = patm_dump_unit(unit)) == NULL) 1019 return (0); 1020 1021 for (i = 0; i < 8; i++) 1022 tct[i] = patm_sram_read(sc, vc * 8 + i); 1023 for (i = 0; i < 4; i++) 1024 rct[i] = patm_sram_read(sc, sc->mmap->rct + vc * 4 + i); 1025 for (i = 0; i < 12; i++) 1026 scd[i] = patm_sram_read(sc, (tct[0] & 0x7ffff) + i); 1027 1028 printf("TCT%3u: %08x %08x %08x %08x %08x %08x %08x %08x\n", vc, 1029 tct[0], tct[1], tct[2], tct[3], tct[4], tct[5], tct[6], tct[7]); 1030 printf("RCT%3u: %08x %08x %08x %08x\n", vc, 1031 rct[0], rct[1], rct[2], rct[3]); 1032 printf("SCD%3u: %08x %08x %08x %08x %08x %08x %08x %08x\n", vc, 1033 scd[0], scd[1], scd[2], scd[3], scd[4], scd[5], scd[6], scd[7]); 1034 printf(" %08x %08x %08x %08x\n", 1035 scd[8], scd[9], scd[10], scd[11]); 1036 1037 return (0); 1038} 1039 1040int 1041patm_dump_regs(u_int unit) 1042{ 1043 struct patm_softc *sc; 1044 u_int i; 1045 1046 if ((sc = patm_dump_unit(unit)) == NULL) 1047 return (0); 1048 1049 for (i = 0; i <= IDT_NOR_DNOW; i += 4) 1050 printf("%x: %08x\n", i, patm_nor_read(sc, i)); 1051 1052 return (0); 1053} 1054 1055int 1056patm_dump_sram(u_int unit, u_int from, u_int words) 1057{ 1058 struct patm_softc *sc; 1059 u_int i; 1060 1061 if ((sc = patm_dump_unit(unit)) == NULL) 1062 return (0); 1063 1064 for (i = 0; i < words; i++) { 1065 if (i % 8 == 0) 1066 printf("%05x:", from + i); 1067 printf(" %08x", patm_sram_read(sc, from + i)); 1068 if (i % 8 == 7) 1069 printf("\n"); 1070 } 1071 if (i % 8 != 0) 1072 printf("\n"); 1073 return (0); 1074} 1075#endif 1076