• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************/
18 /***************************************************************************
19 *                                                                          *
20 * INSERT COPYRIGHT HERE!                                                   *
21 *                                                                          *
22 ****************************************************************************
23 PURPOSE: Zigbee packet buffers pool
24 */
25 #include "zb_buffer.h"
26 #include "common/compiler.h"
27 
28 /*! \addtogroup buf */
29 /*! @{ */
30 
31 /*
32  * the buffer for zigbee stack  initilization
33  *
34  * */
tl_zbBufferInit(void)35 void tl_zbBufferInit(void)
36 {
37     memset((u8 *)&g_mPool, 0, sizeof(zb_buf_pool_t));
38 
39     zb_buf_t *p = g_mPool.head = &g_mPool.pool[0];
40 
41     for (s32 i = 0; i < ZB_BUF_POOL_SIZE - 1; i++) {
42         p->next = (p + 1);
43         p++;
44     }
45     p->next = NULL;
46 }
47 
48 /*
49  * allocate a buffer directly
50  * return success, if the pool has a empty buffer,
51  * if not, return failure
52  *
53  * */
54 #if ZB_BUFFER_DEBUG
my_zb_buf_get(u16 line)55 static _attribute_ram_code_ zb_buf_t *my_zb_buf_get(u16 line)
56 #else
57 static _attribute_ram_code_ zb_buf_t *zb_buf_get(void)
58 #endif
59 {
60     zb_buf_t *buf = NULL;
61 
62     u8 r = irq_disable();
63     if (g_mPool.usedNum < ZB_BUF_POOL_SIZE) {
64         if ((((u32)(g_mPool.head) < (u32)(&g_mPool.pool[0])) && (g_mPool.head != NULL)) ||
65             ((u32)(g_mPool.head) > (u32)(&g_mPool.pool[ZB_BUF_POOL_SIZE - 1]))) {
66         }
67 
68         buf = g_mPool.head;
69         if (buf) {
70             g_mPool.head = buf->next;
71             buf->next = NULL;
72             memset(&buf->hdr, 0, sizeof(buf->hdr));
73             memset(buf->buf, 0, ZB_BUF_SIZE);
74             g_mPool.usedNum++;
75             buf->hdr.used = 1;
76 #if ZB_BUFFER_DEBUG
77             u32 idx = buf->allocCnt % ZB_BUFF_DBG_NUM;
78             buf->allocInfo[idx].allocLine = line;
79 #endif
80             buf->allocCnt++;
81         } else {
82             if (g_mPool.usedNum < ZB_BUF_POOL_SIZE) {
83             }
84         }
85     }
86     irq_restore(r);
87 
88     if (!buf) {
89     }
90 
91     return buf;
92 }
93 
tl_phyRxBufTozbBuf(u8 * p)94 inline u8 *tl_phyRxBufTozbBuf(u8 *p)
95 {
96     return (p - RX_ZBBUF_OFFSET);
97 }
98 
tl_zbBufToPhyRxBuf(u8 * p)99 inline u8 *tl_zbBufToPhyRxBuf(u8 *p)
100 {
101     return (p + RX_ZBBUF_OFFSET);
102 }
103 
104 /*
105  * allocate a buffer directly for ZB stack
106  * return success, if the pool has a empty buffer,
107  * if not, return failure
108  *
109  * */
110 #if ZB_BUFFER_DEBUG
my_zb_buf_allocate(u16 line)111 zb_buf_t *my_zb_buf_allocate(u16 line)
112 {
113     return my_zb_buf_get(line);
114 }
tl_getRxBuf(void)115 _attribute_ram_code_ u8 *tl_getRxBuf(void)
116 {
117     u8 *buf = (u8 *)my_zb_buf_get(90);
118     if (buf) {
119         return TL_INBUF_TO_RXBUF(buf);
120     }
121     return NULL;
122 }
123 #else
zb_buf_allocate(void)124 _attribute_ram_code_ zb_buf_t *zb_buf_allocate(void)
125 {
126     return zb_buf_get();
127 }
128 
tl_getRxBuf(void)129 _attribute_ram_code_ u8 *tl_getRxBuf(void)
130 {
131     u8 *buf = (u8 *)zb_buf_get();
132     if (buf) {
133         return TL_INBUF_TO_RXBUF(buf);
134     }
135     return NULL;
136 }
137 
138 #endif
139 
140 /*
141  * free the buffer
142  * */
143 volatile u32 T_zbBufDbg = 0;
144 volatile u32 T_zbBufFreeDbg = 0;
145 #if ZB_BUFFER_DEBUG
146 volatile u32 T_zbBufFreeDbgLine = 0;
147 volatile u32 T_zbBufFreeDbgIdx = 0;
148 volatile u32 T_zbBufFreeDbgIdx1 = 0;
my_zb_buf_free(zb_buf_t * buf,u16 line)149 u8 my_zb_buf_free(zb_buf_t *buf, u16 line)
150 #else
151 u8 zb_buf_free(zb_buf_t *buf)
152 #endif
153 {
154     u8 r = irq_disable();
155 
156     if (!is_zb_buf((void *)buf)) {
157     }
158 
159 #if ZB_BUFFER_DEBUG
160     u32 idx = buf->freeCnt % ZB_BUFF_DBG_NUM;
161     T_zbBufFreeDbgLine = buf->allocInfo[idx].freeLine;
162     T_zbBufFreeDbgIdx1 = buf->allocCnt;
163     T_zbBufFreeDbgIdx = idx;
164     buf->allocInfo[idx].freeLine = line;
165     buf->allocInfo[idx].handler = buf->hdr.handle;
166     buf->allocInfo[idx].id = buf->hdr.id;
167     buf->allocInfo[idx].nlmeStatus = buf->hdr.resvHdr;
168     T_zbBufDbg = (u32)buf;
169 #endif
170 
171     buf->freeCnt++;
172     if (buf->hdr.macTxFifo == 1 || buf->freeCnt > buf->allocCnt || buf->hdr.used == 0) {
173         T_zbBufFreeDbg = (buf->hdr.macTxFifo << 24) | ((buf->freeCnt > buf->allocCnt) << 16) | buf->hdr.used;
174         T_zbBufDbg = (u32)buf;
175     }
176 
177     if ((((u32)(g_mPool.head) < (u32)(&g_mPool.pool[0])) && (g_mPool.head != NULL)) ||
178         ((u32)(g_mPool.head) > (u32)(&g_mPool.pool[ZB_BUF_POOL_SIZE - 1]))) {
179     }
180 
181     g_mPool.usedNum--;
182     buf->next = g_mPool.head;
183     g_mPool.head = buf;
184 
185     if ((((u32)(g_mPool.head) < (u32)(&g_mPool.pool[0])) && (g_mPool.head != NULL)) ||
186         ((u32)(g_mPool.head) > (u32)(&g_mPool.pool[ZB_BUF_POOL_SIZE - 1]))) {
187     }
188     buf->hdr.used = 0;
189     buf->hdr.handle = 0xff;
190 
191     irq_restore(r);
192     return SUCCESS;
193 }
194 
tl_bufInitalloc(zb_buf_t * p,u8 size)195 void *tl_bufInitalloc(zb_buf_t *p, u8 size)
196 {
197 #ifdef ZB_SECURITY
198     size += 8;  // Extra 4 bytes for APS MIC and 4 bytes for NWK MIC
199 #endif
200     return (void *)((u8 *)p + ((ZB_BUF_SIZE - size) & (~0x03)));
201 }
202 
203 /* clear the buffer, some info set as 0 */
zb_buf_clear(zb_buf_t * p)204 void zb_buf_clear(zb_buf_t *p)
205 {
206     u8 used = p->hdr.used;
207 
208     u8 r = irq_disable();
209     memset(&p->hdr, 0, sizeof(p->hdr));
210     p->hdr.used = used;
211     irq_restore(r);
212 }
213 
is_zb_buf(void * p)214 bool is_zb_buf(void *p)
215 {
216     if (((u32)p >= (u32)(&g_mPool.pool[0])) && ((u32)p < (u32)((&g_mPool.pool[ZB_BUF_POOL_SIZE - 1])) + ZB_BUF_SIZE)) {
217         return 1;
218     }
219     return 0;
220 }
221 
222 #if ZB_BUFFER_DEBUG
223 volatile u8 T_zbbud_debug_start = 0;
224 typedef struct {
225     u8 id;
226     u8 handle;
227     u16 allocateLine;
228 } zb_bufDbg_t;
229 zb_bufDbg_t g_zbBufDBG[ZB_BUF_POOL_NUM];
230 
zb_buf_debug_start(void)231 void zb_buf_debug_start(void)
232 {
233     if (T_zbbud_debug_start) {
234         u8 cnt = 0;
235         T_zbbud_debug_start = 0;
236         for (s32 i = 0; i < ZB_BUF_POOL_SIZE - 1; i++) {
237             if (g_mPool.pool[i].hdr.used) {
238                 g_zbBufDBG[cnt].handle = g_mPool.pool[i].hdr.handle;
239                 g_zbBufDBG[cnt].id = g_mPool.pool[i].hdr.id;
240                 cnt++;
241             }
242         }
243     }
244 }
245 #endif
246 
247 /*! @} */
248