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 /* 1 头文件包含 */
19 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
20 #include "hi_task.h"
21 #endif
22 #include "frw_event.h"
23 #include "frw_task.h"
24 #include "frw_main.h"
25
26 #ifdef __cplusplus
27 #if __cplusplus
28 extern "C" {
29 #endif
30 #endif
31 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
32 #define FRW_THREAD_NAME_MAX_SIZE 20
33 #endif
34 #if (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_THREAD)
35 #define FRW_TASK_PRIO 4 /* 驱动task的优先级,建议比上层高 */
36 hi_char g_frw_thread_name[] = { "hisi_frw" };
37 #endif
38 /* *****************************************************************************
39 事件处理全局变量
40 ****************************************************************************** */
41 frw_task_stru g_ast_event_task;
42 /* ****************************************************************************
43 线程退出标志全局变量
44 ****************************************************************************** */
45 hi_u8 g_frw_exit = HI_FALSE;
46 hi_u8 g_frw_stop = HI_FALSE;
47 /* ****************************************************************************
48 3 函数实现
49 **************************************************************************** */
50 #if (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_THREAD)
51 /* ****************************************************************************S
52 功能描述 : frw 内核线程主程序
53 **************************************************************************** */
54 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
frw_task_thread(hi_void * bind_cpu)55 hi_void *frw_task_thread(hi_void *bind_cpu)
56 {
57 #if (_PRE_MULTI_CORE_MODE != _PRE_MULTI_CORE_MODE_OFFLOAD_HMAC)
58 hi_u32 event;
59 #else
60 hi_s32 ret;
61 #endif
62 hi_unref_param(bind_cpu);
63 /* 死循环直至事件调度完 */
64 for (;;) {
65 #if (_PRE_MULTI_CORE_MODE != _PRE_MULTI_CORE_MODE_OFFLOAD_HMAC)
66 while (!frw_task_thread_condition_check()) {
67 hi_event_wait(get_app_event_id(), HI_EVENT_FRW_TASK, &event, HI_SYS_WAIT_FOREVER,
68 HI_EVENT_WAITMODE_AND | HI_EVENT_WAITMODE_CLR);
69 }
70 #else
71 /* state为TASK_INTERRUPTIBLE,condition不成立则线程阻塞,直到被唤醒进入waitqueue */
72 ret = hi_wait_event_interruptible(g_ast_event_task.frw_wq, frw_task_thread_condition_check() == HI_TRUE);
73 if (oal_unlikely(ret == -ERESTARTSYS)) {
74 hi_diag_log_msg_i0(0, "wifi task was interrupted by a signal\n");
75 break;
76 }
77 #endif
78 frw_event_process_all_event();
79 }
80 return HI_NULL; /* 任务管理函数,for (;;) 死循环后需要return,lin_t e527告警屏蔽 */
81 }
82 #endif
83 #endif /* #if (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_THREAD) */
84 /* ****************************************************************************
85 功能描述 : kthread初始化接口
86 **************************************************************************** */
87 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
frw_task_init(void)88 hi_u32 frw_task_init(void)
89 {
90 /* 对固定长度的数组进行初始化,或对固定长度的结构体进行内存初始化 */
91 memset_s(&g_ast_event_task, sizeof(g_ast_event_task), 0, sizeof(g_ast_event_task));
92
93 hi_wait_queue_init_head(&g_ast_event_task.frw_wq);
94
95 #if (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_THREAD)
96 hi_u32 ret, taskid;
97 hi_task_attr attr = { 0 };
98
99 attr.stack_size = FRW_TASK_SIZE;
100 attr.task_prio = FRW_TASK_PRIO;
101 attr.task_name = g_frw_thread_name;
102 attr.task_policy = 1; /* SCHED_FIFO */
103 attr.task_cpuid = 0;
104 ret = hi_task_create(&taskid, &attr, frw_task_thread, 0);
105 if (ret != HI_SUCCESS) {
106 return HI_FAIL;
107 }
108 g_ast_event_task.taskid = taskid;
109 #elif (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_TASKLET)
110 oal_task_kill(&g_ast_event_task.event_tasklet);
111 #endif
112 return HI_SUCCESS;
113 }
114 #endif
115
116 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
117 /* ****************************************************************************
118 功能描述 : 线程退出函数
119 修改历史 :
120 1.日 期 : 2015年4月9日
121 **************************************************************************** */
frw_task_exit(hi_void)122 hi_void frw_task_exit(hi_void)
123 {
124 #if (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_THREAD)
125 if (g_ast_event_task.taskid) {
126 hi_task_delete(g_ast_event_task.taskid);
127 g_ast_event_task.taskid = 0;
128 }
129 #elif (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_TASKLET)
130 oal_task_kill(&g_ast_event_task.event_tasklet);
131 #endif
132 }
133 #endif /* #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) */
134
135 /* ****************************************************************************
136 功能描述 : 供外部模块注册tasklet处理函数中执行的函数
137 输入参数 : p_func: 需要被执行的函数
138
139 修改历史 :
140 1.日 期 : 2015年4月9日
141 作 者 : HiSilicon
142 修改内容 : 新生成函数
143 **************************************************************************** */
frw_task_event_handler_register(hi_void (* func)(hi_void))144 hi_void frw_task_event_handler_register(hi_void (*func)(hi_void))
145 {
146 if (oal_unlikely(func == HI_NULL)) {
147 hi_diag_log_msg_i0(0, "{frw_task_event_handler_register:: p_func is null ptr}");
148 return;
149 }
150
151 #if (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_TASKLET)
152 g_ast_event_task.event_handler_func = func;
153 #endif
154 }
155
156 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
157 /* ****************************************************************************
158 功能描述 : 唤醒event时间处理线程,与wake_event_interruptible对应
159 修改历史 :
160 1.日 期 : 2015年4月9日
161 作 者 : HiSilicon
162 修改内容 : 新生成函数
163 **************************************************************************** */
frw_task_sched(hi_void)164 hi_void frw_task_sched(hi_void)
165 {
166 #if (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_THREAD)
167 #if (_PRE_MULTI_CORE_MODE != _PRE_MULTI_CORE_MODE_OFFLOAD_HMAC)
168 (hi_void)hi_event_send(get_app_event_id(), HI_EVENT_FRW_TASK);
169 #else
170 hi_wait_queue_wake_up_interrupt(&g_ast_event_task.frw_wq);
171 #endif
172 #elif (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_TASKLET)
173 if (oal_task_is_scheduled(&g_ast_event_task.event_tasklet)) {
174 return;
175 }
176 oal_task_sched(&g_ast_event_task.event_tasklet);
177 #endif
178 }
179 #endif
180
181 #if (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_TASKLET)
182 /* ****************************************************************************
183 功能描述 : 将tasklet调度执行,被IPI中断调度执行
184 **************************************************************************** */
frw_remote_task_receive(hi_void * info)185 hi_void frw_remote_task_receive(hi_void *info)
186 {
187 oal_tasklet_stru *task = (oal_tasklet_stru *)info;
188 oal_task_sched(task);
189 }
190
191 /* ****************************************************************************
192 功能描述 : 使用IPI中断,调度目标core上的tasklet执行处理事件
193 **************************************************************************** */
frw_task_sched_on_cpu(oal_tasklet_stru * task)194 hi_void frw_task_sched_on_cpu(oal_tasklet_stru *task)
195 {
196 oal_smp_call_function_single(0, frw_remote_task_receive, (hi_void *)task, 0);
197 }
198 #endif
199
200 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
frw_task_thread(hi_void * ul_bind_cpu)201 static hi_s32 frw_task_thread(hi_void *ul_bind_cpu)
202 {
203 hi_s32 ret;
204 #if (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_THREAD)
205 hi_u32 ul_empty_count = 0;
206 #endif
207 g_frw_exit = HI_FALSE; /* 线程初始化时为此全局变量赋值 */
208 g_frw_stop = HI_FALSE; /* 线程初始化时为此全局变量赋值 */
209 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
210 allow_signal(SIGTERM);
211 #endif
212 for (;;) {
213 #if (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_THREAD)
214 hi_u32 ul_event_count;
215 #endif
216 if (oal_kthread_should_stop()) {
217 break;
218 }
219
220 /* state为TASK_INTERRUPTIBLE,condition不成立则线程阻塞,直到被唤醒进入waitqueue */
221 /*lint -e730*/
222 #ifdef _PRE_FRW_EVENT_PROCESS_TRACE_DEBUG
223 frw_event_last_pc_trace(__FUNCTION__, __LINE__, (hi_u32)(unsigned long)ul_bind_cpu);
224 #endif
225 ret = hi_wait_event_interruptible(g_ast_event_task.frw_wq,
226 (HI_TRUE == frw_task_thread_condition_check() || g_frw_exit));
227 /*lint +e730*/
228 if (oal_unlikely(ret == -ERESTARTSYS)) {
229 oal_io_print1("wifi task %s was interrupted by a signal\n", oal_get_current_task_name());
230 break;
231 }
232 if (g_frw_exit == HI_TRUE) {
233 break;
234 }
235 #if (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_THREAD)
236 g_ast_event_task.ul_total_loop_cnt++;
237
238 ul_event_count = g_ast_event_task.ul_total_event_cnt;
239 #endif
240 frw_event_process_all_event();
241 #if (_PRE_FRW_FEATURE_PROCESS_ENTITY_TYPE == _PRE_FRW_FEATURE_PROCESS_ENTITY_THREAD)
242 if (ul_event_count == g_ast_event_task.ul_total_event_cnt) {
243 /* 空转 */
244 ul_empty_count++;
245 if (ul_empty_count == 10000) { /* empty count 10000 */
246 }
247 } else {
248 if (ul_empty_count > g_ast_event_task.ul_max_empty_count) {
249 g_ast_event_task.ul_max_empty_count = ul_empty_count;
250 }
251 ul_empty_count = 0;
252 }
253 #endif
254 #ifdef _PRE_FRW_EVENT_PROCESS_TRACE_DEBUG
255 frw_event_last_pc_trace(__FUNCTION__, __LINE__, (hi_u32)(unsigned long)ul_bind_cpu);
256 #endif
257 #if (!defined(CONFIG_PREEMPT) && (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION))
258 cond_resched();
259 #endif
260 }
261 g_frw_stop = HI_TRUE;
262 return 0;
263 }
264
frw_task_init()265 hi_u32 frw_task_init()
266 {
267 oal_kthread_stru *kthread = HI_NULL;
268 oal_kthread_param_stru st_thread_param = { 0 };
269
270 memset_s(&g_ast_event_task, sizeof(g_ast_event_task), 0, sizeof(g_ast_event_task));
271
272 hi_wait_queue_init_head(&g_ast_event_task.frw_wq);
273
274 st_thread_param.l_cpuid = 0;
275 st_thread_param.l_policy = OAL_SCHED_RR;
276 st_thread_param.l_prio = FRW_TASK_PRIO;
277 st_thread_param.ul_stacksize = FRW_TASK_SIZE;
278
279 kthread = oal_kthread_create(g_frw_thread_name, frw_task_thread,
280 (hi_void *)(st_thread_param.l_cpuid), &st_thread_param);
281 if (IS_ERR_OR_NULL(kthread)) {
282 return HI_FAIL;
283 }
284
285 g_ast_event_task.pst_event_kthread = kthread;
286 g_ast_event_task.uc_task_state = FRW_TASK_STATE_IRQ_UNBIND;
287 return HI_SUCCESS;
288 }
289
frw_task_exit(hi_void)290 hi_void frw_task_exit(hi_void)
291 {
292 int times = 0;
293 if (g_ast_event_task.pst_event_kthread != HI_NULL) {
294 g_frw_exit = HI_TRUE;
295 frw_task_sched();
296 while (!g_frw_stop && times < 10000) {
297 usleep_range(50, 100); /* 50 100 均为延时参数,最小延时50,最大100 */
298 times++;
299 }
300 }
301 }
frw_task_sched(hi_void)302 hi_void frw_task_sched(hi_void)
303 {
304 hi_wait_queue_wake_up_interrupt(&g_ast_event_task.frw_wq);
305 }
306 #endif /* #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) */
307
308 #ifdef __cplusplus
309 #if __cplusplus
310 }
311 #endif
312 #endif
313