1 1.1 jklos /************************************************************************** 2 1.1 jklos * 3 1.1 jklos * Copyright (c) 2007, Kip Macy kmacy (at) freebsd.org 4 1.1 jklos * All rights reserved. 5 1.1 jklos * 6 1.1 jklos * Redistribution and use in source and binary forms, with or without 7 1.1 jklos * modification, are permitted provided that the following conditions are met: 8 1.1 jklos * 9 1.1 jklos * 1. Redistributions of source code must retain the above copyright notice, 10 1.1 jklos * this list of conditions and the following disclaimer. 11 1.1 jklos * 12 1.1 jklos * 2. The name of Kip Macy nor the names of other 13 1.1 jklos * contributors may be used to endorse or promote products derived from 14 1.1 jklos * this software without specific prior written permission. 15 1.1 jklos * 16 1.1 jklos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 1.1 jklos * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 1.1 jklos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 1.1 jklos * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 1.1 jklos * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 1.1 jklos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 1.1 jklos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 1.1 jklos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 1.1 jklos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 1.1 jklos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 1.1 jklos * POSSIBILITY OF SUCH DAMAGE. 27 1.1 jklos * 28 1.1 jklos ***************************************************************************/ 29 1.1 jklos 30 1.1 jklos #ifndef _MVEC_H_ 31 1.1 jklos #define _MVEC_H_ 32 1.1 jklos 33 1.1 jklos #include <sys/mbuf.h> 34 1.1 jklos 35 1.1 jklos #define mtomv(m) ((struct mbuf_vec *)((m)->m_pktdat)) 36 1.1 jklos 37 1.1 jklos #define M_IOVEC 0x100000 /* mbuf immediate data area is used for cluster ptrs */ 38 1.1 jklos #define MBUF_IOV_TYPE_MASK ((1<<3)-1) 39 1.1 jklos #define mbuf_vec_set_type(mv, i, type) \ 40 1.1 jklos (mv)->mv_vec[(i)].mi_flags = (((mv)->mv_vec[(i)].mi_flags \ 41 1.1 jklos & ~MBUF_IOV_TYPE_MASK) | type) 42 1.1 jklos 43 1.1 jklos #define mbuf_vec_get_type(mv, i) \ 44 1.1 jklos ((mv)->mv_vec[(i)].mi_flags & MBUF_IOV_TYPE_MASK) 45 1.1 jklos 46 1.1 jklos 47 1.1 jklos struct mbuf_iovec { 48 1.1 jklos uint16_t mi_flags; /* per-cluster flags */ 49 1.1 jklos uint16_t mi_len; /* length of cluster */ 50 1.1 jklos uint32_t mi_offset; /* data offsets into cluster */ 51 1.1 jklos uint8_t *mi_base; /* pointers to cluster */ 52 1.1 jklos volatile uint32_t *mi_refcnt; /* refcnt for cluster*/ 53 1.1 jklos #ifdef __i386__ 54 1.1 jklos void *mi_args; /* for sf_buf */ 55 1.1 jklos #endif 56 1.1 jklos }; 57 1.1 jklos 58 1.1 jklos #define MAX_MBUF_IOV ((MHLEN-8)/sizeof(struct mbuf_iovec)) 59 1.1 jklos struct mbuf_vec { 60 1.1 jklos uint16_t mv_first; /* first valid cluster */ 61 1.1 jklos uint16_t mv_count; /* # of clusters */ 62 1.1 jklos uint32_t mv_flags; /* flags for iovec */ 63 1.1 jklos struct mbuf_iovec mv_vec[MAX_MBUF_IOV]; 64 1.1 jklos }; 65 1.1 jklos 66 1.1 jklos int _m_explode(struct mbuf *); 67 1.1 jklos int _m_collapse(struct mbuf *, int maxbufs, struct mbuf **); 68 1.1 jklos void mb_free_vec(struct mbuf *m); 69 1.1 jklos 70 1.3 christos static __inline void 71 1.1 jklos m_iovinit(struct mbuf *m) 72 1.1 jklos { 73 1.1 jklos struct mbuf_vec *mv = mtomv(m); 74 1.1 jklos 75 1.1 jklos mv->mv_first = mv->mv_count = 0; 76 1.1 jklos m->m_pkthdr.len = m->m_len = 0; 77 1.1 jklos m->m_flags |= M_IOVEC; 78 1.1 jklos } 79 1.1 jklos 80 1.3 christos static __inline void 81 1.1 jklos m_iovappend(struct mbuf *m, uint8_t *cl, int size, int len, int offset) 82 1.1 jklos { 83 1.1 jklos struct mbuf_vec *mv = mtomv(m); 84 1.1 jklos struct mbuf_iovec *iov; 85 1.1 jklos int idx = mv->mv_first + mv->mv_count; 86 1.1 jklos 87 1.1 jklos if ((m->m_flags & M_EXT) != 0) 88 1.1 jklos panic("invalid flags in %s", __func__); 89 1.1 jklos 90 1.1 jklos if (mv->mv_count == 0) 91 1.1 jklos m->m_data = cl + offset; 92 1.1 jklos 93 1.1 jklos iov = &mv->mv_vec[idx]; 94 1.1 jklos iov->mi_base = cl; 95 1.1 jklos iov->mi_len = len; 96 1.1 jklos iov->mi_offset = offset; 97 1.1 jklos m->m_pkthdr.len += len; 98 1.1 jklos m->m_len += len; 99 1.1 jklos mv->mv_count++; 100 1.1 jklos } 101 1.1 jklos 102 1.3 christos static __inline int 103 1.1 jklos m_explode(struct mbuf *m) 104 1.1 jklos { 105 1.1 jklos if ((m->m_flags & M_IOVEC) == 0) 106 1.1 jklos return (0); 107 1.1 jklos 108 1.1 jklos return _m_explode(m); 109 1.1 jklos } 110 1.1 jklos 111 1.3 christos static __inline int 112 1.1 jklos m_collapse(struct mbuf *m, int maxbufs, struct mbuf **mnew) 113 1.1 jklos { 114 1.1 jklos #if (!defined(__sparc64__) && !defined(__sun4v__)) 115 1.1 jklos if (m->m_next == NULL) 116 1.1 jklos #endif 117 1.1 jklos { 118 1.1 jklos *mnew = m; 119 1.1 jklos return (0); 120 1.1 jklos } 121 1.1 jklos return _m_collapse(m, maxbufs, mnew); 122 1.1 jklos } 123 1.1 jklos 124 1.3 christos static __inline struct mbuf * 125 1.1 jklos m_free_vec(struct mbuf *m) 126 1.1 jklos { 127 1.2 christos return m_free(m); 128 1.1 jklos } 129 1.1 jklos 130 1.3 christos static __inline void 131 1.1 jklos m_freem_vec(struct mbuf *m) 132 1.1 jklos { 133 1.1 jklos while (m != NULL) 134 1.1 jklos m = m_free_vec(m); 135 1.1 jklos } 136 1.1 jklos 137 1.1 jklos #if (!defined(__sparc64__) && !defined(__sun4v__)) 138 1.1 jklos int 139 1.1 jklos bus_dmamap_load_mvec_sg(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0, 140 1.1 jklos bus_dma_segment_t *segs, int *nsegs, int flags); 141 1.1 jklos 142 1.1 jklos #else 143 1.1 jklos #define bus_dmamap_load_mvec_sg bus_dmamap_load_mbuf_sg 144 1.1 jklos #endif 145 1.1 jklos 146 1.1 jklos #endif 147