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