1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: osl_Mbuf.h
4 Copyright (C)2009 Nintendo Co., Ltd. All rights reserved.
5 These coded instructions, statements, and computer programs contain
6 proprietary information of Nintendo of America Inc. and/or Nintendo
7 Company Ltd., and are protected by Federal copyright law. They may
8 not be disclosed to third parties or copied or duplicated in any form,
9 in whole or in part, without the prior written consent of Nintendo.
10 $Rev: 20396 $
11 *---------------------------------------------------------------------------
12
13
14 */
15
16 #ifndef NN_NET_OSL_OSL_MBUF_H_
17 #define NN_NET_OSL_OSL_MBUF_H_
18
19 #include <nn/os.h>
20 #include <nn/util/util_StaticAssert.h>
21 #include <string.h>
22
23 #define NN_NET_MAC_ADDRESS_SIZE 6
24
25 #define NN_NET_OSL_PAGE_SIZE NN_OS_MEMORY_PAGE_SIZE
26 /* Use pagesize(=4096) / n to avoid crossing page-boundary for DMA. */
27 #define NN_NET_OSL_MBUF_UNIT_SIZE (NN_OS_MEMORY_PAGE_SIZE / 2)
28 #define NN_NET_OSL_MBUF_HEADER_SIZE 40
29 #define NN_NET_OSL_MBUF_DATA_SIZE ((NN_NET_OSL_MBUF_UNIT_SIZE) - (NN_NET_OSL_MBUF_HEADER_SIZE))
30 #define NN_NET_OSL_MBUF_DATA_MIN_SIZE ((NN_NET_OSL_MBUF_UNIT_SIZE) - (NN_NET_OSL_MBUF_HEADER_SIZE))
31
32 #define NN_NET_OSL_M_DONTWAIT 0
33 #define NN_NET_OSL_M_WAIT 1
34 #define NN_NET_OSL_M_FREELIST 0x8000 /* Please see man pages for details */
35
36 #define NN_NET_OSL_M_BCAST 0x0200 /* Please see man pages for details */
37 #define NN_NET_OSL_M_MCAST 0x0400 /* Please see man pages for details */
38 #define NN_NET_OSL_M_LOOPBACK 0x0800 /* Please see man pages for details */
39
40 #define NN_NET_OSL_M_COPYALL 1000000000
41
42 #define NN_NET_OSL_MT_DATA 1 /* Please see man pages for details */
43 #define NN_NET_OSL_MT_ATH_WMI 2 /* Please see man pages for details */
44
45 #define NN_NET_OSL_CAT_DRIVER 1
46 #define NN_NET_OSL_CAT_ATH NN_NET_OSL_CAT_DRIVER /* Please see man pages for details */
47
48 struct nnnetOslMbuf;
49 typedef struct nnnetOslMbuf nnnetOslMbuf;
50
51 /* mbuf data structure */
52 typedef struct nnnetOslMbuf
53 {
54 nnnetOslMbuf* m_next; /* Please see man pages for details */
55 nnnetOslMbuf* m_prev; /* Please see man pages for details */
56 nnnetOslMbuf* m_nextpkt; /* Please see man pages for details */
57 s16 m_len; /* Please see man pages for details */
58 s16 m_capacity;
59 s16 m_top; /* Please see man pages for details */
60 u16 m_flags; /* Please see man pages for details */
61 u16 m_protocol; /* Please see man pages for details */
62 u16 m_owner; /* Owner module. NN_NET_OSL_M_OWN_XXXX */
63 u16 m_name; /* Please see man pages for details */
64 u16 m_pool;
65 u8 m_dst[NN_NET_MAC_ADDRESS_SIZE]; /* Please see man pages for details */
66 u8 m_src[NN_NET_MAC_ADDRESS_SIZE]; /* Please see man pages for details */
67 u8 m_data[NN_NET_OSL_MBUF_DATA_MIN_SIZE]; /* Please see man pages for details */
68 } nnnetOslMbuf;
69
70 /* mbuf in free pool */
71 typedef struct nnnetOslMbufFree
72 {
73 s32 m_nextFree; /* Please see man pages for details */
74 } nnnetOslMbufFree;
75
76 /* size validation */
77 NN_STATIC_ASSERT(sizeof(nnnetOslMbuf) == NN_NET_OSL_MBUF_UNIT_SIZE);
78 NN_STATIC_ASSERT(offsetof(nnnetOslMbuf, m_data) == NN_NET_OSL_MBUF_HEADER_SIZE);
79
80
81 // C declarations follow
82
83 #include <nn/util/detail/util_CLibImpl.h>
84
85 NN_EXTERN_C nnnetOslMbuf* nnnetOslMbuf_getm (u32 name, nnnetOslMbuf *orig, s32 len, s32 how, u8 type);
86 NN_EXTERN_C void nnnetOslMbuf_freem (nnnetOslMbuf* pMbuf_);
87 NN_EXTERN_C s32 nnnetOslMbuf_adj (nnnetOslMbuf* pMbuf_, s32 len);
88 NN_EXTERN_C s32 nnnetOslMbuf_append (nnnetOslMbuf* pMbuf_, s32 len, const u8 *cp);
89 NN_EXTERN_C nnnetOslMbuf* nnnetOslMbuf_prepend_a (nnnetOslMbuf* pMbuf_, s32 len, int how);
90 NN_EXTERN_C nnnetOslMbuf* nnnetOslMbuf_pullup (nnnetOslMbuf* pMbuf_, s32 len);
91 NN_EXTERN_C nnnetOslMbuf* nnnetOslMbuf_dup (nnnetOslMbuf* pMbuf_, int how);
92 NN_EXTERN_C s32 nnnetOslMbuf_copydata (const nnnetOslMbuf* pMbuf_, s32 offset, s32 len, u8 *buf);
93 NN_EXTERN_C s32 nnnetOslMbuf_copyback (nnnetOslMbuf* pMbuf_, s32 offset, s32 len, const u8 *buf);
94 NN_EXTERN_C s32 nnnetOslMbuf_cat (nnnetOslMbuf* pMbuf_, nnnetOslMbuf *n);
95 NN_EXTERN_C nnnetOslMbuf* nnnetOslMbuf_split (nnnetOslMbuf* pMbuf_, s32 len, int how);
96 NN_EXTERN_C s32 nnnetOslMbuf_length (nnnetOslMbuf* pMbuf_, nnnetOslMbuf **last);
97 NN_EXTERN_C s32 nnnetOslMbuf_apply (nnnetOslMbuf* pMbuf_, s32 offset, s32 len, s32 (* f)(void* arg, void* data, s32 len), void* arg);
98 NN_EXTERN_C void nnnetOslMbuf_dump (nnnetOslMbuf* pMbuf_);
99 NN_EXTERN_C bool nnnetOslMbuf_align (nnnetOslMbuf* pMbuf_, u8 align, s8 offset);
100
nnnetOslMbuf_leadingspace(const nnnetOslMbuf * pMbuf_)101 NN_EXTERN_C inline s32 nnnetOslMbuf_leadingspace(const nnnetOslMbuf* pMbuf_)
102 {
103 return pMbuf_->m_top;
104 }
105
nnnetOslMbuf_trailingspace(const nnnetOslMbuf * pMbuf_)106 NN_EXTERN_C inline s32 nnnetOslMbuf_trailingspace(const nnnetOslMbuf* pMbuf_)
107 {
108 return pMbuf_->m_capacity - (pMbuf_->m_top + pMbuf_->m_len);
109 }
110
nnnetOslMbuf_prepend(nnnetOslMbuf * pMbuf_,s32 len,int how)111 NN_EXTERN_C inline nnnetOslMbuf* nnnetOslMbuf_prepend(nnnetOslMbuf* pMbuf_, s32 len, int how)
112 {
113 if (pMbuf_->m_top >= len)
114 {
115 pMbuf_->m_top -= len;
116 pMbuf_->m_len += len;
117 return pMbuf_;
118 }
119 else
120 {
121 return nnnetOslMbuf_prepend_a(pMbuf_, len, how);
122 }
123 }
124
nnnetOslMbuf_tod(nnnetOslMbuf * pMbuf_)125 NN_EXTERN_C inline void* nnnetOslMbuf_tod (nnnetOslMbuf* pMbuf_)
126 {
127 //TODO: Check consistency here.
128 return &(pMbuf_->m_data[pMbuf_->m_top]);
129 }
130
nnnetOslMbuf_setUserPointer(nnnetOslMbuf * pMbuf_,void * p)131 NN_EXTERN_C inline void nnnetOslMbuf_setUserPointer(nnnetOslMbuf* pMbuf_, void* p)
132 {
133 pMbuf_->m_nextpkt = (nnnetOslMbuf*)p;
134 }
135
nnnetOslMbuf_getUserPointer(nnnetOslMbuf * pMbuf_)136 NN_EXTERN_C inline void* nnnetOslMbuf_getUserPointer(nnnetOslMbuf* pMbuf_)
137 {
138 return pMbuf_->m_nextpkt;
139 }
140
nnnetOslMbuf_expand(nnnetOslMbuf * pMbuf_,s32 len,int how)141 NN_EXTERN_C inline bool nnnetOslMbuf_expand(nnnetOslMbuf* pMbuf_, s32 len, int how)
142 {
143 NN_UNUSED_VAR(how);
144 if (pMbuf_->m_top + pMbuf_->m_len + len > pMbuf_->m_capacity)
145 {
146 NN_LOG("nnnetOslMbuf_expand: out of capacity.(len = %d)\n", len);
147 return false;
148 }
149
150 pMbuf_->m_len += len;
151 return true;
152 }
153
nnnetOslMbuf_reserve(nnnetOslMbuf * pMbuf_,s32 len)154 NN_EXTERN_C inline void nnnetOslMbuf_reserve(nnnetOslMbuf* pMbuf_, s32 len)
155 {
156 NN_TASSERT_(pMbuf_->m_len == 0 && pMbuf_->m_top + len <= pMbuf_->m_capacity);
157 pMbuf_->m_top += len;
158 }
159
160 #ifdef __cplusplus
161
162 #include <new>
163
164 namespace nn { namespace net { namespace osl {
165
166 class MbufPool;
167
168 class Mbuf : public nnnetOslMbuf
169 {
170 public:
171 typedef s32 FreeIndex;
172 static const size_t HEADER_SIZE = NN_NET_OSL_MBUF_HEADER_SIZE;
173
Initialize(size_t unitSize,u16 poolId)174 void Initialize(size_t unitSize, u16 poolId)
175 {
176 std::memset(static_cast<nnnetOslMbuf*>(this), 0x00, HEADER_SIZE);
177 m_capacity = unitSize - HEADER_SIZE;
178 m_pool = poolId;
179 }
180
Mbuf(FreeIndex nextFree)181 Mbuf(FreeIndex nextFree)
182 {
183 Initialize(0, 0xffff);
184 reinterpret_cast<nnnetOslMbufFree*>(this)->m_nextFree = nextFree;
185 }
186
GetNextFreeIndexPtr(void)187 FreeIndex* GetNextFreeIndexPtr(void)
188 { return &reinterpret_cast<nnnetOslMbufFree*>(this)->m_nextFree; }
189
SetNextFreeIndex(FreeIndex freeIndex)190 void SetNextFreeIndex(FreeIndex freeIndex)
191 { reinterpret_cast<nnnetOslMbufFree*>(this)->m_nextFree = freeIndex; }
192
GetNextFreeIndex(void)193 FreeIndex GetNextFreeIndex(void) const
194 { return reinterpret_cast<const nnnetOslMbufFree*>(this)->m_nextFree; }
195
196 operator nnnetOslMbuf*()
197 { return reinterpret_cast<nnnetOslMbuf*>(this); }
198
GetNext(void)199 Mbuf* GetNext(void)
200 {
201 return reinterpret_cast<Mbuf*>(m_next);
202 }
203
GetNext(void)204 const Mbuf* GetNext(void) const
205 {
206 return reinterpret_cast<const Mbuf*>(m_next);
207 }
208
GetPrevious(void)209 Mbuf* GetPrevious(void)
210 {
211 return reinterpret_cast<Mbuf*>(m_prev);
212 }
213
GetPrevious(void)214 const Mbuf* GetPrevious(void) const
215 {
216 return reinterpret_cast<const Mbuf*>(m_prev);
217 }
218
SetNext(Mbuf * pMbuf)219 void SetNext(Mbuf* pMbuf)
220 {
221 m_next = reinterpret_cast<nnnetOslMbuf*>(pMbuf);
222 }
223
SetPrevious(Mbuf * pMbuf)224 void SetPrevious(Mbuf* pMbuf)
225 {
226 m_prev = reinterpret_cast<nnnetOslMbuf*>(pMbuf);
227 }
228
IsLinking(void)229 bool IsLinking(void) const
230 { return m_prev != NULL || m_next != NULL; }
231
Unlink(void)232 Mbuf* Unlink(void)
233 {
234 Mbuf* pNext = GetNext();
235 if (pNext)
236 {
237 SetNext(NULL);
238 pNext->SetPrevious(NULL);
239 return pNext;
240 }
241 else
242 {
243 return NULL;
244 }
245 }
246
247 void CopyFrom(const Mbuf* pSource);
248
249 Mbuf* GetTail(void);
250 const Mbuf* GetHead(void) const;
251
SetLengthTrimed(size_t len)252 size_t SetLengthTrimed(size_t len)
253 {
254 m_len = (len > m_capacity) ? m_capacity : len;
255 return m_len;
256 }
257
GetLength(void)258 size_t GetLength(void) const
259 {
260 NN_TASSERT_(m_len <= m_capacity);
261 return m_len;
262 }
263
SetLength(size_t len)264 size_t SetLength(size_t len)
265 {
266 NN_TASSERT_(len <= m_capacity);
267 return m_len = len;
268 }
269
Length(void)270 s16& Length(void)
271 { return m_len; }
272
GetFlags(void)273 u16 GetFlags(void) const
274 { return m_flags; }
275
SetFlags(u16 flags)276 void SetFlags(u16 flags)
277 { m_flags = flags; }
278
SetName(u32 name)279 void SetName(u32 name)
280 { m_name = name; }
281
GetName(void)282 u32 GetName(void) const
283 { return m_name; }
284
SetProtocol(u32 protocol)285 void SetProtocol(u32 protocol)
286 { m_protocol = protocol; }
287
GetProtocol(void)288 u32 GetProtocol(void) const
289 { return m_protocol; }
290
SetTop(s32 top)291 void SetTop(s32 top)
292 {
293 NN_TASSERT_(top < m_capacity);
294 m_top = top;
295 }
296
GetWritableLength(void)297 size_t GetWritableLength(void) const
298 {
299 NN_TASSERT_(m_top < m_capacity);
300 return m_capacity - m_top;
301 }
302
GetTop(void)303 s32 GetTop(void) const
304 {
305 return m_top;
306 }
307
GetLeadingSpace(void)308 s32 GetLeadingSpace(void) const
309 {
310 return m_top;
311 }
312
GetTrailingSpace(void)313 s32 GetTrailingSpace(void) const
314 {
315 return m_capacity - (m_top + m_len);
316 }
317
318 u8* GetTopPtr(s32 offset = 0)
319 {
320 NN_TASSERT_(m_top + offset < m_capacity);
321 return &m_data[m_top + offset];
322 }
323
324 const u8* GetTopPtr(s32 offset = 0) const
325 {
326 NN_TASSERT_(m_top + offset < m_capacity);
327 return &m_data[m_top + offset];
328 }
329
330 bool IsDataAligned(u8 align, s8 offset = 0) const
331 {
332 return IsAligned(reinterpret_cast<uptr>(GetTopPtr()), align, offset);
333 }
334
GetCapacity(void)335 s16 GetCapacity(void) const
336 {
337 return m_capacity;
338 }
339
GetUnitSize(void)340 s16 GetUnitSize(void) const
341 {
342 return m_capacity + HEADER_SIZE;
343 }
344
GetPoolId(void)345 u16 GetPoolId(void) const
346 {
347 return m_pool;
348 }
349
IsAligned(uptr address,u8 align,s8 offset)350 static bool IsAligned(uptr address, u8 align, s8 offset)
351 {
352 NN_TASSERT_(align != 0 && (align & (align - 1)) == 0);
353 return ((address + offset) & (align - 1)) == 0;
354 }
355
356 // TORIAEZU:
GetTotalLength(void)357 s32 GetTotalLength(void) const
358 {
359 const nnnetOslMbuf* p = reinterpret_cast<const nnnetOslMbuf*>(this);
360 return nnnetOslMbuf_length(const_cast<nnnetOslMbuf*>(p), NULL);
361 }
362
363 bool CopyChainTo(u8* pDst, s32 offset = 0, s32 len = NN_NET_OSL_M_COPYALL) const
364 {
365 return nnnetOslMbuf_copydata(reinterpret_cast<const nnnetOslMbuf*>(this), offset, len, pDst) == 0;
366 }
367
368 // Also emphasize speed in the C version
AlignData(u8 align,s8 offset)369 bool AlignData(u8 align, s8 offset)
370 {
371 return nnnetOslMbuf_align(reinterpret_cast<nnnetOslMbuf*>(this), align, offset);
372 }
373
Link(Mbuf * pNext)374 void Link(Mbuf* pNext)
375 {
376 SetNext(pNext);
377 pNext->SetPrevious(this);
378 }
379
380 void Dump(void) const;
381 void DumpAll(void) const;
382 void DumpChain(void) const;
383
384 protected:
385 };
386
387 }}} // namespace nn::net::osl
388
389 #endif // __cplusplus
390
391
392 #endif // NN_NET_OSL_OSL_MBUF_H_
393