1db03a1ceSFan Gong /* SPDX-License-Identifier: GPL-2.0 */ 2db03a1ceSFan Gong /* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. */ 3db03a1ceSFan Gong 4db03a1ceSFan Gong #ifndef _HINIC3_CMDQ_H_ 5db03a1ceSFan Gong #define _HINIC3_CMDQ_H_ 6db03a1ceSFan Gong 7db03a1ceSFan Gong #include <linux/dmapool.h> 8db03a1ceSFan Gong 9db03a1ceSFan Gong #include "hinic3_hw_intf.h" 10db03a1ceSFan Gong #include "hinic3_wq.h" 11db03a1ceSFan Gong 12db03a1ceSFan Gong #define CMDQ_DEPTH 4096 13db03a1ceSFan Gong 14db03a1ceSFan Gong struct cmdq_db { 15db03a1ceSFan Gong __le32 db_head; 16db03a1ceSFan Gong __le32 db_info; 17db03a1ceSFan Gong }; 18db03a1ceSFan Gong 19db03a1ceSFan Gong /* hw defined cmdq wqe header */ 20db03a1ceSFan Gong struct cmdq_header { 21db03a1ceSFan Gong __le32 header_info; 22db03a1ceSFan Gong __le32 saved_data; 23db03a1ceSFan Gong }; 24db03a1ceSFan Gong 25db03a1ceSFan Gong struct cmdq_lcmd_bufdesc { 26db03a1ceSFan Gong struct hinic3_sge sge; 27db03a1ceSFan Gong __le64 rsvd2; 28db03a1ceSFan Gong __le64 rsvd3; 29db03a1ceSFan Gong }; 30db03a1ceSFan Gong 31db03a1ceSFan Gong struct cmdq_status { 32db03a1ceSFan Gong __le32 status_info; 33db03a1ceSFan Gong }; 34db03a1ceSFan Gong 35db03a1ceSFan Gong struct cmdq_ctrl { 36db03a1ceSFan Gong __le32 ctrl_info; 37db03a1ceSFan Gong }; 38db03a1ceSFan Gong 39db03a1ceSFan Gong struct cmdq_direct_resp { 40db03a1ceSFan Gong __le64 val; 41db03a1ceSFan Gong __le64 rsvd; 42db03a1ceSFan Gong }; 43db03a1ceSFan Gong 44db03a1ceSFan Gong struct cmdq_completion { 45db03a1ceSFan Gong union { 46db03a1ceSFan Gong struct hinic3_sge sge; 47db03a1ceSFan Gong struct cmdq_direct_resp direct; 48db03a1ceSFan Gong } resp; 49db03a1ceSFan Gong }; 50db03a1ceSFan Gong 51db03a1ceSFan Gong struct cmdq_wqe_scmd { 52db03a1ceSFan Gong struct cmdq_header header; 53db03a1ceSFan Gong __le64 rsvd3; 54db03a1ceSFan Gong struct cmdq_status status; 55db03a1ceSFan Gong struct cmdq_ctrl ctrl; 56db03a1ceSFan Gong struct cmdq_completion completion; 57db03a1ceSFan Gong __le32 rsvd10[6]; 58db03a1ceSFan Gong }; 59db03a1ceSFan Gong 60db03a1ceSFan Gong struct cmdq_wqe_lcmd { 61db03a1ceSFan Gong struct cmdq_header header; 62db03a1ceSFan Gong struct cmdq_status status; 63db03a1ceSFan Gong struct cmdq_ctrl ctrl; 64db03a1ceSFan Gong struct cmdq_completion completion; 65db03a1ceSFan Gong struct cmdq_lcmd_bufdesc buf_desc; 66db03a1ceSFan Gong }; 67db03a1ceSFan Gong 68db03a1ceSFan Gong struct cmdq_wqe { 69db03a1ceSFan Gong union { 70db03a1ceSFan Gong struct cmdq_wqe_scmd wqe_scmd; 71db03a1ceSFan Gong struct cmdq_wqe_lcmd wqe_lcmd; 72db03a1ceSFan Gong }; 73db03a1ceSFan Gong }; 74db03a1ceSFan Gong 75db03a1ceSFan Gong static_assert(sizeof(struct cmdq_wqe) == 64); 76db03a1ceSFan Gong 77db03a1ceSFan Gong enum hinic3_cmdq_type { 78db03a1ceSFan Gong HINIC3_CMDQ_SYNC = 0, 79db03a1ceSFan Gong HINIC3_MAX_CMDQ_TYPES = 4 80db03a1ceSFan Gong }; 81db03a1ceSFan Gong 82db03a1ceSFan Gong enum hinic3_cmdq_status { 83db03a1ceSFan Gong HINIC3_CMDQ_ENABLE = BIT(0), 84db03a1ceSFan Gong }; 85db03a1ceSFan Gong 86db03a1ceSFan Gong enum hinic3_cmdq_cmd_type { 87db03a1ceSFan Gong HINIC3_CMD_TYPE_NONE, 88db03a1ceSFan Gong HINIC3_CMD_TYPE_DIRECT_RESP, 89db03a1ceSFan Gong HINIC3_CMD_TYPE_FAKE_TIMEOUT, 90db03a1ceSFan Gong HINIC3_CMD_TYPE_TIMEOUT, 91db03a1ceSFan Gong HINIC3_CMD_TYPE_FORCE_STOP, 92db03a1ceSFan Gong }; 93db03a1ceSFan Gong 94db03a1ceSFan Gong struct hinic3_cmd_buf { 95db03a1ceSFan Gong void *buf; 96db03a1ceSFan Gong dma_addr_t dma_addr; 97db03a1ceSFan Gong __le16 size; 98db03a1ceSFan Gong refcount_t ref_cnt; 99db03a1ceSFan Gong }; 100db03a1ceSFan Gong 101db03a1ceSFan Gong struct hinic3_cmdq_cmd_info { 102db03a1ceSFan Gong enum hinic3_cmdq_cmd_type cmd_type; 103db03a1ceSFan Gong struct completion *done; 104db03a1ceSFan Gong int *errcode; 105db03a1ceSFan Gong /* completion code */ 106db03a1ceSFan Gong int *cmpt_code; 107db03a1ceSFan Gong __le64 *direct_resp; 108db03a1ceSFan Gong u64 cmdq_msg_id; 109db03a1ceSFan Gong struct hinic3_cmd_buf *buf_in; 110db03a1ceSFan Gong }; 111db03a1ceSFan Gong 112db03a1ceSFan Gong struct hinic3_cmdq { 113db03a1ceSFan Gong struct hinic3_wq wq; 114db03a1ceSFan Gong enum hinic3_cmdq_type cmdq_type; 115db03a1ceSFan Gong u8 wrapped; 116db03a1ceSFan Gong /* synchronize command submission with completions via event queue */ 117db03a1ceSFan Gong spinlock_t cmdq_lock; 118db03a1ceSFan Gong struct hinic3_cmdq_cmd_info *cmd_infos; 119db03a1ceSFan Gong struct hinic3_hwdev *hwdev; 120db03a1ceSFan Gong }; 121db03a1ceSFan Gong 122db03a1ceSFan Gong struct hinic3_cmdqs { 123db03a1ceSFan Gong struct hinic3_hwdev *hwdev; 124db03a1ceSFan Gong struct hinic3_cmdq cmdq[HINIC3_MAX_CMDQ_TYPES]; 125db03a1ceSFan Gong struct dma_pool *cmd_buf_pool; 126db03a1ceSFan Gong /* doorbell area */ 127db03a1ceSFan Gong u8 __iomem *cmdqs_db_base; 128db03a1ceSFan Gong 129db03a1ceSFan Gong /* When command queue uses multiple memory pages (1-level CLA), this 130db03a1ceSFan Gong * block will hold aggregated indirection table for all command queues 131db03a1ceSFan Gong * of cmdqs. Not used for small cmdq (0-level CLA). 132db03a1ceSFan Gong */ 133db03a1ceSFan Gong dma_addr_t wq_block_paddr; 134db03a1ceSFan Gong void *wq_block_vaddr; 135db03a1ceSFan Gong 136db03a1ceSFan Gong u32 status; 137db03a1ceSFan Gong u32 disable_flag; 138db03a1ceSFan Gong u8 cmdq_num; 139db03a1ceSFan Gong }; 140db03a1ceSFan Gong 141db03a1ceSFan Gong int hinic3_cmdqs_init(struct hinic3_hwdev *hwdev); 142db03a1ceSFan Gong void hinic3_cmdqs_free(struct hinic3_hwdev *hwdev); 143db03a1ceSFan Gong 144*16a6fce0SFan Gong struct hinic3_cmd_buf *hinic3_alloc_cmd_buf(struct hinic3_hwdev *hwdev); 145db03a1ceSFan Gong void hinic3_free_cmd_buf(struct hinic3_hwdev *hwdev, 146db03a1ceSFan Gong struct hinic3_cmd_buf *cmd_buf); 147*16a6fce0SFan Gong void hinic3_cmdq_ceq_handler(struct hinic3_hwdev *hwdev, __le32 ceqe_data); 148*16a6fce0SFan Gong 149*16a6fce0SFan Gong int hinic3_cmdq_direct_resp(struct hinic3_hwdev *hwdev, u8 mod, u8 cmd, 150*16a6fce0SFan Gong struct hinic3_cmd_buf *buf_in, __le64 *out_param); 151db03a1ceSFan Gong 152db03a1ceSFan Gong void hinic3_cmdq_flush_sync_cmd(struct hinic3_hwdev *hwdev); 153db03a1ceSFan Gong int hinic3_reinit_cmdq_ctxts(struct hinic3_hwdev *hwdev); 154db03a1ceSFan Gong bool hinic3_cmdq_idle(struct hinic3_cmdq *cmdq); 155db03a1ceSFan Gong 156db03a1ceSFan Gong #endif 157