1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 /* ****************************************************************************
20 1 头文件包含
21 **************************************************************************** */
22 #include "oal_mem.h"
23 #include "oam_ext_if.h"
24 #include "hcc_comm.h"
25
26 #ifdef __cplusplus
27 #if __cplusplus
28 extern "C" {
29 #endif
30 #endif
31
32 /* 2 宏定义 */
33 /* ****************************************************************************
34 2 结构体定义
35 **************************************************************************** */
36 /* ****************************************************************************
37 结构名 : oal_mem_subpool_stat
38 结构说明: 子内存池统计结构体,维测使用
39 **************************************************************************** */
40 typedef struct {
41 hi_u16 us_free_cnt; /* 本子内存池可用内存块数 */
42 hi_u16 us_total_cnt; /* 本子内存池内存块总数 */
43 } oal_mem_subpool_stat;
44
45 /* ****************************************************************************
46 结构名 : oal_mem_pool_stat
47 结构说明: 单个内存池统计结构体,维测使用
48 **************************************************************************** */
49 typedef struct {
50 hi_u16 us_mem_used_cnt; /* 本内存池已用内存块 */
51 hi_u16 us_mem_total_cnt; /* 本内存池一共有多少内存块 */
52
53 oal_mem_subpool_stat ast_subpool_stat[WLAN_MEM_MAX_SUBPOOL_NUM];
54 } oal_mem_pool_stat;
55
56 /* ****************************************************************************
57 结构名 : oal_mem_stat
58 结构说明: 内存池统计结构体,维测使用
59 **************************************************************************** */
60 typedef struct {
61 oal_mem_pool_stat ast_mem_start_stat[OAL_MEM_POOL_ID_BUTT]; /* 起始统计信息 */
62 oal_mem_pool_stat ast_mem_end_stat[OAL_MEM_POOL_ID_BUTT]; /* 终止统计信息 */
63 } oal_mem_stat;
64
65 /* ****************************************************************************
66 3 全局变量定义
67 **************************************************************************** */
68 /* *****************************************************************************
69 共享描述符内存池配置信息全局变量
70 ****************************************************************************** */
71 oal_mem_subpool_cfg_stru g_ast_shared_dscr_cfg_table[WLAN_MEM_SHARE_DSCR_SUBPOOL_CNT];
72
73 /* *****************************************************************************
74 本地数据内存池配置信息全局变量 修改为根据定制化用户数量配置
75 ****************************************************************************** */
76 oal_mem_subpool_cfg_stru g_ast_local_cfg_table[WLAN_MEM_LOCAL_SUBPOOL_CNT];
77
78 /* *****************************************************************************
79 事件内存池配置信息全局变量
80 ****************************************************************************** */
81 oal_mem_subpool_cfg_stru g_ast_event_cfg_table[WLAN_MEM_EVENT_SUBPOOL_CNT];
82
83 /* *****************************************************************************
84 MIB内存池配置信息全局变量
85 ****************************************************************************** */
86 oal_mem_subpool_cfg_stru g_ast_mib_cfg_table[WLAN_MEM_MIB_SUBPOOL_CNT];
87
88 /* *****************************************************************************
89 netbuf内存池配置信息全局变量
90 ****************************************************************************** */
91 oal_mem_subpool_cfg_stru g_ast_netbuf_cfg_table[OAL_MEM_NETBUF_POOL_ID_BUTT];
92
93 /* *****************************************************************************
94 总的内存池配置信息全局变量
95 ****************************************************************************** */
96 const oal_mem_pool_cfg_stru g_ast_mem_pool_cfg_table[] = {
97 /* 内存池ID 内存池子内存池个数 四字节对齐 内存池配置信息 */
98 {OAL_MEM_POOL_ID_EVENT, hi_array_size(g_ast_event_cfg_table), {0, 0}, g_ast_event_cfg_table},
99 {OAL_MEM_POOL_ID_LOCAL, hi_array_size(g_ast_local_cfg_table), {0, 0}, g_ast_local_cfg_table},
100 {OAL_MEM_POOL_ID_MIB, hi_array_size(g_ast_mib_cfg_table), {0, 0}, g_ast_mib_cfg_table},
101 };
102
103 /* *****************************************************************************
104 内存池信息全局变量,存储整个内存管理中所有内存池信息
105 所有内存管理的函数都基于此全局变量进行操作
106 ****************************************************************************** */
107 oal_mem_pool_stru g_ast_mem_pool[OAL_MEM_POOL_ID_BUTT];
108 /* *****************************************************************************
109 malloc内存指针记录
110 ****************************************************************************** */
111 hi_u8 *g_pauc_pool_base_addr[OAL_MEM_POOL_ID_BUTT] = {HI_NULL};
112
113 /* 一个内存块结构大小 + 一个指针大小 */
114 #define OAL_MEM_CTRL_BLK_SIZE (sizeof(oal_mem_stru *) + sizeof(oal_mem_stru))
115
116 /* *****************************************************************************
117 控制块内存空间,为内存块结构体和指向内存块结构体的指针分配空间
118 由函数oal_mem_ctrl_blk_alloc调用
119 ****************************************************************************** */
120 oal_mem_ctrl_blk_stru g_ctrl_blk;
121 hi_u8 g_vap_res_num; /* vap资源数量 内存规格 api入参指定 */
122 hi_u8 g_user_res_num; /* vap资源数量 内存规格 api入参指定 */
123
124 /* ****************************************************************************
125 功能描述 : 配置驱动支持同时启动的vap个数 用户配置范围1-3, mac层固定占用一个配置vap,故vap资源需要+1
126 修改历史 :
127 1.日 期 : 2019年6月28日
128 作 者 : HiSilicon
129 **************************************************************************** */
oal_mem_set_vap_res_num(const hi_u8 vap_res_num,const hi_u8 vap_spec)130 hi_u32 oal_mem_set_vap_res_num(const hi_u8 vap_res_num, const hi_u8 vap_spec)
131 {
132 if ((vap_res_num == 0) || (vap_res_num > vap_spec)) {
133 hi_diag_log_msg_e1(0, "oal_mem_set_vap_res_num, invalid vap res num = %d!", vap_res_num);
134 return HI_FAIL;
135 }
136 g_vap_res_num = vap_res_num + WLAN_CFG_VAP_NUM_PER_DEVICE;
137 return HI_SUCCESS;
138 }
139
140 /* ****************************************************************************
141 功能描述 : 获取驱动支持vap个数
142 **************************************************************************** */
oal_mem_get_vap_res_num(hi_void)143 hi_u8 oal_mem_get_vap_res_num(hi_void)
144 {
145 return g_vap_res_num;
146 }
147
148 /* ****************************************************************************
149 功能描述 : 配置驱动支持最大接入的用户个数多VAP时共享 范围1-8
150 **************************************************************************** */
oal_mem_set_user_res_num(const hi_u8 user_res_num,const hi_u8 user_spec)151 hi_u32 oal_mem_set_user_res_num(const hi_u8 user_res_num, const hi_u8 user_spec)
152 {
153 if ((user_res_num == 0) || (user_res_num > user_spec)) {
154 hi_diag_log_msg_e1(0, "oal_mem_set_user_res_num, invalid user res num = %d!", user_res_num);
155 return HI_FAIL;
156 }
157 g_user_res_num = user_res_num;
158 return HI_SUCCESS;
159 }
160
161 /* ****************************************************************************
162 功能描述 : 获取驱动支持最大接入的用户个数
163 **************************************************************************** */
oal_mem_get_user_res_num(hi_void)164 hi_u8 oal_mem_get_user_res_num(hi_void)
165 {
166 return g_user_res_num;
167 }
168
169 /* ****************************************************************************
170 功能描述 : 配置对应内存池size和cnt,供定制化调用,修改内存池配置
171 **************************************************************************** */
oal_mem_set_subpool_config(const oal_mem_subpool_cfg_stru * subpool_cfg,oal_mem_pool_id_enum_uint8 pool_id,hi_u8 subpool_num)172 hi_u32 oal_mem_set_subpool_config(const oal_mem_subpool_cfg_stru *subpool_cfg, oal_mem_pool_id_enum_uint8 pool_id,
173 hi_u8 subpool_num)
174 {
175 oal_mem_subpool_cfg_stru *cfg = HI_NULL;
176 hi_u8 loop;
177
178 if (pool_id >= OAL_MEM_POOL_ID_BUTT) {
179 return HI_FAIL;
180 }
181
182 cfg = g_ast_mem_pool_cfg_table[pool_id].subpool_cfg_info;
183 for (loop = 0; loop < subpool_num; loop++) {
184 cfg[loop].us_size = subpool_cfg[loop].us_size;
185 cfg[loop].us_cnt = subpool_cfg[loop].us_cnt;
186 }
187 return HI_SUCCESS;
188 }
189
190 /* ****************************************************************************
191 功能描述 : 获取对应内存池申请的内存个数
192 输入参数 : en_pool_id : 内存池ID
193 输出参数 : pul_total_cnt : 对应内存池占用的总个数
194 **************************************************************************** */
oal_mem_get_total_cnt_in_pool(oal_mem_pool_id_enum_uint8 pool_id)195 hi_u16 oal_mem_get_total_cnt_in_pool(oal_mem_pool_id_enum_uint8 pool_id)
196 {
197 hi_u16 us_subpool_idx;
198 hi_u16 us_total_cnt; /* 本内存池总字节数 */
199 const oal_mem_pool_cfg_stru *mem_pool_cfg = HI_NULL;
200
201 mem_pool_cfg = &g_ast_mem_pool_cfg_table[pool_id];
202 us_total_cnt = 0;
203 for (us_subpool_idx = 0; us_subpool_idx < mem_pool_cfg->subpool_cnt; us_subpool_idx++) {
204 us_total_cnt += mem_pool_cfg->subpool_cfg_info[us_subpool_idx].us_cnt;
205 }
206 return us_total_cnt;
207 }
208
209 /* ****************************************************************************
210 功能描述 : 为每个内存块结构体或指向内存块结构体的指针提供内存
211 输入参数 : ul_size:要分配内存的大小
212 返 回 值 : 指向一块内存的指针 或空指针
213 **************************************************************************** */
oal_mem_ctrl_blk_alloc(hi_u32 size)214 hi_u8 *oal_mem_ctrl_blk_alloc(hi_u32 size)
215 {
216 hi_u8 *puc_alloc = HI_NULL;
217
218 size = hi_byte_align(size, 4); /* 4: 4bytes 对齐 */
219 if ((g_ctrl_blk.idx + size) > g_ctrl_blk.max_size) {
220 hi_diag_log_msg_e1(0, "oal_mem_ctrl_blk_alloc, not_enough memory, size = %d!", size);
221 return HI_NULL;
222 }
223 puc_alloc = g_ctrl_blk.puc_base_addr + g_ctrl_blk.idx;
224 g_ctrl_blk.idx += size;
225 return puc_alloc;
226 }
227
228 /* ****************************************************************************
229 功能描述 : 创建子内存池
230 输入参数 : en_pool_id : 内存池ID
231 puc_base_addr: 内存池基地址
232 返 回 值 : HI_SUCCESS或其它错误码
233 **************************************************************************** */
oal_mem_create_subpool(oal_mem_pool_id_enum_uint8 pool_id,hi_u8 * puc_base_addr)234 hi_u32 oal_mem_create_subpool(oal_mem_pool_id_enum_uint8 pool_id, hi_u8 *puc_base_addr)
235 {
236 oal_mem_pool_stru *mem_pool = HI_NULL;
237 oal_mem_subpool_stru *mem_subpool = HI_NULL;
238 oal_mem_stru *mem = HI_NULL;
239 oal_mem_stru **stack_mem = HI_NULL;
240 hi_u8 subpool_id;
241 hi_u32 blk_id;
242
243 mem_pool = &g_ast_mem_pool[pool_id];
244 /* 申请可用内存地址索引表,每个内存池申请一次,后面分割给每个子内存池使用 */
245 stack_mem = (oal_mem_stru **)oal_mem_ctrl_blk_alloc(sizeof(oal_mem_stru *) * mem_pool->us_mem_total_cnt);
246 if (stack_mem == HI_NULL) {
247 hi_diag_log_msg_e0(0, "oal_mem_create_subpool, pointer is NULL!");
248 return HI_ERR_CODE_MEM_ALLOC_CTRL_BLK_FAIL;
249 }
250
251 /* 申请oal_mem_stru结构体,每个内存池申请一次,后面分割给每个子内存池使用 */
252 mem = (oal_mem_stru *)oal_mem_ctrl_blk_alloc(sizeof(oal_mem_stru) * mem_pool->us_mem_total_cnt);
253 if (mem == HI_NULL) {
254 hi_diag_log_msg_e0(0, "oal_mem_create_subpool, pointer is NULL!");
255 return HI_ERR_CODE_MEM_ALLOC_CTRL_BLK_FAIL;
256 }
257
258 /* 安全编程规则6.6例外(3) 从堆中分配内存后,赋予初值 */
259 memset_s(stack_mem, sizeof(oal_mem_stru *) * mem_pool->us_mem_total_cnt, 0,
260 sizeof(oal_mem_stru *) * mem_pool->us_mem_total_cnt);
261 memset_s((hi_void *)mem, sizeof(oal_mem_stru) * mem_pool->us_mem_total_cnt, 0,
262 sizeof(oal_mem_stru) * mem_pool->us_mem_total_cnt);
263
264 /* 记录该内存池初始oal_mem_stru结构的指针,检查内存信息时使用 */
265 mem_pool->mem_start_addr = mem;
266
267 /* 设置各子池所有内存块结构体信息,建立各内存块与payload的关系 */
268 for (subpool_id = 0; subpool_id < mem_pool->subpool_cnt; subpool_id++) {
269 /* 得到每一级子内存池信息 */
270 mem_subpool = &(mem_pool->ast_subpool_table[subpool_id]);
271 /* 建立子内存数索引表和可用内存索引表的关系 */
272 mem_subpool->free_stack = (hi_void **)stack_mem;
273 oal_spin_lock_init(&mem_subpool->st_spinlock);
274 for (blk_id = 0; blk_id < mem_subpool->us_total_cnt; blk_id++) {
275 mem->pool_id = pool_id;
276 mem->subpool_id = subpool_id;
277 mem->us_len = mem_subpool->us_len;
278 mem->mem_state_flag = OAL_MEM_STATE_FREE;
279 mem->user_cnt = 0;
280 mem->puc_origin_data = puc_base_addr; /* 建立oal_mem_st与对应payload的关系 */
281 mem->puc_data = mem->puc_origin_data;
282 *stack_mem = mem;
283 stack_mem++;
284 mem++;
285 puc_base_addr += mem_subpool->us_len;
286 }
287 }
288 return HI_SUCCESS;
289 }
290
291 /* ****************************************************************************
292 功能描述 : 设置每个内存池的子内存池结构体
293 输入参数 : en_pool_id : 内存池ID
294 puc_data_mem_addr: 内存池基地址
295 返 回 值 : HI_SUCCESS 或其它错误码
296 **************************************************************************** */
oal_mem_create_pool(oal_mem_pool_id_enum_uint8 pool_id,hi_u8 * puc_base_addr)297 hi_u32 oal_mem_create_pool(oal_mem_pool_id_enum_uint8 pool_id, hi_u8 *puc_base_addr)
298 {
299 hi_u8 subpool_id = 0;
300 hi_u8 subpool_cnt;
301 oal_mem_pool_stru *mem_pool = HI_NULL;
302 oal_mem_subpool_stru *mem_subpool = HI_NULL;
303 const oal_mem_pool_cfg_stru *mem_pool_cfg = HI_NULL;
304 oal_mem_subpool_cfg_stru *mem_subpool_cfg = HI_NULL;
305
306 mem_pool = &g_ast_mem_pool[pool_id];
307 mem_pool_cfg = &g_ast_mem_pool_cfg_table[pool_id];
308 /* 初始化内存池的通用变量 */
309 subpool_cnt = mem_pool_cfg->subpool_cnt;
310 mem_pool->subpool_cnt = mem_pool_cfg->subpool_cnt;
311 mem_pool->us_mem_used_cnt = 0;
312 mem_pool->us_max_byte_len = mem_pool_cfg->subpool_cfg_info[subpool_cnt - 1].us_size;
313
314 if (mem_pool->subpool_cnt > WLAN_MEM_MAX_SUBPOOL_NUM) {
315 hi_diag_log_msg_e0(0, "oal_mem_create_pool, exceeds the max subpool number!");
316 return HI_ERR_CODE_MEM_EXCEED_SUBPOOL_CNT;
317 }
318
319 /* 设置每一级子内存池 */
320 mem_pool->us_mem_total_cnt = 0;
321 for (subpool_id = 0; subpool_id < subpool_cnt; subpool_id++) {
322 mem_subpool_cfg = mem_pool_cfg->subpool_cfg_info + subpool_id;
323 mem_subpool = &(mem_pool->ast_subpool_table[subpool_id]);
324 mem_subpool->us_free_cnt = mem_subpool_cfg->us_cnt;
325 mem_subpool->us_total_cnt = mem_subpool_cfg->us_cnt;
326 mem_subpool->us_len = mem_subpool_cfg->us_size;
327 mem_pool->us_mem_total_cnt += mem_subpool_cfg->us_cnt; /* 设置总内存块数 */
328 }
329 return oal_mem_create_subpool(pool_id, puc_base_addr);
330 }
331
332 /* ****************************************************************************
333 功能描述 : 分配内存
334 输入参数 : uc_pool_id : 所申请内存的内存池ID
335 us_len : 所申请内存块长度
336 返 回 值 : 成功: 指向所分配内存起始地址的指针
337 失败: 空指针
338 **************************************************************************** */
oal_mem_alloc(oal_mem_pool_id_enum_uint8 pool_id,hi_u16 us_len)339 hi_void *oal_mem_alloc(oal_mem_pool_id_enum_uint8 pool_id, hi_u16 us_len)
340 {
341 oal_mem_stru *mem = HI_NULL;
342
343 /* 异常: 申请长度为零 */
344 if (oal_unlikely(us_len == 0)) {
345 return HI_NULL;
346 }
347 us_len += OAL_MEM_INFO_SIZE;
348 mem = oal_mem_alloc_enhanced(pool_id, us_len);
349 if (oal_unlikely(mem == HI_NULL)) {
350 return HI_NULL;
351 }
352 mem->puc_data = mem->puc_origin_data + OAL_MEM_INFO_SIZE;
353 *((uintptr_t *)(mem->puc_data - OAL_MEM_INFO_SIZE)) = (uintptr_t)mem;
354 return (hi_void *)mem->puc_data;
355 }
356
357 /* ****************************************************************************
358 功能描述 : 释放内存
359 输入参数 : p_data : 要释放内存块地址
360 返 回 值 : HI_SUCCESS 或者其它错误码
361 **************************************************************************** */
oal_mem_free(const hi_void * data)362 hi_u32 oal_mem_free(const hi_void *data)
363 {
364 oal_mem_stru *mem = HI_NULL;
365
366 if (oal_unlikely(data == HI_NULL)) {
367 return HI_ERR_CODE_PTR_NULL;
368 }
369 mem = (oal_mem_stru *)(*((uintptr_t *)((hi_u8 *)data - OAL_MEM_INFO_SIZE)));
370 return oal_mem_free_enhanced(mem);
371 }
372
373 /* ****************************************************************************
374 功能描述 : 恢复(释放)已经分配的内存
375 **************************************************************************** */
oal_mem_release(hi_void)376 hi_void oal_mem_release(hi_void)
377 {
378 hi_u32 pool_id;
379
380 if (g_ctrl_blk.puc_base_addr != HI_NULL) {
381 hi_free(HI_MOD_ID_WIFI_DRV, (hi_void *)g_ctrl_blk.puc_base_addr);
382 g_ctrl_blk.puc_base_addr = HI_NULL;
383 }
384 for (pool_id = 0; pool_id < OAL_MEM_POOL_ID_BUTT; pool_id++) {
385 if (g_pauc_pool_base_addr[pool_id] != HI_NULL) {
386 hi_free(HI_MOD_ID_WIFI_DRV, (hi_void *)g_pauc_pool_base_addr[pool_id]);
387 g_pauc_pool_base_addr[pool_id] = HI_NULL;
388 }
389 }
390 }
391
392 /* ****************************************************************************
393 功能描述 : 初始化控制块内存
394 **************************************************************************** */
oal_mem_init_ctrl_blk(hi_void)395 hi_u32 oal_mem_init_ctrl_blk(hi_void)
396 {
397 hi_u16 us_total_cnt = 0;
398 hi_u8 pool_id;
399
400 g_ctrl_blk.idx = 0;
401 for (pool_id = 0; pool_id < OAL_MEM_POOL_ID_BUTT; pool_id++) {
402 us_total_cnt += oal_mem_get_total_cnt_in_pool(pool_id);
403 }
404 g_ctrl_blk.max_size = (hi_u32)(us_total_cnt * OAL_MEM_CTRL_BLK_SIZE);
405 /* 申请内存 */
406 g_ctrl_blk.puc_base_addr = (hi_u8 *)hi_malloc(HI_MOD_ID_WIFI_DRV, g_ctrl_blk.max_size);
407 if (g_ctrl_blk.puc_base_addr == HI_NULL) {
408 return HI_ERR_CODE_PTR_NULL;
409 }
410 return HI_SUCCESS;
411 }
412
413 /* ****************************************************************************
414 功能描述 : 内存模块卸载接口
415 返 回 值 : HI_SUCCESS
416 **************************************************************************** */
oal_mem_exit(hi_void)417 hi_void oal_mem_exit(hi_void)
418 {
419 /* 卸载普通内存池 */
420 oal_mem_release();
421 }
422
423 #ifdef __cplusplus
424 #if __cplusplus
425 }
426 #endif
427 #endif
428
429 /* ****************************************************************************
430 功能描述 : 分配内存
431 输入参数 : uc_pool_id : 所申请内存的内存池ID
432 us_len : 所申请内存块长度
433 返 回 值 : 分配的内存块结构体指针,或空指针
434 **************************************************************************** */
oal_mem_alloc_enhanced(oal_mem_pool_id_enum_uint8 pool_id,hi_u16 us_len)435 oal_mem_stru *oal_mem_alloc_enhanced(oal_mem_pool_id_enum_uint8 pool_id, hi_u16 us_len)
436 {
437 oal_mem_pool_stru *mem_pool = HI_NULL;
438 oal_mem_subpool_stru *mem_subpool = HI_NULL;
439 oal_mem_stru *mem = HI_NULL;
440 unsigned long irq_flag = 0;
441 hi_u8 subpool_id;
442
443 /* 获取内存池 */
444 mem_pool = &g_ast_mem_pool[pool_id];
445 #ifdef _PRE_DEBUG_MODE
446 us_len += OAL_DOG_TAG_SIZE;
447 #endif
448 /* 异常: 申请长度不在该内存池内 */
449 if (oal_unlikely(us_len > mem_pool->us_max_byte_len)) {
450 return HI_NULL;
451 }
452 for (subpool_id = 0; subpool_id < mem_pool->subpool_cnt; subpool_id++) {
453 mem_subpool = &(mem_pool->ast_subpool_table[subpool_id]);
454 oal_spin_lock_irq_save(&mem_subpool->st_spinlock, &irq_flag);
455 if ((mem_subpool->us_len < us_len) || (mem_subpool->us_free_cnt == 0)) {
456 oal_spin_unlock_irq_restore(&mem_subpool->st_spinlock, &irq_flag);
457 continue;
458 }
459 /* 获取一个没有使用的oal_mem_stru结点 */
460 mem_subpool->us_free_cnt--;
461 mem = (oal_mem_stru *)mem_subpool->free_stack[mem_subpool->us_free_cnt];
462 mem->puc_data = mem->puc_origin_data;
463 mem->user_cnt = 1;
464 mem->mem_state_flag = OAL_MEM_STATE_ALLOC;
465 mem_pool->us_mem_used_cnt++;
466 oal_spin_unlock_irq_restore(&mem_subpool->st_spinlock, &irq_flag);
467 break;
468 }
469 return mem;
470 }
471
oal_mem_free_enhanced(oal_mem_stru * mem)472 hi_u32 oal_mem_free_enhanced(oal_mem_stru *mem)
473 {
474 oal_mem_pool_stru *mem_pool = HI_NULL;
475 oal_mem_subpool_stru *mem_subpool = HI_NULL;
476 unsigned long irq_flag;
477
478 if (oal_unlikely(mem == HI_NULL)) {
479 return HI_ERR_CODE_PTR_NULL;
480 }
481 if (mem->pool_id >= OAL_MEM_POOL_ID_BUTT) {
482 return HI_ERR_CODE_PTR_NULL;
483 }
484 mem_pool = &g_ast_mem_pool[mem->pool_id];
485 if (mem->subpool_id >= mem_pool->subpool_cnt) {
486 return HI_ERR_CODE_PTR_NULL;
487 }
488 mem_subpool = &(mem_pool->ast_subpool_table[mem->subpool_id]);
489 oal_spin_lock_irq_save(&mem_subpool->st_spinlock, &irq_flag);
490 /* 异常: 释放一块已经被释放的内存 */
491 if (oal_unlikely(mem->mem_state_flag == OAL_MEM_STATE_FREE)) {
492 oal_spin_unlock_irq_restore(&mem_subpool->st_spinlock, &irq_flag);
493 return HI_ERR_CODE_MEM_ALREADY_FREE;
494 }
495 /* 异常: 释放一块引用计数为0的内存 */
496 if (oal_unlikely(mem->user_cnt == 0)) {
497 oal_spin_unlock_irq_restore(&mem_subpool->st_spinlock, &irq_flag);
498 return HI_ERR_CODE_MEM_USER_CNT_ERR;
499 }
500 mem->user_cnt--;
501 /* 该内存块上是否还有其他共享用户,直接返回 */
502 if (mem->user_cnt != 0) {
503 oal_spin_unlock_irq_restore(&mem_subpool->st_spinlock, &irq_flag);
504 return HI_SUCCESS;
505 }
506 /* 异常: 该子内存池可用内存块数目超过整个子内存池总内存块数 */
507 if (oal_unlikely(mem_subpool->us_free_cnt >= mem_subpool->us_total_cnt)) {
508 oal_spin_unlock_irq_restore(&mem_subpool->st_spinlock, &irq_flag);
509 return HI_ERR_CODE_MEM_EXCEED_TOTAL_CNT;
510 }
511 mem->mem_state_flag = OAL_MEM_STATE_FREE;
512 mem_subpool->free_stack[mem_subpool->us_free_cnt] = (hi_void *)mem;
513 mem_subpool->us_free_cnt++;
514 mem_pool->us_mem_used_cnt--;
515 oal_spin_unlock_irq_restore(&mem_subpool->st_spinlock, &irq_flag);
516 return HI_SUCCESS;
517 }
518
519 /* ****************************************************************************
520 功能描述 : 获取对应内存池占用的总字节数
521 输入参数 : en_pool_id : 内存池ID
522 输出参数 : pul_total_bytes: 对应内存池占用的总字节数
523 **************************************************************************** */
oal_mem_get_total_bytes_in_pool(oal_mem_pool_id_enum_uint8 pool_id)524 hi_u32 oal_mem_get_total_bytes_in_pool(oal_mem_pool_id_enum_uint8 pool_id)
525 {
526 hi_u32 total_bytes = 0; /* 本内存池总字节数 */
527 oal_mem_subpool_cfg_stru *mem_subpool_cfg = HI_NULL;
528 hi_u16 us_size;
529 hi_u16 us_cnt;
530 hi_u8 subpool_idx;
531 hi_u8 subpool_cnt;
532
533 mem_subpool_cfg = g_ast_mem_pool_cfg_table[pool_id].subpool_cfg_info;
534 subpool_cnt = g_ast_mem_pool_cfg_table[pool_id].subpool_cnt;
535
536 for (subpool_idx = 0; subpool_idx < subpool_cnt; subpool_idx++) {
537 us_size = mem_subpool_cfg[subpool_idx].us_size;
538 us_cnt = mem_subpool_cfg[subpool_idx].us_cnt;
539 total_bytes += us_size * us_cnt;
540 }
541 return total_bytes;
542 }
543
544 /* ****************************************************************************
545 功能描述 : 初始化全部内存池
546 返 回 值 : HI_SUCCESS 或其它错误码
547 **************************************************************************** */
oal_mem_init_pool(hi_void)548 hi_u32 oal_mem_init_pool(hi_void)
549 {
550 hi_u32 total_bytes;
551 hi_u32 pool_id;
552 hi_u32 ret;
553 hi_u8 *puc_base_addr = HI_NULL;
554
555 if (oal_mem_init_ctrl_blk() != HI_SUCCESS) {
556 hi_diag_log_msg_e0(0, "oal_mem_init_pool, init ctrl blk fail!");
557 return HI_ERR_CODE_ALLOC_MEM_FAIL;
558 }
559 for (pool_id = 0; pool_id < OAL_MEM_POOL_ID_BUTT; pool_id++) {
560 total_bytes = oal_mem_get_total_bytes_in_pool((hi_u8)pool_id);
561 puc_base_addr = (hi_u8 *)hi_malloc(HI_MOD_ID_WIFI_DRV, total_bytes);
562 if (puc_base_addr == HI_NULL) {
563 oal_mem_release();
564 hi_diag_log_msg_e1(0, "oal_mem_init_pool, memory allocation fail, size=%d!", total_bytes);
565 return HI_ERR_CODE_ALLOC_MEM_FAIL;
566 }
567 /* 记录每个内存池oal_malloc分配的地址 */
568 g_pauc_pool_base_addr[pool_id] = puc_base_addr;
569 puc_base_addr = (hi_u8 *)hi_byte_align((uintptr_t)puc_base_addr, 4); /* 4: 4bytes 对齐 */
570 ret = oal_mem_create_pool((hi_u8)pool_id, puc_base_addr);
571 if (ret != HI_SUCCESS) {
572 oal_mem_release();
573 hi_diag_log_msg_e0(0, "oal_mem_init_pool, oal_mem_create_pool failed!");
574 return ret;
575 }
576 }
577 return HI_SUCCESS;
578 }
579
oal_mem_dump_cfg(void)580 void oal_mem_dump_cfg(void)
581 {
582 oal_mem_pool_stru *mem_pool = HI_NULL;
583 oal_mem_subpool_stru *mem_subpool = HI_NULL;
584 int pool_id;
585 int sub_id;
586
587 oam_print("%8s %8s %8s %8s %8s %8s\r\n", "pool_id", "max_bytes", "sub_cnt", "used_cnt", "total_cnt", "start_addr");
588
589 for (pool_id = 0; pool_id < OAL_MEM_POOL_ID_BUTT; pool_id++) {
590 mem_pool = &g_ast_mem_pool[pool_id];
591
592 oam_print("%8d %8u %8u %8u %8u %p\r\n", pool_id, mem_pool->us_max_byte_len, mem_pool->subpool_cnt,
593 mem_pool->us_mem_used_cnt, mem_pool->us_mem_total_cnt, mem_pool->mem_start_addr);
594
595 oam_print("\t\t%8s %8s %8s %8s\r\n", "sub_id", "length", "free_cnt", "total_cnt");
596
597 for (sub_id = 0; sub_id < mem_pool->subpool_cnt; sub_id++) {
598 mem_subpool = &g_ast_mem_pool[pool_id].ast_subpool_table[sub_id];
599 oam_print("\t\t%8d %8u %8u %8u\r\n", sub_id, mem_subpool->us_len, mem_subpool->us_free_cnt,
600 mem_subpool->us_total_cnt);
601 }
602 }
603 }
604
605 #ifdef __cplusplus
606 #if __cplusplus
607 }
608 #endif
609 #endif
610