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