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