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