12025cf9eSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
2a5564e7eSAviad Krawczyk /*
3a5564e7eSAviad Krawczyk  * Huawei HiNIC PCI Express Linux driver
4a5564e7eSAviad Krawczyk  * Copyright(c) 2017 Huawei Technologies Co., Ltd
5a5564e7eSAviad Krawczyk  */
6a5564e7eSAviad Krawczyk 
7a5564e7eSAviad Krawczyk #ifndef HINIC_HW_EQS_H
8a5564e7eSAviad Krawczyk #define HINIC_HW_EQS_H
9a5564e7eSAviad Krawczyk 
10a5564e7eSAviad Krawczyk #include <linux/types.h>
11a5564e7eSAviad Krawczyk #include <linux/workqueue.h>
12a5564e7eSAviad Krawczyk #include <linux/pci.h>
13a5564e7eSAviad Krawczyk #include <linux/sizes.h>
14a5564e7eSAviad Krawczyk #include <linux/bitops.h>
15fc9319e4SAviad Krawczyk #include <linux/interrupt.h>
16a5564e7eSAviad Krawczyk 
17a5564e7eSAviad Krawczyk #include "hinic_hw_if.h"
18a5564e7eSAviad Krawczyk 
19f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_0_INT_IDX_SHIFT          0
20f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_0_DMA_ATTR_SHIFT         12
21f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_0_PCI_INTF_IDX_SHIFT     20
22f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_0_INT_MODE_SHIFT         31
23f00fe738SAviad Krawczyk 
24f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_0_INT_IDX_MASK           0x3FF
25f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_0_DMA_ATTR_MASK          0x3F
26f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_0_PCI_INTF_IDX_MASK      0x3
27f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_0_INT_MODE_MASK          0x1
28f00fe738SAviad Krawczyk 
29f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_0_SET(val, member)       \
30f00fe738SAviad Krawczyk 			(((u32)(val) & HINIC_AEQ_CTRL_0_##member##_MASK) << \
31f00fe738SAviad Krawczyk 			 HINIC_AEQ_CTRL_0_##member##_SHIFT)
32f00fe738SAviad Krawczyk 
33f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_0_CLEAR(val, member)     \
34f00fe738SAviad Krawczyk 			((val) & (~(HINIC_AEQ_CTRL_0_##member##_MASK \
35f00fe738SAviad Krawczyk 			 << HINIC_AEQ_CTRL_0_##member##_SHIFT)))
36f00fe738SAviad Krawczyk 
37f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_1_LEN_SHIFT              0
38f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_1_ELEM_SIZE_SHIFT        24
39f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_1_PAGE_SIZE_SHIFT        28
40f00fe738SAviad Krawczyk 
41f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_1_LEN_MASK               0x1FFFFF
42f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_1_ELEM_SIZE_MASK         0x3
43f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_1_PAGE_SIZE_MASK         0xF
44f00fe738SAviad Krawczyk 
45f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_1_SET(val, member)       \
46f00fe738SAviad Krawczyk 			(((u32)(val) & HINIC_AEQ_CTRL_1_##member##_MASK) << \
47f00fe738SAviad Krawczyk 			 HINIC_AEQ_CTRL_1_##member##_SHIFT)
48f00fe738SAviad Krawczyk 
49f00fe738SAviad Krawczyk #define HINIC_AEQ_CTRL_1_CLEAR(val, member)     \
50f00fe738SAviad Krawczyk 			((val) & (~(HINIC_AEQ_CTRL_1_##member##_MASK \
51f00fe738SAviad Krawczyk 			 << HINIC_AEQ_CTRL_1_##member##_SHIFT)))
52f00fe738SAviad Krawczyk 
53fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_0_INTR_IDX_SHIFT         0
54fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_0_DMA_ATTR_SHIFT         12
55fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_0_KICK_THRESH_SHIFT      20
56fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_0_PCI_INTF_IDX_SHIFT     24
57fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_0_INTR_MODE_SHIFT        31
58fc9319e4SAviad Krawczyk 
59fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_0_INTR_IDX_MASK          0x3FF
60fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_0_DMA_ATTR_MASK          0x3F
61fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_0_KICK_THRESH_MASK       0xF
62fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_0_PCI_INTF_IDX_MASK      0x3
63fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_0_INTR_MODE_MASK         0x1
64fc9319e4SAviad Krawczyk 
65fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_0_SET(val, member)       \
66fc9319e4SAviad Krawczyk 			(((u32)(val) & HINIC_CEQ_CTRL_0_##member##_MASK) << \
67fc9319e4SAviad Krawczyk 			 HINIC_CEQ_CTRL_0_##member##_SHIFT)
68fc9319e4SAviad Krawczyk 
69fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_0_CLEAR(val, member)     \
70fc9319e4SAviad Krawczyk 			((val) & (~(HINIC_CEQ_CTRL_0_##member##_MASK \
71fc9319e4SAviad Krawczyk 			 << HINIC_CEQ_CTRL_0_##member##_SHIFT)))
72fc9319e4SAviad Krawczyk 
73fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_1_LEN_SHIFT              0
74fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_1_PAGE_SIZE_SHIFT        28
75fc9319e4SAviad Krawczyk 
76fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_1_LEN_MASK               0x1FFFFF
77fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_1_PAGE_SIZE_MASK         0xF
78fc9319e4SAviad Krawczyk 
79fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_1_SET(val, member)       \
80fc9319e4SAviad Krawczyk 			(((u32)(val) & HINIC_CEQ_CTRL_1_##member##_MASK) << \
81fc9319e4SAviad Krawczyk 			 HINIC_CEQ_CTRL_1_##member##_SHIFT)
82fc9319e4SAviad Krawczyk 
83fc9319e4SAviad Krawczyk #define HINIC_CEQ_CTRL_1_CLEAR(val, member)     \
84fc9319e4SAviad Krawczyk 			((val) & (~(HINIC_CEQ_CTRL_1_##member##_MASK \
85fc9319e4SAviad Krawczyk 			 << HINIC_CEQ_CTRL_1_##member##_SHIFT)))
86fc9319e4SAviad Krawczyk 
87f00fe738SAviad Krawczyk #define HINIC_EQ_ELEM_DESC_TYPE_SHIFT           0
88f00fe738SAviad Krawczyk #define HINIC_EQ_ELEM_DESC_SRC_SHIFT            7
89f00fe738SAviad Krawczyk #define HINIC_EQ_ELEM_DESC_SIZE_SHIFT           8
90f00fe738SAviad Krawczyk #define HINIC_EQ_ELEM_DESC_WRAPPED_SHIFT        31
91f00fe738SAviad Krawczyk 
92f00fe738SAviad Krawczyk #define HINIC_EQ_ELEM_DESC_TYPE_MASK            0x7F
93f00fe738SAviad Krawczyk #define HINIC_EQ_ELEM_DESC_SRC_MASK             0x1
94f00fe738SAviad Krawczyk #define HINIC_EQ_ELEM_DESC_SIZE_MASK            0xFF
95f00fe738SAviad Krawczyk #define HINIC_EQ_ELEM_DESC_WRAPPED_MASK         0x1
96f00fe738SAviad Krawczyk 
97f00fe738SAviad Krawczyk #define HINIC_EQ_ELEM_DESC_SET(val, member)     \
98f00fe738SAviad Krawczyk 			(((u32)(val) & HINIC_EQ_ELEM_DESC_##member##_MASK) << \
99f00fe738SAviad Krawczyk 			 HINIC_EQ_ELEM_DESC_##member##_SHIFT)
100f00fe738SAviad Krawczyk 
101f00fe738SAviad Krawczyk #define HINIC_EQ_ELEM_DESC_GET(val, member)     \
102f00fe738SAviad Krawczyk 			(((val) >> HINIC_EQ_ELEM_DESC_##member##_SHIFT) & \
103f00fe738SAviad Krawczyk 			 HINIC_EQ_ELEM_DESC_##member##_MASK)
104f00fe738SAviad Krawczyk 
105f00fe738SAviad Krawczyk #define HINIC_EQ_CI_IDX_SHIFT                   0
106f00fe738SAviad Krawczyk #define HINIC_EQ_CI_WRAPPED_SHIFT               20
107f00fe738SAviad Krawczyk #define HINIC_EQ_CI_XOR_CHKSUM_SHIFT            24
108f00fe738SAviad Krawczyk #define HINIC_EQ_CI_INT_ARMED_SHIFT             31
109f00fe738SAviad Krawczyk 
110f00fe738SAviad Krawczyk #define HINIC_EQ_CI_IDX_MASK                    0xFFFFF
111f00fe738SAviad Krawczyk #define HINIC_EQ_CI_WRAPPED_MASK                0x1
112f00fe738SAviad Krawczyk #define HINIC_EQ_CI_XOR_CHKSUM_MASK             0xF
113f00fe738SAviad Krawczyk #define HINIC_EQ_CI_INT_ARMED_MASK              0x1
114f00fe738SAviad Krawczyk 
115f00fe738SAviad Krawczyk #define HINIC_EQ_CI_SET(val, member)            \
116f00fe738SAviad Krawczyk 			(((u32)(val) & HINIC_EQ_CI_##member##_MASK) << \
117f00fe738SAviad Krawczyk 			 HINIC_EQ_CI_##member##_SHIFT)
118f00fe738SAviad Krawczyk 
119f00fe738SAviad Krawczyk #define HINIC_EQ_CI_CLEAR(val, member)          \
120f00fe738SAviad Krawczyk 			((val) & (~(HINIC_EQ_CI_##member##_MASK \
121f00fe738SAviad Krawczyk 			 << HINIC_EQ_CI_##member##_SHIFT)))
122f00fe738SAviad Krawczyk 
123a5564e7eSAviad Krawczyk #define HINIC_MAX_AEQS                  4
124fc9319e4SAviad Krawczyk #define HINIC_MAX_CEQS                  32
125a5564e7eSAviad Krawczyk 
126f00fe738SAviad Krawczyk #define HINIC_AEQE_SIZE                 64
127fc9319e4SAviad Krawczyk #define HINIC_CEQE_SIZE                 4
128f00fe738SAviad Krawczyk 
129f00fe738SAviad Krawczyk #define HINIC_AEQE_DESC_SIZE            4
130f00fe738SAviad Krawczyk #define HINIC_AEQE_DATA_SIZE            \
131f00fe738SAviad Krawczyk 			(HINIC_AEQE_SIZE - HINIC_AEQE_DESC_SIZE)
132f00fe738SAviad Krawczyk 
133a5564e7eSAviad Krawczyk #define HINIC_DEFAULT_AEQ_LEN           64
134fc9319e4SAviad Krawczyk #define HINIC_DEFAULT_CEQ_LEN           1024
135a5564e7eSAviad Krawczyk 
136a5564e7eSAviad Krawczyk #define HINIC_EQ_PAGE_SIZE              SZ_4K
137a5564e7eSAviad Krawczyk 
138d0b9805eSAviad Krawczyk #define HINIC_CEQ_ID_CMDQ               0
139d0b9805eSAviad Krawczyk 
140a5564e7eSAviad Krawczyk enum hinic_eq_type {
141a5564e7eSAviad Krawczyk 	HINIC_AEQ,
142fc9319e4SAviad Krawczyk 	HINIC_CEQ,
143a5564e7eSAviad Krawczyk };
144a5564e7eSAviad Krawczyk 
145a5564e7eSAviad Krawczyk enum hinic_aeq_type {
146a425b6e1SLuo bin 	HINIC_MBX_FROM_FUNC = 1,
147a5564e7eSAviad Krawczyk 	HINIC_MSG_FROM_MGMT_CPU = 2,
148a425b6e1SLuo bin 	HINIC_MBX_SEND_RSLT = 5,
149a5564e7eSAviad Krawczyk 	HINIC_MAX_AEQ_EVENTS,
150a5564e7eSAviad Krawczyk };
151a5564e7eSAviad Krawczyk 
152fc9319e4SAviad Krawczyk enum hinic_ceq_type {
153fc9319e4SAviad Krawczyk 	HINIC_CEQ_CMDQ = 3,
154fc9319e4SAviad Krawczyk 
155fc9319e4SAviad Krawczyk 	HINIC_MAX_CEQ_EVENTS,
156fc9319e4SAviad Krawczyk };
157fc9319e4SAviad Krawczyk 
158a5564e7eSAviad Krawczyk enum hinic_eqe_state {
159a5564e7eSAviad Krawczyk 	HINIC_EQE_ENABLED = BIT(0),
160a5564e7eSAviad Krawczyk 	HINIC_EQE_RUNNING = BIT(1),
161a5564e7eSAviad Krawczyk };
162a5564e7eSAviad Krawczyk 
163f00fe738SAviad Krawczyk struct hinic_aeq_elem {
164f00fe738SAviad Krawczyk 	u8      data[HINIC_AEQE_DATA_SIZE];
16590f86b8aSLuo bin 	__be32  desc;
166f00fe738SAviad Krawczyk };
167f00fe738SAviad Krawczyk 
168a5564e7eSAviad Krawczyk struct hinic_eq_work {
169a5564e7eSAviad Krawczyk 	struct work_struct      work;
170a5564e7eSAviad Krawczyk 	void                    *data;
171a5564e7eSAviad Krawczyk };
172a5564e7eSAviad Krawczyk 
173a5564e7eSAviad Krawczyk struct hinic_eq {
174a5564e7eSAviad Krawczyk 	struct hinic_hwif       *hwif;
1757dd29ee1SLuo bin 	struct hinic_hwdev      *hwdev;
176a5564e7eSAviad Krawczyk 	enum hinic_eq_type      type;
177a5564e7eSAviad Krawczyk 	int                     q_id;
178a5564e7eSAviad Krawczyk 	u32                     q_len;
179a5564e7eSAviad Krawczyk 	u32                     page_size;
180a5564e7eSAviad Krawczyk 
181a5564e7eSAviad Krawczyk 	u32                     cons_idx;
182a5564e7eSAviad Krawczyk 	int                     wrapped;
183a5564e7eSAviad Krawczyk 
184a5564e7eSAviad Krawczyk 	size_t                  elem_size;
185a5564e7eSAviad Krawczyk 	int                     num_pages;
186a5564e7eSAviad Krawczyk 	int                     num_elem_in_pg;
187a5564e7eSAviad Krawczyk 
188a5564e7eSAviad Krawczyk 	struct msix_entry       msix_entry;
189a9fd686aSLuo bin 	char			irq_name[64];
190a5564e7eSAviad Krawczyk 
191a5564e7eSAviad Krawczyk 	dma_addr_t              *dma_addr;
192a5564e7eSAviad Krawczyk 	void                    **virt_addr;
193a5564e7eSAviad Krawczyk 
194a5564e7eSAviad Krawczyk 	struct hinic_eq_work    aeq_work;
195fc9319e4SAviad Krawczyk 
196fc9319e4SAviad Krawczyk 	struct tasklet_struct   ceq_tasklet;
197a5564e7eSAviad Krawczyk };
198a5564e7eSAviad Krawczyk 
199a5564e7eSAviad Krawczyk struct hinic_hw_event_cb {
200a5564e7eSAviad Krawczyk 	void    (*hwe_handler)(void *handle, void *data, u8 size);
201a5564e7eSAviad Krawczyk 	void                    *handle;
202a5564e7eSAviad Krawczyk 	unsigned long           hwe_state;
203a5564e7eSAviad Krawczyk };
204a5564e7eSAviad Krawczyk 
205a5564e7eSAviad Krawczyk struct hinic_aeqs {
206a5564e7eSAviad Krawczyk 	struct hinic_hwif       *hwif;
207a5564e7eSAviad Krawczyk 
208a5564e7eSAviad Krawczyk 	struct hinic_eq         aeq[HINIC_MAX_AEQS];
209a5564e7eSAviad Krawczyk 	int                     num_aeqs;
210a5564e7eSAviad Krawczyk 
211a5564e7eSAviad Krawczyk 	struct hinic_hw_event_cb hwe_cb[HINIC_MAX_AEQ_EVENTS];
212a5564e7eSAviad Krawczyk 
213a5564e7eSAviad Krawczyk 	struct workqueue_struct *workq;
214a5564e7eSAviad Krawczyk };
215a5564e7eSAviad Krawczyk 
216fc9319e4SAviad Krawczyk struct hinic_ceq_cb {
217fc9319e4SAviad Krawczyk 	void    (*handler)(void *handle, u32 ceqe_data);
218fc9319e4SAviad Krawczyk 	void                    *handle;
219fc9319e4SAviad Krawczyk 	enum hinic_eqe_state    ceqe_state;
220fc9319e4SAviad Krawczyk };
221fc9319e4SAviad Krawczyk 
222fc9319e4SAviad Krawczyk struct hinic_ceqs {
223fc9319e4SAviad Krawczyk 	struct hinic_hwif       *hwif;
2247dd29ee1SLuo bin 	struct hinic_hwdev		*hwdev;
225fc9319e4SAviad Krawczyk 	struct hinic_eq         ceq[HINIC_MAX_CEQS];
226fc9319e4SAviad Krawczyk 	int                     num_ceqs;
227fc9319e4SAviad Krawczyk 
228fc9319e4SAviad Krawczyk 	struct hinic_ceq_cb     ceq_cb[HINIC_MAX_CEQ_EVENTS];
229fc9319e4SAviad Krawczyk };
230fc9319e4SAviad Krawczyk 
231a5564e7eSAviad Krawczyk void hinic_aeq_register_hw_cb(struct hinic_aeqs *aeqs,
232a5564e7eSAviad Krawczyk 			      enum hinic_aeq_type event, void *handle,
233a5564e7eSAviad Krawczyk 			      void (*hwe_handler)(void *handle, void *data,
234a5564e7eSAviad Krawczyk 						  u8 size));
235a5564e7eSAviad Krawczyk 
236a5564e7eSAviad Krawczyk void hinic_aeq_unregister_hw_cb(struct hinic_aeqs *aeqs,
237a5564e7eSAviad Krawczyk 				enum hinic_aeq_type event);
238a5564e7eSAviad Krawczyk 
239fc9319e4SAviad Krawczyk void hinic_ceq_register_cb(struct hinic_ceqs *ceqs,
240fc9319e4SAviad Krawczyk 			   enum hinic_ceq_type event, void *handle,
241fc9319e4SAviad Krawczyk 			   void (*ceq_cb)(void *handle, u32 ceqe_data));
242fc9319e4SAviad Krawczyk 
243fc9319e4SAviad Krawczyk void hinic_ceq_unregister_cb(struct hinic_ceqs *ceqs,
244fc9319e4SAviad Krawczyk 			     enum hinic_ceq_type event);
245fc9319e4SAviad Krawczyk 
246a5564e7eSAviad Krawczyk int hinic_aeqs_init(struct hinic_aeqs *aeqs, struct hinic_hwif *hwif,
247a5564e7eSAviad Krawczyk 		    int num_aeqs, u32 q_len, u32 page_size,
248a5564e7eSAviad Krawczyk 		    struct msix_entry *msix_entries);
249a5564e7eSAviad Krawczyk 
250a5564e7eSAviad Krawczyk void hinic_aeqs_free(struct hinic_aeqs *aeqs);
251a5564e7eSAviad Krawczyk 
252fc9319e4SAviad Krawczyk int hinic_ceqs_init(struct hinic_ceqs *ceqs, struct hinic_hwif *hwif,
253fc9319e4SAviad Krawczyk 		    int num_ceqs, u32 q_len, u32 page_size,
254fc9319e4SAviad Krawczyk 		    struct msix_entry *msix_entries);
255fc9319e4SAviad Krawczyk 
256fc9319e4SAviad Krawczyk void hinic_ceqs_free(struct hinic_ceqs *ceqs);
257fc9319e4SAviad Krawczyk 
25890f86b8aSLuo bin void hinic_dump_ceq_info(struct hinic_hwdev *hwdev);
25990f86b8aSLuo bin 
26090f86b8aSLuo bin void hinic_dump_aeq_info(struct hinic_hwdev *hwdev);
26190f86b8aSLuo bin 
262a5564e7eSAviad Krawczyk #endif
263