3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
27 * Author: Hartmut Brandt <harti@freebsd.org>
29 * Driver for IDT77252 based cards like ProSum's.
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
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>
44 #include <sys/errno.h>
46 #include <sys/module.h>
48 #include <sys/mutex.h>
49 #include <sys/sysctl.h>
50 #include <sys/queue.h>
51 #include <sys/condvar.h>
54 #include <sys/sockio.h>
56 #include <sys/socket.h>
59 #include <net/if_media.h>
60 #include <net/if_atm.h>
61 #include <net/route.h>
65 #include <netinet/in.h>
66 #include <netinet/if_atm.h>
68 #include <machine/bus.h>
69 #include <machine/resource.h>
72 #include <sys/mbpool.h>
73 #include <dev/pci/pcireg.h>
74 #include <dev/pci/pcivar.h>
76 #include <dev/utopia/utopia.h>
77 #include <dev/patm/idt77252reg.h>
78 #include <dev/patm/if_patmvar.h>
80 MODULE_DEPEND(patm, utopia, 1, 1, 1);
81 MODULE_DEPEND(patm, pci, 1, 1, 1);
82 MODULE_DEPEND(patm, atm, 1, 1, 1);
83 MODULE_DEPEND(patm, libmbpool, 1, 1, 1);
85 devclass_t patm_devclass;
87 static int patm_probe(device_t dev);
88 static int patm_attach(device_t dev);
89 static int patm_detach(device_t dev);
90 static device_method_t patm_methods[] = {
91 DEVMETHOD(device_probe, patm_probe),
92 DEVMETHOD(device_attach, patm_attach),
93 DEVMETHOD(device_detach, patm_detach),
96 static driver_t patm_driver = {
99 sizeof(struct patm_softc),
101 DRIVER_MODULE(patm, pci, patm_driver, patm_devclass, NULL, 0);
103 static const struct {
107 { PCI_DEVICE_IDT77252, "NICStAR (77222/77252) ATM adapter" },
108 { PCI_DEVICE_IDT77v252, "NICStAR (77v252) ATM adapter" },
109 { PCI_DEVICE_IDT77v222, "NICStAR (77v222) ATM adapter" },
113 SYSCTL_DECL(_hw_atm);
115 static int patm_phy_readregs(struct ifatm *, u_int, uint8_t *, u_int *);
116 static int patm_phy_writereg(struct ifatm *, u_int, u_int, u_int);
117 static const struct utopia_methods patm_utopia_methods = {
122 static void patm_destroy(struct patm_softc *sc);
124 static int patm_sysctl_istats(SYSCTL_HANDLER_ARGS);
125 static int patm_sysctl_eeprom(SYSCTL_HANDLER_ARGS);
127 static void patm_read_eeprom(struct patm_softc *sc);
128 static int patm_sq_init(struct patm_softc *sc);
129 static int patm_rbuf_init(struct patm_softc *sc);
130 static int patm_txmap_init(struct patm_softc *sc);
132 static void patm_env_getuint(struct patm_softc *, u_int *, const char *);
135 static int patm_sysctl_regs(SYSCTL_HANDLER_ARGS);
136 static int patm_sysctl_tsq(SYSCTL_HANDLER_ARGS);
137 int patm_dump_vc(u_int unit, u_int vc) __unused;
138 int patm_dump_regs(u_int unit) __unused;
139 int patm_dump_sram(u_int unit, u_int from, u_int words) __unused;
143 * Probe for a IDT77252 controller
146 patm_probe(device_t dev)
150 if (pci_get_vendor(dev) == PCI_VENDOR_IDT) {
151 for (i = 0; devs[i].desc != NULL; i++)
152 if (pci_get_device(dev) == devs[i].devid) {
153 device_set_desc(dev, devs[i].desc);
164 patm_attach(device_t dev)
166 struct patm_softc *sc;
172 static const struct idt_mmap idt_mmap[4] = IDT_MMAP;
174 sc = device_get_softc(dev);
178 sc->debug = IATM_DEBUG;
180 sc->ifatm.mib.device = ATM_DEVICE_IDTABR25;
181 sc->ifatm.mib.serial = 0;
182 sc->ifatm.mib.hw_version = 0;
183 sc->ifatm.mib.sw_version = 0;
184 sc->ifatm.mib.vpi_bits = PATM_VPI_BITS;
185 sc->ifatm.mib.vci_bits = 0; /* set below */;
186 sc->ifatm.mib.max_vpcs = 0;
187 sc->ifatm.mib.max_vccs = 0; /* set below */
188 sc->ifatm.mib.media = IFM_ATM_UNKNOWN;
189 sc->ifatm.phy = &sc->utopia;
191 ifp = &sc->ifatm.ifnet;
193 if_initname(ifp, device_get_name(dev), device_get_unit(dev));
194 ifp->if_flags = IFF_SIMPLEX;
195 ifp->if_watchdog = NULL;
196 ifp->if_init = patm_init;
197 ifp->if_ioctl = patm_ioctl;
198 ifp->if_start = patm_start;
199 ifp->if_watchdog = NULL;
201 /* do this early so we can destroy unconditionally */
202 mtx_init(&sc->mtx, device_get_nameunit(dev),
203 MTX_NETWORK_LOCK, MTX_DEF);
204 mtx_init(&sc->tst_lock, "tst lock", NULL, MTX_DEF);
205 cv_init(&sc->vcc_cv, "vcc_close");
207 callout_init(&sc->tst_callout, CALLOUT_MPSAFE);
209 sysctl_ctx_init(&sc->sysctl_ctx);
214 sc->revision = pci_read_config(dev, PCIR_REVID, 4) & 0xf;
217 * Enable PCI bus master and memory
219 pci_enable_busmaster(dev);
221 rid = IDT_PCI_REG_MEMBASE;
222 sc->memres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
224 if (sc->memres == NULL) {
225 patm_printf(sc, "could not map memory\n");
229 sc->memh = rman_get_bushandle(sc->memres);
230 sc->memt = rman_get_bustag(sc->memres);
233 * Allocate the interrupt (enable it later)
236 sc->irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
237 RF_SHAREABLE | RF_ACTIVE);
238 if (sc->irqres == 0) {
239 patm_printf(sc, "could not allocate irq\n");
245 * Construct the sysctl tree
248 if ((sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
249 SYSCTL_STATIC_CHILDREN(_hw_atm), OID_AUTO,
250 device_get_nameunit(dev), CTLFLAG_RD, 0, "")) == NULL)
253 if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
254 OID_AUTO, "istats", CTLFLAG_RD, sc, 0, patm_sysctl_istats,
255 "S", "internal statistics") == NULL)
258 if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
259 OID_AUTO, "eeprom", CTLFLAG_RD, sc, 0, patm_sysctl_eeprom,
260 "S", "EEPROM contents") == NULL)
263 if (SYSCTL_ADD_UINT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
264 OID_AUTO, "lbuf_max", CTLFLAG_RD, &sc->lbuf_max,
265 0, "maximum number of large receive buffers") == NULL)
267 patm_env_getuint(sc, &sc->lbuf_max, "lbuf_max");
269 if (SYSCTL_ADD_UINT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
270 OID_AUTO, "max_txmaps", CTLFLAG_RW, &sc->tx_maxmaps,
271 0, "maximum number of TX DMA maps") == NULL)
273 patm_env_getuint(sc, &sc->tx_maxmaps, "tx_maxmaps");
276 if (SYSCTL_ADD_UINT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
277 OID_AUTO, "debug", CTLFLAG_RW, &sc->debug,
278 0, "debug flags") == NULL)
280 sc->debug = PATM_DEBUG;
281 patm_env_getuint(sc, &sc->debug, "debug");
283 if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
284 OID_AUTO, "regs", CTLFLAG_RD, sc, 0, patm_sysctl_regs,
285 "S", "registers") == NULL)
288 if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
289 OID_AUTO, "tsq", CTLFLAG_RD, sc, 0, patm_sysctl_tsq,
297 * Detect and attach the phy.
299 patm_debug(sc, ATTACH, "attaching utopia");
300 sc->ifatm.phy = &sc->utopia;
301 utopia_attach(&sc->utopia, &sc->ifatm, &sc->media, &sc->mtx,
302 &sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
303 &patm_utopia_methods);
306 * Start the PHY because we need the autodetection
308 patm_debug(sc, ATTACH, "starting utopia");
310 utopia_start(&sc->utopia);
311 utopia_reset(&sc->utopia);
312 mtx_unlock(&sc->mtx);
315 patm_read_eeprom(sc);
318 if (strncmp(sc->eeprom + PATM_PROATM_NAME_OFFSET, PATM_PROATM_NAME,
319 strlen(PATM_PROATM_NAME)) == 0) {
320 if (sc->utopia.chip->type == UTP_TYPE_IDT77105) {
321 sc->ifatm.mib.device = ATM_DEVICE_PROATM25;
322 sc->ifatm.mib.pcr = ATM_RATE_25_6M;
323 sc->ifatm.mib.media = IFM_ATM_UTP_25;
324 sc->flags |= PATM_25M;
325 patm_printf(sc, "ProATM 25 interface; ");
328 /* cannot really know which media */
329 sc->ifatm.mib.device = ATM_DEVICE_PROATM155;
330 sc->ifatm.mib.pcr = ATM_RATE_155M;
331 sc->ifatm.mib.media = IFM_ATM_MM_155;
332 patm_printf(sc, "ProATM 155 interface; ");
335 bcopy(sc->eeprom + PATM_PROATM_MAC_OFFSET, sc->ifatm.mib.esi,
336 sizeof(sc->ifatm.mib.esi));
339 if (sc->utopia.chip->type == UTP_TYPE_IDT77105) {
340 sc->ifatm.mib.device = ATM_DEVICE_IDTABR25;
341 sc->ifatm.mib.pcr = ATM_RATE_25_6M;
342 sc->ifatm.mib.media = IFM_ATM_UTP_25;
343 sc->flags |= PATM_25M;
344 patm_printf(sc, "IDT77252 25MBit interface; ");
347 /* cannot really know which media */
348 sc->ifatm.mib.device = ATM_DEVICE_IDTABR155;
349 sc->ifatm.mib.pcr = ATM_RATE_155M;
350 sc->ifatm.mib.media = IFM_ATM_MM_155;
351 patm_printf(sc, "IDT77252 155MBit interface; ");
354 bcopy(sc->eeprom + PATM_IDT_MAC_OFFSET, sc->ifatm.mib.esi,
355 sizeof(sc->ifatm.mib.esi));
357 printf("idt77252 Rev. %c; %s PHY\n", 'A' + sc->revision,
358 sc->utopia.chip->name);
360 utopia_reset_media(&sc->utopia);
361 utopia_init_media(&sc->utopia);
366 for (a = 0; a < 0x20000; a++)
367 patm_sram_write(sc, a, 0);
368 patm_sram_write(sc, 0, 0xdeadbeef);
369 if (patm_sram_read(sc, 0x4004) == 0xdeadbeef)
370 sc->mmap = &idt_mmap[0];
371 else if (patm_sram_read(sc, 0x8000) == 0xdeadbeef)
372 sc->mmap = &idt_mmap[1];
373 else if (patm_sram_read(sc, 0x20000) == 0xdeadbeef)
374 sc->mmap = &idt_mmap[2];
376 sc->mmap = &idt_mmap[3];
378 sc->ifatm.mib.vci_bits = sc->mmap->vcbits - sc->ifatm.mib.vpi_bits;
379 sc->ifatm.mib.max_vccs = sc->mmap->max_conn;
380 patm_sram_write(sc, 0, 0);
381 patm_printf(sc, "%uK x 32 SRAM; %u connections\n", sc->mmap->sram,
384 /* initialize status queues */
385 error = patm_sq_init(sc);
390 sc->tst_soft = malloc(sizeof(uint32_t) * sc->mmap->tst_size,
393 /* allocate all the receive buffer stuff */
394 error = patm_rbuf_init(sc);
401 * Don't use BUS_DMA_ALLOCNOW, because we never need bouncing with
404 error = bus_dma_tag_create(NULL, PAGE_SIZE, 0,
405 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
406 NULL, NULL, sizeof(struct patm_scd), 1,
407 sizeof(struct patm_scd), 0, NULL, NULL, &sc->scd_tag);
409 patm_printf(sc, "SCD DMA tag create %d\n", error);
412 LIST_INIT(&sc->scd_list);
414 /* allocate VCC zone and pointers */
415 if ((sc->vcc_zone = uma_zcreate("PATM vccs", sizeof(struct patm_vcc),
416 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0)) == NULL) {
417 patm_printf(sc, "cannot allocate zone for vccs\n");
420 sc->vccs = malloc(sizeof(sc->vccs[0]) * sc->mmap->max_conn,
421 M_DEVBUF, M_WAITOK | M_ZERO);
423 /* allocate transmission resources */
424 error = patm_txmap_init(sc);
428 /* poll while we are not running */
429 sc->utopia.flags |= UTP_FL_POLL_CARRIER;
431 patm_debug(sc, ATTACH, "attaching interface");
435 bpfattach(ifp, DLT_ATM_RFC1483, sizeof(struct atmllc));
438 patm_debug(sc, ATTACH, "attaching interrupt handler");
439 error = bus_setup_intr(dev, sc->irqres, INTR_TYPE_NET, patm_intr,
442 patm_printf(sc, "could not setup interrupt\n");
443 atm_ifdetach(&sc->ifatm.ifnet);
458 patm_detach(device_t dev)
460 struct patm_softc *sc;
462 sc = (struct patm_softc *)device_get_softc(dev);
466 if (sc->utopia.state & UTP_ST_ATTACHED) {
467 patm_debug(sc, ATTACH, "detaching utopia");
468 utopia_stop(&sc->utopia);
469 utopia_detach(&sc->utopia);
471 mtx_unlock(&sc->mtx);
473 atm_ifdetach(&sc->ifatm.ifnet);
481 * Destroy everything. Assume we are stopped.
484 patm_destroy(struct patm_softc *sc)
487 struct patm_txmap *map;
490 bus_teardown_intr(sc->dev, sc->irqres, sc->ih);
492 if (sc->tx_mapzone != NULL) {
493 /* all maps must be free */
494 while ((map = SLIST_FIRST(&sc->tx_maps_free)) != NULL) {
495 bus_dmamap_destroy(sc->tx_tag, map->map);
496 SLIST_REMOVE_HEAD(&sc->tx_maps_free, link);
497 uma_zfree(sc->tx_mapzone, map);
499 uma_zdestroy(sc->tx_mapzone);
502 if (sc->scd_tag != NULL)
503 bus_dma_tag_destroy(sc->scd_tag);
505 if (sc->tx_tag != NULL)
506 bus_dma_tag_destroy(sc->scd_tag);
508 if (sc->vccs != NULL) {
509 for (i = 0; i < sc->mmap->max_conn; i++)
510 if (sc->vccs[i] != NULL)
511 uma_zfree(sc->vcc_zone, sc->vccs[i]);
512 free(sc->vccs, M_DEVBUF);
514 if (sc->vcc_zone != NULL)
515 uma_zdestroy(sc->vcc_zone);
517 if (sc->lbufs != NULL) {
518 for (i = 0; i < sc->lbuf_max; i++)
519 bus_dmamap_destroy(sc->lbuf_tag, sc->lbufs[i].map);
520 free(sc->lbufs, M_DEVBUF);
523 if (sc->lbuf_tag != NULL)
524 bus_dma_tag_destroy(sc->lbuf_tag);
526 if (sc->sbuf_pool != NULL)
527 mbp_destroy(sc->sbuf_pool);
528 if (sc->vbuf_pool != NULL)
529 mbp_destroy(sc->vbuf_pool);
531 if (sc->sbuf_tag != NULL)
532 bus_dma_tag_destroy(sc->sbuf_tag);
534 if (sc->tst_soft != NULL)
535 free(sc->tst_soft, M_DEVBUF);
538 * Free all status queue memory resources
540 if (sc->tsq != NULL) {
541 bus_dmamap_unload(sc->sq_tag, sc->sq_map);
542 bus_dmamem_free(sc->sq_tag, sc->tsq, sc->sq_map);
543 bus_dma_tag_destroy(sc->sq_tag);
546 if (sc->irqres != NULL)
547 bus_release_resource(sc->dev, SYS_RES_IRQ,
548 sc->irqid, sc->irqres);
549 if (sc->memres != NULL)
550 bus_release_resource(sc->dev, SYS_RES_MEMORY,
551 IDT_PCI_REG_MEMBASE, sc->memres);
553 /* this was initialize unconditionally */
554 sysctl_ctx_free(&sc->sysctl_ctx);
555 cv_destroy(&sc->vcc_cv);
556 mtx_destroy(&sc->tst_lock);
557 mtx_destroy(&sc->mtx);
561 * Try to find a variable in the environment and parse it as an unsigned
565 patm_env_getuint(struct patm_softc *sc, u_int *var, const char *name)
567 char full[IFNAMSIZ + 3 + 20];
571 snprintf(full, sizeof(full), "hw.%s.%s",
572 device_get_nameunit(sc->dev), name);
574 if ((val = getenv(full)) != NULL) {
575 u = strtoul(val, &end, 0);
576 if (end > val && *end == '\0') {
578 patm_printf(sc, "%s=%lu\n", full, u);
586 * Sysctl handler for internal statistics
588 * LOCK: unlocked, needed
591 patm_sysctl_istats(SYSCTL_HANDLER_ARGS)
593 struct patm_softc *sc = arg1;
597 ret = malloc(sizeof(sc->stats), M_TEMP, M_WAITOK);
600 bcopy(&sc->stats, ret, sizeof(sc->stats));
601 mtx_unlock(&sc->mtx);
603 error = SYSCTL_OUT(req, ret, sizeof(sc->stats));
610 * Sysctl handler for EEPROM
612 * LOCK: unlocked, needed
615 patm_sysctl_eeprom(SYSCTL_HANDLER_ARGS)
617 struct patm_softc *sc = arg1;
621 ret = malloc(sizeof(sc->eeprom), M_TEMP, M_WAITOK);
624 bcopy(sc->eeprom, ret, sizeof(sc->eeprom));
625 mtx_unlock(&sc->mtx);
627 error = SYSCTL_OUT(req, ret, sizeof(sc->eeprom));
634 * Read the EEPROM. We assume that this is a XIRCOM 25020
637 patm_read_eeprom(struct patm_softc *sc)
643 static const uint32_t tab[] = {
644 /* CS transition to reset the chip */
645 IDT_GP_EECS | IDT_GP_EESCLK, 0,
646 /* read command 0x03 */
652 IDT_GP_EESCLK, IDT_GP_EEDO,
653 IDT_GP_EESCLK | IDT_GP_EEDO, IDT_GP_EEDO,
654 IDT_GP_EESCLK | IDT_GP_EEDO, 0,
666 /* go to a known state (chip enabled) */
667 gp = patm_nor_read(sc, IDT_NOR_GP);
668 gp &= ~(IDT_GP_EESCLK | IDT_GP_EECS | IDT_GP_EEDO);
670 for (i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
671 patm_nor_write(sc, IDT_NOR_GP, gp | tab[i]);
675 /* read out the prom */
676 for (addr = 0; addr < 256; addr++) {
678 for (i = 0; i < 8; i++) {
680 if (patm_nor_read(sc, IDT_NOR_GP) & IDT_GP_EEDI)
683 patm_nor_write(sc, IDT_NOR_GP, gp | IDT_GP_EESCLK);
686 patm_nor_write(sc, IDT_NOR_GP, gp);
689 sc->eeprom[addr] = byte;
697 patm_phy_readregs(struct ifatm *ifatm, u_int reg, uint8_t *val, u_int *n)
699 struct patm_softc *sc = ifatm->ifnet.if_softc;
706 while (reg < 0x100 && cnt > 0) {
707 patm_nor_write(sc, IDT_NOR_CMD, IDT_MKCMD_RUTIL(1, 0, reg));
709 *val = patm_nor_read(sc, IDT_NOR_D0);
710 patm_debug(sc, PHY, "phy(%02x)=%02x", reg, *val);
723 patm_phy_writereg(struct ifatm *ifatm, u_int reg, u_int mask, u_int val)
725 struct patm_softc *sc = ifatm->ifnet.if_softc;
732 patm_nor_write(sc, IDT_NOR_CMD, IDT_MKCMD_RUTIL(1, 0, reg));
735 old = patm_nor_read(sc, IDT_NOR_D0);
736 new = (old & ~mask) | (val & mask);
737 patm_debug(sc, PHY, "phy(%02x) %02x -> %02x", reg, old, new);
739 patm_nor_write(sc, IDT_NOR_D0, new);
740 patm_nor_write(sc, IDT_NOR_CMD, IDT_MKCMD_WUTIL(1, 0, reg));
747 * Allocate a large chunk of DMA able memory for the transmit
748 * and receive status queues. We align this to a page boundary
749 * to ensure the alignment.
752 patm_sq_init(struct patm_softc *sc)
757 /* compute size of the two queues */
758 sc->sq_size = IDT_TSQ_SIZE * IDT_TSQE_SIZE +
759 PATM_RSQ_SIZE * IDT_RSQE_SIZE +
762 patm_debug(sc, ATTACH,
763 "allocating status queues (%zu) ...", sc->sq_size);
767 * Don't use BUS_DMA_ALLOCNOW, because we never need bouncing with
770 error = bus_dma_tag_create(NULL, PATM_SQ_ALIGNMENT, 0,
771 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
772 NULL, NULL, sc->sq_size, 1, sc->sq_size,
773 0, NULL, NULL, &sc->sq_tag);
775 patm_printf(sc, "memory DMA tag create %d\n", error);
779 /* allocate memory */
780 error = bus_dmamem_alloc(sc->sq_tag, &p, 0, &sc->sq_map);
782 patm_printf(sc, "memory DMA alloc %d\n", error);
783 bus_dma_tag_destroy(sc->sq_tag);
788 sc->tsq_phy = 0x1fff;
789 error = bus_dmamap_load(sc->sq_tag, sc->sq_map, p,
790 sc->sq_size, patm_load_callback, &sc->tsq_phy, BUS_DMA_NOWAIT);
792 patm_printf(sc, "memory DMA map load %d\n", error);
793 bus_dmamem_free(sc->sq_tag, p, sc->sq_map);
794 bus_dma_tag_destroy(sc->sq_tag);
798 /* set queue start */
800 sc->rsq = (void *)((char *)p + IDT_TSQ_SIZE * IDT_TSQE_SIZE);
801 sc->rsq_phy = sc->tsq_phy + IDT_TSQ_SIZE * IDT_TSQE_SIZE;
802 sc->rawhnd = (void *)((char *)sc->rsq + PATM_RSQ_SIZE * IDT_RSQE_SIZE);
803 sc->rawhnd_phy = sc->rsq_phy + PATM_RSQ_SIZE * IDT_RSQE_SIZE;
809 * Initialize all receive buffer stuff
812 patm_rbuf_init(struct patm_softc *sc)
817 patm_debug(sc, ATTACH, "allocating Rx buffer resources ...");
819 * Create a tag for small buffers. We allocate these page wise.
820 * Don't use BUS_DMA_ALLOCNOW, because we never need bouncing with
823 if ((error = bus_dma_tag_create(NULL, PAGE_SIZE, 0,
824 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
825 SMBUF_PAGE_SIZE, 1, SMBUF_PAGE_SIZE, 0,
826 NULL, NULL, &sc->sbuf_tag)) != 0) {
827 patm_printf(sc, "sbuf DMA tag create %d\n", error);
831 error = mbp_create(&sc->sbuf_pool, "patm sbufs", sc->sbuf_tag,
832 SMBUF_MAX_PAGES, SMBUF_PAGE_SIZE, SMBUF_CHUNK_SIZE);
834 patm_printf(sc, "smbuf pool create %d\n", error);
838 error = mbp_create(&sc->vbuf_pool, "patm vbufs", sc->sbuf_tag,
839 VMBUF_MAX_PAGES, SMBUF_PAGE_SIZE, VMBUF_CHUNK_SIZE);
841 patm_printf(sc, "vmbuf pool create %d\n", error);
846 * Create a tag for large buffers.
847 * Don't use BUS_DMA_ALLOCNOW, because it makes no sense with multiple
848 * maps using one tag. Rather use BUS_DMA_NOWAIT when loading the map
849 * to prevent EINPROGRESS.
851 if ((error = bus_dma_tag_create(NULL, 4, 0,
852 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
853 MCLBYTES, 1, MCLBYTES, 0,
854 NULL, NULL, &sc->lbuf_tag)) != 0) {
855 patm_printf(sc, "lbuf DMA tag create %d\n", error);
859 if (sc->lbuf_max < IDT_FBQ_SIZE)
860 sc->lbuf_max = LMBUF_MAX;
861 sc->lbufs = malloc(sizeof(sc->lbufs[0]) * sc->lbuf_max,
862 M_DEVBUF, M_ZERO | M_WAITOK);
864 SLIST_INIT(&sc->lbuf_free_list);
865 for (i = 0; i < sc->lbuf_max; i++) {
866 struct lmbuf *b = &sc->lbufs[i];
868 error = bus_dmamap_create(sc->lbuf_tag, 0, &b->map);
870 /* must deallocate here, because a test for NULL
871 * does not work on most archs */
873 bus_dmamap_destroy(sc->lbuf_tag,
875 free(sc->lbufs, M_DEVBUF);
880 SLIST_INSERT_HEAD(&sc->lbuf_free_list, b, link);
887 * Allocate everything needed for the transmission maps.
890 patm_txmap_init(struct patm_softc *sc)
893 struct patm_txmap *map;
895 /* get transmission tag */
896 error = bus_dma_tag_create(NULL, 1, 0,
897 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
898 NULL, NULL, 65536, IDT_SCQ_SIZE - 1, 65536,
899 0, NULL, NULL, &sc->tx_tag);
901 patm_printf(sc, "cannot allocate TX tag %d\n", error);
905 if ((sc->tx_mapzone = uma_zcreate("PATM tx maps",
906 sizeof(struct patm_txmap), NULL, NULL, NULL, NULL,
907 UMA_ALIGN_PTR, 0)) == NULL)
910 if (sc->tx_maxmaps < PATM_CFG_TXMAPS_MAX)
911 sc->tx_maxmaps = PATM_CFG_TXMAPS_MAX;
912 sc->tx_nmaps = PATM_CFG_TXMAPS_INIT;
914 for (sc->tx_nmaps = 0; sc->tx_nmaps < PATM_CFG_TXMAPS_INIT;
916 map = uma_zalloc(sc->tx_mapzone, M_WAITOK);
917 error = bus_dmamap_create(sc->tx_tag, 0, &map->map);
919 uma_zfree(sc->tx_mapzone, map);
922 SLIST_INSERT_HEAD(&sc->tx_maps_free, map, link);
931 * Sysctl handler for REGS
933 * LOCK: unlocked, needed
936 patm_sysctl_regs(SYSCTL_HANDLER_ARGS)
938 struct patm_softc *sc = arg1;
942 ret = malloc(IDT_NOR_END, M_TEMP, M_WAITOK);
945 for (i = 0; i < IDT_NOR_END; i += 4)
946 ret[i / 4] = patm_nor_read(sc, i);
947 mtx_unlock(&sc->mtx);
949 error = SYSCTL_OUT(req, ret, IDT_NOR_END);
956 * Sysctl handler for TSQ
958 * LOCK: unlocked, needed
961 patm_sysctl_tsq(SYSCTL_HANDLER_ARGS)
963 struct patm_softc *sc = arg1;
967 ret = malloc(IDT_TSQ_SIZE * IDT_TSQE_SIZE, M_TEMP, M_WAITOK);
970 memcpy(ret, sc->tsq, IDT_TSQ_SIZE * IDT_TSQE_SIZE);
971 mtx_unlock(&sc->mtx);
973 error = SYSCTL_OUT(req, ret, IDT_TSQ_SIZE * IDT_TSQE_SIZE);
982 static struct patm_softc *
983 patm_dump_unit(u_int unit)
986 struct patm_softc *sc;
988 dc = devclass_find("patm");
990 printf("%s: can't find devclass\n", __func__);
993 sc = devclass_get_softc(dc, unit);
995 printf("%s: invalid unit number: %d\n", __func__, unit);
1002 patm_dump_vc(u_int unit, u_int vc)
1004 struct patm_softc *sc;
1010 if ((sc = patm_dump_unit(unit)) == NULL)
1013 for (i = 0; i < 8; i++)
1014 tct[i] = patm_sram_read(sc, vc * 8 + i);
1015 for (i = 0; i < 4; i++)
1016 rct[i] = patm_sram_read(sc, sc->mmap->rct + vc * 4 + i);
1017 for (i = 0; i < 12; i++)
1018 scd[i] = patm_sram_read(sc, (tct[0] & 0x7ffff) + i);
1020 printf("TCT%3u: %08x %08x %08x %08x %08x %08x %08x %08x\n", vc,
1021 tct[0], tct[1], tct[2], tct[3], tct[4], tct[5], tct[6], tct[7]);
1022 printf("RCT%3u: %08x %08x %08x %08x\n", vc,
1023 rct[0], rct[1], rct[2], rct[3]);
1024 printf("SCD%3u: %08x %08x %08x %08x %08x %08x %08x %08x\n", vc,
1025 scd[0], scd[1], scd[2], scd[3], scd[4], scd[5], scd[6], scd[7]);
1026 printf(" %08x %08x %08x %08x\n",
1027 scd[8], scd[9], scd[10], scd[11]);
1033 patm_dump_regs(u_int unit)
1035 struct patm_softc *sc;
1038 if ((sc = patm_dump_unit(unit)) == NULL)
1041 for (i = 0; i <= IDT_NOR_DNOW; i += 4)
1042 printf("%x: %08x\n", i, patm_nor_read(sc, i));
1048 patm_dump_sram(u_int unit, u_int from, u_int words)
1050 struct patm_softc *sc;
1053 if ((sc = patm_dump_unit(unit)) == NULL)
1056 for (i = 0; i < words; i++) {
1058 printf("%05x:", from + i);
1059 printf(" %08x", patm_sram_read(sc, from + i));