summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/hatm/if_hatm_intr.c106
-rw-r--r--sys/dev/hatm/if_hatmvar.h38
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 {
OpenPOWER on IntegriCloud