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 1 头文件包含
20 **************************************************************************** */
21 #include "frw_timer.h"
22 #include "frw_main.h"
23 #ifdef _PRE_HDF_LINUX
24 #include "hdf_dlist.h"
25 #endif
26 #ifdef __cplusplus
27 #if __cplusplus
28 extern "C" {
29 #endif
30 #endif
31
32 /* ****************************************************************************
33 2 全局变量定义
34 **************************************************************************** */
35 hi_list g_ast_timer_list;
36 oal_spin_lock_stru g_ast_timer_list_spinlock;
37 hi_u32 g_timer_id = 0;
38
39 /* ****************************************************************************
40 3 函数实现
41 **************************************************************************** */
42 /* 功能描述:FRW定时器超时处理事件 */
frw_timer_timeout_event(uintptr_t data)43 hi_void frw_timer_timeout_event(uintptr_t data)
44 {
45 frw_event_mem_stru *event_mem = HI_NULL;
46 frw_event_stru *event = HI_NULL;
47 frw_timeout_stru *timeout = HI_NULL;
48 hi_u32 ret;
49
50 timeout = (frw_timeout_stru *)data;
51 event_mem = frw_event_alloc(sizeof(hi_u32));
52 if (event_mem == HI_NULL) {
53 oam_error_log0(0, OAM_SF_FRW, "{frw_timer_timeout_event:: event_mem == HI_NULL}");
54 return;
55 }
56
57 event = (frw_event_stru *)event_mem->puc_data;
58 frw_field_setup((&event->event_hdr), type, (FRW_EVENT_TYPE_TIMEOUT));
59 frw_field_setup((&event->event_hdr), sub_type, (FRW_TIMEOUT_TIMER_EVENT));
60 frw_field_setup((&event->event_hdr), us_length, (WLAN_MEM_EVENT_SIZE1));
61 frw_field_setup((&event->event_hdr), pipeline, (FRW_EVENT_PIPELINE_STAGE_0));
62 frw_field_setup((&event->event_hdr), vap_id, (0));
63
64 *(hi_u32 *)event->auc_event_data = timeout->timer_id;
65
66 ret = frw_event_dispatch_event(event_mem);
67 if (ret != HI_SUCCESS) {
68 oam_warning_log1(0, OAM_SF_FRW, "{frw_timer_timeout_event::frw_event_dispatch_event failed[%d].}", ret);
69 }
70
71 /* 释放事件 */
72 frw_event_free(event_mem);
73 }
74
75 /*
76 * 功能描述:FRW定时器超时处理函数
77 */ /* 是全局变量g_ast_frw_timeout_event_sub_table引用,不用const修饰,lin_t e801告警屏蔽,lin_t e818告警屏蔽 */
frw_timer_timeout_proc(frw_event_mem_stru * event_mem)78 hi_u32 frw_timer_timeout_proc(frw_event_mem_stru *event_mem)
79 {
80 hi_list *timeout_entry = HI_NULL;
81 frw_event_stru *event = HI_NULL;
82 frw_timeout_stru *timeout_element = HI_NULL;
83 hi_u32 timer_id;
84
85 event = (frw_event_stru *)event_mem->puc_data;
86 timer_id = *(hi_u32 *)event->auc_event_data;
87
88 timeout_entry = g_ast_timer_list.next;
89 while (timeout_entry != &g_ast_timer_list) {
90 if (timeout_entry == HI_NULL) {
91 oam_warning_log0(0, OAM_SF_FRW, "{frw_timer_timeout_proc:: pst_timeout_entry is null! }");
92 break;
93 }
94
95 timeout_element = hi_list_entry(timeout_entry, frw_timeout_stru, entry);
96 /* 如果该定时器没有使能或者待删除,则直接看下一个 */
97 if ((timeout_element->is_deleting == HI_TRUE) ||
98 (timeout_element->is_enabled == HI_FALSE)) {
99 timeout_entry = timeout_entry->next;
100 continue;
101 }
102
103 if ((timeout_element->timer_id == timer_id) &&
104 (timeout_element->func != HI_NULL)) {
105 timeout_element->func(timeout_element->timeout_arg);
106 break;
107 }
108 timeout_entry = timeout_entry->next;
109 }
110 return HI_SUCCESS;
111 }
112
113 /*
114 * 功能描述:删除所有定时器
115 */
frw_timer_delete_all_timer(hi_void)116 hi_void frw_timer_delete_all_timer(hi_void)
117 {
118 /* 无用函数,待上层统一删除 */
119 }
120
121 const frw_event_sub_table_item_stru g_ast_frw_timeout_event_sub_table[FRW_TIMEOUT_SUB_TYPE_BUTT] = {
122 { frw_timer_timeout_proc, HI_NULL, HI_NULL } /* FRW_TIMEOUT_TIMER_EVENT */
123 };
124
125 /* 功能描述:FRW定时器初始化 */
frw_timer_init(hi_void)126 hi_void frw_timer_init(hi_void)
127 {
128 oal_spin_lock_init(&g_ast_timer_list_spinlock);
129 hi_list_init(&g_ast_timer_list);
130 frw_event_table_register(FRW_EVENT_TYPE_TIMEOUT, FRW_EVENT_PIPELINE_STAGE_0, g_ast_frw_timeout_event_sub_table);
131 }
132
133 /*
134 * 功能描述:添加定时器
135 */
frw_timer_add_timer(frw_timeout_stru * timeout)136 hi_void frw_timer_add_timer(frw_timeout_stru *timeout)
137 {
138 if (timeout == HI_NULL) {
139 oam_error_log0(0, OAM_SF_FRW, "{frw_timer_add_timer:: pst_timeout == HI_NULL}");
140 return;
141 }
142 hi_list_tail_insert(&timeout->entry, &g_ast_timer_list);
143 }
144
frw_timer_create_timer(frw_timeout_stru * timeout,frw_timeout_func timeout_func,hi_u32 timeoutval,hi_void * timeout_arg,hi_u8 is_periodic)145 hi_void frw_timer_create_timer(frw_timeout_stru *timeout, frw_timeout_func timeout_func,
146 hi_u32 timeoutval, hi_void *timeout_arg, hi_u8 is_periodic)
147 {
148 if (timeout == HI_NULL) {
149 oam_error_log0(0, OAM_SF_FRW, "{frw_timer_create_timer:: HI_NULL == pst_timeout}");
150 return;
151 }
152
153 oal_spin_lock_bh(&g_ast_timer_list_spinlock);
154
155 timeout->func = timeout_func;
156 timeout->timeout_arg = timeout_arg;
157 timeout->timeout = timeoutval;
158 timeout->is_periodic = is_periodic;
159 timeout->is_enabled = HI_TRUE; /* 默认使能 */
160 timeout->is_deleting = HI_FALSE;
161
162 if (timeout->is_registerd != HI_TRUE) {
163 timeout->timer_id = g_timer_id++; /* timer id用于标识定时器的唯一性 */
164 oal_timer_init(&timeout->timer, timeoutval, frw_timer_timeout_proc_event, (unsigned long)timeout->timer_id);
165 oal_timer_add(&timeout->timer);
166 } else {
167 oal_timer_start(&timeout->timer, (unsigned long)timeout->timeout);
168 }
169
170 if (timeout->is_registerd != HI_TRUE) {
171 timeout->is_running = HI_FALSE;
172 timeout->is_registerd = HI_TRUE;
173 frw_timer_add_timer(timeout);
174 }
175 oal_spin_unlock_bh(&g_ast_timer_list_spinlock);
176 return;
177 }
178
179 #ifdef _PRE_HDF_LINUX
frw_timer_timeout_proc_event(oal_timer_list_stru * arg)180 hi_void frw_timer_timeout_proc_event(oal_timer_list_stru *arg)
181 {
182 frw_timeout_stru *timeout = NULL;
183 #else
184 hi_void frw_timer_timeout_proc_event(unsigned long arg)
185 {
186 #endif
187 frw_event_mem_stru *event_mem;
188 frw_event_stru *event = HI_NULL;
189
190 event_mem = frw_event_alloc(sizeof(frw_event_stru));
191 /* 返回值检查 */
192 if (oal_unlikely(event_mem == HI_NULL)) {
193 oam_error_log0(0, OAM_SF_FRW, "{frw_timer_timeout_proc_event:: FRW_EVENT_ALLOC failed!}");
194 return;
195 }
196 event = (frw_event_stru *)event_mem->puc_data;
197 /* 填充事件头 */
198 frw_field_setup((&event->event_hdr), type, (FRW_EVENT_TYPE_TIMEOUT));
199 frw_field_setup((&event->event_hdr), sub_type, (FRW_TIMEOUT_TIMER_EVENT));
200 frw_field_setup((&event->event_hdr), us_length, (WLAN_MEM_EVENT_SIZE1));
201 frw_field_setup((&event->event_hdr), pipeline, (FRW_EVENT_PIPELINE_STAGE_0));
202 frw_field_setup((&event->event_hdr), vap_id, (0));
203 #ifdef _PRE_HDF_LINUX
204 timeout = CONTAINER_OF(arg, frw_timeout_stru, timer);
205 *(hi_u32 *)event->auc_event_data = timeout->timer_id;
206 #else
207 *(hi_u32 *)event->auc_event_data = (hi_u32)arg;
208 #endif
209
210 /* 抛事件 */
211 frw_event_dispatch_event(event_mem);
212 frw_event_free(event_mem);
213 }
214
215 hi_void frw_timer_immediate_destroy_timer(frw_timeout_stru *timeout)
216 {
217 if (timeout == HI_NULL) {
218 oam_error_log0(0, OAM_SF_FRW, "{frw_timer_immediate_destroy_timer:: HI_NULL == pst_timeout}");
219 return;
220 }
221
222 /* 如果定时器未注册,则直接返回 */
223 if (timeout->is_registerd == HI_FALSE) {
224 return;
225 }
226 timeout->is_enabled = HI_FALSE;
227 timeout->is_registerd = HI_FALSE;
228 timeout->is_deleting = HI_FALSE;
229 hi_s32 ret = oal_timer_delete(&timeout->timer);
230 if (ret != 0 && ret != 1) { /* 非激活计时器的del_timer()返回0,激活计时器返回1 */
231 oam_error_log1(0, OAM_SF_FRW, "{frw_timer_immediate_destroy_timer:: fail ret = %d}", ret);
232 }
233
234 oal_spin_lock_bh(&g_ast_timer_list_spinlock);
235 hi_list_delete(&timeout->entry);
236 oal_spin_unlock_bh(&g_ast_timer_list_spinlock);
237 }
238
239 hi_void frw_timer_restart_timer(frw_timeout_stru *timeout, hi_u32 timeoutval, hi_u8 is_periodic)
240 {
241 if (timeout == HI_NULL) {
242 oam_error_log0(0, OAM_SF_FRW, "{frw_timer_restart_timer:: HI_NULL == pst_timeout}");
243 return;
244 }
245
246 if (timeout->is_registerd == HI_FALSE) {
247 return;
248 }
249 timeout->timeout = timeoutval;
250 timeout->is_enabled = HI_TRUE;
251 timeout->is_periodic = is_periodic;
252 timeout->is_deleting = HI_FALSE;
253 hi_u32 ret = (hi_u32)oal_timer_start(&timeout->timer, (unsigned long)timeout->timeout);
254 if (ret != 0 && ret != 1) { /* 非激活计时器的mod_timer()返回0,激活计时器返回1 */
255 oam_error_log1(0, OAM_SF_FRW, "{frw_timer_immediate_destroy_timer:: fail ret = %d}", ret);
256 }
257 }
258
259 /* 功能描述:停止定时器 */
260 hi_void frw_timer_stop_timer(frw_timeout_stru *timeout)
261 {
262 if (timeout == HI_NULL) {
263 oam_error_log0(0, OAM_SF_FRW, "{frw_timer_stop_timer:: HI_NULL == pst_timeout}");
264 return;
265 }
266 if (timeout->is_registerd == HI_FALSE || timeout->is_enabled == HI_FALSE) {
267 return;
268 }
269 timeout->is_enabled = HI_FALSE;
270 }
271
272 #ifdef __cplusplus
273 #if __cplusplus
274 }
275 #endif
276 #endif
277