• 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 "frw_task.h"
23 #include "frw_event.h"
24 #include "frw_main.h"
25 #include "oam_ext_if.h"
26 #include "exception_rst.h"
27 
28 #ifdef __cplusplus
29 #if __cplusplus
30 extern "C" {
31 #endif
32 #endif
33 
34 #define FRW_ENQUEUE_FAIL_LIMIT 10
35 
36 hi_u32 g_app_event_id = 0;
37 hi_u32 g_frw_enqueue_fail_nums = 0;
38 
39 /* ****************************************************************************
40   2 STRUCT定义
41 **************************************************************************** */
42 /* ****************************************************************************
43   结构名  : frw_event_mgmt_stru
44   结构说明: 事件管理结构体
45 **************************************************************************** */
46 typedef struct _frw_event_mgmt_stru_ {
47     frw_event_queue_stru       *event_queue;    /* 事件队列 */
48     frw_event_sched_queue_stru sched_queue[FRW_SCHED_POLICY_BUTT];       /* 可调度队列 */
49     hi_atomic                  total_element_cnt;
50 } frw_event_mgmt_stru;
51 
52 /* *****************************************************************************
53     事件管理实体
54 ****************************************************************************** */
55 frw_event_mgmt_stru g_ast_event_manager;
56 
57 /* *****************************************************************************
58     事件表全局变量
59 ****************************************************************************** */
60 frw_event_table_item_stru g_ast_event_table[FRW_EVENT_TABLE_MAX_ITEMS];
61 
62 /* 事件队列初始化预留回调用于修改事件队列配置值 */
63 typedef hi_u32 (*frw_event_init_queue_cb)(hi_void);
64 
65 /* ****************************************************************************
66   4 函数实现
67 **************************************************************************** */
get_app_event_id(hi_void)68 hi_u32 get_app_event_id(hi_void)
69 {
70     return g_app_event_id;
71 }
72 
73 /* ****************************************************************************
74  功能描述  : 申请事件内存
75  输入参数  : us_length: payload长度 + 事件头长度
76  返 回 值  : 成功: 指向frw_event_mem_stru的指针
77              失败: HI_NULL
78  修改历史      :
79   1.日    期   : 2012年10月12日
80     作    者   : HiSilicon
81     修改内容   : 新生成函数
82 **************************************************************************** */
frw_event_alloc(hi_u16 us_payload_length)83 frw_event_mem_stru *frw_event_alloc(hi_u16 us_payload_length)
84 {
85     us_payload_length += OAL_MEM_INFO_SIZE;
86     return oal_mem_alloc_enhanced(OAL_MEM_POOL_ID_EVENT, (us_payload_length + FRW_EVENT_HDR_LEN));
87 }
88 
89 /* ****************************************************************************
90  功能描述  : 释放事件所占用的内存
91  输入参数  : event_mem: 指向事件内存块的指针
92  返 回 值  : HI_SUCCESS 或其它错误码
93 
94  修改历史      :
95   1.日    期   : 2012年10月12日
96     作    者   : HiSilicon
97     修改内容   : 新生成函数
98 **************************************************************************** */
frw_event_free(frw_event_mem_stru * event_mem)99 hi_u32 frw_event_free(frw_event_mem_stru *event_mem)
100 {
101     hi_u32 ret;
102     frw_event_stru *frw_event = HI_NULL;
103     hi_unref_param(frw_event);
104 
105     ret = oal_mem_free_enhanced(event_mem);
106     if (oal_warn_on(ret != HI_SUCCESS)) {
107         frw_event = (frw_event_stru *)event_mem->puc_data;
108         hi_diag_log_msg_i3(0, "[E]frw event free failed!, ret:%d, type:%d, subtype:%d",
109             ret, frw_event->event_hdr.type, frw_event->event_hdr.sub_type);
110     }
111     return ret;
112 }
113 
114 /* ****************************************************************************
115  功能描述  : 根据事件内容获取相应的事件队列ID
116  输入参数  : event_mem: 指向事件内存块的指针
117  输出参数  : pus_qid      : 队列ID
118  返 回 值  : HI_SUCCESS 或其它错误码
119 **************************************************************************** */
frw_event_to_qid(const frw_event_mem_stru * event_mem,hi_u16 * pus_qid)120 hi_u32 frw_event_to_qid(const frw_event_mem_stru *event_mem, hi_u16 *pus_qid)
121 {
122     hi_u16 us_qid;
123     frw_event_hdr_stru *event_hrd = HI_NULL;
124 
125     /* 获取事件头结构 */
126     event_hrd = (frw_event_hdr_stru *)event_mem->puc_data;
127 
128     us_qid = event_hrd->vap_id * FRW_EVENT_TYPE_BUTT + event_hrd->type;
129     /* 异常: 队列ID超过最大值 */
130     if ((us_qid >= FRW_EVENT_MAX_NUM_QUEUES)) {
131         oam_error_log4(0, OAM_SF_FRW,
132             "{frw_event_to_qid, array overflow! us_qid[%d], vap_id[%d], en_type[%d],sub_type[%d]}",
133             us_qid, event_hrd->vap_id, event_hrd->type, event_hrd->sub_type);
134         return HI_ERR_CODE_ARRAY_OVERFLOW;
135     }
136 
137     *pus_qid = us_qid;
138 
139     return HI_SUCCESS;
140 }
141 
142 /* ****************************************************************************
143  功能描述  : 初始化事件队列
144  修改历史      :
145   1.日    期   : 2012年11月13日
146     作    者   : HiSilicon
147     修改内容   : 新生成函数
148 **************************************************************************** */
frw_event_init_event_queue(hi_void)149 hi_u32 frw_event_init_event_queue(hi_void)
150 {
151     hi_u8  vap_res_num = oal_mem_get_vap_res_num();
152     hi_u16 us_total_cnt = vap_res_num * FRW_EVENT_TYPE_BUTT; /* 逻辑保证不会溢出 */
153     hi_u16 us_qid;
154     hi_u32 ret;
155     frw_event_cfg_stru ast_event_cfg_vap[] = WLAN_FRW_EVENT_CFG_TABLE; /* 事件初始值,最大资源值4vap */
156     /* 钩子函数,误包告警 -g- lin_t !e611 */
157     frw_event_init_queue_cb func_cb = (frw_event_init_queue_cb)frw_get_rom_resv_func(FRW_ROM_RESV_FUNC_QUEUE_INIT);
158     if (func_cb != HI_NULL) {
159         /* 预留回调非空 原有代码不再需要 */
160         return func_cb();
161     }
162     /* 根据支持的vap数量申请配置指针内存 */
163     g_ast_event_manager.event_queue =
164         (frw_event_queue_stru *)hi_malloc(HI_MOD_ID_WIFI_DRV, us_total_cnt * sizeof(frw_event_queue_stru));
165     if (g_ast_event_manager.event_queue == HI_NULL) {
166         hi_diag_log_msg_e0(0, "{frw_event_init_event_queue, hi_malloc event queue null.}");
167         return HI_FAIL;
168     }
169     /* 安全编程规则6.6例外(3)从堆中分配内存后,赋予初值 */
170     memset_s((hi_void *)g_ast_event_manager.event_queue, us_total_cnt * sizeof(frw_event_queue_stru), 0,
171         us_total_cnt * sizeof(frw_event_queue_stru));
172     /* 循环初始化事件队列 */
173     for (us_qid = 0; us_qid < us_total_cnt; us_qid++) {
174         ret = frw_event_queue_init(&g_ast_event_manager.event_queue[us_qid], ast_event_cfg_vap[us_qid].weight,
175             ast_event_cfg_vap[us_qid].policy, FRW_EVENT_QUEUE_STATE_INACTIVE, ast_event_cfg_vap[us_qid].max_events);
176         if (oal_unlikely(ret != HI_SUCCESS)) {
177             hi_free(HI_MOD_ID_WIFI_DRV, g_ast_event_manager.event_queue);
178             g_ast_event_manager.event_queue = HI_NULL;
179             hi_diag_log_msg_e0(0, "{frw_event_init_event_queue, frw_event_queue_init failed.}");
180             return ret;
181         }
182     }
183 
184     return HI_SUCCESS;
185 }
186 
frw_get_event_sub_table(hi_u8 type,hi_u8 pipeline)187 const frw_event_sub_table_item_stru* frw_get_event_sub_table(hi_u8 type, hi_u8 pipeline)
188 {
189     frw_event_table_item_stru *frw_event_table = HI_NULL;
190     hi_u8 index;
191 
192     /* 根据事件类型及分段号计算事件表索引 */
193     index = (hi_u8)((type << 1) | (pipeline & 0x01));
194     frw_event_table = &g_ast_event_table[index];
195 
196     return frw_event_table->sub_table;
197 }
198 
199 /* ****************************************************************************
200  功能描述  : 初始化调度器
201 **************************************************************************** */
frw_event_init_sched(hi_void)202 hi_u32 frw_event_init_sched(hi_void)
203 {
204     hi_u16 us_qid;
205     hi_u32 ret;
206 
207     /* 循环初始化调度器 */
208     for (us_qid = 0; us_qid < FRW_SCHED_POLICY_BUTT; us_qid++) {
209         ret = frw_event_sched_init(&g_ast_event_manager.sched_queue[us_qid]);
210         if (oal_unlikely(ret != HI_SUCCESS)) {
211             oam_warning_log1(0, OAM_SF_FRW, "{frw_event_init_sched, frw_event_sched_init return != HI_SUCCESS!%d}",
212                 ret);
213             return ret;
214         }
215     }
216 
217     return HI_SUCCESS;
218 }
219 
220 /* ****************************************************************************
221  功能描述  : 事件分发接口(分发事件至核间通讯、事件队列、或者查表寻找相应事件处理函数)
222 **************************************************************************** */
frw_event_dispatch_event(frw_event_mem_stru * event_mem)223 hi_u32 frw_event_dispatch_event(frw_event_mem_stru *event_mem)
224 {
225     frw_event_hdr_stru *event_hrd = HI_NULL;
226 #if defined(_PRE_MEM_DEBUG_MODE) || defined(_PRE_DEBUG_MODE)
227     hi_u32 dog_tag;
228 #endif
229 
230     if (oal_unlikely(event_mem == HI_NULL)) {
231         oam_error_log0(0, OAM_SF_FRW, "{frw_event_dispatch_event: event_mem is null ptr!}");
232         return HI_ERR_CODE_PTR_NULL;
233     }
234 
235     /* 异常: 内存写越界 */
236 #if defined(_PRE_MEM_DEBUG_MODE) || defined(_PRE_DEBUG_MODE)
237     dog_tag = (*((hi_u32 *)(event_mem->puc_origin_data + event_mem->us_len - OAL_DOG_TAG_SIZE)));
238     if (dog_tag != OAL_DOG_TAG) {
239         hi_diag_log_msg_i2(0, "[line = %d], frw_event_dispatch_event, ul_dog_tag changed is [%d]\r\n", __LINE__,
240             dog_tag);
241         return HI_ERR_CODE_MEM_DOG_TAG;
242     }
243 #endif
244 
245     /* 获取事件头结构 */
246     event_hrd = (frw_event_hdr_stru *)event_mem->puc_data;
247     if (oal_unlikely(event_hrd->pipeline >= FRW_EVENT_PIPELINE_STAGE_BUTT)) {
248         return HI_ERR_CODE_ARRAY_OVERFLOW;
249     }
250 
251     /* 如果pipleline为0,则将事件入队。否则,
252        根据事件类型,子类型以及分段号,执行相应的事件处理函数 */
253     if (event_hrd->pipeline == FRW_EVENT_PIPELINE_STAGE_0) {
254         return frw_event_post_event(event_mem);
255     }
256 
257     return frw_event_lookup_process_entry(event_mem, event_hrd);
258 }
259 
260 /* ****************************************************************************
261  功能描述  : 事件管理模块初始化总入口
262  返 回 值  : HI_SUCCESS 或其它错误码
263 
264  修改历史      :
265   1.日    期   : 2012年10月12日
266     作    者   : HiSilicon
267     修改内容   : 新生成函数
268 
269 **************************************************************************** */
frw_event_init(hi_void)270 hi_u32 frw_event_init(hi_void)
271 {
272     hi_u32 ret;
273 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
274     hi_event_init(4, HI_NULL); /* 4:设置最大事件数为4 */
275     hi_event_create(&g_app_event_id);
276 #endif
277     ret = frw_event_init_event_queue(); /* 初始化事件队列 */
278     if (oal_unlikely(ret != HI_SUCCESS)) {
279         oam_warning_log1(0, OAM_SF_FRW, "{frw_event_init, frw_event_init_event_queue != HI_SUCCESS!%d}", ret);
280         return ret;
281     }
282     /* 初始化调度器 */
283     ret = frw_event_init_sched();
284     if (oal_unlikely(ret != HI_SUCCESS)) {
285         oam_warning_log1(0, OAM_SF_FRW, "frw_event_init, frw_event_init_sched != HI_SUCCESS!%d", ret);
286         return ret;
287     }
288     frw_task_event_handler_register(frw_event_process_all_event);
289 
290     return HI_SUCCESS;
291 }
292 
293 /* ****************************************************************************
294  功能描述  : 销毁事件队列
295 **************************************************************************** */
frw_event_destroy_event_queue(hi_void)296 hi_void frw_event_destroy_event_queue(hi_void)
297 {
298     hi_u8 vap_res_num;
299     hi_u16 us_total_cnt;
300     hi_u16 us_qid;
301 
302     if (g_ast_event_manager.event_queue == HI_NULL) {
303         return;
304     }
305     vap_res_num = oal_mem_get_vap_res_num();
306     us_total_cnt = vap_res_num * FRW_EVENT_TYPE_BUTT; /* 逻辑保证不会溢出 */
307     /* 循环销毁事件队列 */
308     for (us_qid = 0; us_qid < us_total_cnt; us_qid++) {
309         frw_event_queue_destroy(&g_ast_event_manager.event_queue[us_qid]);
310     }
311     /* 释放事件队列内存 */
312     hi_free(HI_MOD_ID_WIFI_DRV, g_ast_event_manager.event_queue);
313     g_ast_event_manager.event_queue = HI_NULL;
314 }
315 
316 /* ****************************************************************************
317  功能描述  : 事件管理模块卸载接口
318  修改历史      :
319   1.日    期   : 2012年10月12日
320     作    者   : HiSilicon
321     修改内容   : 新生成函数
322 **************************************************************************** */
frw_event_exit(hi_void)323 hi_void frw_event_exit(hi_void)
324 {
325     /* 销毁事件队列 */
326     frw_event_destroy_event_queue();
327 }
328 
329 /* ****************************************************************************
330  功能描述  : 将事件内存放入相应的事件队列
331  输入参数  : event_mem: 指向事件内存块的指针
332  返 回 值  : HI_SUCCESS 或其它错误码
333 
334  修改历史      :
335   1.日    期   : 2015年4月23日
336     作    者   : HiSilicon
337     修改内容   : 新生成函数
338 
339 **************************************************************************** */
frw_event_queue_enqueue(frw_event_queue_stru * event_queue,frw_event_mem_stru * event_mem)340 hi_u32 frw_event_queue_enqueue(frw_event_queue_stru *event_queue, frw_event_mem_stru *event_mem)
341 {
342     return oal_queue_enqueue(&event_queue->queue, (hi_void *)event_mem);
343 }
344 
345 /* ****************************************************************************
346  功能描述  : 注册相应事件对应的事件处理函数
347  输入参数  : en_type:       事件类型
348              en_pipeline:   事件分段号
349              pst_sub_table: 事件子表指针
350  修改历史      :
351   1.日    期   : 2012年10月12日
352     作    者   : HiSilicon
353 **************************************************************************** */
frw_event_table_register(frw_event_type_enum_uint8 type,frw_event_pipeline_enum_uint8 pipeline,const frw_event_sub_table_item_stru * sub_table)354 hi_void frw_event_table_register(frw_event_type_enum_uint8 type, frw_event_pipeline_enum_uint8 pipeline,
355     const frw_event_sub_table_item_stru *sub_table)
356 {
357     hi_u8 index;
358 
359     if (oal_unlikely(sub_table == HI_NULL)) {
360         oam_error_log0(0, OAM_SF_FRW, "{frw_event_table_register: pst_sub_table is null ptr!}");
361         return;
362     }
363     /* 根据事件类型及分段号计算事件表索引 */
364     index = (hi_u8)((type << 1) | (pipeline & 0x01));
365     if (oal_unlikely(index >= FRW_EVENT_TABLE_MAX_ITEMS)) {
366         oam_error_log1(0, OAM_SF_FRW, "{frw_event_table_register, array overflow! %d}", index);
367         return;
368     }
369     g_ast_event_table[index].sub_table = sub_table;
370 }
371 
372 /* ****************************************************************************
373  功能描述  : 清空某个事件队列中的所有事件
374  返 回 值  : HI_SUCCESS 或其它错误码
375 
376  修改历史      :
377   1.日    期   : 2013年11月21日
378     作    者   : HiSilicon
379     修改内容   : 新生成函数
380 **************************************************************************** */
frw_event_flush_event_queue(frw_event_type_enum_uint8 event_type)381 hi_u32 frw_event_flush_event_queue(frw_event_type_enum_uint8 event_type)
382 {
383     frw_event_queue_stru *event_queue = HI_NULL;
384     frw_event_mem_stru   *event_mem = HI_NULL;
385     frw_event_hdr_stru   *event_hrd = HI_NULL;
386     hi_u32               event_succ = 0;
387     hi_u32               ret;
388     hi_u16               us_qid;
389     hi_u8                vap_id;
390     hi_u8                vap_res_num = oal_mem_get_vap_res_num();
391 
392     if (g_ast_event_manager.event_queue == HI_NULL) {
393         hi_diag_log_msg_e0(0, "{frw_event_flush_event_queue, event queue null.}");
394         return event_succ;
395     }
396     /* 遍历每个核的每个vap对应的事件队列 */
397     for (vap_id = 0; vap_id < vap_res_num; vap_id++) {
398         us_qid = vap_id * FRW_EVENT_TYPE_BUTT + event_type;
399         /* 根据核号 + 队列ID,找到相应的事件队列 */
400         event_queue = &(g_ast_event_manager.event_queue[us_qid]);
401         /* flush所有的event */
402         while (event_queue->queue.element_cnt != 0) {
403             event_mem = (frw_event_mem_stru *)frw_event_queue_dequeue(event_queue);
404             if (event_mem == HI_NULL) {
405                 return event_succ;
406             }
407             hi_atomic_dec(&(g_ast_event_manager.total_element_cnt));
408 
409             /* 获取事件头结构 */
410             event_hrd = (frw_event_hdr_stru *)event_mem->puc_data;
411 
412             /* 根据事件找到对应的事件处理函数 */
413             ret = frw_event_lookup_process_entry(event_mem, event_hrd);
414             if (ret != HI_SUCCESS) {
415                 oam_error_log1(0, OAM_SF_FRW,
416                     "{frw_event_process_all_event: frw_event_lookup_process_entry return value :%d}", ret);
417             }
418 
419             /* 释放事件内存 */
420             frw_event_free(event_mem);
421 
422             event_succ++;
423         }
424 
425         /* 如果事件队列变空,需要将其从调度队列上删除,并将事件队列状态置为不活跃(不可被调度) */
426         if (event_queue->queue.element_cnt == 0) {
427             frw_event_sched_deactivate_queue(&g_ast_event_manager.sched_queue[event_queue->policy], event_queue);
428         }
429     }
430 
431     return event_succ;
432 }
433 
434 /* ****************************************************************************
435  功能描述  : 冲刷指定VAP、指定事件类型的所有事件,同时可以指定是丢弃这些事件还是全部处理
436  输入参数  : uc_vap_id:     VAP ID值
437              en_event_type: 事件类型
438              en_drop:       事件丢弃(1)或者处理(0)
439 
440  修改历史      :
441   1.日    期   : 2013年12月23日
442     作    者   : HiSilicon
443     修改内容   : 新生成函数
444 **************************************************************************** */
frw_event_vap_flush_event(hi_u8 vap_id,frw_event_type_enum_uint8 event_type,hi_u8 drop)445 hi_u32 frw_event_vap_flush_event(hi_u8 vap_id, frw_event_type_enum_uint8 event_type, hi_u8 drop)
446 {
447     hi_u16              us_qid;
448     hi_u32              ret;
449     frw_event_queue_stru   *event_queue = HI_NULL;
450     frw_event_mem_stru     *event_mem = HI_NULL;
451     frw_event_hdr_stru     *event_hrd = HI_NULL;
452 
453     if (event_type == FRW_EVENT_TYPE_WLAN_TX_COMP) {
454         vap_id = 0;
455     }
456 
457     if (g_ast_event_manager.event_queue == HI_NULL) {
458         hi_diag_log_msg_e0(0, "{frw_event_flush_event_queue, event queue null.}");
459         return HI_ERR_CODE_PTR_NULL;
460     }
461     us_qid = vap_id * FRW_EVENT_TYPE_BUTT + event_type;
462     /* 根据核号 + 队列ID,找到相应的事件队列 */
463     event_queue = &(g_ast_event_manager.event_queue[us_qid]);
464     /* 如果事件队列本身为空,没有事件,不在调度队列,返回错误 */
465     if (event_queue->queue.element_cnt == 0) {
466         return HI_FAIL;
467     }
468 
469     /* flush所有的event */
470     while (event_queue->queue.element_cnt != 0) {
471         event_mem = (frw_event_mem_stru *)frw_event_queue_dequeue(event_queue);
472         if (event_mem == HI_NULL) {
473             return HI_FAIL;
474         }
475         hi_atomic_dec(&(g_ast_event_manager.total_element_cnt));
476 
477         /* 处理事件,否则直接释放事件内存而丢弃事件 */
478         if (drop == 0) {
479             /* 获取事件头结构 */
480             event_hrd = (frw_event_hdr_stru *)event_mem->puc_data;
481             /* 根据事件找到对应的事件处理函数 */
482             ret = frw_event_lookup_process_entry(event_mem, event_hrd);
483             if (ret != HI_SUCCESS) {
484                 oam_warning_log0(vap_id, OAM_SF_FRW, "frw_event_lookup_process_entry return NON SUCCESS. ");
485             }
486         }
487 
488         /* 释放事件内存 */
489         frw_event_free(event_mem);
490     }
491 
492     /* 若事件队列已经变空,需要将其从调度队列上删除,并将事件队列状态置为不活跃(不可被调度) */
493     if (event_queue->queue.element_cnt == 0) {
494         frw_event_sched_deactivate_queue(&g_ast_event_manager.sched_queue[event_queue->policy], event_queue);
495     } else {
496         oam_error_log1(vap_id, OAM_SF_FRW, "{flush vap event failed, left!=0: type=%d}", event_type);
497     }
498 
499     return HI_SUCCESS;
500 }
501 
502 /* ****************************************************************************
503  功能描述  : 根据核id和事件类型,判断vap事件队列是否空
504  输入参数  : event_type:  事件ID;
505  修改历史      :
506   1.日    期   : 2015年4月25日
507     作    者   : HiSilicon
508     修改内容   : 新生成函数
509 **************************************************************************** */
frw_is_vap_event_queue_empty(hi_u8 vap_id,hi_u8 event_type)510 hi_u8 frw_is_vap_event_queue_empty(hi_u8 vap_id, hi_u8 event_type)
511 {
512     frw_event_queue_stru *event_queue = HI_NULL;
513     hi_u16               us_qid;
514 
515     us_qid = (hi_u16)(vap_id * FRW_EVENT_TYPE_BUTT + event_type);
516     /* 根据核号 + 队列ID,找到相应的事件队列 */
517     if (g_ast_event_manager.event_queue == HI_NULL) {
518         hi_diag_log_msg_e0(0, "{frw_event_flush_event_queue, event queue null.}");
519         return HI_TRUE;
520     }
521     event_queue = &(g_ast_event_manager.event_queue[us_qid]);
522     if (event_queue->queue.element_cnt != 0) {
523         return HI_FALSE;
524     }
525     return HI_TRUE;
526 }
527 
528 /* ****************************************************************************
529  功能描述  : 判断是否有事件需要调度
530 
531  修改历史      :
532   1.日    期   : 2015年4月9日
533     作    者   : HiSilicon
534     修改内容   : 新生成函数
535 
536 **************************************************************************** */
frw_task_thread_condition_check(hi_void)537 hi_u8 frw_task_thread_condition_check(hi_void)
538 {
539     return (hi_atomic_read(&g_ast_event_manager.total_element_cnt) != 0);
540 }
541 
542 /* ****************************************************************************
543  功能描述  : 处理事件队列中的所有事件
544  patch修改 : FRW处理事件时先cnt递减
545 **************************************************************************** */
frw_event_process_all_event(hi_void)546 hi_void frw_event_process_all_event(hi_void)
547 {
548     frw_event_mem_stru            *event_mem = HI_NULL;
549     frw_event_sched_queue_stru    *sched_queue = HI_NULL;
550     frw_event_hdr_stru            *event_hrd = HI_NULL;
551 
552     /* 获取核号 */
553     sched_queue = g_ast_event_manager.sched_queue;
554     /* 调用事件调度模块,选择一个事件 */
555     event_mem = (frw_event_mem_stru *)frw_event_schedule(sched_queue);
556     while (event_mem != HI_NULL) {
557         hi_atomic_dec(&g_ast_event_manager.total_element_cnt);
558         /* 获取事件头结构 */
559         event_hrd = (frw_event_hdr_stru *)event_mem->puc_data;
560         if (event_hrd != HI_NULL) {
561             /* 根据事件找到对应的事件处理函数 */
562             if (frw_event_lookup_process_entry(event_mem, event_hrd) != HI_SUCCESS) {
563                 oam_warning_log0(0, OAM_SF_FRW, "frw_event_process_all_event_patch return NON SUCCESS.");
564             }
565         }
566         /* 释放事件内存 */
567         frw_event_free(event_mem);
568         /* 调用事件调度模块,选择一个事件 */
569         event_mem = (frw_event_mem_stru *)frw_event_schedule(sched_queue);
570     }
571 }
572 
573 /* ****************************************************************************
574  功能描述  : 事件内存出队
575  输入参数  : pst_event_queue: 事件队列
576  返 回 值  : HI_SUCCESS 或其它错误码
577 
578  修改历史      :
579   1.日    期   : 2015年4月23日
580     作    者   : HiSilicon
581     修改内容   : 新生成函数
582 
583 **************************************************************************** */
frw_event_queue_dequeue(frw_event_queue_stru * event_queue)584 frw_event_mem_stru *frw_event_queue_dequeue(frw_event_queue_stru *event_queue)
585 {
586     frw_event_mem_stru *event_mem = HI_NULL;
587     unsigned long irq_flag;
588 
589     oal_spin_lock_irq_save(&event_queue->st_lock, &irq_flag);
590     event_mem = (frw_event_mem_stru *)oal_queue_dequeue(&event_queue->queue);
591     oal_spin_unlock_irq_restore(&event_queue->st_lock, &irq_flag);
592     return event_mem;
593 }
594 
595 /* ****************************************************************************
596  功能描述  : 将事件内存放入相应的事件队列
597  输入参数  : event_mem: 指向事件内存块的指针
598  返 回 值  : HI_SUCCESS 或其它错误码
599 **************************************************************************** */
frw_event_post_event(frw_event_mem_stru * event_mem)600 hi_u32 frw_event_post_event(frw_event_mem_stru *event_mem)
601 {
602     hi_u16                     us_qid;
603     frw_event_queue_stru       *event_queue = HI_NULL;
604     hi_u32                     ret;
605     unsigned long              irq_flag;
606     unsigned long              sched_flag;
607     frw_event_hdr_stru         *event_hdr = HI_NULL;
608     frw_event_sched_queue_stru *sched_queue = HI_NULL;
609 
610     /* 获取事件队列ID */
611     ret = frw_event_to_qid(event_mem, &us_qid);
612     if (oal_unlikely(ret != HI_SUCCESS)) {
613         oam_warning_log1(0, OAM_SF_FRW, "{frw_event_post_event, frw_event_to_qid return != HI_SUCCESS!%d}", ret);
614         return ret;
615     }
616     /* 根据核号 + 队列ID,找到相应的事件队列 */
617     if (g_ast_event_manager.event_queue == HI_NULL) {
618         oam_error_log0(0, OAM_SF_FRW, "{frw_event_post_event, event queue null.}");
619         return HI_ERR_CODE_PTR_NULL;
620     }
621     event_queue = &(g_ast_event_manager.event_queue[us_qid]);
622     /* 检查policy */
623     if (oal_unlikely(event_queue->policy >= FRW_SCHED_POLICY_BUTT)) {
624         oam_error_log1(0, OAM_SF_FRW, "{frw_event_post_event, array overflow!%d}", event_queue->policy);
625         return HI_ERR_CODE_ARRAY_OVERFLOW;
626     }
627     /* 获取调度队列 */
628     sched_queue = &(g_ast_event_manager.sched_queue[event_queue->policy]);
629 
630     /* 先取得引用,防止enqueue与取得引用之间被释放 */
631     event_mem->user_cnt++;
632     oal_spin_lock_irq_save(&sched_queue->st_lock, &sched_flag);
633     /* 事件入队 */
634     oal_spin_lock_irq_save(&event_queue->st_lock, &irq_flag);
635     ret = frw_event_queue_enqueue(event_queue, event_mem);
636     if (oal_unlikely(ret != HI_SUCCESS)) {
637         oal_spin_unlock_irq_restore(&event_queue->st_lock, &irq_flag);
638         oal_spin_unlock_irq_restore(&sched_queue->st_lock, &sched_flag);
639         event_hdr = (frw_event_hdr_stru *)(event_mem->puc_data);
640         oam_error_log4(0, OAM_SF_FRW,
641             "frw_event_post_event:: enqueue fail, type:%d, sub type:%d, pipeline:%d,max num:%d", event_hdr->type,
642             event_hdr->sub_type, event_hdr->pipeline, event_queue->queue.max_elements);
643         g_frw_enqueue_fail_nums++;
644         /* 释放事件内存引用 */
645         frw_event_free(event_mem);
646         if (g_frw_enqueue_fail_nums > FRW_ENQUEUE_FAIL_LIMIT) {
647             oal_frw_exception_report();
648         }
649         return ret;
650     }
651     g_frw_enqueue_fail_nums = 0;
652     hi_atomic_inc(&(g_ast_event_manager.total_element_cnt));
653     /* 根据所属调度策略,将事件队列加入可调度队列 */
654     ret = frw_event_sched_activate_queue_no_lock(sched_queue, event_queue);
655     if (oal_unlikely(ret != HI_SUCCESS)) {
656         oal_spin_unlock_irq_restore(&event_queue->st_lock, &irq_flag);
657         oal_spin_unlock_irq_restore(&sched_queue->st_lock, &sched_flag);
658         oam_error_log0(0, OAM_SF_FRW, "{frw_event_post_event, sched_activate_queue failed!}");
659         return ret;
660     }
661     oal_spin_unlock_irq_restore(&event_queue->st_lock, &irq_flag);
662     oal_spin_unlock_irq_restore(&sched_queue->st_lock, &sched_flag);
663     frw_task_sched();
664 
665     return HI_SUCCESS;
666 }
667 
frw_event_sub_rx_adapt_table_init(frw_event_sub_table_item_stru * pst_sub_table,hi_u32 ul_table_nums,frw_event_mem_stru * (* p_rx_adapt_func)(frw_event_mem_stru *))668 hi_void frw_event_sub_rx_adapt_table_init(frw_event_sub_table_item_stru *pst_sub_table, hi_u32 ul_table_nums,
669     frw_event_mem_stru *(*p_rx_adapt_func)(frw_event_mem_stru *))
670 {
671     hi_u32 i;
672     frw_event_sub_table_item_stru *pst_curr_table = HI_NULL;
673     for (i = 0; i < ul_table_nums; i++) {
674         pst_curr_table = pst_sub_table + i;
675         pst_curr_table->p_rx_adapt_func = p_rx_adapt_func;
676     }
677 }
678 
679 /* ****************************************************************************
680  功能描述  : 根据事件类型,子类型以及分段号,找到相应事件处理函数
681  输入参数  : event_mem: 指向事件内存块的指针
682  返 回 值  : HI_SUCCESS 或其它错误码
683 
684  修改历史      :
685   1.日    期   : 2012年11月13日
686     作    者   : HiSilicon
687     修改内容   : 新生成函数
688 
689 **************************************************************************** */
frw_event_lookup_process_entry(frw_event_mem_stru * event_mem,const frw_event_hdr_stru * event_hrd)690 hi_u32 frw_event_lookup_process_entry(frw_event_mem_stru *event_mem, const frw_event_hdr_stru *event_hrd)
691 {
692     frw_event_table_item_stru *frw_event_table = HI_NULL;
693     hi_u8                     index;
694     hi_u8                     sub_type;
695     frw_event_mem_stru       *rx_adapt_event_mem = HI_NULL;
696     hi_u32                    err_code;
697 
698     sub_type = event_hrd->sub_type;
699 
700     /* 根据事件类型及分段号计算事件表索引 */
701     index = (hi_u8)((event_hrd->type << 1) | (event_hrd->pipeline & 0x01));
702     if (oal_unlikely(index >= FRW_EVENT_TABLE_MAX_ITEMS)) {
703         hi_diag_log_msg_e3(0, "{frw_event_lookup_process_entry::array overflow! type[%d], sub_type[%d], pipeline[%d]}",
704             event_hrd->type, sub_type, event_hrd->pipeline);
705         return HI_ERR_CODE_ARRAY_OVERFLOW;
706     }
707 
708     /* 先把全局变量变成局部变量 */
709     frw_event_table = &g_ast_event_table[index];
710     if (frw_event_table->sub_table == HI_NULL) {
711         hi_diag_log_msg_e2(0, "{frw_event_lookup_process_entry::pst_sub_table is NULL! sub_type[%d], index[%d].}",
712             sub_type, index);
713         return HI_ERR_CODE_PTR_NULL;
714     }
715     /* 直接函数调用 */
716     if (frw_event_table->sub_table[sub_type].func == HI_NULL) {
717         hi_diag_log_msg_e2(0, "{frw_event_lookup_process_entry:: p_func is NULL! sub_type[%d], index[%d].}", sub_type,
718             index);
719         return HI_ERR_CODE_PTR_NULL;
720     }
721 
722     if (event_hrd->pipeline == 0) {
723         if (frw_event_table->sub_table[sub_type].func != HI_NULL) {
724             err_code = frw_event_table->sub_table[sub_type].func(event_mem);
725             return err_code;
726         } else {
727             oam_error_log2(0, OAM_SF_FRW,
728                 "{frw_event_lookup_process_entry:: func is NULL! sub_type[%d], index[0x%x], pipeline=0.}", sub_type,
729                 index);
730             return HI_ERR_CODE_PTR_NULL;
731         }
732     }
733 
734     /* For rx adapt */
735     if (frw_event_table->sub_table[sub_type].p_rx_adapt_func == HI_NULL) {
736         oam_warning_log2(0, 0, "frw_event_lookup_process_entry:: rx_adapt_func is NULL, type[%d], sub_type[%d]",
737             event_hrd->type, sub_type);
738         return HI_ERR_CODE_PTR_NULL;
739     }
740 
741     /* rx adapt first */
742     rx_adapt_event_mem = frw_event_table->sub_table[sub_type].p_rx_adapt_func(event_mem);
743     if (rx_adapt_event_mem == HI_NULL) {
744         oam_error_log0(0, 0, "frw_event_lookup_process_entry:: rx_adapt_event_mem NULL");
745         return HI_ERR_CODE_PTR_NULL;
746     }
747 
748     if (frw_event_table->sub_table[sub_type].func != HI_NULL) {
749         /* then call action frame */
750         err_code = frw_event_table->sub_table[sub_type].func(rx_adapt_event_mem);
751     } else {
752         err_code = HI_ERR_CODE_PTR_NULL;
753     }
754 
755     frw_event_free(rx_adapt_event_mem);
756 
757     return err_code;
758 }
759 
760 #ifdef __cplusplus
761 #if __cplusplus
762 }
763 #endif
764 #endif
765