1 /*-
2  * Copyright (c) 1982, 1986, 1988, 1993
3  *  The Regents of the University of California.
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
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the University nor the names of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  *  @(#)mbuf.h  8.5 (Berkeley) 2/19/95
31  * $FreeBSD: releng/10.1/sys/sys/mbuf.h 269047 2014-07-24 06:03:45Z kevlo $
32  */
33 
34 #ifndef _SYS_MBUF_0_H_
35 #define _SYS_MBUF_0_H_
36 
37 #if (__CONFIG_MBUF_IMPL_MODE == 0)
38 
39 #include <stdint.h>
40 #ifdef __CONFIG_ARCH_DUAL_CORE
41 #include "sys/ducc/ducc_addr.h"
42 #endif
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47 
48 /*
49  * Callback structure
50  */
51 struct m_cb {
52     void *func;
53     void *arg;
54 };
55 
56 /*
57  * Record/packet header in first mbuf of chain; always valid and M_PKTHDR is set.
58  * Size : 24
59  */
60 struct pkthdr {
61     void    *rcvif; /* rcv interface */
62     int32_t len;    /* total packet length */
63 
64     union {
65         uint8_t   eigth[8];
66         uint16_t  sixteen[4];
67         uint32_t  thirtytwo[2];
68         uint64_t  sixtyfour[1];
69         uintptr_t unintptr[1];
70         void      *ptr;
71     } PH_per;
72 
73     struct m_cb cb;
74 };
75 
76 struct ext_info {
77     uint8_t eigth[32];
78 };
79 
80 #define ether_vtag  PH_per.sixteen[0]
81 #define PH_vt       PH_per
82 #define vt_nrecs    sixteen[0]
83 #define tso_segsz   PH_per.sixteen[1]
84 #define csum_phsum  PH_per.sixteen[2]
85 #define csum_data   PH_per.thirtytwo[1]
86 
87 /*
88  * The core of the mbuf object along with some shortcut defines for practical
89  * purposes.
90  */
91 struct mbuf { // Size : 48 + 32 = 80
92     /*
93      * Header present at the beginning of every mbuf.
94      * Size : 24
95      */
96     uint8_t       *m_buf;         /* a continuous buffer */ // useless now
97     struct mbuf   *m_nextpkt;     /* next chain in queue/record */
98     uint8_t       *m_data;        /* location of data */
99     int32_t       m_len;          /* amount of data in this mbuf */
100     uint16_t      m_headspace;    /* empty space available at the head */
101     uint16_t      m_tailspace;    /* empty space available at the tail */
102     uint32_t      m_type  :8,     /* type of data in this mbuf */ // use as flag
103                   m_flags :24;    /* flags; see below */
104     /*** End of the mbuf header ***/
105 
106     struct pkthdr m_pkthdr; /* M_PKTHDR always set */
107     struct ext_info m_ext_info;   /* extend info */
108 };
109 
110 #if (defined(__CONFIG_ARCH_NET_CORE) || !defined(__CONFIG_ARCH_DUAL_CORE))
111 
112 #define MBUF_HEAD_SPACE 68 /* reserved head space in mbuf::m_buf, align to 4 */
113 #define MBUF_TAIL_SPACE 16 /* reserved tail space in mbuf::m_buf, align to 4 */
114 
115 /*
116  * mbuf flags of global significance and layer crossing.
117  * Those of only protocol/layer specific significance are to be mapped
118  * to M_PROTO[1-12] and cleared at layer handoff boundaries.
119  * NB: Limited to the lower 24 bits.
120  */
121 #define M_EXT           0x00000001 /* has associated external storage */
122 #define M_PKTHDR        0x00000002 /* start of record */ // always set
123 #define M_EOR           0x00000004 /* end of record */
124 #define M_RDONLY        0x00000008 /* associated data is marked read-only */
125 #define M_BCAST         0x00000010 /* send/received as link-level broadcast */
126 #define M_MCAST         0x00000020 /* send/received as link-level multicast */
127 #define M_PROMISC       0x00000040 /* packet was not for us */
128 #define M_VLANTAG       0x00000080 /* ether_vtag is valid */
129 #define M_FLOWID        0x00000100 /* deprecated: flowid is valid */
130 #define M_NOFREE        0x00000200 /* do not free mbuf, embedded in cluster */
131 
132 #define M_PROTO1        0x00001000 /* protocol-specific */
133 #define M_PROTO2        0x00002000 /* protocol-specific */
134 #define M_PROTO3        0x00004000 /* protocol-specific */
135 #define M_PROTO4        0x00008000 /* protocol-specific */
136 #define M_PROTO5        0x00010000 /* protocol-specific */
137 #define M_PROTO6        0x00020000 /* protocol-specific */
138 #define M_PROTO7        0x00040000 /* protocol-specific */
139 #define M_PROTO8        0x00080000 /* protocol-specific */
140 #define M_PROTO9        0x00100000 /* protocol-specific */
141 #define M_PROTO10       0x00200000 /* protocol-specific */
142 #define M_PROTO11       0x00400000 /* protocol-specific */
143 #define M_PROTO12       0x00800000 /* protocol-specific */
144 
145 /*
146  * Flags to purge when crossing layers.
147  */
148 #define M_PROTOFLAGS \
149     (M_PROTO1|M_PROTO2|M_PROTO3|M_PROTO4|M_PROTO5|M_PROTO6|M_PROTO7|M_PROTO8|\
150      M_PROTO9|M_PROTO10|M_PROTO11|M_PROTO12)
151 
152 /*
153  * Flags preserved when copying m_pkthdr.
154  */
155 #define M_COPYFLAGS \
156     (M_PKTHDR|M_EOR|M_RDONLY|M_BCAST|M_MCAST|M_VLANTAG|M_PROMISC| \
157      M_PROTOFLAGS)
158 
159 /*
160  * Mbuf flag description for use with printf(9) %b identifier.
161  */
162 #define M_FLAG_BITS \
163     "\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY\5M_BCAST\6M_MCAST" \
164     "\7M_PROMISC\10M_VLANTAG\11M_FLOWID"
165 #define M_FLAG_PROTOBITS \
166     "\15M_PROTO1\16M_PROTO2\17M_PROTO3\20M_PROTO4\21M_PROTO5" \
167     "\22M_PROTO6\23M_PROTO7\24M_PROTO8\25M_PROTO9\26M_PROTO10" \
168     "\27M_PROTO11\30M_PROTO12"
169 #define M_FLAG_PRINTF (M_FLAG_BITS M_FLAG_PROTOBITS)
170 
171 
172 /*
173  * mbuf types describing the content of the mbuf (including external storage).
174  */
175 #define MT_NOTMBUF      0       /* USED INTERNALLY ONLY! Object is not mbuf */
176 #define MT_DATA         1       /* dynamic (data) allocation */
177 #define MT_HEADER       MT_DATA /* packet header, use M_PKTHDR instead */
178 
179 #define MT_VENDOR1      4       /* for vendor-internal use */
180 #define MT_VENDOR2      5       /* for vendor-internal use */
181 #define MT_VENDOR3      6       /* for vendor-internal use */
182 #define MT_VENDOR4      7       /* for vendor-internal use */
183 
184 #define MT_SONAME       8       /* socket name */
185 
186 #define MT_EXP1         9       /* for experimental use */
187 #define MT_EXP2         10      /* for experimental use */
188 #define MT_EXP3         11      /* for experimental use */
189 #define MT_EXP4         12      /* for experimental use */
190 
191 #define MT_CONTROL      14      /* extra-data protocol message */
192 #define MT_OOBDATA      15      /* expedited data  */
193 #define MT_NTYPES       16      /* number of mbuf types for mbtypes[] */
194 
195 #define MT_NOINIT       255     /* Not a type but a flag to allocate
196                                    a non-initialized mbuf */
197 
198 #endif /* (defined(__CONFIG_ARCH_NET_CORE) || !defined(__CONFIG_ARCH_DUAL_CORE)) */
199 
200 #ifdef __CONFIG_ARCH_DUAL_CORE
201 /*
202  * NB: mbuf is allocated from net core, pointer conversion MUST be done when
203  *     transfer mbuf from app core to net core, or vice versa.
204  */
205 
206 #ifdef __CONFIG_ARCH_NET_CORE
207 /* convert mbuf's pointers in net core, the new mbuf is used by net core */
208 #define MBUF_APP2NET(m)                                             \
209     do {                                                            \
210         (m) = (struct mbuf *)DUCC_NETMEM_APP2NET(m);                \
211         (m)->m_data = (uint8_t *)DUCC_NETMEM_APP2NET((m)->m_data);  \
212     } while (0)
213 
214 /* convert mbuf's pointers in net core, the new mbuf is used by app core */
215 #define MBUF_NET2APP(m)                                             \
216     do {                                                            \
217         (m)->m_data = (uint8_t *)DUCC_NETMEM_NET2APP((m)->m_data);  \
218         (m) = (struct mbuf *)DUCC_NETMEM_NET2APP(m);                \
219     } while (0)
220 #endif /* __CONFIG_ARCH_NET_CORE */
221 
222 #ifdef __CONFIG_ARCH_APP_CORE
223 /* convert mbuf's pointers in app core, the new mbuf is used by net core */
224 #define MBUF_APP2NET(m)                                             \
225     do {                                                            \
226         (m)->m_data = (uint8_t *)DUCC_NETMEM_APP2NET((m)->m_data);  \
227         (m) = (struct mbuf *)DUCC_NETMEM_APP2NET(m);                \
228     } while (0)
229 
230 /* convert mbuf's pointers in app core, the new mbuf is used by app core */
231 #define MBUF_NET2APP(m)                                             \
232     do {                                                            \
233         (m) = (struct mbuf *)DUCC_NETMEM_NET2APP(m);                \
234         (m)->m_data = (uint8_t *)DUCC_NETMEM_NET2APP((m)->m_data);  \
235     } while (0)
236 #endif /* __CONFIG_ARCH_APP_CORE */
237 
238 #endif /* __CONFIG_ARCH_DUAL_CORE */
239 
240 #if (defined(__CONFIG_ARCH_NET_CORE) || !defined(__CONFIG_ARCH_DUAL_CORE))
241 
242 struct mbuf *mb_get(int len, int tx);
243 void mb_free(struct mbuf *m);
244 int mb_adj(struct mbuf *m, int req_len);
245 int mb_copydata(const struct mbuf *m, int off, int len, uint8_t *cp);
246 struct mbuf *mb_dup(struct mbuf *m);
247 struct mbuf *mb_pullup(struct mbuf *m, int len); // NOT really support!
248 struct mbuf *mb_split(struct mbuf *m0, int len0);
249 int mb_append(struct mbuf *m, int len, const uint8_t *cp);
250 int mb_reserve(struct mbuf *m, int len, uint16_t headspace, uint16_t tailspace);
251 
252 #define m_freem(m)              mb_free(m)
253 #define m_adj(m, l)             mb_adj(m, l)
254 #define m_copydata(m, o, l, p)  mb_copydata(m, o, l, p)
255 #define m_dup(m, h)             mb_dup(m)
256 #define m_pullup(m, l)          mb_pullup(m, l)
257 #define m_split(m, l, w)        mb_split(m, l)
258 #define m_append(m, l, c)       mb_append(m, l, c)
259 
260 #endif /* (defined(__CONFIG_ARCH_NET_CORE) || !defined(__CONFIG_ARCH_DUAL_CORE)) */
261 
262 /*
263  * Macro for type conversion: convert mbuf pointer to data pointer of correct
264  * type:
265  *
266  * mtod(m, t)   -- Convert mbuf pointer to data pointer of correct type.
267  */
268 #define mtod(m, t)          ((t)((m)->m_data))
269 
270 #if (defined(__CONFIG_ARCH_NET_CORE) || !defined(__CONFIG_ARCH_DUAL_CORE))
271 
272 /*
273  * Compute the amount of space available before the current start of data in
274  * an mbuf.
275  */
276 #define M_LEADINGSPACE(m)   ((m)->m_headspace)
277 
278 /*
279  * Compute the amount of space available after the end of data in an mbuf.
280  */
281 #define M_TRAILINGSPACE(m)  ((m)->m_tailspace)
282 
283 
284 /*
285  * Arrange to prepend space of size plen to mbuf m.  If a new mbuf must be
286  * allocated, how specifies whether to wait.  If the allocation fails, the
287  * original mbuf chain is freed and m is set to NULL.
288  */
289 #define MB_PREPEND(m, plen)                             \
290     do {                                                \
291         int _plen = (plen);                             \
292         if (_plen >= 0 && M_LEADINGSPACE(m) >= _plen) { \
293             (m)->m_headspace -= (_plen);                \
294             (m)->m_data -= (_plen);                     \
295             (m)->m_len += (_plen);                      \
296             (m)->m_pkthdr.len += (_plen);               \
297         } else {                                        \
298             mb_free(m);                                 \
299             (m) = NULL;                                 \
300         }                                               \
301     } while (0)
302 
303 #define M_PREPEND(m, plen, how) MB_PREPEND(m, plen)
304 
m_clrprotoflags(struct mbuf * m)305 static __inline void m_clrprotoflags(struct mbuf *m)
306 {
307     m->m_flags &= ~M_PROTOFLAGS;
308 }
309 
310 /* option of limiting memory usage */
311 #define MBUF_OPT_LIMIT_MEM  1
312 
313 #if MBUF_OPT_LIMIT_MEM
314 /*
315  * Flags for @param tx in mb_get(), which also saved in struct mbuf::m_type
316  *   - MBUF_GET_FLAG_LIMIT_TX: memory usage limit by MBUF_TX_MEM_MAX
317  *   - MBUF_GET_FLAG_LIMIT_RX: memory usage limit by MBUF_RX_MEM_MAX
318  */
319 #define MBUF_GET_FLAG_MASK      (0xF << 4)
320 #define MBUF_GET_FLAG_LIMIT_TX  (1 << 4)
321 #define MBUF_GET_FLAG_LIMIT_RX  (1 << 5)
322 
323 void mb_mem_set_limit(uint32_t tx, uint32_t rx, uint32_t txrx);
324 void mb_mem_get_limit(uint32_t *tx, uint32_t *rx, uint32_t *txrx);
325 
326 #else /* MBUF_OPT_LIMIT_MEM */
327 
328 #define MBUF_GET_FLAG_LIMIT_TX  0
329 #define MBUF_GET_FLAG_LIMIT_RX  0
330 
331 #endif /* MBUF_OPT_LIMIT_MEM */
332 
333 #if 0 // only for test, no need to implement
334 #define MCLSHIFT    11      /* convert bytes to mbuf clusters */
335 #define MCLBYTES    (1 << MCLSHIFT) /* size of an mbuf cluster */
336 
337 /*
338  * Concatenate mbuf chain n to m.
339  * Both chains must be of the same type (e.g. MT_DATA).
340  * Any m_pkthdr is not updated.
341  */
342 void m_cat(struct mbuf *m, struct mbuf *n);
343 struct mbuf *m_getcl(int how, short type, int flags);
344 void m_align(struct mbuf *m, int len);
345 #endif
346 
347 #endif /* (defined(__CONFIG_ARCH_NET_CORE) || !defined(__CONFIG_ARCH_DUAL_CORE)) */
348 
349 #ifdef __cplusplus
350 }
351 #endif
352 
353 #endif /* (__CONFIG_MBUF_IMPL_MODE == 0) */
354 #endif /* !_SYS_MBUF_0_H_ */
355