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