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