• 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 "oal_ext_if.h"
23 #include "hmac_ext_if.h"
24 #include "wal_event_msg.h"
25 #include "wal_main.h"
26 
27 #ifdef __cplusplus
28 #if __cplusplus
29 extern "C" {
30 #endif
31 #endif
32 
33 /* ****************************************************************************
34   2 全局变量定义
35 **************************************************************************** */
36 static wal_msg_queue g_wal_wid_msg_queue;
37 
38 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
39 hi_atomic g_wal_config_seq_num = hi_atomic_init(0);
40 #elif (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
41 hi_atomic g_wal_config_seq_num = hi_atomic_init(0);
42 #else
43 hi_atomic g_wal_config_seq_num = 0;
44 #endif
45 /* 获取msg序列号宏 */
46 #define wal_get_msg_sn() (hi_atomic_inc_return(&g_wal_config_seq_num))
47 
48 /* ****************************************************************************
49   3 函数实现
50 **************************************************************************** */
51 /* ****************************************************************************
52  函 数 名  : wal_msg_queue_init
53  功能描述  : init the wid response queue
54  输入参数  :
55  输出参数  :
56  返 回 值  :
57  调用函数  :
58  被调函数  :
59 
60  修改历史      :
61   1.日    期   : 2015年11月10日
62     作    者   : HiSilicon
63     修改内容   : 新生成函数
64 
65 **************************************************************************** */
wal_msg_queue_init(hi_void)66 hi_void wal_msg_queue_init(hi_void)
67 {
68     if (memset_s((hi_void *)&g_wal_wid_msg_queue, sizeof(g_wal_wid_msg_queue), 0, sizeof(g_wal_wid_msg_queue)) != EOK) {
69         oam_error_log0(0, 0, "{wal_msg_queue_init::mem safe func err!}");
70         return;
71     }
72     oal_spin_lock_init(&g_wal_wid_msg_queue.st_lock);
73     hi_list_init(&g_wal_wid_msg_queue.head);
74     g_wal_wid_msg_queue.count = 0;
75     hi_wait_queue_init_head(&g_wal_wid_msg_queue.wait_queue);
76 }
77 
_wal_msg_request_add_queue_(wal_msg_request_stru * msg)78 static hi_void _wal_msg_request_add_queue_(wal_msg_request_stru *msg)
79 {
80     hi_list_head_insert_optimize(&msg->entry, &g_wal_wid_msg_queue.head);
81     g_wal_wid_msg_queue.count++;
82 }
83 
wal_check_and_release_msg_resp(wal_msg_stru * rsp_msg)84 hi_u32 wal_check_and_release_msg_resp(wal_msg_stru *rsp_msg)
85 {
86     wal_msg_write_rsp_stru *write_rsp_msg = HI_NULL;
87     if (rsp_msg != HI_NULL) {
88         hi_u32 err_code;
89         wlan_cfgid_enum_uint16 wid;
90         write_rsp_msg = (wal_msg_write_rsp_stru *)(rsp_msg->auc_msg_data);
91         err_code = write_rsp_msg->err_code;
92         wid = write_rsp_msg->wid;
93 
94         oal_free(rsp_msg);
95 
96         if (err_code != HI_SUCCESS) {
97             oam_warning_log2(0, OAM_SF_SCAN, "{wal_check_and_release_msg_resp::detect err code:[%u],wid:[%u]}",
98                 err_code, wid);
99             return err_code;
100         }
101     }
102 
103     return HI_SUCCESS;
104 }
105 
106 /* ****************************************************************************
107  函 数 名  : wal_msg_request_add_queue
108  功能描述  : add the request message into queue
109  输入参数  : wal_msg_request_stru* pst_msg
110  输出参数  :
111  返 回 值  :
112  调用函数  :
113  被调函数  :
114 
115  修改历史      :
116   1.日    期   : 2015年11月10日
117     作    者   : HiSilicon
118     修改内容   : 新生成函数
119 
120 **************************************************************************** */
wal_msg_request_add_queue(wal_msg_request_stru * msg)121 hi_void wal_msg_request_add_queue(wal_msg_request_stru *msg)
122 {
123     oal_spin_lock_bh(&g_wal_wid_msg_queue.st_lock);
124     _wal_msg_request_add_queue_(msg);
125     oal_spin_unlock_bh(&g_wal_wid_msg_queue.st_lock);
126 }
127 
_wal_msg_request_remove_queue_(wal_msg_request_stru * msg)128 static hi_void _wal_msg_request_remove_queue_(wal_msg_request_stru *msg)
129 {
130     g_wal_wid_msg_queue.count--;
131     hi_list_delete_optimize(&msg->entry);
132 }
133 
134 /* ****************************************************************************
135  函 数 名  : wal_msg_request_remove_queue
136  功能描述  : remove the request message into queue
137  输入参数  : wal_msg_request_stru* pst_msg
138  输出参数  :
139  返 回 值  :
140  调用函数  :
141  被调函数  :
142 
143  修改历史      :
144   1.日    期   : 2015年11月10日
145     作    者   : HiSilicon
146     修改内容   : 新生成函数
147 
148 **************************************************************************** */
wal_msg_request_remove_queue(wal_msg_request_stru * msg)149 hi_void wal_msg_request_remove_queue(wal_msg_request_stru *msg)
150 {
151     oal_spin_lock_bh(&g_wal_wid_msg_queue.st_lock);
152     _wal_msg_request_remove_queue_(msg);
153     oal_spin_unlock_bh(&g_wal_wid_msg_queue.st_lock);
154 }
155 
156 /* ****************************************************************************
157  函 数 名  : wal_set_msg_response_by_addr
158  功能描述  : set the request message response by the request message's address, the address is only
159  输入参数  : wal_msg_request_stru* pst_msg
160  输出参数  :
161  返 回 值  :
162  调用函数  :
163  被调函数  :
164 
165  修改历史      :
166   1.日    期   : 2015年11月10日
167     作    者   : HiSilicon
168     修改内容   : 新生成函数
169 
170 **************************************************************************** */
wal_set_msg_response_by_addr(hi_u32 addr,hi_u8 * resp_mem,hi_u32 resp_ret,hi_u32 rsp_len)171 hi_u32 wal_set_msg_response_by_addr(hi_u32 addr, hi_u8 *resp_mem, hi_u32 resp_ret, hi_u32 rsp_len)
172 {
173     hi_u32 ret = HI_FAIL;
174     hi_list *pos = HI_NULL;
175     hi_list *entry_temp = HI_NULL;
176     wal_msg_request_stru *request = HI_NULL;
177 
178     oal_spin_lock_bh(&g_wal_wid_msg_queue.st_lock);
179 
180     hi_list_for_each_safe(pos, entry_temp, (&g_wal_wid_msg_queue.head)) {
181         request = (wal_msg_request_stru *)hi_list_entry(pos, wal_msg_request_stru, entry);
182         if (request->request_address == (hi_u32)addr) {
183             /* address match */
184             if (oal_unlikely(request->resp_mem != NULL)) {
185                 oam_error_log0(0, OAM_SF_ANY,
186                     "{wal_set_msg_response_by_addr::wal_set_msg_response_by_addr response had been set!");
187             }
188             request->resp_mem = resp_mem;
189             request->ret = resp_ret;
190             request->resp_len = rsp_len;
191             ret = HI_SUCCESS;
192             break;
193         }
194     }
195 
196     oal_spin_unlock_bh(&g_wal_wid_msg_queue.st_lock);
197 
198     return ret;
199 }
200 
201 /* ****************************************************************************
202  函 数 名  : wal_alloc_cfg_event
203  功能描述  : WAL申请事件,并填充事件头
204  输入参数  : pst_net_dev: net_device
205  输出参数  : ppst_event_mem: 指向事件内存
206              ppst_cfg_priv : 指向私有配置结构
207              ppst_cfg_msg  : 指向配置消息
208  返 回 值  : 错误码
209  调用函数  :
210  被调函数  :
211 
212  修改历史      :
213   1.日    期   : 2013年1月17日
214     作    者   : HiSilicon
215     修改内容   : 新生成函数
216 
217 **************************************************************************** */
wal_alloc_cfg_event(oal_net_device_stru * netdev,frw_event_mem_stru ** event_mem,hi_void * resp_addr,wal_msg_stru ** cfg_msg,hi_u16 us_len)218 hi_u32 wal_alloc_cfg_event(oal_net_device_stru *netdev, frw_event_mem_stru **event_mem, hi_void *resp_addr,
219     wal_msg_stru **cfg_msg, hi_u16 us_len)
220 {
221     mac_vap_stru               *mac_vap = HI_NULL;
222     frw_event_mem_stru         *event_mem_info = HI_NULL;
223     frw_event_stru             *event = HI_NULL;
224     hi_u16                  us_resp_len = 0;
225 
226     wal_msg_rep_hdr *rep_hdr = NULL;
227 
228     mac_vap = oal_net_dev_priv(netdev);
229     if (oal_unlikely(mac_vap == HI_NULL)) {
230         /* 规避wifi关闭状态下,下发hipriv命令显示error日志 */
231         oam_warning_log1(0, OAM_SF_ANY,
232             "{wal_alloc_cfg_event::oal_net_dev_priv(pst_net_dev) is null ptr! pst_net_dev=[%p]}", (uintptr_t)netdev);
233         return HI_ERR_CODE_PTR_NULL;
234     }
235 
236     us_resp_len += sizeof(wal_msg_rep_hdr);
237     us_len += us_resp_len;
238     event_mem_info = frw_event_alloc(us_len);
239     if (oal_unlikely(event_mem_info == HI_NULL)) {
240         oam_error_log2(mac_vap->vap_id, OAM_SF_ANY,
241             "{wal_alloc_cfg_event::event_mem null ptr error,request size:us_len:%d,resp_len:%d}", us_len, us_resp_len);
242         return HI_ERR_CODE_PTR_NULL;
243     }
244 
245     *event_mem = event_mem_info; /* 出参赋值 */
246     event = (frw_event_stru *)event_mem_info->puc_data;
247     /* 填写事件头 */
248     frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_HOST_CRX, WAL_HOST_CRX_SUBTYPE_CFG, us_len,
249         FRW_EVENT_PIPELINE_STAGE_0, mac_vap->vap_id);
250 
251     /* fill the resp hdr */
252     rep_hdr = (wal_msg_rep_hdr *)event->auc_event_data;
253     if (resp_addr == NULL) {
254         /* no response */
255         rep_hdr->request_address = (uintptr_t)0;
256     } else {
257         /* need response */
258         rep_hdr->request_address = (uintptr_t)resp_addr;
259     }
260 
261     *cfg_msg = (wal_msg_stru *)((hi_u8 *)event->auc_event_data + us_resp_len); /* 出参赋值 */
262 
263     return HI_SUCCESS;
264 }
265 
266 /* ****************************************************************************
267  函 数 名  : wal_request_wait_event_condition
268  功能描述  : 判断wal response 完成条件是否满足
269  输入参数  : wal_msg_request_stru *pst_msg_stru
270 
271  输出参数  :
272  返 回 值  : 错误码
273  调用函数  :
274  被调函数  :
275 
276  修改历史      :
277   1.日    期   : 2015年11月10日
278     作    者   : HiSilicon
279     修改内容   : 新生成函数
280 
281 **************************************************************************** */
wal_request_wait_event_condition(const wal_msg_request_stru * msg_stru)282 static inline hi_u32 wal_request_wait_event_condition(const wal_msg_request_stru *msg_stru)
283 {
284     hi_u32 l_ret = HI_FALSE;
285 
286     oal_spin_lock_bh(&g_wal_wid_msg_queue.st_lock);
287     if ((msg_stru->resp_mem != NULL) || (msg_stru->ret != HI_SUCCESS)) {
288         l_ret = HI_TRUE;
289     }
290     oal_spin_unlock_bh(&g_wal_wid_msg_queue.st_lock);
291 
292     return l_ret;
293 }
294 
wal_cfg_msg_task_sched(hi_void)295 hi_void wal_cfg_msg_task_sched(hi_void)
296 {
297     hi_wait_queue_wake_up(&g_wal_wid_msg_queue.wait_queue);
298 }
299 
wal_send_cfg_wait_event(wal_msg_stru ** rsp_msg,wal_msg_request_stru * msg_request)300 hi_u32 wal_send_cfg_wait_event(wal_msg_stru **rsp_msg, wal_msg_request_stru *msg_request)
301 {
302     /* **************************************************************************
303         等待事件返回
304     ************************************************************************** */
305     wal_wake_lock();
306 
307     /* info, boolean argument to function */ /* 使用非wifi目录定义宏函数,误报告警,lin_t e26告警屏蔽 */
308     hi_u32 wal_ret = (hi_u32)hi_wait_event_timeout(g_wal_wid_msg_queue.wait_queue,
309         HI_TRUE == wal_request_wait_event_condition(msg_request), (10 * HZ)); /* 10 频率 */
310     /* response had been set, remove it from the list */
311     wal_msg_request_remove_queue(msg_request);
312 
313     if (oal_warn_on(wal_ret == 0)) {
314         /* 超时 */
315         oam_warning_log2(0, OAM_SF_ANY, "[E]timeout,request ret=%d,addr:0x%lx\n", msg_request->ret,
316             msg_request->request_address);
317         if (msg_request->resp_mem != HI_NULL) {
318             oal_free(msg_request->resp_mem);
319             msg_request->resp_mem = HI_NULL;
320         }
321         wal_wake_unlock();
322         return HI_FAIL;
323     }
324 
325     wal_msg_stru *rsp_msg_info = (wal_msg_stru *)(msg_request->resp_mem);
326     if (rsp_msg_info == HI_NULL) {
327         oam_warning_log0(0, OAM_SF_ANY, "{wal_send_cfg_event:: msg mem null!}");
328         /* 上面由need_rsp非空,来保证这儿rsp_msg非空,误报告警,lin_t e613告警屏蔽 */
329         *rsp_msg = HI_NULL;
330 
331         wal_wake_unlock();
332         return HI_FAIL;
333     }
334 
335     if (rsp_msg_info->msg_hdr.us_msg_len == 0) {
336         oam_warning_log0(0, OAM_SF_ANY, "{wal_send_cfg_event:: no msg resp!}");
337         /* 上面由need_rsp非空,来保证这儿rsp_msg非空,误报告警,lin_t e613告警屏蔽 */
338         *rsp_msg = HI_NULL;
339 
340         oal_free(rsp_msg_info);
341 
342         wal_wake_unlock();
343         return HI_FAIL;
344     }
345     /* 发送配置事件返回的状态信息 */
346     /* 上面由need_rsp非空,来保证这儿rsp_msg非空,误报告警,lin_t e613告警屏蔽 */
347     *rsp_msg = rsp_msg_info;
348 
349     wal_wake_unlock();
350     return HI_SUCCESS;
351 }
352 
353 /* ****************************************************************************
354  函 数 名  : wal_send_cfg_event
355  功能描述  : WAL发送事件
356  输入参数  : pst_net_dev: net_device
357              en_msg_type: 消息类型
358              uc_len:      消息长度
359              puc_param:   消息地址
360              en_need_rsp: 是否需要返回消息处理: HI_TRUE-是; HI_FALSE-否
361 
362  输出参数  : ppst_rsp_msg 二级指针,返回的response 动态内存需要用free释放!
363  返 回 值  : 错误码
364  调用函数  :
365  被调函数  :
366 
367  修改历史      :
368   1.日    期   : 2013年6月6日
369     作    者   : HiSilicon
370     修改内容   : 新生成函数
371 
372 **************************************************************************** */
wal_send_cfg_event(oal_net_device_stru * netdev,wal_msg_type_enum_uint8 msg_type,hi_u16 us_len,const hi_u8 * puc_param,hi_u8 need_rsp,wal_msg_stru ** rsp_msg)373 hi_u32 wal_send_cfg_event(oal_net_device_stru *netdev, wal_msg_type_enum_uint8 msg_type, hi_u16 us_len,
374     const hi_u8 *puc_param, hi_u8 need_rsp, wal_msg_stru **rsp_msg)
375 {
376     wal_msg_stru                *cfg_msg = HI_NULL;
377     frw_event_mem_stru          *event_mem = HI_NULL;
378     wal_msg_request_stru         msg_request;
379 
380     /* 规则6.6:禁止使用内存操作类危险函数 例外(1)对固定长度的数组进行初始化,或对固定长度的结构体进行内存初始化 */
381     memset_s((&msg_request), sizeof(msg_request), 0, sizeof(msg_request));
382     msg_request.request_address = (uintptr_t)&msg_request;
383 
384     if (rsp_msg != NULL) {
385         *rsp_msg = NULL;
386     }
387 
388     if (oal_warn_on((need_rsp == HI_TRUE) && (rsp_msg == HI_NULL))) {
389         oam_error_log0(0, OAM_SF_ANY, "{wal_send_cfg_event::HI_NULL == ppst_rsp_msg!}\r\n");
390         return HI_FAIL;
391     }
392     /* 申请事件 */
393     if (oal_unlikely(wal_alloc_cfg_event(netdev, &event_mem, ((need_rsp == HI_TRUE) ? &msg_request : NULL), &cfg_msg,
394         WAL_MSG_WRITE_MSG_HDR_LENGTH + us_len) != HI_SUCCESS)) {
395         oam_warning_log0(0, OAM_SF_ANY, "{wal_send_cfg_event::wal_alloc_cfg_event return err!}\r\n");
396         return HI_ERR_CODE_PTR_NULL;
397     }
398 
399     /* 填写配置消息 */
400     wal_cfg_msg_hdr_init(&(cfg_msg->msg_hdr), msg_type, us_len, (hi_u8)wal_get_msg_sn());
401     /* 填写WID消息 */
402     if (puc_param != HI_NULL) {
403         /* cfg_msg->auc_msg_data, 可变数组,cfg_msg->auc_msg_data长度已经申请us_len */
404         if (memcpy_s(cfg_msg->auc_msg_data, us_len, puc_param, us_len) != EOK) {
405             oam_error_log0(0, OAM_SF_ANY, "{wal_send_cfg_event::mem safe function err!}");
406             frw_event_free(event_mem);
407             return HI_FAIL;
408         }
409     }
410     if (need_rsp == HI_TRUE) {
411         /* add queue before post event! */
412         wal_msg_request_add_queue(&msg_request);
413     }
414     /* 分发事件 */
415     frw_event_dispatch_event(event_mem);
416     frw_event_free(event_mem);
417 
418     if (need_rsp != HI_TRUE) {
419         return HI_SUCCESS;
420     }
421 
422     /* context can't in interrupt */
423     if (oal_warn_on(oal_in_interrupt())) {
424         oam_error_log0(0, OAM_SF_ANY, "oal_in_interrupt");
425     }
426 
427     return wal_send_cfg_wait_event(rsp_msg, &msg_request);
428 }
429 
430 #ifdef __cplusplus
431 #if __cplusplus
432 }
433 #endif
434 #endif
435