luckfox-pico-sdk/sysdrv/drv_ko/wifi/hichannel/hcc/hcc_task.c
2023-08-08 20:36:47 +08:00

204 lines
6.2 KiB
C
Raw Blame History

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
* Description: hcc layer frw task.
* Author: Hisilicon
* Create: 2020-09-28
*/
#include "hcc_task.h"
#include "hcc_host.h"
#include "oam_ext_if.h"
#include "securec.h"
#include "hcc_list.h"
#include "sdio_host.h"
#include <linux/delay.h>
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define HCC_TASK_PRIO 3
static volatile hi_u8 g_thread_exit_flag = HI_FALSE;
static hi_u8 g_thread_working = HI_FALSE;
hcc_task_stru g_hcc_task;
#define HCC_TASK_NAME "hisi_hcc0"
#define HCC_TASK_TX_NAME "hisi_hcc_tx"
#define HCC_TASK_RX_NAME "hisi_hcc_rx"
#define TX_WRITE 0
#define RX_READ 1
#define DELAY_10_US 10
#define HCC_TASK_SIZE 0x4000
hi_s32 queues_len_check(hcc_handler_stru *hcc_handler, hcc_chan_type dir)
{
hi_s32 i;
hcc_trans_queue_stru *p_queue;
p_queue = hcc_handler->hcc_transer_info.hcc_queues[dir].queues;
for (i = 0; i < HCC_QUEUE_COUNT; i++, p_queue++) {
if (hcc_list_len(&p_queue->queue_info)) {
return HI_TRUE;
}
}
return HI_FALSE;
}
static hi_s32 hcc_thread_tx_wait_event_cond_check(hcc_handler_stru *hcc_handler)
{
hi_s32 ret;
/*
* please first check the condition
* which may be ok likely to reduce the cpu mips
*/
ret = (queues_len_check(hcc_handler, HCC_TX) &&
(hcc_handler->hcc_transer_info.channel_exception_flag == HI_FALSE) &&
hcc_handler->hcc_transer_info.tx_flow_ctrl.flowctrl_flag == D2H_MSG_FLOWCTRL_ON);
#ifdef _PRE_CONFIG_WLAN_THRANS_THREAD_DEBUG
if (ret == HI_TRUE)
hcc_handler->hcc_transer_info.thread_stat.wait_event_run_count++;
if (ret == HI_FALSE)
hcc_handler->hcc_transer_info.thread_stat.wait_event_block_count++;
#endif
return ret;
}
static hi_s32 hcc_thread_rx_wait_event_cond_check(hcc_handler_stru *hcc_handler)
{
hi_s32 ret;
/*
* please first check the condition
* which may be ok likely to reduce the cpu mips
*/
ret = queues_len_check(hcc_handler, HCC_RX);
#ifdef _PRE_CONFIG_WLAN_THRANS_THREAD_DEBUG
if (ret == HI_TRUE)
hcc_handler->hcc_transer_info.thread_stat.wait_event_run_count++;
if (ret == HI_FALSE)
hcc_handler->hcc_transer_info.thread_stat.wait_event_block_count++;
#endif
return ret;
}
hi_s32 hcc_thread_process(hcc_handler_stru *hcc_handler, hi_u8 wr)
{
hi_s32 ret = 0;
if (wr == TX_WRITE) {
ret += hcc_host_proc_tx_queue(hcc_handler, DATA_HI_QUEUE);
ret += hcc_host_proc_tx_queue(hcc_handler, DATA_LO_QUEUE);
} else {
ret += hcc_host_proc_rx_queue(hcc_handler, DATA_HI_QUEUE);
ret += hcc_host_proc_rx_queue(hcc_handler, DATA_LO_QUEUE);
}
return ret;
}
hi_u8 hcc_get_thread_exit_flag(hi_void)
{
return g_thread_exit_flag;
}
hi_void hcc_exit_task_thread(hcc_handler_stru* hcc)
{
hi_u16 retry_time = 10000;
g_thread_exit_flag = HI_TRUE;
hcc_sched_transfer(hcc);
while (g_thread_working && retry_time > 0) {
usleep_range(DELAY_10_US, DELAY_10_US);
retry_time--;
}
}
static hi_s32 hcc_task_rx_thread(hi_void *data)
{
hi_s32 hcc_ret;
#ifdef _PRE_WLAN_TCP_OPT
static hi_u8 ack_loop_count;
#endif
hcc_handler_stru *hcc_handler = (hcc_handler_stru *)data;
allow_signal(SIGTERM);
oam_info_log0("hcc_task_rx_thread:: hcc_task_rx_thread enter");
g_thread_exit_flag = HI_FALSE;
for (;;) {
if (g_thread_exit_flag == HI_TRUE || oal_kthread_should_stop()) {
oam_warning_log0("hcc_task_thread:: hcc_task leave");
break;
}
hcc_ret = hi_wait_event_interruptible(hcc_handler->hcc_transer_info.hcc_rx_wq,
(hcc_thread_rx_wait_event_cond_check(hcc_handler) == HI_TRUE));
if (hcc_ret == -ERESTARTSYS || g_thread_exit_flag == HI_TRUE) {
oam_info_log0("hcc_task_rx_thread:: hcc_task was interupterd by a singnal");
break;
}
hcc_thread_process(hcc_handler, RX_READ);
}
return 0;
}
/*****************************************************************************S
hcc task <20>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*****************************************************************************/
static hi_s32 hcc_task_tx_thread(hi_void *data)
{
hi_s32 hcc_ret = 0;
hcc_handler_stru *hcc_handler = (hcc_handler_stru *)data;
allow_signal(SIGTERM);
oam_info_log0("hcc_task_tx_thread:: hcc_task_tx_thread enter");
g_thread_exit_flag = HI_FALSE;
g_thread_working = HI_TRUE;
for (;;) {
if (g_thread_exit_flag == HI_TRUE || oal_kthread_should_stop()) {
oam_warning_log0("hcc_task_tx_thread:: hcc_task leave");
break;
}
hcc_ret = hi_wait_event_interruptible(hcc_handler->hcc_transer_info.hcc_tx_wq,
(hcc_thread_tx_wait_event_cond_check(hcc_handler) == HI_TRUE));
if (hcc_ret == -ERESTARTSYS || g_thread_exit_flag == HI_TRUE) {
oam_info_log0("hcc_task_tx_thread:: hcc_task was interupterd by a singnal");
break;
}
hcc_thread_process(hcc_handler, TX_WRITE);
}
g_thread_working = HI_FALSE;
return hcc_ret;
}
hi_u32 hcc_task_init(hcc_handler_stru *hcc_handler)
{
oal_kthread_param_stru thread_param = {0};
memset_s(&g_hcc_task, sizeof(hcc_task_stru), 0, sizeof(hcc_task_stru));
hi_wait_queue_init_head(&g_hcc_task.hcc_wq);
memset_s(&thread_param, sizeof(oal_kthread_param_stru), 0, sizeof(oal_kthread_param_stru));
thread_param.l_cpuid = 0;
thread_param.l_policy = OAL_SCHED_FIFO;
thread_param.l_prio = HCC_TASK_PRIO;
thread_param.ul_stacksize = HCC_TASK_SIZE;
hcc_handler->hcc_transer_info.hcc_transfer_thread = oal_kthread_create(HCC_TASK_TX_NAME,
hcc_task_tx_thread, hcc_handler, &thread_param);
hcc_handler->hcc_transer_info.hcc_rx_thread = oal_kthread_create(HCC_TASK_RX_NAME,
hcc_task_rx_thread, hcc_handler, &thread_param);
if (IS_ERR_OR_NULL(hcc_handler->hcc_transer_info.hcc_transfer_thread) ||
IS_ERR_OR_NULL(hcc_handler->hcc_transer_info.hcc_rx_thread)) {
return HI_FAIL;
}
return HI_SUCCESS;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif