* 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 CHAN_INIT_H
#define CHAN_INIT_H
#include "ka_base_pub.h"
#include "ka_task_pub.h"
#include "pbl_kref_safe.h"
#include "chan_ts_inst.h"
struct trs_chan_sq_ctx {
u32 sqid;
u32 status;
u32 sq_head;
u32 sq_tail;
u32 pos;
ka_semaphore_t sem;
void *sq_addr;
void *sq_dev_vaddr;
u32 type;
struct trs_chan_mem_attr mem_attr;
u64 head_addr;
u64 tail_addr;
u64 db_addr;
struct trs_chan_sq_para para;
ka_wait_queue_head_t wait_queue;
ka_task_spinlock_t lock;
u32 long_sqe_cnt;
};
struct trs_chan_cq_ctx {
u32 cqid;
u32 loop;
u32 cq_head;
u32 cq_tail;
u32 cqe_valid;
void *cq_addr;
u32 type;
struct trs_chan_mem_attr mem_attr;
struct trs_chan_cq_para para;
ka_mutex_t mutex;
ka_wait_queue_head_t wait_queue;
};
struct trs_chan_stat {
u64 tx;
u64 rx;
u64 tx_full;
u64 rx_empty;
u64 tx_timeout;
u64 rx_dispatch;
u64 rx_wakeup;
u64 hw_err;
u64 rx_in;
};
struct trs_chan {
int id;
struct kref_safe ref;
u32 flag;
u32 irq;
int pid;
int ssid;
u32 msg[SQCQ_INFO_LENGTH];
u32 ext_msg_len;
void *ext_msg;
ka_atomic_t chan_status;
struct trs_chan_ts_inst *ts_inst;
struct trs_chan_irq_ctx *irq_ctx;
ka_list_head_t node;
struct trs_id_inst inst;
struct trs_chan_type types;
struct trs_chan_ops ops;
struct trs_chan_sq_ctx sq;
struct trs_chan_cq_ctx cq;
struct trs_chan_stat stat;
ka_work_struct_t work;
ka_proc_dir_entry_t *entry;
ka_task_spinlock_t lock;
int work_running;
int tasklet_running;
u32 retry_times;
u64 interrupt_time_us;
};
static inline bool trs_chan_has_sq(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_ALLOC_SQ_BIT)) != 0);
}
static inline bool trs_chan_has_cq(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_ALLOC_CQ_BIT)) != 0);
}
static inline bool trs_chan_is_notice_ts(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_NOTICE_TS_BIT)) != 0);
}
static inline bool trs_chan_is_auto_update_sq_head(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_AUTO_UPDATE_SQ_HEAD_BIT)) != 0);
}
static inline bool trs_chan_is_recv_block(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_RECV_BLOCK_BIT)) != 0);
}
static inline void trs_chan_set_not_notice_ts(struct trs_chan *chan)
{
chan->flag &= ~(0x1 << CHAN_FLAG_NOTICE_TS_BIT);
}
static inline bool trs_chan_has_sq_mem(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_NO_SQ_MEM_BIT)) == 0);
}
static inline bool trs_chan_has_cq_mem(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_NO_CQ_MEM_BIT)) == 0);
}
static inline bool trs_chan_specified_sq_id(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_SPECIFIED_SQ_ID_BIT)) != 0);
}
static inline bool trs_chan_specified_cq_id(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_SPECIFIED_CQ_ID_BIT)) != 0);
}
static inline bool trs_chan_reserved_sq_id(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_RESERVED_SQ_ID_BIT)) != 0);
}
static inline bool trs_chan_reserved_cq_id(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_RESERVED_CQ_ID_BIT)) != 0);
}
static inline bool trs_chan_ranged_sq_id(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_RANGE_SQ_ID_BIT)) != 0);
}
static inline bool trs_chan_ranged_cq_id(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_RANGE_CQ_ID_BIT)) != 0);
}
static inline bool trs_chan_rts_rsv_sq_id(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_RTS_RSV_SQ_ID_BIT)) != 0);
}
static inline bool trs_chan_rts_rsv_cq_id(struct trs_chan *chan)
{
return ((chan->flag & (0x1 << CHAN_FLAG_RTS_RSV_CQ_ID_BIT)) != 0);
}
struct trs_chan *trs_chan_get(struct trs_id_inst *inst, u32 chan_id);
void trs_chan_put(struct trs_chan *chan);
void trs_all_chan_cq_work_cancel(struct trs_chan_ts_inst *ts_inst);
#endif