diff options
-rw-r--r-- | sys/dev/hatm/if_hatm_intr.c | 106 | ||||
-rw-r--r-- | sys/dev/hatm/if_hatmvar.h | 38 |
2 files changed, 72 insertions, 72 deletions
diff --git a/sys/dev/hatm/if_hatm_intr.c b/sys/dev/hatm/if_hatm_intr.c index 97c4e20..b359ecb 100644 --- a/sys/dev/hatm/if_hatm_intr.c +++ b/sys/dev/hatm/if_hatm_intr.c @@ -250,50 +250,6 @@ hatm_mbuf1_free(void *buf, void *args) hatm_ext_free(&sc->mbuf_list[1], (struct mbufx_free *)c); } -/* - * Allocate an external mbuf storage - */ -static int -hatm_mbuf_alloc(struct hatm_softc *sc, u_int group, uint32_t *phys, - uint32_t *handle) -{ - struct mbufx_free *cf; - struct mbuf_page *pg; - - if (group == 0) { - struct mbuf0_chunk *buf0; - - if ((cf = hatm_ext_alloc(sc, 0)) == NULL) - return (-1); - buf0 = (struct mbuf0_chunk *)cf; - pg = sc->mbuf_pages[buf0->hdr.pageno]; - MBUF_SET_BIT(pg->hdr.card, buf0->hdr.chunkno); - - *handle = MBUF_MAKE_HANDLE(buf0->hdr.pageno, buf0->hdr.chunkno); - *phys = pg->hdr.phys + buf0->hdr.chunkno * MBUF0_CHUNK + - MBUF0_OFFSET; - - } else if (group == 1) { - struct mbuf1_chunk *buf1; - - if ((cf = hatm_ext_alloc(sc, 1)) == NULL) - return (-1); - buf1 = (struct mbuf1_chunk *)cf; - pg = sc->mbuf_pages[buf1->hdr.pageno]; - MBUF_SET_BIT(pg->hdr.card, buf1->hdr.chunkno); - - *handle = MBUF_MAKE_HANDLE(buf1->hdr.pageno, buf1->hdr.chunkno); - *phys = pg->hdr.phys + buf1->hdr.chunkno * MBUF1_CHUNK + - MBUF1_OFFSET; - - } else - return (-1); - - bus_dmamap_sync(sc->mbuf_tag, pg->hdr.map, BUS_DMASYNC_PREREAD); - - return (0); -} - static void hatm_mbuf_helper(void *arg, bus_dma_segment_t *segs, int nsegs, int error) { @@ -321,6 +277,10 @@ he_intr_rbp(struct hatm_softc *sc, struct herbp *rbp, u_int large, u_int ntail; struct mbuf *m; int error; + struct mbufx_free *cf; + struct mbuf_page *pg; + struct mbuf0_chunk *buf0; + struct mbuf1_chunk *buf1; DBG(sc, INTR, ("%s buffer supply threshold crossed for group %u", large ? "large" : "small", group)); @@ -333,6 +293,7 @@ he_intr_rbp(struct hatm_softc *sc, struct herbp *rbp, u_int large, ntail = 0; if (ntail == rbp->head) break; + m = NULL; if (large) { /* allocate the MBUF */ @@ -358,24 +319,54 @@ he_intr_rbp(struct hatm_softc *sc, struct herbp *rbp, u_int large, sc->rmaps[sc->lbufs_next], BUS_DMASYNC_PREREAD); - rbp->rbp[rbp->tail].handle = sc->lbufs_next | - MBUF_LARGE_FLAG; + rbp->rbp[rbp->tail].handle = + MBUF_MAKE_LHANDLE(sc->lbufs_next); if (++sc->lbufs_next == sc->lbufs_size) sc->lbufs_next = 0; - } else { - m = NULL; - if (hatm_mbuf_alloc(sc, group, - &rbp->rbp[rbp->tail].phys, - &rbp->rbp[rbp->tail].handle)) { - m_freem(m); + } else if (group == 0) { + /* + * Allocate small buffer in group 0 + */ + if ((cf = hatm_ext_alloc(sc, 0)) == NULL) break; - } - } + buf0 = (struct mbuf0_chunk *)cf; + pg = sc->mbuf_pages[buf0->hdr.pageno]; + MBUF_SET_BIT(pg->hdr.card, buf0->hdr.chunkno); + rbp->rbp[rbp->tail].phys = pg->hdr.phys + + buf0->hdr.chunkno * MBUF0_CHUNK + MBUF0_OFFSET; + rbp->rbp[rbp->tail].handle = + MBUF_MAKE_HANDLE(buf0->hdr.pageno, + buf0->hdr.chunkno); + + bus_dmamap_sync(sc->mbuf_tag, pg->hdr.map, + BUS_DMASYNC_PREREAD); + + } else if (group == 1) { + /* + * Allocate small buffer in group 1 + */ + if ((cf = hatm_ext_alloc(sc, 1)) == NULL) + break; + buf1 = (struct mbuf1_chunk *)cf; + pg = sc->mbuf_pages[buf1->hdr.pageno]; + MBUF_SET_BIT(pg->hdr.card, buf1->hdr.chunkno); + rbp->rbp[rbp->tail].phys = pg->hdr.phys + + buf1->hdr.chunkno * MBUF1_CHUNK + MBUF1_OFFSET; + rbp->rbp[rbp->tail].handle = + MBUF_MAKE_HANDLE(buf1->hdr.pageno, + buf1->hdr.chunkno); + + bus_dmamap_sync(sc->mbuf_tag, pg->hdr.map, + BUS_DMASYNC_PREREAD); + + } else + /* ups */ + break; + DBG(sc, DMA, ("MBUF loaded: handle=%x m=%p phys=%x", rbp->rbp[rbp->tail].handle, m, rbp->rbp[rbp->tail].phys)); - rbp->rbp[rbp->tail].handle <<= HE_REGS_RBRQ_ADDR; rbp->tail = ntail; } @@ -395,7 +386,7 @@ hatm_rx_buffer(struct hatm_softc *sc, u_int group, u_int handle) if (handle & MBUF_LARGE_FLAG) { /* large buffer - sync and unload */ - handle &= ~MBUF_LARGE_FLAG; + MBUF_PARSE_LHANDLE(handle, handle); DBG(sc, RX, ("RX large handle=%x", handle)); bus_dmamap_sync(sc->mbuf_tag, sc->rmaps[handle], @@ -475,8 +466,7 @@ he_intr_rbrq(struct hatm_softc *sc, struct herbrq *rq, u_int group) flags = e->addr & HE_REGM_RBRQ_FLAGS; if (!(flags & HE_REGM_RBRQ_HBUF_ERROR)) - m = hatm_rx_buffer(sc, group, - (e->addr & HE_REGM_RBRQ_ADDR) >> HE_REGS_RBRQ_ADDR); + m = hatm_rx_buffer(sc, group, e->addr); else m = NULL; diff --git a/sys/dev/hatm/if_hatmvar.h b/sys/dev/hatm/if_hatmvar.h index 7686e48..da44932 100644 --- a/sys/dev/hatm/if_hatmvar.h +++ b/sys/dev/hatm/if_hatmvar.h @@ -220,19 +220,19 @@ SLIST_HEAD(tpd_list, tpd); * queue for both tasks. This is done with the lbufs member of softc. The * handle for these buffer is the lbufs index ored with a flag. */ + +/* data space in each external mbuf */ #define MBUF0_SIZE (5 * 48) /* 240 */ -#define MBUF1_SIZE (52) +#define MBUF1_SIZE (52) /* 1 raw cell */ +/* size of the buffer. Must fit data, offset and header */ #define MBUF0_CHUNK 256 /* 16 free bytes */ #define MBUF1_CHUNK 96 /* 44 free bytes */ -#ifdef XXX -#define MBUF0_OFFSET (MBUF0_CHUNK - sizeof(struct mbuf_chunk_hdr) \ - - MBUF0_SIZE) -#else + +/* start of actual data in buffer */ #define MBUF0_OFFSET 0 -#endif -#define MBUF1_OFFSET (MBUF1_CHUNK - sizeof(struct mbuf_chunk_hdr) \ - - MBUF1_SIZE) +#define MBUF1_OFFSET 16 + #define MBUFL_OFFSET 16 /* two pointers for HARP */ #define MBUF_ALLOC_SIZE (PAGE_SIZE) @@ -261,15 +261,25 @@ struct mbuf_page { #define MBUF_SET_BIT(ARRAY, BIT) ((ARRAY)[(BIT) / 8] |= (1 << ((BIT) % 8))) #define MBUF_TST_BIT(ARRAY, BIT) ((ARRAY)[(BIT) / 8] & (1 << ((BIT) % 8))) +/* + * Convert to/from handles + */ +/* small buffers */ #define MBUF_MAKE_HANDLE(PAGENO, CHUNKNO) \ - (((PAGENO) << 10) | (CHUNKNO)) - -#define MBUF_PARSE_HANDLE(HANDLE, PAGENO, CHUNKNO) do { \ - (CHUNKNO) = (HANDLE) & 0x3ff; \ - (PAGENO) = ((HANDLE) >> 10) & 0x3ff; \ + ((((PAGENO) << 10) | (CHUNKNO)) << HE_REGS_RBRQ_ADDR) +#define MBUF_MAKE_LHANDLE(INDEX) \ + (MBUF_LARGE_FLAG | ((INDEX) << HE_REGS_RBRQ_ADDR)) + +/* large buffers */ +#define MBUF_PARSE_HANDLE(HANDLE, PAGENO, CHUNKNO) do { \ + (CHUNKNO) = ((HANDLE) >> HE_REGS_RBRQ_ADDR) & 0x3ff; \ + (PAGENO) = (((HANDLE) >> 10) >> HE_REGS_RBRQ_ADDR) & 0x3fff; \ + } while (0) +#define MBUF_PARSE_LHANDLE(HANDLE, INDEX) do { \ + (INDEX) = ((HANDLE) >> HE_REGS_RBRQ_ADDR) & 0xffffff; \ } while (0) -#define MBUF_LARGE_FLAG (1 << 20) +#define MBUF_LARGE_FLAG 0x80000000 /* chunks have the following structure at the end (4 byte) */ struct mbuf_chunk_hdr { |