* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _DMA_COMMON_H_
#define _DMA_COMMON_H_
#include "ka_task_pub.h"
#include "ka_base_pub.h"
#include "ka_memory_pub.h"
#include "ka_system_pub.h"
#include "dma_adapt.h"
#include "comm_kernel_interface.h"
#define DMA_DONE_BUDGET 64
#define DEVDRV_DMA_MAX_REMOTE_IRQ 128
#define DEVDRV_DMA_SQ_LDIE_ENABEL 1
#define DEVDRV_MAX_TS_DMA_CH_SQ_DEPTH 4096
#define DEVDRV_MAX_TS_DMA_CH_CQ_DEPTH 4096
#define DEVDRV_SECOND_TO_MICROSECOND 1000000ULL
#define DEVDRV_MICROSECOND_TO_NANOSECOND 1000ULL
#define DEVDRV_LOG_DOWN_TIME_MAX 500000U
#define DEVDRV_LOG_SYNC_DMA_COPY_TIME 500U
#define DEVDRV_DMA_SQCQ_SIDE_BIT 0U
#define DEVDRV_DMA_SML_PKT_BIT 1U
#define DEVDRV_DMA_SYNC 1
#define DEVDRV_DMA_ASYNC 2
#define DEVDRV_INVALID_INSTANCE (-1)
#define DEVDRV_DMA_SO_RELEX_ORDER 0x0
#define DEVDRV_DMA_RO_RELEX_ORDER 0x2
#define DEVDRV_SOFTBD_STATUS_INVALID (-2)
#define DEVDRV_DELAY_US 1000
#define DEVDRV_CB_TIME_OVER_10MS 10
#define DEVDRV_CB_TIME_OVER_10S 10000
#define DEVDRV_DMA_ALIVE 0
#define DEVDRV_DMA_DEAD 1
#define DEVDRV_DMA_CHAN_ENABLED 0
#define DEVDRV_DMA_CHAN_DISABLED 1
#define DEVDRV_DMA_SQ_TAIL_SUB_CNT 0
#define DEVDRV_DMA_SQ_TAIL_ADD_CNT 1
#define DEVDRV_DMA_VA_COPY 0
#define DEVDRV_DMA_PA_COPY 1
#define DEVDRV_DMA_MAX_CHAN_NUM 48
enum {
DEVDRV_DMA_SUCCESS = 0x0,
DEVDRV_DMA_FAILED = 0x1
};
enum devdrv_dma_sqcq_side {
DEVDRV_DMA_LOCAL_SIDE = 0x0,
DEVDRV_DMA_REMOTE_SIDE = 0x1,
DEVDRV_DMA_TS_SIDE = 0x2
};
enum devdrv_dma_process_status {
DEVDRV_DMA_PROCESS_INIT = 0x0,
DEVDRV_DMA_PROCESS_HANDLING = 0x1,
DEVDRV_DMA_PROCESS_WAIT_TIMEOUT = 0x2
};
#define DEVDRV_DMA_TYPE_ERR 101
#define DEVDRV_DMA_NO_PARA 102
#define DEVDRV_DMA_NO_NOTIFY 103
#define DEVDRV_DMA_NO_DEV 104
#define DEVDRV_DMA_CNT_ERR 105
#define DEVDRV_DMA_NO_NODE 106
#define DEVDRV_DMA_SIZE_ERR 107
#define DEVDRV_DMA_DIR_ERR 108
#define DEVDRV_DMA_SQ_DESC_SIZE sizeof(struct devdrv_dma_sq_node)
#define DEVDRV_DMA_CQ_DESC_SIZE sizeof(struct devdrv_dma_cq_node)
struct devdrv_dma_soft_bd {
int valid;
int copy_type;
int wait_type;
int owner_bd;
int status;
u32 trans_id;
ka_semaphore_t sync_sem;
void *priv;
void (*callback_func)(void *, u32, u32);
ka_atomic_t process_flag;
};
struct devdrv_dma_soft_bd_wait_status {
int status;
int valid;
};
struct devdrv_sync_dma_stat {
u64 dma_chan_copy_cnt;
u64 sync_submit_cnt;
u64 async_submit_cnt;
u64 sml_submit_cnt;
u64 trigger_remot_int_cnt;
u64 trigger_local_128;
u64 done_int_cnt;
u64 done_int_in_time;
u64 re_schedule_cnt;
u64 done_tasklet_in_cnt;
u64 done_tasklet_in_time;
u64 done_tasklet_out_time;
u64 err_int_cnt;
u64 err_work_cnt;
u64 sync_sem_up_cnt;
u64 callback_time_stamp;
u64 callback_time_over10s;
u64 callback_time_over10ms;
u64 new_callback_time;
u64 max_callback_time;
u64 async_proc_cnt;
u64 max_task_op_time;
u64 last_soft_bd_proced;
u64 sq_idle_bd_cnt;
u64 flag;
};
#define DEVDRV_IRQ_IS_INIT 1
#define DEVDRV_IRQ_IS_UNINIT 0
struct devdrv_dma_channel {
ka_device_t *dev;
void __ka_mm_iomem *io_base;
u32 func_id;
u32 chan_id;
u32 flag;
bit1: DMA small packet is supported or not; */
struct devdrv_dma_sq_node *sq_desc_base;
struct devdrv_dma_cq_node *cq_desc_base;
ka_dma_addr_t sq_desc_dma;
ka_dma_addr_t cq_desc_dma;
#ifdef CFG_FEATURE_AGENT_SMMU
ka_page_t *sq_desc_page;
ka_page_t *cq_desc_page;
#endif
u32 sq_depth;
u32 cq_depth;
u32 sq_tail;
u32 cq_head;
u32 sq_head;
struct devdrv_dma_soft_bd *dma_soft_bd;
ka_tasklet_struct_t dma_done_task;
u32 err_work_magic1;
ka_work_struct_t err_work;
u32 err_work_magic2;
ka_workqueue_struct_t *dma_done_workqueue;
ka_work_struct_t dma_done_work;
int done_irq;
int done_irq_state;
int err_irq;
int err_irq_flag;
int err_irq_state;
ka_task_spinlock_t lock;
ka_task_spinlock_t cq_lock;
ka_mutex_t vm_sq_lock;
ka_mutex_t vm_cq_lock;
u32 rounds;
u32 remote_irq_cnt;
struct devdrv_sync_dma_stat status;
struct devdrv_dma_dev *dma_dev;
struct devdrv_vpc_msg *sq_submit;
u32 last_irq_type;
u32 chan_status;
u32 dma_data_type;
};
struct devdrv_dma_chan_irq_info {
u32 done_irq;
u32 err_irq;
int err_irq_flag;
};
struct data_type_chan {
u32 chan_start_id;
u32 chan_num;
u32 last_use_chan;
};
struct devdrv_dma_ops {
bool (*devdrv_dma_get_cq_valid)(struct devdrv_dma_cq_node *cq_desc, u32 rounds);
void (*devdrv_dma_set_cq_invalid)(struct devdrv_dma_cq_node *cq_desc);
};
struct devdrv_dma_sq_cq_info {
u32 sq_depth;
u32 sq_rsv_num;
u32 cq_depth;
};
#define DEVDRV_DMA_GUARD_WORK_MAGIC 0x4567abcd
struct devdrv_dma_guard_work {
u32 work_magic;
ka_delayed_work_t dma_guard_work;
struct devdrv_dma_dev *dma_dev;
};
#define DEVDRV_DMA_ERR_SUPPRESSION_PERIOD_MS (5 * 60 * 1000)
#define DEVDRV_DMA_ERR_SUPPRESSION_MAX_CNT 3
#define DEVDRV_DMA_NO_NEED_SUPPRESSION 0
#define DEVDRV_DMA_NEED_SUPPRESSION 1
struct devdrv_dma_suppression {
u32 log_cnt;
u32 suppress_cnt;
u64 start_time;
};
struct devdrv_dma_dev {
u32 dev_id;
u32 func_id;
struct devdrv_pci_ctrl *pci_ctrl;
ka_device_t *dev;
void __ka_mm_iomem *io_base;
void __ka_mm_iomem *dma_chan_base;
void *drvdata;
u32 dma_pf_num;
u32 dma_vf_en;
u32 dma_vf_num;
u32 sq_cq_side;
u32 dev_status;
u32 done_irq_base;
u32 err_irq_base;
u32 err_flag;
struct devdrv_dma_sq_cq_info sq_cq_info;
struct devdrv_dma_ops ops;
unsigned long dma_bitmap;
u32 local_chan_num;
u32 local_chan[DEVDRV_DMA_MAX_CHAN_NUM];
u32 remote_chan_begin;
u32 remote_bar_begin;
u32 remote_chan_num;
u32 remote_chan[DEVDRV_DMA_MAX_CHAN_NUM];
u32 ts_chan_num;
u32 ts_chan[DEVDRV_DMA_MAX_CHAN_NUM];
struct data_type_chan data_chan[DEVDRV_DMA_DATA_TYPE_MAX];
struct devdrv_dma_guard_work guard_work;
ka_tasklet_struct_t single_fault_task;
struct devdrv_dma_suppression suppression;
struct devdrv_dma_channel dma_chan[];
};
struct devdrv_dma_res {
void __ka_mm_iomem *dma_addr;
void __ka_mm_iomem *dma_chan_addr;
u32 dma_chan_start_id;
u32 chan_start_id;
u32 use_chan[DEVDRV_DMA_MAX_CHAN_NUM];
u32 dma_chan_num;
u32 pf_num;
u32 sq_depth;
u32 sq_rsv_num;
u32 cq_depth;
u32 vf_id;
};
struct devdrv_dma_func_para {
u32 dev_id;
u32 chip_id;
u32 func_id;
u32 dma_pf_num;
u32 dma_vf_en;
u32 dma_vf_num;
ka_device_t *dev;
void __ka_mm_iomem *io_base;
void __ka_mm_iomem *dma_chan_base;
void *drvdata;
u32 dma_chan_begin;
u32 chan_begin;
u32 use_chan[DEVDRV_DMA_MAX_CHAN_NUM];
u32 chan_num;
u32 done_irq_base;
u32 err_irq_base;
u32 err_flag;
u32 chip_type;
struct devdrv_dma_sq_cq_info sq_cq_info;
};
struct devdrv_dma_copy_para {
int instance;
enum devdrv_dma_data_type type;
int wait_type;
int copy_type;
struct devdrv_asyn_dma_para_info *asyn_info;
int pa_va_flag;
};
bool is_need_dma_copy_retry(u32 dev_id, int wait_status);
void devdrv_dma_copy_type_info_init(struct devdrv_dma_copy_para *para, enum devdrv_dma_data_type type,
int wait_type, int copy_type);
void devdrv_dma_copy_para_info_init(struct devdrv_dma_copy_para *para, int pava_flag, int instance,
struct devdrv_asyn_dma_para_info *asyn_info);
int devdrv_peh_dma_node_addr_check(struct devdrv_dma_node *dma_node);
void devdrv_dma_config_axim_aruser_mode(void __ka_mm_iomem *io_base);
struct devdrv_dma_dev *devdrv_dma_init(struct devdrv_dma_func_para *para_in, u32 sq_cq_side, u32 func_id);
void devdrv_dma_exit(struct devdrv_dma_dev *dma_dev, u32 sriov_flag);
void devdrv_dma_stop_business(unsigned long data);
struct devdrv_dma_dev *devdrv_get_dma_dev(u32 dev_id);
void devdrv_dfx_dma_report_to_bbox(struct devdrv_dma_channel *dma_chan, u32 queue_init_sts);
void devdrv_dma_check_sram_init_status(const void __ka_mm_iomem *io_base, unsigned long timeout);
int devdrv_register_irq_func(void *drvdata, int vector_index, ka_irqreturn_t (*callback_func)(int, void *), void *para,
const char *name);
int devdrv_unregister_irq_func(void *drvdata, int vector_index, void *para);
int devdrv_notify_dma_err_irq(void *drvdata, u32 dma_chan_id, int err_irq);
int devdrv_check_dl_dlcmsm_state(void *drvdata);
int devdrv_dma_copy(struct devdrv_dma_dev *dma_dev, struct devdrv_dma_node *dma_node, u32 node_cnt,
struct devdrv_dma_copy_para *para);
int devdrv_dma_copy_sml_pkt(struct devdrv_dma_dev *dma_dev, enum devdrv_dma_data_type type, ka_dma_addr_t dst,
const void *data, u32 size);
int devdrv_dma_chan_copy(u32 dev_id, struct devdrv_dma_channel *dma_chan, struct devdrv_dma_node *dma_node,
u32 node_cnt, struct devdrv_dma_copy_para *para);
struct devdrv_dma_channel *devdrv_dma_get_chan(u32 dev_id, enum devdrv_dma_data_type type);
int devdrv_dma_get_sq_idle_bd_cnt(struct devdrv_dma_channel *dma_chan);
int devdrv_dma_chan_copy_by_vpc(u32 dev_id, struct devdrv_dma_channel *dma_chan, struct devdrv_dma_node *dma_node,
u32 node_cnt, struct devdrv_dma_copy_para *para);
void devdrv_dma_err_proc(struct devdrv_dma_channel *dma_chan);
int devdrv_dma_para_check(u32 dev_id, enum devdrv_dma_data_type type, int copy_type,
const struct devdrv_asyn_dma_para_info *para_info);
int devdrv_dma_node_check(u32 dev_id, const struct devdrv_dma_node *dma_node, u32 node_cnt,
const struct devdrv_dma_dev *dma_dev);
void devdrv_set_dma_status(struct devdrv_dma_dev *dma_dev, u32 status);
void devdrv_set_dma_chan_status(struct devdrv_dma_channel *dma_chan, u32 status);
void devdrv_dma_ops_init(struct devdrv_dma_dev *dma_dev, u32 chip_type);
int devdrv_dma_chan_init(struct devdrv_dma_channel *dma_chan, u32 sriov_flag);
int devdrv_dma_chan_reset(struct devdrv_dma_channel *dma_chan, u32 sriov_flag);
int devdrv_dma_chan_err_proc(struct devdrv_dma_channel *dma_chan);
void devdrv_dma_update_msix_entry_offset(void *drvdata, int *irq, int flag);
void devdrv_dma_done_task(unsigned long data);
void devdrv_res_dma_traffic(struct devdrv_dma_dev *dma_dev);
void devdrv_traffic_and_manage_dma_chan_config(struct devdrv_dma_dev *dma_dev);
int agentdrv_is_remote_dma_chan(struct devdrv_dma_dev *dma_dev, u32 chan_id);
void devdrv_sriov_pf_dma_traffic(struct devdrv_dma_dev *dma_dev);
int devdrv_sriov_dma_init_pf_chan(struct devdrv_dma_dev *dma_dev);
int devdrv_sriov_dma_init_chan(struct devdrv_dma_dev *dma_dev);
int devdrv_dma_init_chan(struct devdrv_dma_dev *dma_dev, u32 entry_id, u32 dma_chan_id, u32 sriov_flag);
int devdrv_alloc_dma_sq_cq(struct devdrv_dma_channel *dma_chan);
void devdrv_free_dma_sq_cq(struct devdrv_dma_channel *dma_chan);
int agentdrv_sriov_init_dma(u32 dev_id, u32 computility, u32 total, unsigned long *dma_bitmap);
void agentdrv_sriov_uninit_dma(u32 dev_id);
void devdrv_dma_sram_init(struct devdrv_dma_func_para *para_in, u32 sq_cq_side, u32 func_id);
void devdrv_dma_stop_bussiness_task(unsigned long data);
void devdrv_dma_stop_bussiness(struct devdrv_dma_dev *dma_dev);
void devdrv_dma_chan_info_init(struct devdrv_dma_dev *dma_dev, u32 entry_id, u32 dma_chan_id);
void devdrv_dma_err_task(ka_work_struct_t *p_work);
#endif