]>
Commit | Line | Data |
---|---|---|
2025cf9e | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
a5564e7e AK |
2 | /* |
3 | * Huawei HiNIC PCI Express Linux driver | |
4 | * Copyright(c) 2017 Huawei Technologies Co., Ltd | |
a5564e7e AK |
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> | |
fc9319e4 | 15 | #include <linux/interrupt.h> |
a5564e7e AK |
16 | |
17 | #include "hinic_hw_if.h" | |
18 | ||
f00fe738 AK |
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 | ||
fc9319e4 AK |
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 | ||
f00fe738 AK |
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 | ||
a5564e7e | 123 | #define HINIC_MAX_AEQS 4 |
fc9319e4 | 124 | #define HINIC_MAX_CEQS 32 |
a5564e7e | 125 | |
f00fe738 | 126 | #define HINIC_AEQE_SIZE 64 |
fc9319e4 | 127 | #define HINIC_CEQE_SIZE 4 |
f00fe738 AK |
128 | |
129 | #define HINIC_AEQE_DESC_SIZE 4 | |
130 | #define HINIC_AEQE_DATA_SIZE \ | |
131 | (HINIC_AEQE_SIZE - HINIC_AEQE_DESC_SIZE) | |
132 | ||
a5564e7e | 133 | #define HINIC_DEFAULT_AEQ_LEN 64 |
fc9319e4 | 134 | #define HINIC_DEFAULT_CEQ_LEN 1024 |
a5564e7e AK |
135 | |
136 | #define HINIC_EQ_PAGE_SIZE SZ_4K | |
137 | ||
d0b9805e AK |
138 | #define HINIC_CEQ_ID_CMDQ 0 |
139 | ||
a5564e7e AK |
140 | enum hinic_eq_type { |
141 | HINIC_AEQ, | |
fc9319e4 | 142 | HINIC_CEQ, |
a5564e7e AK |
143 | }; |
144 | ||
145 | enum hinic_aeq_type { | |
146 | HINIC_MSG_FROM_MGMT_CPU = 2, | |
147 | ||
148 | HINIC_MAX_AEQ_EVENTS, | |
149 | }; | |
150 | ||
fc9319e4 AK |
151 | enum hinic_ceq_type { |
152 | HINIC_CEQ_CMDQ = 3, | |
153 | ||
154 | HINIC_MAX_CEQ_EVENTS, | |
155 | }; | |
156 | ||
a5564e7e AK |
157 | enum hinic_eqe_state { |
158 | HINIC_EQE_ENABLED = BIT(0), | |
159 | HINIC_EQE_RUNNING = BIT(1), | |
160 | }; | |
161 | ||
f00fe738 AK |
162 | struct hinic_aeq_elem { |
163 | u8 data[HINIC_AEQE_DATA_SIZE]; | |
164 | u32 desc; | |
165 | }; | |
166 | ||
a5564e7e AK |
167 | struct hinic_eq_work { |
168 | struct work_struct work; | |
169 | void *data; | |
170 | }; | |
171 | ||
172 | struct hinic_eq { | |
173 | struct hinic_hwif *hwif; | |
174 | ||
175 | enum hinic_eq_type type; | |
176 | int q_id; | |
177 | u32 q_len; | |
178 | u32 page_size; | |
179 | ||
180 | u32 cons_idx; | |
181 | int wrapped; | |
182 | ||
183 | size_t elem_size; | |
184 | int num_pages; | |
185 | int num_elem_in_pg; | |
186 | ||
187 | struct msix_entry msix_entry; | |
188 | ||
189 | dma_addr_t *dma_addr; | |
190 | void **virt_addr; | |
191 | ||
192 | struct hinic_eq_work aeq_work; | |
fc9319e4 AK |
193 | |
194 | struct tasklet_struct ceq_tasklet; | |
a5564e7e AK |
195 | }; |
196 | ||
197 | struct hinic_hw_event_cb { | |
198 | void (*hwe_handler)(void *handle, void *data, u8 size); | |
199 | void *handle; | |
200 | unsigned long hwe_state; | |
201 | }; | |
202 | ||
203 | struct hinic_aeqs { | |
204 | struct hinic_hwif *hwif; | |
205 | ||
206 | struct hinic_eq aeq[HINIC_MAX_AEQS]; | |
207 | int num_aeqs; | |
208 | ||
209 | struct hinic_hw_event_cb hwe_cb[HINIC_MAX_AEQ_EVENTS]; | |
210 | ||
211 | struct workqueue_struct *workq; | |
212 | }; | |
213 | ||
fc9319e4 AK |
214 | struct hinic_ceq_cb { |
215 | void (*handler)(void *handle, u32 ceqe_data); | |
216 | void *handle; | |
217 | enum hinic_eqe_state ceqe_state; | |
218 | }; | |
219 | ||
220 | struct hinic_ceqs { | |
221 | struct hinic_hwif *hwif; | |
222 | ||
223 | struct hinic_eq ceq[HINIC_MAX_CEQS]; | |
224 | int num_ceqs; | |
225 | ||
226 | struct hinic_ceq_cb ceq_cb[HINIC_MAX_CEQ_EVENTS]; | |
227 | }; | |
228 | ||
a5564e7e AK |
229 | void hinic_aeq_register_hw_cb(struct hinic_aeqs *aeqs, |
230 | enum hinic_aeq_type event, void *handle, | |
231 | void (*hwe_handler)(void *handle, void *data, | |
232 | u8 size)); | |
233 | ||
234 | void hinic_aeq_unregister_hw_cb(struct hinic_aeqs *aeqs, | |
235 | enum hinic_aeq_type event); | |
236 | ||
fc9319e4 AK |
237 | void hinic_ceq_register_cb(struct hinic_ceqs *ceqs, |
238 | enum hinic_ceq_type event, void *handle, | |
239 | void (*ceq_cb)(void *handle, u32 ceqe_data)); | |
240 | ||
241 | void hinic_ceq_unregister_cb(struct hinic_ceqs *ceqs, | |
242 | enum hinic_ceq_type event); | |
243 | ||
a5564e7e AK |
244 | int hinic_aeqs_init(struct hinic_aeqs *aeqs, struct hinic_hwif *hwif, |
245 | int num_aeqs, u32 q_len, u32 page_size, | |
246 | struct msix_entry *msix_entries); | |
247 | ||
248 | void hinic_aeqs_free(struct hinic_aeqs *aeqs); | |
249 | ||
fc9319e4 AK |
250 | int hinic_ceqs_init(struct hinic_ceqs *ceqs, struct hinic_hwif *hwif, |
251 | int num_ceqs, u32 q_len, u32 page_size, | |
252 | struct msix_entry *msix_entries); | |
253 | ||
254 | void hinic_ceqs_free(struct hinic_ceqs *ceqs); | |
255 | ||
a5564e7e | 256 | #endif |