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 "hcc_slave.h"
23 #include "oal_net.h"
24 #include "oal_util.h"
25 #include "oal_mem.h"
26 #include "hcc_comm.h"
27 #include "hcc_task.h"
28
29 #ifdef __cplusplus
30 #if __cplusplus
31 extern "C" {
32 #endif
33 #endif
34
35 /* ****************************************************************************
36 1 全局变量定义
37 **************************************************************************** */
38 #define HCC_FRW_EVENT_SIZE WLAN_MEM_EVENT_SIZE1
39 #define SHIF_8_BIT 8
40 #define SHIF_16_BIT 16
41 #define SHIF_24_BIT 24
42
43 voidfuncptr g_pm_wlan_forceslp_msg_proc = HI_NULL;
44 oal_dev_netbuf_stru *g_reserve_netbuff = HI_NULL; /* 用于内存申请不到时的备用内存 */
45 oal_dev_netbuf_head_stru g_hcc_tx_queue;
46 oal_dev_netbuf_head_stru g_hcc_rx_queue;
47 volatile hi_u8 g_sdio_init_ok = HI_FALSE;
48 struct hcc_handler g_hcc_slave_handler;
49
50 typedef hi_void (*hcc_descr_ctrl_func)(hi_void *data);
51 hcc_descr_ctrl_func g_descr_control_func[HCC_DESCR_TYPE_BUTT];
52 hcc_netbuf_queue_type g_current_queue_type = HCC_NETBUF_NORMAL_QUEUE;
53
54 hi_u32 g_hcc_panic_flag = 0;
55 hi_u16 g_used_mem_forstop = 20;
56 hi_u16 g_used_mem_forstart = 40;
57 hi_u32 g_flow_ctrl_reg_info = 0x0;
58 hi_u32 g_max_adma_descr_pkt_len = 0;
59 hi_u8 g_flowctrl_flashed = HI_FALSE;
60 hcc_msg_cb g_process_msg_callback = NULL;
61
62 volatile hcc_slave_tx_info g_tx_aggr_info = { 0 };
63 volatile hcc_slave_rx_info g_rx_aggr_info = { 0 };
64 hi_u32 g_flowctrl_pending = 0; /* 1 means pending, 0 means no pending */
65 hi_u8 g_h2d_assem_descr[HISDIO_HOST2DEV_SCATT_SIZE]; /* Used to receive the first assem info descr. */
66 hi_u8 g_thruput_bypass_enable[HCC_THRUPUT_BYPASS_BUTT] = {0};
67
68 hi_u8 g_sdio_txpkt_index = 0; /* 发送帧序号 */
69
70 /* HOST下发数据过程标志,SDIO_RX_BUSY表示正在传输,SDIO_RX_IDLE表示传输结束 */
71 hi_u8 g_chan_write_flag = CHAN_RX_IDLE;
72 hi_u32 g_d2h_hcc_assemble_count = HISDIO_DEV2HOST_SCATT_MAX;
73
74
75 /* ****************************************************************************
76 2 函数实现
77 **************************************************************************** */
hcc_get_default_handler(hi_void)78 struct hcc_handler *hcc_get_default_handler(hi_void)
79 {
80 return &g_hcc_slave_handler;
81 }
82
hcc_get_thruput_bypass_enable(hcc_thruput_bypass bypass_type)83 hi_u8 hcc_get_thruput_bypass_enable(hcc_thruput_bypass bypass_type)
84 {
85 if (bypass_type >= HCC_THRUPUT_BYPASS_BUTT) {
86 return 0;
87 }
88 return g_thruput_bypass_enable[bypass_type];
89 }
90
hcc_set_thruput_bypass_enable(hcc_thruput_bypass bypass_type,hi_u8 value)91 hi_void hcc_set_thruput_bypass_enable(hcc_thruput_bypass bypass_type, hi_u8 value)
92 {
93 if (bypass_type >= HCC_THRUPUT_BYPASS_BUTT) {
94 return;
95 }
96
97 g_thruput_bypass_enable[bypass_type] = value;
98 }
99
100 /* ****************************************************************************
101 功能描述 : 获取hcc TCM头得扩展区有效数据首地址
102
103 修改历史 :
104 1.日 期 : 2019-05-30
105 作 者 : HiSilicon
106 修改内容 : 新生成函数
107 **************************************************************************** */
hcc_get_extend_payload_addr(const oal_dev_netbuf_stru * dev_netbuf)108 hi_u8 *hcc_get_extend_payload_addr(const oal_dev_netbuf_stru *dev_netbuf)
109 {
110 hi_u8 *hdr = HI_NULL;
111 hcc_header_stru *hcc_hdr = HI_NULL;
112
113 /* Device侧Netbuf 头/体分离,扩展区默认从高向低地址扩展! */
114 hdr = oal_dev_netbuf_hcchdr(dev_netbuf);
115 if (hdr == HI_NULL) {
116 return HI_NULL;
117 }
118 hcc_hdr = (hcc_header_stru *)hdr;
119 hdr += HCC_HDR_LEN;
120 hdr += hcc_hdr->pad_hdr;
121 if (hcc_hdr->pad_hdr > HCC_HDR_RESERVED_MAX_LEN) {
122 return HI_NULL;
123 }
124 return hdr;
125 }
126
127 /* ****************************************************************************
128 功能描述 : 获取hcc TCM头得扩展区首地址
129
130 修改历史 :
131 1.日 期 : 2019-05-30
132 作 者 : HiSilicon
133 修改内容 : 新生成函数
134 **************************************************************************** */
hcc_get_extend_addr(const oal_dev_netbuf_stru * dev_netbuf,hi_u32 extend_len)135 hi_u8 *hcc_get_extend_addr(const oal_dev_netbuf_stru *dev_netbuf, hi_u32 extend_len)
136 {
137 hi_u8 *hdr = HI_NULL;
138 /* Device侧Netbuf 头/体分离,扩展区默认从高向低地址扩展! */
139 if (extend_len > (hi_u32)HCC_HDR_RESERVED_MAX_LEN) {
140 return HI_NULL;
141 }
142
143 hdr = oal_dev_netbuf_hcchdr(dev_netbuf);
144 hdr += HCC_HDR_LEN;
145 hdr += HCC_HDR_RESERVED_MAX_LEN - extend_len;
146 return hdr;
147 }
148
hcc_delay_bug_on_detect(hi_void)149 hi_void hcc_delay_bug_on_detect(hi_void)
150 {
151 if (g_hcc_panic_flag != 0) {
152 g_hcc_panic_flag = 0;
153 hi_diag_log_msg_e0(0, "hcc panic detected.\n");
154 }
155 }
156
157 #undef CONFIG_HCC_NETBUF_LIST_REPEAT_CHECK
158 #ifdef CONFIG_HCC_NETBUF_LIST_REPEAT_CHECK
hcc_netbuf_list_repeat_check(oal_dev_netbuf_stru * dev_netbuf,oal_dev_netbuf_head_stru * head)159 hi_u32 hcc_netbuf_list_repeat_check(oal_dev_netbuf_stru *dev_netbuf, oal_dev_netbuf_head_stru *head)
160 {
161 hi_u32 status;
162 oal_dev_netbuf_stru *dev_netbuf_temp = HI_NULL;
163
164 status = hi_int_lock();
165 dev_netbuf_temp = head->next;
166 while ((hi_u32)dev_netbuf_temp != (hi_u32)head) {
167 if (dev_netbuf_temp == dev_netbuf) {
168 hi_int_restore(status);
169 return HI_FALSE;
170 }
171 dev_netbuf_temp = dev_netbuf_temp->next;
172 }
173
174 hi_int_restore(status);
175 return HI_TRUE;
176 }
177 #endif
178
hcc_netbuf_add_to_list_tail(oal_dev_netbuf_stru * dev_netbuf,oal_dev_netbuf_head_stru * head)179 hi_void hcc_netbuf_add_to_list_tail(oal_dev_netbuf_stru *dev_netbuf, oal_dev_netbuf_head_stru *head)
180 {
181 hi_u32 status;
182
183 #ifdef CONFIG_HCC_NETBUF_LIST_REPEAT_CHECK
184 if (hcc_netbuf_list_repeat_check(dev_netbuf, head) != HI_TRUE) {
185 return;
186 }
187 #endif
188
189 status = hi_int_lock();
190 head->prev->next = dev_netbuf;
191 dev_netbuf->next = (oal_dev_netbuf_stru *)head;
192 head->prev = dev_netbuf;
193 head->num++;
194 hi_int_restore(status);
195 }
196
hcc_netbuf_delist(oal_dev_netbuf_head_stru * head)197 oal_dev_netbuf_stru *hcc_netbuf_delist(oal_dev_netbuf_head_stru *head)
198 {
199 hi_u32 status;
200 oal_dev_netbuf_stru *dev_netbuf = HI_NULL;
201
202 status = hi_int_lock();
203 if (head->num == 0) {
204 hi_int_restore(status);
205 return HI_NULL;
206 }
207
208 if ((uintptr_t)head->prev == (uintptr_t)head) {
209 hi_int_restore(status);
210 return HI_NULL;
211 }
212
213 dev_netbuf = head->next;
214 if (head->num == 1) {
215 /* one node */
216 head->prev = (oal_dev_netbuf_stru *)head;
217 }
218 head->next = (oal_dev_netbuf_stru *)head->next->next;
219
220 head->num--;
221 hi_int_restore(status);
222 return dev_netbuf;
223 }
224
hcc_slave_get_netbuf_align_len(const oal_dev_netbuf_stru * dev_netbuf,hi_u32 align_size)225 hi_u32 hcc_slave_get_netbuf_align_len(const oal_dev_netbuf_stru *dev_netbuf, hi_u32 align_size)
226 {
227 hi_u32 send_len;
228 hi_u32 total_len;
229
230 hcc_header_stru *hcc_hdr = (hcc_header_stru *)oal_dev_netbuf_hcchdr(dev_netbuf);
231 if (hcc_hdr == HI_NULL) {
232 hi_diag_log_msg_e0(0, "{hcc_slave_get_netbuf_align_len::hcc_hdr null.}");
233 return 0;
234 }
235 total_len = hcc_hdr->pay_len + HCC_HDR_TOTAL_LEN;
236
237 send_len = hi_byte_align(total_len, align_size);
238 return send_len;
239 }
240
hcc_slave_build_header(const oal_dev_netbuf_stru * dev_netbuf,hi_u16 pay_load_len,const hcc_transfer_param * param)241 hi_void hcc_slave_build_header(const oal_dev_netbuf_stru *dev_netbuf, hi_u16 pay_load_len,
242 const hcc_transfer_param *param)
243 {
244 hcc_header_stru *hcc_hdr = HI_NULL;
245
246 if ((dev_netbuf == HI_NULL) || (param == HI_NULL)) {
247 hi_diag_log_msg_e0(0, "{hcc_slave_build_header:: net_buf/param null.}");
248 return;
249 }
250
251 /* build hcc header */
252 hcc_hdr = (hcc_header_stru *)oal_dev_netbuf_hcchdr(dev_netbuf);
253 if (hcc_hdr == HI_NULL) {
254 hi_diag_log_msg_e0(0, "{hcc_slave_build_header:: hcc_hdr null.}");
255 return;
256 }
257 hcc_hdr->main_type = param->main_type;
258 hcc_hdr->sub_type = param->sub_type;
259 hcc_hdr->pay_len = pay_load_len;
260 hcc_hdr->seq = g_sdio_txpkt_index++;
261 hcc_hdr->pad_hdr = HCC_HDR_RESERVED_MAX_LEN - param->extend_len;
262 hcc_hdr->pad_payload = 0; /* Device alloc netbuf's payload all 4B aligned! */
263 }
264
hcc_rx_process(oal_dev_netbuf_stru * dev_netbuf)265 hi_void hcc_rx_process(oal_dev_netbuf_stru *dev_netbuf)
266 {
267 hcc_netbuf_add_to_list_tail(dev_netbuf, &g_hcc_rx_queue);
268 /* sched the hcc rx */
269 hcc_task_sched();
270 }
271
272 /* ****************************************************************************
273 功能描述 : 发送sdio 消息 低16 bits有效
274
275 修改历史 :
276 1.日 期 : 2019-05-30
277 作 者 : HiSilicon
278 修改内容 : 新生成函数
279 **************************************************************************** */
hcc_send_msg2host(hi_u32 msg)280 hi_s32 hcc_send_msg2host(hi_u32 msg)
281 {
282 return hi_sdio_send_sync_msg(msg);
283 }
284
hcc_device2host_netbuf_multi_post_check(oal_dev_netbuf_stru * dev_netbuf,hi_s32 num)285 hi_s32 hcc_device2host_netbuf_multi_post_check(oal_dev_netbuf_stru *dev_netbuf, hi_s32 num)
286 {
287 #ifdef CONFIG_HCC_TX_MULTI_BUF_CHECK
288 hi_s32 i;
289 hi_u32 status;
290
291 status = hi_int_lock();
292 for (i = 0; i < num; i++) {
293 if (g_tx_aggr_info.hcc_tx_aggr[i].netbuf == dev_netbuf) {
294 hi_int_restore(status);
295 hi_diag_log_msg_i3(0, "[ERROR][d2h]netbuf[%d], num: %d[%p]multi post!\r\n", i, num,
296 g_tx_aggr_info.hcc_tx_aggr[i].netbuf);
297 return HI_FAIL;
298 }
299 }
300 hi_int_restore(status);
301 #else
302 hi_unref_param(dev_netbuf);
303 hi_unref_param(num);
304 #endif
305 return HI_SUCCESS;
306 }
307
308 /* ****************************************************************************
309 功能描述 : 发hcc消息到host侧,更新高优先级buffer credit值
310
311 修改历史 :
312 1.日 期 : 2019-05-30
313 作 者 : HiSilicon
314 修改内容 : 新生成函数
315 **************************************************************************** */
hcc_update_high_priority_buffer_credit(hi_u8 free_large_buffer,hi_u8 free_mgmt_buffer,hi_u8 tx_dscr_free_cnt)316 hi_void hcc_update_high_priority_buffer_credit(hi_u8 free_large_buffer, hi_u8 free_mgmt_buffer, hi_u8 tx_dscr_free_cnt)
317 {
318 hi_sdio_extendfunc *hcc_extfunc = hi_sdio_get_extend_info();
319
320 memset_s(hcc_extfunc, sizeof(hi_sdio_extendfunc), 0, sizeof(hi_sdio_extendfunc));
321 /* 8-15bit 大包free个数;16-23bit管理帧free个数 */
322 g_flow_ctrl_reg_info = ((g_flow_ctrl_reg_info & 0x000000FF) |
323 ((free_large_buffer & 0xFF) << SHIF_8_BIT) |
324 ((free_mgmt_buffer & 0xFF) << SHIF_16_BIT) |
325 ((tx_dscr_free_cnt & 0xFF) << SHIF_24_BIT));
326 if (hi_sdio_is_pending_msg(D2H_MSG_CREDIT_UPDATE) || hi_sdio_is_sending_msg(D2H_MSG_CREDIT_UPDATE)) {
327 g_flowctrl_flashed = HI_TRUE;
328 return;
329 }
330 /* 更新寄存器 */
331 hcc_extfunc->credit_info = g_flow_ctrl_reg_info;
332 hcc_extfunc->credit_isvalid = 1;
333 (hi_void)hi_sdio_write_extinfo(hcc_extfunc);
334 g_flowctrl_flashed = HI_FALSE;
335 }
336
337 /* ****************************************************************************
338 功能描述 : 从netbuf创建DMA表
339
340 修改历史 :
341 1.日 期 : 2019-05-30
342 作 者 : HiSilicon
343 修改内容 : 新生成函数
344 **************************************************************************** */
hcc_build_adma_descr_from_netbuf(hi_u8 * adma_table,hi_u32 * index,hi_u32 pkt_len,const oal_dev_netbuf_stru * dev_netbuf)345 hi_void hcc_build_adma_descr_from_netbuf(hi_u8 *adma_table, hi_u32 *index, hi_u32 pkt_len,
346 const oal_dev_netbuf_stru *dev_netbuf)
347 {
348 hi_u32 *hcc_hdr = HI_NULL;
349 hi_u32 *payload_hdr = HI_NULL;
350
351 if (dev_netbuf == HI_NULL) {
352 return;
353 }
354
355 hcc_hdr = (hi_u32 *)oal_dev_netbuf_hcchdr(dev_netbuf);
356 payload_hdr = (hi_u32 *)oal_dev_netbuf_get_payload(dev_netbuf);
357
358 /* 填写MAC头传输DMA表 */
359 if (pkt_len >= HCC_HDR_TOTAL_LEN) {
360 (hi_void)hi_sdio_set_admatable(adma_table, (*index)++, (hi_u32 *)hcc_hdr, HCC_HDR_TOTAL_LEN);
361 }
362
363 /* 填写Payload头传输DMA表 */
364 if (pkt_len > HCC_HDR_TOTAL_LEN) {
365 (hi_void)hi_sdio_set_admatable(adma_table, (*index)++, (hi_u32 *)payload_hdr, pkt_len - HCC_HDR_TOTAL_LEN);
366 }
367
368 if (g_max_adma_descr_pkt_len < pkt_len) {
369 g_max_adma_descr_pkt_len = pkt_len;
370 }
371 }
372
hcc_rx_assem_info_reset(hi_void * data)373 hi_void hcc_rx_assem_info_reset(hi_void *data)
374 {
375 hi_unref_param(data);
376 for (hi_u16 i = 0; i < g_rx_aggr_info.aggr_rx_num; i++) {
377 g_rx_aggr_info.hcc_rx_aggr[i].netbuf = HI_NULL;
378 g_rx_aggr_info.hcc_rx_aggr[i].rx_pkt_bytes = 0;
379 }
380
381 /* Reset assem info package */
382 g_rx_aggr_info.aggr_rx_num = 0;
383 g_rx_aggr_info.rx_aggr_total_len = 0;
384 }
385
hcc_rx_netbuf_queue_pri_switch(const hi_void * data)386 hi_void hcc_rx_netbuf_queue_pri_switch(const hi_void *data)
387 {
388 hcc_netbuf_queue_type queue_type = *(hcc_netbuf_queue_type *)data;
389
390 if (queue_type >= HCC_NETBUF_QUEUE_BUTT) {
391 return;
392 }
393
394 g_current_queue_type = queue_type;
395 }
396
hcc_process_single_package(hi_u32 len)397 hi_void hcc_process_single_package(hi_u32 len)
398 {
399 hi_u32 pkt_len;
400 hi_u32 remain_len;
401 hi_u32 size = len;
402 hi_u32 ret;
403 oal_dev_netbuf_stru *dev_netbuf = HI_NULL;
404
405 g_rx_aggr_info.aggr_rx_num = 1;
406 /* strip the assem info */
407 size -= HISDIO_HOST2DEV_SCATT_SIZE;
408 if (size > HCC_LONG_PACKAGE_SIZE + HCC_HDR_TOTAL_LEN) {
409 remain_len = size - HCC_LONG_PACKAGE_SIZE - HCC_HDR_TOTAL_LEN;
410 pkt_len = HCC_LONG_PACKAGE_SIZE;
411 } else {
412 remain_len = 0;
413 pkt_len = size - HCC_HDR_TOTAL_LEN;
414 }
415
416 /* single package, we think it's one pkt assembled, and if the pkt is too long,
417 the pkt must algin to 512 */
418 g_rx_aggr_info.hcc_rx_aggr[0].rx_pkt_bytes = pkt_len + HCC_HDR_TOTAL_LEN;
419
420 /* 高优先级队列调用高优先级buffer申请接口 */
421 if (g_current_queue_type == HCC_NETBUF_HIGH_QUEUE) {
422 dev_netbuf = oal_mem_dev_netbuf_alloc(OAL_NORMAL_NETBUF, (hi_u16)pkt_len, OAL_NETBUF_PRIORITY_HIGH);
423 } else {
424 dev_netbuf = oal_mem_dev_netbuf_alloc(OAL_NORMAL_NETBUF, (hi_u16)pkt_len, OAL_NETBUF_PRIORITY_MID);
425 }
426
427 if (dev_netbuf == HI_NULL) {
428 ret = hi_sdio_procmem_alloc_fail(g_current_queue_type, (hi_void**) &(g_rx_aggr_info.hcc_rx_aggr[0].netbuf),
429 (hi_void*)g_reserve_netbuff);
430 if (ret != HI_SUCCESS) {
431 return;
432 }
433 } else {
434 g_rx_aggr_info.hcc_rx_aggr[0].netbuf = dev_netbuf;
435 }
436
437 /* If single pkt too long? */
438 if (remain_len) {
439 g_rx_aggr_info.aggr_rx_num++;
440 g_rx_aggr_info.hcc_rx_aggr[1].netbuf = g_reserve_netbuff;
441 g_rx_aggr_info.hcc_rx_aggr[1].rx_pkt_bytes = remain_len;
442
443 /* 单包过长,Host有下发限制,不应该走到这里。 */
444 if (remain_len > HCC_LONG_PACKAGE_SIZE) {
445 g_hcc_panic_flag = 1;
446 hi_diag_log_msg_e1(0, "ERROR: remain_len is %d\r\n", remain_len);
447 }
448 }
449 /* Total Len Useless!TBD */
450 g_rx_aggr_info.rx_aggr_total_len = size - HISDIO_HOST2DEV_SCATT_SIZE;
451 }
452
hcc_process_multi_package(hi_void)453 hi_void hcc_process_multi_package(hi_void)
454 {
455 hi_u32 i;
456 hi_u16 rx_pkt_len = 0;
457 oal_dev_netbuf_stru *dev_netbuf = HI_NULL;
458
459 /* assem transfer, host to device */
460 for (i = 0; i < g_rx_aggr_info.aggr_rx_num; i++) {
461 if (g_rx_aggr_info.hcc_rx_aggr[i].rx_pkt_bytes <= (HCC_LONG_PACKAGE_SIZE + HCC_HDR_TOTAL_LEN)) {
462 rx_pkt_len = (hi_u16)(g_rx_aggr_info.hcc_rx_aggr[i].rx_pkt_bytes - HCC_HDR_TOTAL_LEN);
463 dev_netbuf = oal_mem_dev_netbuf_alloc(OAL_NORMAL_NETBUF, rx_pkt_len, OAL_NETBUF_PRIORITY_HIGH);
464 } else {
465 dev_netbuf = HI_NULL;
466 }
467
468 if (dev_netbuf == HI_NULL) {
469 hi_sdio_procmem_alloc_fail(g_current_queue_type,
470 (hi_void**) &(g_rx_aggr_info.hcc_rx_aggr[i].netbuf),
471 (hi_void*) g_reserve_netbuff);
472
473 /* 聚合包每包大小超过了DEVICE最大内存池的长度,预留内存接收将会踩狗牌。 */
474 if (g_rx_aggr_info.hcc_rx_aggr[i].rx_pkt_bytes > HCC_LONG_PACKAGE_SIZE + HCC_HDR_TOTAL_LEN) {
475 hi_diag_log_msg_e0(0, "rx_pkt is too large.\r\n");
476 }
477 #ifdef CONFIG_HCC_DEBUG
478 hi_diag_log_msg_i1(0, "netbuf fail,len:%d\n",
479 g_rx_aggr_info.hcc_rx_aggr[i].rx_pkt_bytes - HCC_HDR_TOTAL_LEN);
480 #endif
481 } else {
482 g_rx_aggr_info.hcc_rx_aggr[i].netbuf = dev_netbuf;
483 }
484 }
485 }
486
hcc_write_start_callback(hi_u32 len,hi_u8 * adma_table)487 hi_s32 hcc_write_start_callback(hi_u32 len, hi_u8 *adma_table)
488 {
489 hi_u32 index = 0;
490 hi_u32 pad_len = 0;
491 hi_u32 non_pad_total_len = 0;
492
493 if (len < HISDIO_HOST2DEV_SCATT_SIZE) {
494 return 0;
495 }
496
497 /* The flag protect sdio host to device transfer! */
498 g_chan_write_flag = CHAN_RX_BUSY;
499 g_rx_aggr_info.trans_len = len;
500
501 /* The frist descr fixed to assem descr! */
502 (hi_void)hi_sdio_set_admatable(adma_table, index++, (hi_u32 *)g_h2d_assem_descr, HISDIO_HOST2DEV_SCATT_SIZE);
503
504 non_pad_total_len += HISDIO_HOST2DEV_SCATT_SIZE;
505
506 if (g_rx_aggr_info.trans_len == HISDIO_HOST2DEV_SCATT_SIZE) {
507 /* when transfer just assem scatt size buff, it's control message from host! */
508 (hi_void)hi_sdio_complete_send(adma_table, index);
509 return (hi_s32)index;
510 }
511
512 if (g_rx_aggr_info.aggr_rx_num == 0) {
513 hcc_process_single_package(len);
514 } else {
515 hcc_process_multi_package();
516 }
517
518 if (g_rx_aggr_info.aggr_rx_num > HISDIO_HOST2DEV_SCATT_MAX) {
519 g_hcc_panic_flag = 1;
520 hi_diag_log_msg_e1(0, "Error: rx_num(%d) more than SCATT_MAX\r\n", g_rx_aggr_info.aggr_rx_num);
521 return 0;
522 }
523
524 for (hi_u32 i = 0; i < g_rx_aggr_info.aggr_rx_num; i++) {
525 non_pad_total_len += g_rx_aggr_info.hcc_rx_aggr[i].rx_pkt_bytes;
526 hcc_build_adma_descr_from_netbuf(adma_table,
527 &index,
528 g_rx_aggr_info.hcc_rx_aggr[i].rx_pkt_bytes,
529 g_rx_aggr_info.hcc_rx_aggr[i].netbuf);
530 }
531
532 if (non_pad_total_len < len) {
533 pad_len = len - non_pad_total_len;
534 }
535
536 if (pad_len != 0) {
537 (hi_void)hi_sdio_set_pad_admatab(pad_len, adma_table, index++);
538 }
539
540 /* IP问题需多加一行无用数据,表示表格终止 */
541 (hi_void)hi_sdio_complete_send(adma_table, index);
542
543 return (hi_s32)index;
544 }
545
hcc_write_over_aggr_package(hi_void)546 hi_void hcc_write_over_aggr_package(hi_void)
547 {
548 hi_u32 i;
549 hi_u16 pkt_len;
550 hi_u16 total_len = 0;
551 hi_u8 *h2d_assem_descr = HI_NULL;
552
553 for (i = 0; i < g_rx_aggr_info.aggr_rx_num; i++) {
554 if (((uintptr_t)g_rx_aggr_info.hcc_rx_aggr[i].netbuf != (uintptr_t)g_reserve_netbuff)) {
555 if (hcc_get_thruput_bypass_enable(HCC_TX_SDIO_SLAVE_BYPASS)) {
556 oal_mem_dev_netbuf_free(g_rx_aggr_info.hcc_rx_aggr[i].netbuf);
557 } else {
558 /* not reserved mem */
559 hcc_rx_process(g_rx_aggr_info.hcc_rx_aggr[i].netbuf);
560 }
561 }
562
563 g_rx_aggr_info.hcc_rx_aggr[i].netbuf = HI_NULL;
564 g_rx_aggr_info.hcc_rx_aggr[i].rx_pkt_bytes = 0;
565 }
566
567 /* prepare the next assem info */
568 g_rx_aggr_info.aggr_rx_num = 0;
569 g_rx_aggr_info.rx_aggr_total_len = 0;
570
571 /* assem info 64B */
572 h2d_assem_descr = (hi_u8 *)g_h2d_assem_descr;
573 for (i = 0; i < HISDIO_HOST2DEV_SCATT_MAX; i++) {
574 if (h2d_assem_descr[i] == 0) {
575 break;
576 }
577
578 pkt_len = (h2d_assem_descr[i] << HISDIO_H2D_SCATT_BUFFLEN_ALIGN_BITS);
579
580 g_rx_aggr_info.hcc_rx_aggr[i].netbuf = HI_NULL;
581 g_rx_aggr_info.hcc_rx_aggr[i].rx_pkt_bytes = pkt_len;
582 total_len += pkt_len;
583 }
584
585 g_rx_aggr_info.aggr_rx_num = i;
586 g_rx_aggr_info.rx_aggr_total_len = total_len;
587 }
588
589
hcc_write_over_callback(hi_void)590 hi_s32 hcc_write_over_callback(hi_void)
591 {
592 struct hcc_descr_header *dscr_hdr = HI_NULL;
593 hi_void *h2d_ctrl_descr = (hi_void *)g_h2d_assem_descr;
594
595 if (g_rx_aggr_info.trans_len == HISDIO_HOST2DEV_SCATT_SIZE) {
596 /* dscr control data */
597 dscr_hdr = (struct hcc_descr_header *)h2d_ctrl_descr;
598 if (dscr_hdr->descr_type < HCC_DESCR_TYPE_BUTT && g_descr_control_func[dscr_hdr->descr_type] != HI_NULL) {
599 g_descr_control_func[dscr_hdr->descr_type]((hi_u8 *)h2d_ctrl_descr + sizeof(struct hcc_descr_header));
600 }
601 } else {
602 hcc_write_over_aggr_package();
603 }
604
605 #ifdef CONFIG_HCC_DEBUG
606 hi_diag_log_msg_i2(0, "h2d: next assem num: %d, totol: %d\r\n", g_rx_aggr_info.aggr_rx_num,
607 g_rx_aggr_info.rx_aggr_total_len);
608 #endif
609 g_chan_write_flag = CHAN_RX_IDLE;
610
611 if (g_pm_wlan_forceslp_msg_proc != HI_NULL) {
612 g_pm_wlan_forceslp_msg_proc();
613 }
614 return HI_SUCCESS;
615 }
616
hcc_read_start_callback(hi_u32 len,hi_u8 * adma_table)617 hi_s32 hcc_read_start_callback(hi_u32 len, hi_u8 *adma_table)
618 {
619 hi_u32 i;
620 hi_u32 index = 0;
621 hi_u32 total_pad;
622 hi_u32 pad_len;
623 hi_unref_param(len);
624
625 if (g_tx_aggr_info.aggr_tx_num == 0) {
626 return 0;
627 }
628
629 if (g_tx_aggr_info.tx_aggr_total_len < HISDIO_BLOCK_SIZE) {
630 pad_len = hi_byte_align(g_tx_aggr_info.tx_aggr_total_len, 4); /* 4 bytes align */
631 } else {
632 pad_len = hi_byte_align(g_tx_aggr_info.tx_aggr_total_len, HISDIO_BLOCK_SIZE);
633 }
634
635 if (pad_len >= g_tx_aggr_info.tx_aggr_total_len) {
636 total_pad = pad_len - g_tx_aggr_info.tx_aggr_total_len;
637 } else {
638 total_pad = 0;
639 }
640
641 if (g_tx_aggr_info.aggr_tx_num > HISDIO_DEV2HOST_SCATT_MAX) {
642 #ifdef CONFIG_HCC_DEBUG
643 hi_diag_log_msg_i1(0, "unvaild d2h aggr num: %d\r\n", g_tx_aggr_info.aggr_tx_num);
644 #endif
645 }
646
647 for (i = 0; i < g_tx_aggr_info.aggr_tx_num; i++) {
648 if (g_tx_aggr_info.hcc_tx_aggr[i].netbuf == HI_NULL) {
649 return 0;
650 }
651
652 hcc_build_adma_descr_from_netbuf(adma_table, &index,
653 g_tx_aggr_info.hcc_tx_aggr[i].tx_pkt_bytes,
654 g_tx_aggr_info.hcc_tx_aggr[i].netbuf);
655 }
656
657 /* The padding descr */
658 if (total_pad != 0) {
659 #ifdef CONFIG_HCC_DEBUG
660 hi_diag_log_msg_i1(0, "add pad %u descr\r\n", total_pad);
661 #endif
662 (hi_void)hi_sdio_set_pad_admatab(total_pad, adma_table, index++);
663 }
664
665 /* IP问题需多加一行无用数据,表示表格终止 */
666 (hi_void)hi_sdio_complete_send(adma_table, index);
667 return (hi_s32)index;
668 }
669
hcc_read_over_callback(hi_void)670 hi_s32 hcc_read_over_callback(hi_void)
671 {
672 hi_sdio_status_info status_info;
673
674 for (hi_u32 i = 0; i < g_tx_aggr_info.aggr_tx_num; i++) {
675 oal_mem_dev_netbuf_free(g_tx_aggr_info.hcc_tx_aggr[i].netbuf);
676 g_tx_aggr_info.hcc_tx_aggr[i].netbuf = HI_NULL;
677 }
678
679 g_tx_aggr_info.tx_aggr_total_len = 0;
680 g_tx_aggr_info.aggr_tx_num = 0;
681
682 (hi_void)hi_sdio_get_status(&status_info);
683 status_info.tx_status = CHAN_TX_IDLE;
684 (hi_void)hi_sdio_set_status(&status_info);
685
686 if (g_pm_wlan_forceslp_msg_proc != HI_NULL) {
687 g_pm_wlan_forceslp_msg_proc();
688 }
689 return HI_SUCCESS;
690 }
691
692
hcc_slave_tx(oal_dev_netbuf_stru * dev_netbuf,hi_u16 pay_load_len,const hcc_transfer_param * param)693 hi_void hcc_slave_tx(oal_dev_netbuf_stru *dev_netbuf, hi_u16 pay_load_len, const hcc_transfer_param *param)
694 {
695 /* build the head */
696 hcc_slave_build_header(dev_netbuf, pay_load_len, param);
697
698 /* put the pst_buf enqueue */
699 hcc_netbuf_add_to_list_tail(dev_netbuf, &g_hcc_tx_queue);
700
701 /* sched the hcc tx */
702 hcc_task_sched();
703 }
704
hcc_oam_fill_payload_data(const hi_u8 * data,hi_u16 pay_load_len,oal_dev_netbuf_stru ** dev_netbuf)705 hi_u32 hcc_oam_fill_payload_data(const hi_u8 *data, hi_u16 pay_load_len, oal_dev_netbuf_stru **dev_netbuf)
706 {
707 hi_u8 *cb = HI_NULL;
708 oal_dev_netbuf_stru *temp_netbuf;
709 temp_netbuf = oal_mem_dev_netbuf_alloc(OAL_NORMAL_NETBUF, (hi_u16)pay_load_len, OAL_NETBUF_PRIORITY_HIGH);
710 if (temp_netbuf == HI_NULL) {
711 return HI_ERR_FAILURE;
712 }
713 cb = oal_dev_netbuf_cb(temp_netbuf->us_index);
714 if (cb == HI_NULL) {
715 oal_mem_dev_netbuf_free(temp_netbuf);
716 return HI_ERR_FAILURE;
717 }
718 memset_s(cb, OAL_TX_CB_LEN, 0, OAL_TX_CB_LEN);
719 if (memcpy_s((hi_u8 *)(oal_dev_netbuf_get_payload(temp_netbuf)), pay_load_len,
720 (hi_u8 *)data, pay_load_len) != HI_SUCCESS) {
721 oal_mem_dev_netbuf_free(temp_netbuf);
722 return HI_ERR_FAILURE;
723 }
724 *dev_netbuf = temp_netbuf;
725 return HI_ERR_SUCCESS;
726 }
727
hcc_oam_log_tx(const hi_u8 * data,hi_u16 data_len,hi_u16 cmd_id)728 hi_u32 hcc_oam_log_tx(const hi_u8 *data, hi_u16 data_len, hi_u16 cmd_id)
729 {
730 oal_dev_netbuf_stru *dev_netbuf = HI_NULL;
731 hcc_transfer_param param = { 0 };
732 hi_u16 pay_load_len;
733 frw_event_mem_stru *event_mem = HI_NULL;
734 frw_event_stru *event = HI_NULL;
735 frw_hcc_extend_hdr_stru *ext_hdr = HI_NULL;
736 frw_event_hdr_stru *event_hdr = HI_NULL;
737 if (g_sdio_init_ok == HI_FALSE) {
738 return HI_ERR_SUCCESS;
739 }
740 pay_load_len = data_len;
741 event_mem = frw_event_alloc(data_len);
742 if (oal_unlikely(event_mem == HI_NULL)) {
743 return HI_ERR_CODE_PTR_NULL;
744 }
745 event = (frw_event_stru *)event_mem->puc_data;
746 /* 需要把数据拷贝到event_mem中 */
747 frw_event_hdr_init(&(event->event_hdr), FRW_EVENT_TYPE_HCC, cmd_id, pay_load_len, FRW_EVENT_PIPELINE_STAGE_1, 0);
748 if (hcc_oam_fill_payload_data(data, pay_load_len, &dev_netbuf) != HI_ERR_SUCCESS) {
749 goto failed_netbuf;
750 }
751 ext_hdr = (frw_hcc_extend_hdr_stru *)hcc_get_extend_addr(dev_netbuf, HCC_EXTEND_TOTAL_SIZE);
752 event_hdr = frw_get_event_hdr(event_mem);
753 if (ext_hdr == HI_NULL || event_hdr == HI_NULL) {
754 goto failed_netbuf;
755 }
756 ext_hdr->nest_type = event_hdr->type;
757 ext_hdr->nest_sub_type = event_hdr->sub_type;
758 ext_hdr->vap_id = event_hdr->vap_id;
759 hcc_hdr_param_init(¶m, HCC_ACTION_TYPE_OAM, WIFI_CONTROL_TYPE, HCC_EXTEND_TOTAL_SIZE, DATA_HI_QUEUE,
760 HCC_FC_NONE);
761 hcc_slave_tx(dev_netbuf, pay_load_len, ¶m);
762 frw_event_free(event_mem);
763 return HI_ERR_SUCCESS;
764 failed_netbuf:
765 if (dev_netbuf != HI_NULL) {
766 oal_mem_dev_netbuf_free(dev_netbuf);
767 }
768 if (event_mem != HI_NULL) {
769 frw_event_free(event_mem);
770 }
771 return HI_ERR_FAILURE;
772 }
773
774
hcc_get_extern_address(const oal_dev_netbuf_stru * dev_netbuf,hi_u32 extend_len)775 hi_void *hcc_get_extern_address(const oal_dev_netbuf_stru *dev_netbuf, hi_u32 extend_len)
776 {
777 if (extend_len > (HCC_HDR_TOTAL_LEN - HCC_HDR_LEN)) {
778 /* invalid extend len */
779 #ifdef CONFIG_HCC_DEBUG
780 hi_diag_log_msg_i1(0, "invalid extend len:%u\r\n", extend_len);
781 #endif
782 return HI_NULL;
783 }
784
785 return (hi_void *)((uintptr_t)oal_dev_netbuf_hcchdr(dev_netbuf) + HCC_HDR_TOTAL_LEN - extend_len);
786 }
787
hcc_check_header_vaild(const hcc_header_stru * hdr)788 hi_bool hcc_check_header_vaild(const hcc_header_stru *hdr)
789 {
790 if ((hdr->main_type >= HCC_ACTION_TYPE_BUTT) || (hdr->sub_type >= WIFI_SUB_TYPE_BUTT) ||
791 ((HCC_HDR_LEN + (hi_u16)(hdr->pad_hdr) + (hi_u16)(hdr->pad_payload)) > HCC_HDR_TOTAL_LEN)) {
792 return HI_FALSE;
793 }
794 return HI_TRUE;
795 }
796
hcc_exec_action(oal_dev_netbuf_stru * nb_prefetch,const hcc_header_stru * hcc_head,oal_dev_netbuf_stru * nb_postdo)797 hi_bool hcc_exec_action(oal_dev_netbuf_stru *nb_prefetch, const hcc_header_stru *hcc_head,
798 oal_dev_netbuf_stru *nb_postdo)
799 {
800 hcc_slave_netbuf slave_netbuf;
801 hi_u8 *pre_context = HI_NULL;
802 hcc_rx_action *rx_action = &g_hcc_slave_handler.rx_action_info.action[hcc_head->main_type];
803
804 /* prepare */
805 if (rx_action->pre_do) {
806 slave_netbuf.net_buf = nb_prefetch;
807 slave_netbuf.len = (hi_s32)hcc_head->pay_len;
808 if (rx_action->pre_do(hcc_head->sub_type, &slave_netbuf, &pre_context) != HI_SUCCESS) {
809 printf("rx_action->pre_do break\n");
810 return HI_FALSE;
811 }
812 }
813 /* prepare do ok,delist the netbuf. */
814 nb_postdo = hcc_netbuf_delist(&g_hcc_rx_queue);
815 if (nb_postdo == HI_NULL) {
816 printf("dev_netbuf_postdo break\n");
817 return HI_FALSE;
818 }
819
820 if (rx_action->post_do != HI_NULL) {
821 nb_postdo->next = HI_NULL;
822 hcc_head = (hcc_header_stru *)oal_dev_netbuf_hcchdr(nb_postdo);
823 if (hcc_head == HI_NULL) {
824 hi_diag_log_msg_e0(0, "{hcc_slave_rx_queue_sched::pst_hcc_head null.}");
825 printf("dev_netbuf_postdo continue\n");
826 return HI_TRUE;
827 }
828 slave_netbuf.net_buf = nb_postdo;
829 slave_netbuf.len = (hi_s32)hcc_head->pay_len;
830 (hi_void)rx_action->post_do(hcc_head->sub_type, &slave_netbuf, pre_context);
831 } else {
832 /* Debug,unregistered mtype */
833 hi_diag_log_msg_e0(0, "rx_action->post_do is null\r\n");
834 oal_mem_dev_netbuf_free(nb_postdo);
835 printf("dev_netbuf_postdo else\n");
836 }
837 return HI_TRUE;
838 }
839
hcc_slave_rx_queue_sched(hi_void)840 hi_void hcc_slave_rx_queue_sched(hi_void)
841 {
842 oal_dev_netbuf_stru *dev_netbuf_prefetch = HI_NULL;
843 oal_dev_netbuf_stru *dev_netbuf_postdo = HI_NULL;
844
845 hcc_delay_bug_on_detect();
846
847 for (hi_u32 i = 0; i < FRW_EVENT_HCC_BURST_COUNT; ++i) {
848 if (g_hcc_rx_queue.num == 0) {
849 break;
850 }
851
852 /* action prepare, if failed keep the netbuf in the list */
853 dev_netbuf_prefetch = (oal_dev_netbuf_stru *)oal_netbuf_head_next(&g_hcc_rx_queue);
854 hcc_header_stru *hcc_head = (hcc_header_stru *)oal_dev_netbuf_hcchdr(dev_netbuf_prefetch);
855 if (hcc_head == HI_NULL) {
856 hi_diag_log_msg_e0(0, "{hcc_slave_rx_queue_sched::pst_hcc_head null.}");
857 continue;
858 }
859 if (hcc_check_header_vaild(hcc_head) != HI_TRUE) {
860 hi_diag_log_msg_e0(0, "hcc rx header valid\r\n");
861 dev_netbuf_postdo = hcc_netbuf_delist(&g_hcc_rx_queue);
862 oal_mem_dev_netbuf_free(dev_netbuf_postdo);
863 continue;
864 }
865
866 if (!hcc_exec_action(dev_netbuf_prefetch, hcc_head, dev_netbuf_postdo)) {
867 break;
868 }
869 }
870 }
871
hcc_slave_tx_queue_sched(hi_void)872 hi_void hcc_slave_tx_queue_sched(hi_void)
873 {
874 hi_u32 i;
875 hi_u32 total_len = 0;
876 hi_sdio_status_info status_info;
877 hi_sdio_extendfunc *hcc_extfunc = hi_sdio_get_extend_info();
878
879 hi_u32 status = hi_int_lock();
880 (hi_void)hi_sdio_get_status(&status_info);
881 if ((status_info.tx_status == CHAN_TX_BUSY) || (status_info.allow_sleep == HI_TRUE) ||
882 (status_info.work_status != SDIO_CHAN_WORK) || (g_hcc_tx_queue.num == 0)) {
883 hi_int_restore(status);
884 return;
885 }
886
887 status_info.tx_status = CHAN_TX_BUSY;
888 (hi_void)hi_sdio_set_status(&status_info);
889
890 memset_s(hcc_extfunc, sizeof(hi_sdio_extendfunc), 0, sizeof(hi_sdio_extendfunc));
891
892 /* 是否有高优先级buffer credit值要更新 */
893 if (g_flowctrl_flashed == HI_TRUE) {
894 if (!hi_sdio_is_sending_msg(D2H_MSG_CREDIT_UPDATE) && !hi_sdio_is_pending_msg(D2H_MSG_CREDIT_UPDATE)) {
895 /* 更新寄存器 */
896 hcc_extfunc->credit_info = g_flow_ctrl_reg_info;
897 hcc_extfunc->credit_isvalid = 1;
898 (hi_void)hi_sdio_write_extinfo(hcc_extfunc);
899 g_flowctrl_flashed = HI_FALSE;
900 }
901 }
902
903 memset_s(hcc_extfunc, sizeof(hi_sdio_extendfunc), 0, sizeof(hi_sdio_extendfunc));
904
905 for (i = 0; i < g_d2h_hcc_assemble_count; ++i) {
906 oal_dev_netbuf_stru *dev_netbuf = hcc_netbuf_delist(&g_hcc_tx_queue);
907 if (dev_netbuf == HI_NULL) {
908 break;
909 }
910
911 /* set the tx aggr information */
912 hi_u32 send_len = hcc_slave_get_netbuf_align_len(dev_netbuf, HISDIO_D2H_SCATT_BUFFLEN_ALIGN);
913 total_len += send_len;
914 g_tx_aggr_info.hcc_tx_aggr[i].netbuf = dev_netbuf;
915 g_tx_aggr_info.hcc_tx_aggr[i].tx_pkt_bytes = send_len;
916 hcc_extfunc->comm_reg[i] = (send_len >> HISDIO_D2H_SCATT_BUFFLEN_ALIGN_BITS) & 0xFF;
917 }
918
919 /* The sdio register must access by 4 bytes */
920 hcc_extfunc->valid_commreg_cnt = (hi_s32)(i & (~3)); /* 3 is used for 4 bytes down align. */
921 hcc_extfunc->commreg_isvalid = 1;
922 /* tx_aggr_total_len 32 B对齐,未作512对齐 */
923 g_tx_aggr_info.tx_aggr_total_len = total_len;
924 g_tx_aggr_info.aggr_tx_num = i;
925
926 if (total_len < HISDIO_BLOCK_SIZE) {
927 hcc_extfunc->xfer_count = hi_byte_align(total_len, 4); /* 4 bytes align */
928 } else {
929 hcc_extfunc->xfer_count = hi_byte_align(total_len, HISDIO_BLOCK_SIZE); /* 4 bytes align */
930 }
931 /* write ext info */
932 (hi_void)hi_sdio_write_extinfo(hcc_extfunc);
933
934 hi_sdio_send_data(hcc_extfunc->xfer_count);
935
936 hi_int_restore(status);
937 }
938
939 /* ****************************************************************************
940 功能描述 : 收到host的sleep request消息处理,应答允许或forbid sleep应答
941
942 修改历史 :
943 1.日 期 : 2019-05-30
944 作 者 : HiSilicon
945 修改内容 : 新生成函数
946 **************************************************************************** */
hcc_sleep_request_msg_proc(hi_void)947 hi_void hcc_sleep_request_msg_proc(hi_void)
948 {
949 hi_u32 msg;
950 hi_sdio_status_info status_info;
951
952 (hi_void)hi_sdio_get_status(&status_info);
953 if ((status_info.tx_status != CHAN_TX_BUSY) &&
954 (g_hcc_tx_queue.num == 0) &&
955 (g_chan_write_flag == CHAN_RX_IDLE)) {
956 msg = D2H_MSG_ALLOW_SLEEP;
957 status_info.sleep_status = SLEEP_ALLOW_SND;
958 status_info.allow_sleep = HI_TRUE;
959 } else {
960 msg = D2H_MSG_DISALLOW_SLEEP;
961 status_info.sleep_status = SLEEP_DISALLOW_SND;
962 }
963
964 hi_sdio_send_sync_msg(msg);
965 (hi_void)hi_sdio_set_status(&status_info);
966 }
967
hcc_msg_process(hi_u32 msg)968 hi_void hcc_msg_process(hi_u32 msg)
969 {
970 if (msg & (1 << H2D_MSG_PM_WLAN_OFF)) {
971 printf("reboot\n");
972 hi_diag_log_msg_i0(0, "recieve msg H2D_MSG_PM_WLAN_OFF, need reboot\n");
973 hi_reboot();
974 }
975 }
976
hcc_msg_callback(hi_u32 msg)977 hi_void hcc_msg_callback(hi_u32 msg)
978 {
979 static hi_u8 msg_callback_flag = 0;
980 if (g_process_msg_callback != HI_NULL) {
981 g_process_msg_callback(msg);
982 } else {
983 if (msg_callback_flag == 0) { /* print related log every 256 messages. */
984 hi_diag_log_msg_e0(0, "call hcc_register_msg_callback to register callback firstly\r\n");
985 }
986 ++msg_callback_flag;
987 }
988 }
989
hcc_read_err_callback(hi_void)990 hi_void hcc_read_err_callback(hi_void)
991 {
992 hi_diag_log_msg_i0(0, "hcc_read_err_callback occurs.\r\n");
993 }
994
hcc_soft_rst_callback(hi_void)995 hi_void hcc_soft_rst_callback(hi_void)
996 {
997 sdio_soft_reset_valid(); /* must set before reinit. */
998 (hi_void)hi_sdio_reinit();
999 }
1000
hcc_slave_clean(hi_void)1001 hi_void hcc_slave_clean(hi_void)
1002 {
1003 if (g_reserve_netbuff != HI_NULL) {
1004 oal_mem_dev_netbuf_free(g_reserve_netbuff);
1005 g_reserve_netbuff = HI_NULL;
1006 }
1007 }
1008
1009 /* ****************************************************************************
1010 功能描述 : 注册消息处理中断函数
1011
1012 修改历史 :
1013 1.日 期 : 2019-05-30
1014 作 者 : HiSilicon
1015 修改内容 : 新生成函数
1016 **************************************************************************** */
hcc_register_msg_callback(hcc_msg_cb msg_callback)1017 hi_void hcc_register_msg_callback(hcc_msg_cb msg_callback)
1018 {
1019 g_process_msg_callback = msg_callback;
1020 }
1021
1022 /* ****************************************************************************
1023 功能描述 : HCC slave初始化
1024
1025 修改历史 :
1026 1.日 期 : 2019-05-30
1027 作 者 : HiSilicon
1028 修改内容 : 新生成函数
1029 **************************************************************************** */
hcc_slave_init(hi_void)1030 hi_u32 hcc_slave_init(hi_void)
1031 {
1032 hi_sdio_intcallback callback;
1033 g_sdio_init_ok = HI_FALSE;
1034 /* 申请一个保留netbuff用来申请不到内存时使用 */
1035 g_reserve_netbuff = oal_mem_dev_netbuf_alloc(OAL_NORMAL_NETBUF, HCC_LONG_PACKAGE_SIZE, OAL_NETBUF_PRIORITY_HIGH);
1036 if (g_reserve_netbuff == HI_NULL) {
1037 return HI_FAIL;
1038 }
1039 /* 逻辑需要保证宏HCC_LONG_PACKAGE_SIZE是 4 字节整数倍 */
1040 if ((HCC_LONG_PACKAGE_SIZE % 4) != 0) {
1041 hi_diag_log_msg_e0(0, "must 4 bytes algin\r\n");
1042 return HI_FAIL;
1043 }
1044
1045 /* 安全编程规则6.6例外(1) 对固定长度的数组进行初始化,或对固定长度的结构体进行内存初始化 */
1046 memset_s((hi_void *)&g_tx_aggr_info, sizeof(hcc_slave_tx_info), 0, sizeof(hcc_slave_tx_info));
1047 memset_s((hi_void *)&g_rx_aggr_info, sizeof(hcc_slave_rx_info), 0, sizeof(hcc_slave_rx_info));
1048 memset_s((hi_void *)g_h2d_assem_descr, HISDIO_HOST2DEV_SCATT_SIZE, 0, HISDIO_HOST2DEV_SCATT_SIZE);
1049 memset_s((hi_void *)&g_hcc_slave_handler, sizeof(struct hcc_handler), 0, sizeof(struct hcc_handler));
1050 memset_s((hi_void *)g_descr_control_func, sizeof(g_descr_control_func), 0, sizeof(g_descr_control_func));
1051
1052 g_descr_control_func[HCC_DESCR_ASSEM_RESET] = hcc_rx_assem_info_reset;
1053 g_descr_control_func[HCC_NETBUF_QUEUE_SWITCH] = hcc_rx_netbuf_queue_pri_switch;
1054 g_current_queue_type = HCC_NETBUF_NORMAL_QUEUE;
1055
1056 oal_dev_netbuf_list_head_init(&g_hcc_tx_queue);
1057 oal_dev_netbuf_list_head_init(&g_hcc_rx_queue);
1058
1059 callback.rdover_callback = hcc_read_over_callback;
1060 callback.rdstart_callback = hcc_read_start_callback;
1061 callback.wrstart_callback = hcc_write_start_callback;
1062 callback.wrover_callback = hcc_write_over_callback;
1063 callback.processmsg_callback = hcc_msg_callback;
1064 callback.rderr_callback = hcc_read_err_callback;
1065 callback.soft_rst_callback = hcc_soft_rst_callback;
1066 (hi_void)hi_sdio_register_callback(&callback);
1067 (hi_void)hi_sdio_memory_init();
1068
1069 hcc_register_msg_callback(hcc_msg_process);
1070
1071 return HI_SUCCESS;
1072 }
1073
1074 /* ****************************************************************************
1075 功能描述 : HCC slave重新初始化
1076
1077 修改历史 :
1078 1.日 期 : 2019-05-30
1079 作 者 : HiSilicon
1080 修改内容 : 新生成函数
1081 **************************************************************************** */
hcc_slave_reinit(hi_void)1082 hi_u32 hcc_slave_reinit(hi_void)
1083 {
1084 hi_sdio_intcallback callback;
1085 hi_u32 ret;
1086
1087 /* 申请一个保留netbuff用来申请不到内存时使用 */
1088 g_reserve_netbuff = oal_mem_dev_netbuf_alloc(OAL_NORMAL_NETBUF, HCC_LONG_PACKAGE_SIZE, OAL_NETBUF_PRIORITY_HIGH);
1089 if (g_reserve_netbuff == HI_NULL) {
1090 return HI_FAIL;
1091 }
1092 // 逻辑需要保证宏HCC_LONG_PACKAGE_SIZE是 4 字节整数倍,lin_t e506/e774告警屏蔽
1093 if ((HCC_LONG_PACKAGE_SIZE % 4) != 0) {
1094 hi_diag_log_msg_e0(0, "must 4 bytes algin\r\n");
1095 return HI_FAIL;
1096 }
1097
1098 callback.rdover_callback = hcc_read_over_callback;
1099 callback.rdstart_callback = hcc_read_start_callback;
1100 callback.wrstart_callback = hcc_write_start_callback;
1101 callback.wrover_callback = hcc_write_over_callback;
1102 callback.processmsg_callback = hcc_msg_callback;
1103 callback.rderr_callback = hcc_read_err_callback;
1104 callback.soft_rst_callback = hcc_soft_rst_callback;
1105
1106 ret = hi_sdio_register_callback(&callback);
1107 if (ret != HI_SUCCESS) {
1108 return ret;
1109 }
1110 ret = hi_sdio_reinit();
1111 if (ret != HI_SUCCESS) {
1112 return ret;
1113 }
1114
1115 return HI_SUCCESS;
1116 }
1117
1118 /* ****************************************************************************
1119 功能描述 : HCC接收处理注册函数
1120
1121 修改历史 :
1122 1.日 期 : 2019-05-30
1123 作 者 : HiSilicon
1124 修改内容 : 新生成函数
1125 **************************************************************************** */
hcc_rx_register(struct hcc_handler * hcc,hi_u8 mtype,hcc_rx_post_do post_do,hcc_rx_pre_do pre_do)1126 hi_u32 hcc_rx_register(struct hcc_handler *hcc, hi_u8 mtype, hcc_rx_post_do post_do, hcc_rx_pre_do pre_do)
1127 {
1128 hcc_rx_action *rx_action = HI_NULL;
1129
1130 if ((hcc == HI_NULL) || (post_do == HI_NULL) || (mtype >= HCC_ACTION_TYPE_BUTT)) {
1131 return HI_FAIL;
1132 }
1133
1134 rx_action = &hcc->rx_action_info.action[mtype];
1135
1136 if (rx_action->post_do != HI_NULL) {
1137 return HI_FAIL;
1138 }
1139
1140 rx_action->post_do = post_do;
1141 rx_action->pre_do = pre_do;
1142
1143 return HI_SUCCESS;
1144 }
1145
1146 #ifdef __cplusplus
1147 #if __cplusplus
1148 }
1149 #endif
1150 #endif
1151