• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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