/* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2017 Huawei Technologies Co., Ltd */ #ifndef _HINIC_PMD_CMDQ_H_ #define _HINIC_PMD_CMDQ_H_ #define HINIC_DB_OFF 0x00000800 #define HINIC_SCMD_DATA_LEN 16 /* pmd driver uses 64, kernel l2nic use 4096 */ #define HINIC_CMDQ_DEPTH 64 #define HINIC_CMDQ_BUF_SIZE 2048U #define HINIC_CMDQ_BUF_HW_RSVD 8 #define HINIC_CMDQ_MAX_DATA_SIZE (HINIC_CMDQ_BUF_SIZE \ - HINIC_CMDQ_BUF_HW_RSVD) #define HINIC_CEQ_ID_CMDQ 0 enum cmdq_scmd_type { CMDQ_SET_ARM_CMD = 2, }; enum cmdq_wqe_type { WQE_LCMD_TYPE, WQE_SCMD_TYPE, }; enum ctrl_sect_len { CTRL_SECT_LEN = 1, CTRL_DIRECT_SECT_LEN = 2, }; enum bufdesc_len { BUFDESC_LCMD_LEN = 2, BUFDESC_SCMD_LEN = 3, }; enum data_format { DATA_SGE, }; enum completion_format { COMPLETE_DIRECT, COMPLETE_SGE, }; enum completion_request { CEQ_SET = 1, }; enum cmdq_cmd_type { SYNC_CMD_DIRECT_RESP, SYNC_CMD_SGE_RESP, ASYNC_CMD, }; enum hinic_cmdq_type { HINIC_CMDQ_SYNC, HINIC_CMDQ_ASYNC, HINIC_MAX_CMDQ_TYPES, }; enum hinic_db_src_type { HINIC_DB_SRC_CMDQ_TYPE, HINIC_DB_SRC_L2NIC_SQ_TYPE, }; enum hinic_cmdq_db_type { HINIC_DB_SQ_RQ_TYPE, HINIC_DB_CMDQ_TYPE, }; /* CMDQ WQE CTRLS */ struct hinic_cmdq_header { u32 header_info; u32 saved_data; }; struct hinic_scmd_bufdesc { u32 buf_len; u32 rsvd; u8 data[HINIC_SCMD_DATA_LEN]; }; struct hinic_lcmd_bufdesc { struct hinic_sge sge; u32 rsvd1; u64 saved_async_buf; u64 rsvd3; }; struct hinic_cmdq_db { u32 db_info; u32 rsvd; }; struct hinic_status { u32 status_info; }; struct hinic_ctrl { u32 ctrl_info; }; struct hinic_sge_resp { struct hinic_sge sge; u32 rsvd; }; struct hinic_cmdq_completion { /* HW Format */ union { struct hinic_sge_resp sge_resp; u64 direct_resp; }; }; struct hinic_cmdq_wqe_scmd { struct hinic_cmdq_header header; struct hinic_cmdq_db db; struct hinic_status status; struct hinic_ctrl ctrl; struct hinic_cmdq_completion completion; struct hinic_scmd_bufdesc buf_desc; }; struct hinic_cmdq_wqe_lcmd { struct hinic_cmdq_header header; struct hinic_status status; struct hinic_ctrl ctrl; struct hinic_cmdq_completion completion; struct hinic_lcmd_bufdesc buf_desc; }; struct hinic_cmdq_inline_wqe { struct hinic_cmdq_wqe_scmd wqe_scmd; }; struct hinic_cmdq_wqe { /* HW Format */ union{ struct hinic_cmdq_inline_wqe inline_wqe; struct hinic_cmdq_wqe_lcmd wqe_lcmd; }; }; struct hinic_cmdq_ctxt_info { u64 curr_wqe_page_pfn; u64 wq_block_pfn; }; /* New interface */ struct hinic_cmdq_ctxt { u8 status; u8 version; u8 resp_aeq_num; u8 rsvd0[5]; u16 func_idx; u8 cmdq_id; u8 ppf_idx; u8 rsvd1[4]; struct hinic_cmdq_ctxt_info ctxt_info; }; enum hinic_cmdq_status { HINIC_CMDQ_ENABLE = BIT(0), HINIC_CMDQ_SET_FAIL = BIT(1) }; enum hinic_cmdq_cmd_type { HINIC_CMD_TYPE_NONE, HINIC_CMD_TYPE_SET_ARM, HINIC_CMD_TYPE_NORMAL, }; struct hinic_cmdq_cmd_info { enum hinic_cmdq_cmd_type cmd_type; }; struct hinic_cmdq { struct hinic_wq *wq; enum hinic_cmdq_type cmdq_type; int wrapped; hinic_spinlock_t cmdq_lock; int *errcode; /* doorbell area */ u8 __iomem *db_base; struct hinic_cmdq_ctxt cmdq_ctxt; struct hinic_cmdq_cmd_info *cmd_infos; }; struct hinic_cmdqs { struct hinic_hwdev *hwdev; struct pci_pool *cmd_buf_pool; struct hinic_wq *saved_wqs; struct hinic_cmdq cmdq[HINIC_MAX_CMDQ_TYPES]; u32 status; }; struct hinic_cmd_buf { void *buf; dma_addr_t dma_addr; struct rte_mbuf *mbuf; u16 size; }; int hinic_reinit_cmdq_ctxts(struct hinic_hwdev *hwdev); bool hinic_cmdq_idle(struct hinic_cmdq *cmdq); struct hinic_cmd_buf *hinic_alloc_cmd_buf(void *hwdev); void hinic_free_cmd_buf(void *hwdev, struct hinic_cmd_buf *cmd_buf); /* PF/VF send cmd to ucode by cmdq, and return if success. * timeout=0, use default timeout. */ int hinic_cmdq_direct_resp(void *hwdev, enum hinic_ack_type ack_type, enum hinic_mod_type mod, u8 cmd, struct hinic_cmd_buf *buf_in, u64 *out_param, u32 timeout); int hinic_comm_cmdqs_init(struct hinic_hwdev *hwdev); void hinic_comm_cmdqs_free(struct hinic_hwdev *hwdev); #endif /* _HINIC_PMD_CMDQ_H_ */