• 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   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