367 lines
9.9 KiB
C
367 lines
9.9 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Huawei Hifc PCI Express Linux driver
|
|
* Copyright(c) 2017 Huawei Technologies Co., Ltd
|
|
*
|
|
*/
|
|
#ifndef __CQM_MAIN_H__
|
|
#define __CQM_MAIN_H__
|
|
|
|
#define CHIPIF_SUCCESS 0
|
|
#define CQM_TIMER_ENABLE 1
|
|
|
|
enum cqm_object_type_e {
|
|
CQM_OBJECT_ROOT_CTX = 0,
|
|
CQM_OBJECT_SERVICE_CTX,
|
|
CQM_OBJECT_NONRDMA_EMBEDDED_RQ = 10,
|
|
CQM_OBJECT_NONRDMA_EMBEDDED_SQ,
|
|
CQM_OBJECT_NONRDMA_SRQ,
|
|
CQM_OBJECT_NONRDMA_EMBEDDED_CQ,
|
|
CQM_OBJECT_NONRDMA_SCQ,
|
|
};
|
|
|
|
struct service_register_template_s {
|
|
u32 service_type;
|
|
u32 srq_ctx_size; /* srq,scq context_size config */
|
|
u32 scq_ctx_size;
|
|
void *service_handle; /* ceq/aeq callback fun */
|
|
|
|
void (*aeq_callback)(void *service_handle, u8 event_type, u64 val);
|
|
};
|
|
|
|
struct cqm_service_s {
|
|
bool has_register;
|
|
void __iomem *hardware_db_vaddr;
|
|
void __iomem *dwqe_vaddr;
|
|
u32 buf_order; /* size of per buf 2^buf_order page */
|
|
struct service_register_template_s service_template;
|
|
};
|
|
|
|
struct cqm_func_capability_s {
|
|
bool qpc_alloc_static; /* Allocate qpc memory dynamicly/statically */
|
|
bool scqc_alloc_static;
|
|
u8 timer_enable; /* whether timer enable */
|
|
|
|
u32 flow_table_based_conn_number;
|
|
u32 flow_table_based_conn_cache_number; /* Maximum number in cache */
|
|
u32 bloomfilter_length; /* Bloomfilter table size, aligned by 64B */
|
|
/* The starting position of the bloomfilter table in the cache */
|
|
u32 bloomfilter_addr;
|
|
u32 qpc_reserved; /* Reserved bits in bitmap */
|
|
u32 mpt_reserved; /* There are also reserved bits in ROCE/IWARP mpt */
|
|
/* All basic_size must be 2^n aligned */
|
|
u32 hash_number;
|
|
/* Number of hash buckets, BAT table fill size is
|
|
* aligned with 64 buckets, at least 64
|
|
*/
|
|
u32 hash_basic_size;
|
|
/* Hash bucket size is 64B, including 5 valid
|
|
* entries and 1 nxt_entry
|
|
*/
|
|
u32 qpc_number;
|
|
u32 qpc_basic_size;
|
|
|
|
/* Note: for cqm specail test */
|
|
u32 pagesize_reorder;
|
|
bool xid_alloc_mode;
|
|
bool gpa_check_enable;
|
|
u32 scq_reserved;
|
|
|
|
u32 mpt_number;
|
|
u32 mpt_basic_size;
|
|
u32 scqc_number;
|
|
u32 scqc_basic_size;
|
|
u32 srqc_number;
|
|
u32 srqc_basic_size;
|
|
|
|
u32 gid_number;
|
|
u32 gid_basic_size;
|
|
u32 lun_number;
|
|
u32 lun_basic_size;
|
|
u32 taskmap_number;
|
|
u32 taskmap_basic_size;
|
|
u32 l3i_number;
|
|
u32 l3i_basic_size;
|
|
u32 childc_number;
|
|
u32 childc_basic_size;
|
|
u32 child_qpc_id_start; /* Child ctx of FC is global addressing */
|
|
/* The maximum number of child ctx in
|
|
* chip is 8096
|
|
*/
|
|
u32 childc_number_all_function;
|
|
|
|
u32 timer_number;
|
|
u32 timer_basic_size;
|
|
u32 xid2cid_number;
|
|
u32 xid2cid_basic_size;
|
|
u32 reorder_number;
|
|
u32 reorder_basic_size;
|
|
};
|
|
|
|
#define CQM_PF TYPE_PF
|
|
#define CQM_PPF TYPE_PPF
|
|
#define CQM_BAT_ENTRY_MAX (16)
|
|
#define CQM_BAT_ENTRY_SIZE (16)
|
|
|
|
struct cqm_buf_list_s {
|
|
void *va;
|
|
dma_addr_t pa;
|
|
u32 refcount;
|
|
};
|
|
|
|
struct cqm_buf_s {
|
|
struct cqm_buf_list_s *buf_list;
|
|
struct cqm_buf_list_s direct;
|
|
u32 page_number; /* page_number=2^n buf_number */
|
|
u32 buf_number; /* buf_list node count */
|
|
u32 buf_size; /* buf_size=2^n PAGE_SIZE */
|
|
};
|
|
|
|
struct cqm_bitmap_s {
|
|
ulong *table;
|
|
u32 max_num;
|
|
u32 last;
|
|
/* The index that cannot be allocated is reserved in the front */
|
|
u32 reserved_top;
|
|
/* Lock for bitmap allocation */
|
|
spinlock_t lock;
|
|
};
|
|
|
|
struct completion;
|
|
struct cqm_object_s {
|
|
u32 service_type;
|
|
u32 object_type; /* context,queue,mpt,mtt etc */
|
|
u32 object_size;
|
|
/* for queue, ctx, MPT Byte */
|
|
atomic_t refcount;
|
|
struct completion free;
|
|
void *cqm_handle;
|
|
};
|
|
|
|
struct cqm_object_table_s {
|
|
struct cqm_object_s **table;
|
|
u32 max_num;
|
|
rwlock_t lock;
|
|
};
|
|
|
|
struct cqm_cla_table_s {
|
|
u32 type;
|
|
u32 max_buffer_size;
|
|
u32 obj_num;
|
|
bool alloc_static; /* Whether the buffer is statically allocated */
|
|
u32 cla_lvl;
|
|
/* The value of x calculated by the cacheline, used for chip */
|
|
u32 cacheline_x;
|
|
/* The value of y calculated by the cacheline, used for chip */
|
|
u32 cacheline_y;
|
|
/* The value of z calculated by the cacheline, used for chip */
|
|
u32 cacheline_z;
|
|
/* The value of x calculated by the obj_size, used for software */
|
|
u32 x;
|
|
/* The value of y calculated by the obj_size, used for software */
|
|
u32 y;
|
|
/* The value of z calculated by the obj_size, used for software */
|
|
u32 z;
|
|
struct cqm_buf_s cla_x_buf;
|
|
struct cqm_buf_s cla_y_buf;
|
|
struct cqm_buf_s cla_z_buf;
|
|
u32 trunk_order;/* A continuous physical page contains 2^order pages */
|
|
u32 obj_size;
|
|
/* Lock for cla buffer allocation and free */
|
|
struct mutex lock;
|
|
struct cqm_bitmap_s bitmap;
|
|
/* The association mapping table of index and object */
|
|
struct cqm_object_table_s obj_table;
|
|
};
|
|
|
|
typedef void (*init_handler)(void *cqm_handle,
|
|
struct cqm_cla_table_s *cla_table,
|
|
void *cap);
|
|
|
|
struct cqm_cla_entry_init_s {
|
|
u32 type;
|
|
init_handler cqm_cla_init_handler;
|
|
};
|
|
|
|
struct cqm_bat_table_s {
|
|
u32 bat_entry_type[CQM_BAT_ENTRY_MAX];
|
|
u8 bat[CQM_BAT_ENTRY_MAX * CQM_BAT_ENTRY_SIZE];
|
|
struct cqm_cla_table_s entry[CQM_BAT_ENTRY_MAX];
|
|
u32 bat_size;
|
|
};
|
|
|
|
struct cqm_handle_s {
|
|
struct hifc_hwdev *ex_handle;
|
|
struct pci_dev *dev;
|
|
struct hifc_func_attr func_attribute; /* vf or pf */
|
|
struct cqm_func_capability_s func_capability;
|
|
struct cqm_service_s service;
|
|
struct cqm_bat_table_s bat_table;
|
|
|
|
struct list_head node;
|
|
};
|
|
|
|
struct cqm_cmd_buf_s {
|
|
void *buf;
|
|
dma_addr_t dma;
|
|
u16 size;
|
|
};
|
|
|
|
struct cqm_queue_header_s {
|
|
u64 doorbell_record;
|
|
u64 ci_record;
|
|
u64 rsv1; /* the share area bettween driver and ucode */
|
|
u64 rsv2; /* the share area bettween driver and ucode*/
|
|
};
|
|
|
|
struct cqm_queue_s {
|
|
struct cqm_object_s object;
|
|
u32 index; /* embedded queue QP has not index, SRQ and SCQ have */
|
|
void *priv; /* service driver private info */
|
|
u32 current_q_doorbell;
|
|
u32 current_q_room;
|
|
/* nonrdma: only select q_room_buf_1 for q_room_buf */
|
|
struct cqm_buf_s q_room_buf_1;
|
|
struct cqm_buf_s q_room_buf_2;
|
|
struct cqm_queue_header_s *q_header_vaddr;
|
|
dma_addr_t q_header_paddr;
|
|
u8 *q_ctx_vaddr; /* SRQ and SCQ ctx space */
|
|
dma_addr_t q_ctx_paddr;
|
|
u32 valid_wqe_num;
|
|
/*add for srq*/
|
|
u8 *tail_container;
|
|
u8 *head_container;
|
|
u8 queue_link_mode; /*link,ring */
|
|
};
|
|
|
|
struct cqm_nonrdma_qinfo_s {
|
|
struct cqm_queue_s common;
|
|
u32 wqe_size;
|
|
/* The number of wqe contained in each buf (excluding link wqe),
|
|
* For srq, it is the number of wqe contained in 1 container
|
|
*/
|
|
u32 wqe_per_buf;
|
|
u32 q_ctx_size;
|
|
/* When different services use different sizes of ctx, a large ctx will
|
|
* occupy multiple consecutive indexes of the bitmap
|
|
*/
|
|
u32 index_count;
|
|
u32 container_size;
|
|
};
|
|
|
|
/* service context, QPC, mpt */
|
|
struct cqm_qpc_mpt_s {
|
|
struct cqm_object_s object;
|
|
u32 xid;
|
|
dma_addr_t paddr;
|
|
void *priv; /* service driver private info */
|
|
u8 *vaddr;
|
|
};
|
|
|
|
struct cqm_qpc_mpt_info_s {
|
|
struct cqm_qpc_mpt_s common;
|
|
/* When different services use different sizes of QPC, large QPC/mpt
|
|
* will occupy multiple consecutive indexes of the bitmap
|
|
*/
|
|
u32 index_count;
|
|
};
|
|
|
|
#define CQM_ADDR_COMBINE(high_addr, low_addr) \
|
|
((((dma_addr_t)(high_addr)) << 32) + ((dma_addr_t)(low_addr)))
|
|
#define CQM_ADDR_HI(addr) ((u32)((u64)(addr) >> 32))
|
|
#define CQM_ADDR_LW(addr) ((u32)((u64)(addr) & 0xffffffff))
|
|
#define CQM_HASH_BUCKET_SIZE_64 (64)
|
|
#define CQM_LUN_SIZE_8 (8)
|
|
#define CQM_L3I_SIZE_8 (8)
|
|
#define CQM_TIMER_SIZE_32 (32)
|
|
#define CQM_LUN_FC_NUM (64)
|
|
#define CQM_TASKMAP_FC_NUM (4)
|
|
#define CQM_L3I_COMM_NUM (64)
|
|
#define CQM_TIMER_SCALE_NUM (2*1024)
|
|
#define CQM_TIMER_ALIGN_WHEEL_NUM (8)
|
|
#define CQM_TIMER_ALIGN_SCALE_NUM \
|
|
(CQM_TIMER_SCALE_NUM*CQM_TIMER_ALIGN_WHEEL_NUM)
|
|
#define CQM_FC_PAGESIZE_ORDER (0)
|
|
#define CQM_QHEAD_ALIGN_ORDER (6)
|
|
|
|
s32 cqm_mem_init(void *ex_handle);
|
|
void cqm_mem_uninit(void *ex_handle);
|
|
s32 cqm_event_init(void *ex_handle);
|
|
void cqm_event_uninit(void *ex_handle);
|
|
s32 cqm_db_init(void *ex_handle);
|
|
void cqm_db_uninit(void *ex_handle);
|
|
s32 cqm_init(void *ex_handle);
|
|
void cqm_uninit(void *ex_handle);
|
|
s32 cqm_service_register(void *ex_handle,
|
|
struct service_register_template_s *service_template);
|
|
void cqm_service_unregister(void *ex_handle);
|
|
s32 cqm_ring_hardware_db(void *ex_handle,
|
|
u32 service_type,
|
|
u8 db_count, u64 db);
|
|
s32 cqm_send_cmd_box(void *ex_handle, u8 ack_type, u8 mod, u8 cmd,
|
|
struct cqm_cmd_buf_s *buf_in,
|
|
struct cqm_cmd_buf_s *buf_out,
|
|
u32 timeout);
|
|
u8 cqm_aeq_callback(void *ex_handle, u8 event, u64 data);
|
|
void cqm_object_delete(struct cqm_object_s *object);
|
|
struct cqm_cmd_buf_s *cqm_cmd_alloc(void *ex_handle);
|
|
void cqm_cmd_free(void *ex_handle, struct cqm_cmd_buf_s *cmd_buf);
|
|
struct cqm_queue_s *cqm_object_fc_srq_create(
|
|
void *ex_handle,
|
|
enum cqm_object_type_e object_type,
|
|
u32 wqe_number,
|
|
u32 wqe_size,
|
|
void *object_priv);
|
|
struct cqm_qpc_mpt_s *cqm_object_qpc_mpt_create(
|
|
void *ex_handle,
|
|
enum cqm_object_type_e object_type,
|
|
u32 object_size,
|
|
void *object_priv,
|
|
u32 index);
|
|
struct cqm_queue_s *cqm_object_nonrdma_queue_create(
|
|
void *ex_handle,
|
|
enum cqm_object_type_e object_type,
|
|
u32 wqe_number,
|
|
u32 wqe_size,
|
|
void *object_priv);
|
|
|
|
#define CQM_PTR_NULL(x) "%s: "#x" is null\n", __func__
|
|
#define CQM_ALLOC_FAIL(x) "%s: "#x" alloc fail\n", __func__
|
|
#define CQM_MAP_FAIL(x) "%s: "#x" map fail\n", __func__
|
|
#define CQM_FUNCTION_FAIL(x) "%s: "#x" return failure\n", __func__
|
|
#define CQM_WRONG_VALUE(x) "%s: "#x" %u is wrong\n", __func__, (u32)x
|
|
|
|
#define cqm_err(dev, format, ...) \
|
|
dev_err(dev, "[CQM]"format, ##__VA_ARGS__)
|
|
#define cqm_warn(dev, format, ...) \
|
|
dev_warn(dev, "[CQM]"format, ##__VA_ARGS__)
|
|
#define cqm_notice(dev, format, ...) \
|
|
dev_notice(dev, "[CQM]"format, ##__VA_ARGS__)
|
|
#define cqm_info(dev, format, ...) \
|
|
dev_info(dev, "[CQM]"format, ##__VA_ARGS__)
|
|
#define cqm_dbg(format, ...)
|
|
|
|
#define CQM_PTR_CHECK_RET(ptr, ret, desc) \
|
|
do {\
|
|
if (unlikely(NULL == (ptr))) {\
|
|
pr_err("[CQM]"desc);\
|
|
ret; \
|
|
} \
|
|
} while (0)
|
|
|
|
#define CQM_PTR_CHECK_NO_RET(ptr, desc, ret) \
|
|
do {\
|
|
if (unlikely((ptr) == NULL)) {\
|
|
pr_err("[CQM]"desc);\
|
|
ret; \
|
|
} \
|
|
} while (0)
|
|
#define CQM_CHECK_EQUAL_RET(dev_hdl, actual, expect, ret, desc) \
|
|
do {\
|
|
if (unlikely((expect) != (actual))) {\
|
|
cqm_err(dev_hdl, desc);\
|
|
ret; \
|
|
} \
|
|
} while (0)
|
|
|
|
#endif /* __CQM_MAIN_H__ */
|