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