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