xref: /linux/drivers/net/ethernet/huawei/hinic3/hinic3_cmdq.h (revision ec2e0fb07d789976c601bec19ecced7a501c3705)
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