Home | History | Annotate | Line # | Download | only in dev
octeon_fpa.c revision 1.6
      1 /*	$NetBSD: octeon_fpa.c,v 1.6 2020/06/18 13:52:08 simonb Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2007 Internet Initiative Japan, Inc.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #undef	FPADEBUG
     30 
     31 #include <sys/cdefs.h>
     32 __KERNEL_RCSID(0, "$NetBSD: octeon_fpa.c,v 1.6 2020/06/18 13:52:08 simonb Exp $");
     33 
     34 #include "opt_octeon.h"
     35 
     36 #include <sys/param.h>
     37 #include <sys/systm.h>
     38 #include <sys/types.h>
     39 #include <sys/malloc.h>
     40 
     41 #include <sys/bus.h>
     42 #include <machine/locore.h>
     43 #include <machine/vmparam.h>
     44 
     45 #include <mips/cavium/octeonvar.h>
     46 #include <mips/cavium/include/iobusvar.h>
     47 #include <mips/cavium/dev/octeon_fpareg.h>
     48 #include <mips/cavium/dev/octeon_fpavar.h>
     49 
     50 #ifdef FPADEBUG
     51 #define	DPRINTF(x)	printf x
     52 #else
     53 #define	DPRINTF(x)
     54 #endif
     55 
     56 #define	_DMA_NSEGS	1
     57 #define	_DMA_BUFLEN	0x01000000
     58 
     59 /* pool descriptor */
     60 struct octfpa_desc {
     61 };
     62 
     63 struct octfpa_softc {
     64 	int			sc_initialized;
     65 
     66 	bus_space_tag_t		sc_regt;
     67 	bus_space_handle_t	sc_regh;
     68 
     69 	bus_space_tag_t		sc_opst;
     70 	bus_space_handle_t	sc_opsh;
     71 
     72 	bus_dma_tag_t		sc_dmat;
     73 
     74 	struct octfpa_desc	sc_descs[8];
     75 
     76 #ifdef CNMAC_DEBUG
     77 	struct evcnt		sc_ev_fpaq7perr;
     78 	struct evcnt		sc_ev_fpaq7coff;
     79 	struct evcnt		sc_ev_fpaq7und;
     80 	struct evcnt		sc_ev_fpaq6perr;
     81 	struct evcnt		sc_ev_fpaq6coff;
     82 	struct evcnt		sc_ev_fpaq6und;
     83 	struct evcnt		sc_ev_fpaq5perr;
     84 	struct evcnt		sc_ev_fpaq5coff;
     85 #endif
     86 };
     87 
     88 void			octfpa_bootstrap(struct octeon_config *);
     89 void			octfpa_reset(void);
     90 void			octfpa_int_enable(struct octfpa_softc *, int);
     91 void			octfpa_buf_dma_alloc(struct octfpa_buf *);
     92 
     93 static void		octfpa_init(struct octfpa_softc *);
     94 #ifdef notyet
     95 static uint64_t		octfpa_iobdma(struct octfpa_softc *, int, int);
     96 #endif
     97 
     98 #ifdef CNMAC_DEBUG
     99 void			octfpa_intr_evcnt_attach(struct octfpa_softc *);
    100 void			octfpa_intr_rml(void *);
    101 #endif
    102 
    103 static struct octfpa_softc	octfpa_softc;
    104 
    105 /* ---- global functions */
    106 
    107 void
    108 octfpa_bootstrap(struct octeon_config *mcp)
    109 {
    110 	struct octfpa_softc *sc = &octfpa_softc;
    111 
    112 	sc->sc_regt = &mcp->mc_iobus_bust;
    113 	sc->sc_opst = &mcp->mc_iobus_bust;
    114 	sc->sc_dmat = &mcp->mc_iobus_dmat;
    115 
    116 	octfpa_init(sc);
    117 }
    118 
    119 void
    120 octfpa_reset(void)
    121 {
    122 	/* XXX */
    123 }
    124 
    125 #ifdef CNMAC_DEBUG
    126 int			octfpa_intr_rml_verbose;
    127 struct evcnt		octfpa_intr_evcnt;
    128 
    129 static const struct octeon_evcnt_entry octfpa_intr_evcnt_entries[] = {
    130 #define	_ENTRY(name, type, parent, descr) \
    131 	OCTEON_EVCNT_ENTRY(struct octfpa_softc, name, type, parent, descr)
    132 	_ENTRY(fpaq7perr,          MISC, NULL, "fpa q7 pointer"),
    133 	_ENTRY(fpaq7coff,          MISC, NULL, "fpa q7 counter offset"),
    134 	_ENTRY(fpaq7und,           MISC, NULL, "fpa q7 underflow"),
    135 	_ENTRY(fpaq6perr,          MISC, NULL, "fpa q6 pointer"),
    136 	_ENTRY(fpaq6coff,          MISC, NULL, "fpa q6 counter offset"),
    137 	_ENTRY(fpaq6und,           MISC, NULL, "fpa q6 underflow"),
    138 	_ENTRY(fpaq5perr,          MISC, NULL, "fpa q5 pointer"),
    139 	_ENTRY(fpaq5coff,          MISC, NULL, "fpa q5 counter offset"),
    140 #undef	_ENTRY
    141 };
    142 
    143 void
    144 octfpa_intr_evcnt_attach(struct octfpa_softc *sc)
    145 {
    146 	OCTEON_EVCNT_ATTACH_EVCNTS(sc, octfpa_intr_evcnt_entries, "fpa0");
    147 }
    148 
    149 void
    150 octfpa_intr_rml(void *arg)
    151 {
    152 	struct octfpa_softc *sc;
    153 	uint64_t reg;
    154 
    155 	octfpa_intr_evcnt.ev_count++;
    156 	sc = &octfpa_softc;
    157 	KASSERT(sc != NULL);
    158 	reg = octfpa_int_summary();
    159 	if (octfpa_intr_rml_verbose)
    160 		printf("%s: FPA_INT_SUM=0x%016" PRIx64 "\n", __func__, reg);
    161 	if (reg & FPA_INT_SUM_Q7_PERR)
    162 		OCTEON_EVCNT_INC(sc, fpaq7perr);
    163 	if (reg & FPA_INT_SUM_Q7_COFF)
    164 		OCTEON_EVCNT_INC(sc, fpaq7coff);
    165 	if (reg & FPA_INT_SUM_Q7_UND)
    166 		OCTEON_EVCNT_INC(sc, fpaq7und);
    167 	if (reg & FPA_INT_SUM_Q6_PERR)
    168 		OCTEON_EVCNT_INC(sc, fpaq6perr);
    169 	if (reg & FPA_INT_SUM_Q6_COFF)
    170 		OCTEON_EVCNT_INC(sc, fpaq6coff);
    171 	if (reg & FPA_INT_SUM_Q6_UND)
    172 		OCTEON_EVCNT_INC(sc, fpaq6und);
    173 	if (reg & FPA_INT_SUM_Q5_PERR)
    174 		OCTEON_EVCNT_INC(sc, fpaq5perr);
    175 	if (reg & FPA_INT_SUM_Q5_COFF)
    176 		OCTEON_EVCNT_INC(sc, fpaq5coff);
    177 }
    178 
    179 void
    180 octfpa_int_enable(struct octfpa_softc *sc, int enable)
    181 {
    182 	const uint64_t int_xxx =
    183 	    FPA_INT_ENB_Q7_PERR | FPA_INT_ENB_Q7_COFF | FPA_INT_ENB_Q7_UND |
    184 	    FPA_INT_ENB_Q6_PERR | FPA_INT_ENB_Q6_COFF | FPA_INT_ENB_Q6_UND |
    185 	    FPA_INT_ENB_Q5_PERR | FPA_INT_ENB_Q5_COFF | FPA_INT_ENB_Q5_UND |
    186 	    FPA_INT_ENB_Q4_PERR | FPA_INT_ENB_Q4_COFF | FPA_INT_ENB_Q4_UND |
    187 	    FPA_INT_ENB_Q3_PERR | FPA_INT_ENB_Q3_COFF | FPA_INT_ENB_Q3_UND |
    188 	    FPA_INT_ENB_Q2_PERR | FPA_INT_ENB_Q2_COFF | FPA_INT_ENB_Q2_UND |
    189 	    FPA_INT_ENB_Q1_PERR | FPA_INT_ENB_Q1_COFF | FPA_INT_ENB_Q1_UND |
    190 	    FPA_INT_ENB_Q0_PERR | FPA_INT_ENB_Q0_COFF | FPA_INT_ENB_Q0_UND |
    191 	    FPA_INT_ENB_FED1_DBE | FPA_INT_ENB_FED1_SBE |
    192 	    FPA_INT_ENB_FED0_DBE | FPA_INT_ENB_FED0_SBE;
    193 
    194 	bus_space_write_8(sc->sc_regt, sc->sc_regh, FPA_INT_SUM_OFFSET,
    195 	    int_xxx);
    196 	if (enable)
    197 		bus_space_write_8(sc->sc_regt, sc->sc_regh, FPA_INT_ENB_OFFSET,
    198 		    int_xxx);
    199 }
    200 
    201 uint64_t
    202 octfpa_int_summary(void)
    203 {
    204 	struct octfpa_softc *sc = &octfpa_softc;
    205 	uint64_t summary;
    206 
    207 	summary = bus_space_read_8(sc->sc_regt, sc->sc_regh, FPA_INT_SUM_OFFSET);
    208 	bus_space_write_8(sc->sc_regt, sc->sc_regh, FPA_INT_SUM_OFFSET, summary);
    209 	return summary;
    210 }
    211 #endif
    212 
    213 int
    214 octfpa_buf_init(int poolno, size_t size, size_t nelems, struct octfpa_buf **rfb)
    215 {
    216 	struct octfpa_softc *sc = &octfpa_softc;
    217 	struct octfpa_buf *fb;
    218 	int nsegs;
    219 	paddr_t paddr;
    220 
    221 	nsegs = 1/* XXX */;
    222 	fb = malloc(sizeof(*fb) + sizeof(*fb->fb_dma_segs) * nsegs, M_DEVBUF,
    223 	    M_WAITOK | M_ZERO);
    224 	if (fb == NULL)
    225 		return 1;
    226 	fb->fb_poolno = poolno;
    227 	fb->fb_size = size;
    228 	fb->fb_nelems = nelems;
    229 	fb->fb_len = size * nelems;
    230 	fb->fb_dmat = sc->sc_dmat;
    231 	fb->fb_dma_segs = (void *)(fb + 1);
    232 	fb->fb_dma_nsegs = nsegs;
    233 
    234 	octfpa_buf_dma_alloc(fb);
    235 
    236 	for (paddr = fb->fb_paddr; paddr < fb->fb_paddr + fb->fb_len;
    237 	    paddr += fb->fb_size)
    238 		octfpa_buf_put_paddr(fb, paddr);
    239 
    240 	*rfb = fb;
    241 
    242 	return 0;
    243 }
    244 
    245 void *
    246 octfpa_buf_get(struct octfpa_buf *fb)
    247 {
    248 	paddr_t paddr;
    249 	vaddr_t addr;
    250 
    251 	paddr = octfpa_buf_get_paddr(fb);
    252 	if (paddr == 0)
    253 		addr = 0;
    254 	else
    255 		addr = fb->fb_addr + (vaddr_t/* XXX */)(paddr - fb->fb_paddr);
    256 	return (void *)addr;
    257 }
    258 
    259 void
    260 octfpa_buf_dma_alloc(struct octfpa_buf *fb)
    261 {
    262 	int status;
    263 	int nsegs;
    264 	void *va;
    265 
    266 	status = bus_dmamap_create(fb->fb_dmat, fb->fb_len,
    267 	    fb->fb_len / PAGE_SIZE,	/* # of segments */
    268 	    fb->fb_len,			/* we don't use s/g for FPA buf */
    269 	    PAGE_SIZE,			/* OCTEON hates >PAGE_SIZE boundary */
    270 	    0, &fb->fb_dmah);
    271 	if (status != 0)
    272 		panic("%s failed", "bus_dmamap_create");
    273 
    274 	status = bus_dmamem_alloc(fb->fb_dmat, fb->fb_len, 128, 0,
    275 	    fb->fb_dma_segs, fb->fb_dma_nsegs, &nsegs, 0);
    276 	if (status != 0 || fb->fb_dma_nsegs != nsegs)
    277 		panic("%s failed", "bus_dmamem_alloc");
    278 
    279 	status = bus_dmamem_map(fb->fb_dmat, fb->fb_dma_segs, fb->fb_dma_nsegs,
    280 	    fb->fb_len, &va, 0);
    281 	if (status != 0)
    282 		panic("%s failed", "bus_dmamem_map");
    283 
    284 	status = bus_dmamap_load(fb->fb_dmat, fb->fb_dmah, va, fb->fb_len,
    285 	    NULL,		/* kernel */
    286 	    0);
    287 	if (status != 0)
    288 		panic("%s failed", "bus_dmamap_load");
    289 
    290 	fb->fb_addr = (vaddr_t)va;
    291 	fb->fb_paddr = fb->fb_dma_segs[0].ds_addr;
    292 }
    293 
    294 uint64_t
    295 octfpa_query(int poolno)
    296 {
    297 	struct octfpa_softc *sc = &octfpa_softc;
    298 
    299 	return bus_space_read_8(sc->sc_regt, sc->sc_regh,
    300 	    FPA_QUE0_AVAILABLE_OFFSET + sizeof(uint64_t) * poolno);
    301 }
    302 
    303 /* ---- local functions */
    304 
    305 static inline void	octfpa_init_bus(struct octfpa_softc *);
    306 static inline void	octfpa_init_bus_space(struct octfpa_softc *);
    307 static inline void	octfpa_init_regs(struct octfpa_softc *);
    308 
    309 void
    310 octfpa_init(struct octfpa_softc *sc)
    311 {
    312 	if (sc->sc_initialized != 0)
    313 		panic("%s: already initialized", __func__);
    314 	sc->sc_initialized = 1;
    315 
    316 	octfpa_init_bus(sc);
    317 	octfpa_init_regs(sc);
    318 #ifdef CNMAC_DEBUG
    319 	octfpa_int_enable(sc, 1);
    320 	octfpa_intr_evcnt_attach(sc);
    321 #endif
    322 }
    323 
    324 void
    325 octfpa_init_bus(struct octfpa_softc *sc)
    326 {
    327 	octfpa_init_bus_space(sc);
    328 }
    329 
    330 void
    331 octfpa_init_bus_space(struct octfpa_softc *sc)
    332 {
    333 	int status;
    334 
    335 	status = bus_space_map(sc->sc_regt, FPA_BASE, FPA_SIZE, 0, &sc->sc_regh);
    336 	if (status != 0)
    337 		panic("can't map %s space", "register");
    338 
    339 	status = bus_space_map(sc->sc_opst,
    340 	    0x0001180028000000ULL/* XXX */, 0x0200/* XXX */, 0, &sc->sc_opsh);
    341 	if (status != 0)
    342 		panic("can't map %s space", "operations");
    343 }
    344 
    345 void
    346 octfpa_init_regs(struct octfpa_softc *sc)
    347 {
    348 
    349 	bus_space_write_8(sc->sc_regt, sc->sc_regh, FPA_CTL_STATUS_OFFSET,
    350 	    FPA_CTL_STATUS_ENB);
    351 
    352 /* XXX */
    353 #ifdef CNMAC_DEBUG
    354 	bus_space_write_8(sc->sc_regt, sc->sc_regh, FPA_INT_ENB_OFFSET,
    355 	    FPA_INT_ENB_Q7_PERR | FPA_INT_ENB_Q7_COFF | FPA_INT_ENB_Q7_UND |
    356 	    FPA_INT_ENB_Q6_PERR | FPA_INT_ENB_Q6_COFF | FPA_INT_ENB_Q6_UND |
    357 	    FPA_INT_ENB_Q5_PERR | FPA_INT_ENB_Q5_COFF | FPA_INT_ENB_Q5_UND |
    358 	    FPA_INT_ENB_Q4_PERR | FPA_INT_ENB_Q4_COFF | FPA_INT_ENB_Q4_UND |
    359 	    FPA_INT_ENB_Q3_PERR | FPA_INT_ENB_Q3_COFF | FPA_INT_ENB_Q3_UND |
    360 	    FPA_INT_ENB_Q2_PERR | FPA_INT_ENB_Q2_COFF | FPA_INT_ENB_Q2_UND |
    361 	    FPA_INT_ENB_Q1_PERR | FPA_INT_ENB_Q1_COFF | FPA_INT_ENB_Q1_UND |
    362 	    FPA_INT_ENB_Q0_PERR | FPA_INT_ENB_Q0_COFF | FPA_INT_ENB_Q0_UND |
    363 	    FPA_INT_ENB_FED1_DBE | FPA_INT_ENB_FED1_SBE |
    364 	    FPA_INT_ENB_FED0_DBE | FPA_INT_ENB_FED0_SBE);
    365 #endif
    366 }
    367 
    368 int
    369 octfpa_available_fpa_pool(int *available, int pool_no) {
    370 	struct octfpa_softc *sc = &octfpa_softc;
    371 	size_t offset;
    372 	uint64_t tmp;
    373 
    374 	switch (pool_no) {
    375 	case OCTEON_POOL_NO_PKT:
    376 		offset = FPA_QUE0_AVAILABLE_OFFSET;
    377 		break;
    378 	case OCTEON_POOL_NO_WQE:
    379 		offset = FPA_QUE1_AVAILABLE_OFFSET;
    380 		break;
    381 	case OCTEON_POOL_NO_CMD:
    382 		offset = FPA_QUE2_AVAILABLE_OFFSET;
    383 		break;
    384 	case OCTEON_POOL_NO_SG:
    385 		offset = FPA_QUE3_AVAILABLE_OFFSET;
    386 		break;
    387 	case OCTEON_POOL_NO_XXX_4:
    388 		offset = FPA_QUE4_AVAILABLE_OFFSET;
    389 		break;
    390 	case OCTEON_POOL_NO_XXX_5:
    391 		offset = FPA_QUE5_AVAILABLE_OFFSET;
    392 		break;
    393 	case OCTEON_POOL_NO_XXX_6:
    394 		offset = FPA_QUE6_AVAILABLE_OFFSET;
    395 		break;
    396 	case OCTEON_POOL_NO_DUMP:
    397 		offset = FPA_QUE7_AVAILABLE_OFFSET;
    398 		break;
    399 	default:
    400 		return EINVAL;
    401 	}
    402 	tmp = bus_space_read_8(sc->sc_regt, sc->sc_regh, offset);
    403 	if (available) {
    404 		*available = (int)(tmp & FPA_QUEX_AVAILABLE_QUE_SIZ);
    405 	}
    406 
    407 	return 0;
    408 }
    409 
    410 #ifdef CNMAC_DEBUG
    411 void		octfpa_dump_regs(void);
    412 void		octfpa_dump_bufs(void);
    413 void		octfpa_dump_buf(int);
    414 
    415 #define	_ENTRY(x)	{ #x, x##_BITS, x##_OFFSET }
    416 
    417 struct octfpa_dump_reg_ {
    418 	const char *name;
    419 	const char *format;
    420 	size_t	offset;
    421 };
    422 
    423 static const struct octfpa_dump_reg_ octfpa_dump_regs_[] = {
    424 	_ENTRY(FPA_INT_SUM),
    425 	_ENTRY(FPA_INT_ENB),
    426 	_ENTRY(FPA_CTL_STATUS),
    427 	_ENTRY(FPA_QUE0_AVAILABLE),
    428 	_ENTRY(FPA_QUE1_AVAILABLE),
    429 	_ENTRY(FPA_QUE2_AVAILABLE),
    430 	_ENTRY(FPA_QUE3_AVAILABLE),
    431 	_ENTRY(FPA_QUE4_AVAILABLE),
    432 	_ENTRY(FPA_QUE5_AVAILABLE),
    433 	_ENTRY(FPA_QUE6_AVAILABLE),
    434 	_ENTRY(FPA_QUE7_AVAILABLE),
    435 	_ENTRY(FPA_WART_CTL),
    436 	_ENTRY(FPA_WART_STATUS),
    437 	_ENTRY(FPA_BIST_STATUS),
    438 	_ENTRY(FPA_QUE0_PAGE_INDEX),
    439 	_ENTRY(FPA_QUE1_PAGE_INDEX),
    440 	_ENTRY(FPA_QUE2_PAGE_INDEX),
    441 	_ENTRY(FPA_QUE3_PAGE_INDEX),
    442 	_ENTRY(FPA_QUE4_PAGE_INDEX),
    443 	_ENTRY(FPA_QUE5_PAGE_INDEX),
    444 	_ENTRY(FPA_QUE6_PAGE_INDEX),
    445 	_ENTRY(FPA_QUE7_PAGE_INDEX),
    446 	_ENTRY(FPA_QUE_EXP),
    447 	_ENTRY(FPA_QUE_ACT),
    448 };
    449 
    450 static const char *octfpa_dump_bufs_[8] = {
    451 	[0] = "recv",
    452 	[1] = "wq",
    453 	[2] = "cmdbuf",
    454 	[3] = "gbuf",
    455 };
    456 
    457 void
    458 octfpa_dump(void)
    459 {
    460 	octfpa_dump_regs();
    461 	octfpa_dump_bufs();
    462 }
    463 
    464 void
    465 octfpa_dump_regs(void)
    466 {
    467 	struct octfpa_softc *sc = &octfpa_softc;
    468 	const struct octfpa_dump_reg_ *reg;
    469 	uint64_t tmp;
    470 	char buf[512];
    471 	int i;
    472 
    473 	for (i = 0; i < (int)__arraycount(octfpa_dump_regs_); i++) {
    474 		reg = &octfpa_dump_regs_[i];
    475 		tmp = bus_space_read_8(sc->sc_regt, sc->sc_regh, reg->offset);
    476 		if (reg->format == NULL) {
    477 			snprintf(buf, sizeof(buf), "%16" PRIx64, tmp);
    478 		} else {
    479 			snprintb(buf, sizeof(buf), reg->format, tmp);
    480 		}
    481 		printf("\t%-24s: %s\n", reg->name, buf);
    482 	}
    483 }
    484 
    485 /*
    486  * XXX assume pool 7 is unused!
    487  */
    488 void
    489 octfpa_dump_bufs(void)
    490 {
    491 	int i;
    492 
    493 	for (i = 0; i < 8; i++)
    494 		octfpa_dump_buf(i);
    495 }
    496 
    497 void
    498 octfpa_dump_buf(int pool)
    499 {
    500 	int i;
    501 	uint64_t ptr;
    502 	const char *name;
    503 
    504 	name = octfpa_dump_bufs_[pool];
    505 	if (name == NULL)
    506 		return;
    507 	printf("%s pool:\n", name);
    508 	for (i = 0; (ptr = octfpa_load(pool)) != 0; i++) {
    509 		printf("\t%016" PRIx64 "%s", ptr, ((i % 4) == 3) ? "\n" : "");
    510 		octfpa_store(ptr, OCTEON_POOL_NO_DUMP, 0);
    511 	}
    512 	if (i % 4 != 3)
    513 		printf("\n");
    514 	printf("total = %d buffers\n", i);
    515 	while ((ptr = octfpa_load(OCTEON_POOL_NO_DUMP)) != 0)
    516 		octfpa_store(ptr, pool, 0);
    517 }
    518 #endif
    519