Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2024 ZTE Corporation
3 : : */
4 : :
5 : : #include "zsda_qp.h"
6 : :
7 : : #define MAGIC_SEND 0xab
8 : : #define MAGIC_RECV 0xcd
9 : : #define ADMIN_VER 1
10 : : #define RING_DIR_TX 0
11 : : #define RING_DIR_RX 1
12 : :
13 : : static uint8_t zsda_num_used_qps;
14 : :
15 : : static struct ring_size zsda_qp_hw_ring_size[ZSDA_MAX_SERVICES] = {
16 : : [ZSDA_SERVICE_COMPRESSION] = {32, 16},
17 : : [ZSDA_SERVICE_DECOMPRESSION] = {32, 16},
18 : : [ZSDA_SERVICE_CRYPTO_ENCRY] = {128, 16},
19 : : [ZSDA_SERVICE_CRYPTO_DECRY] = {128, 16},
20 : : [ZSDA_SERVICE_HASH_ENCODE] = {32, 16},
21 : : };
22 : :
23 : : static const uint8_t crc8_table[256] = {
24 : : 0x00, 0x41, 0x13, 0x52, 0x26, 0x67, 0x35, 0x74, 0x4c, 0x0d, 0x5f, 0x1e,
25 : : 0x6a, 0x2b, 0x79, 0x38, 0x09, 0x48, 0x1a, 0x5b, 0x2f, 0x6e, 0x3c, 0x7d,
26 : : 0x45, 0x04, 0x56, 0x17, 0x63, 0x22, 0x70, 0x31, 0x12, 0x53, 0x01, 0x40,
27 : : 0x34, 0x75, 0x27, 0x66, 0x5e, 0x1f, 0x4d, 0x0c, 0x78, 0x39, 0x6b, 0x2a,
28 : : 0x1b, 0x5a, 0x08, 0x49, 0x3d, 0x7c, 0x2e, 0x6f, 0x57, 0x16, 0x44, 0x05,
29 : : 0x71, 0x30, 0x62, 0x23, 0x24, 0x65, 0x37, 0x76, 0x02, 0x43, 0x11, 0x50,
30 : : 0x68, 0x29, 0x7b, 0x3a, 0x4e, 0x0f, 0x5d, 0x1c, 0x2d, 0x6c, 0x3e, 0x7f,
31 : : 0x0b, 0x4a, 0x18, 0x59, 0x61, 0x20, 0x72, 0x33, 0x47, 0x06, 0x54, 0x15,
32 : : 0x36, 0x77, 0x25, 0x64, 0x10, 0x51, 0x03, 0x42, 0x7a, 0x3b, 0x69, 0x28,
33 : : 0x5c, 0x1d, 0x4f, 0x0e, 0x3f, 0x7e, 0x2c, 0x6d, 0x19, 0x58, 0x0a, 0x4b,
34 : : 0x73, 0x32, 0x60, 0x21, 0x55, 0x14, 0x46, 0x07, 0x48, 0x09, 0x5b, 0x1a,
35 : : 0x6e, 0x2f, 0x7d, 0x3c, 0x04, 0x45, 0x17, 0x56, 0x22, 0x63, 0x31, 0x70,
36 : : 0x41, 0x00, 0x52, 0x13, 0x67, 0x26, 0x74, 0x35, 0x0d, 0x4c, 0x1e, 0x5f,
37 : : 0x2b, 0x6a, 0x38, 0x79, 0x5a, 0x1b, 0x49, 0x08, 0x7c, 0x3d, 0x6f, 0x2e,
38 : : 0x16, 0x57, 0x05, 0x44, 0x30, 0x71, 0x23, 0x62, 0x53, 0x12, 0x40, 0x01,
39 : : 0x75, 0x34, 0x66, 0x27, 0x1f, 0x5e, 0x0c, 0x4d, 0x39, 0x78, 0x2a, 0x6b,
40 : : 0x6c, 0x2d, 0x7f, 0x3e, 0x4a, 0x0b, 0x59, 0x18, 0x20, 0x61, 0x33, 0x72,
41 : : 0x06, 0x47, 0x15, 0x54, 0x65, 0x24, 0x76, 0x37, 0x43, 0x02, 0x50, 0x11,
42 : : 0x29, 0x68, 0x3a, 0x7b, 0x0f, 0x4e, 0x1c, 0x5d, 0x7e, 0x3f, 0x6d, 0x2c,
43 : : 0x58, 0x19, 0x4b, 0x0a, 0x32, 0x73, 0x21, 0x60, 0x14, 0x55, 0x07, 0x46,
44 : : 0x77, 0x36, 0x64, 0x25, 0x51, 0x10, 0x42, 0x03, 0x3b, 0x7a, 0x28, 0x69,
45 : : 0x1d, 0x5c, 0x0e, 0x4f};
46 : :
47 : : static uint8_t
48 : : zsda_crc8(const uint8_t *message, const int length)
49 : : {
50 : : uint8_t crc = 0;
51 : : int i;
52 : :
53 [ # # # # ]: 0 : for (i = 0; i < length; i++)
54 : 0 : crc = crc8_table[crc ^ message[i]];
55 : : return crc;
56 : : }
57 : :
58 : : static uint8_t
59 : : zsda_used_qps_num_get(const struct rte_pci_device *pci_dev)
60 : : {
61 : 0 : uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
62 : : uint8_t num_used_qps;
63 : :
64 : : num_used_qps = ZSDA_CSR_READ8(mmio_base + 0);
65 : :
66 : : return num_used_qps;
67 : : }
68 : :
69 : : static int
70 : 0 : zsda_check_write(uint8_t *addr, const uint32_t dst_value)
71 : : {
72 : : int times = ZSDA_TIME_NUM;
73 : : uint32_t val;
74 : :
75 : : val = ZSDA_CSR_READ32(addr);
76 : :
77 [ # # # # ]: 0 : while ((val != dst_value) && times--) {
78 : : val = ZSDA_CSR_READ32(addr);
79 : 0 : rte_delay_us_sleep(ZSDA_TIME_SLEEP_US);
80 : : }
81 [ # # ]: 0 : if (val == dst_value)
82 : : return ZSDA_SUCCESS;
83 : : else
84 : 0 : return ZSDA_FAILED;
85 : : }
86 : :
87 : : static int
88 : : zsda_admin_q_start(const struct rte_pci_device *pci_dev)
89 : : {
90 : 0 : uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
91 : : int ret;
92 : :
93 : : ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_START, 0);
94 : :
95 : : ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_START, ZSDA_Q_START);
96 : 0 : ret = zsda_check_write(mmio_base + ZSDA_ADMIN_Q_START, ZSDA_Q_START);
97 : :
98 : : return ret;
99 : : }
100 : :
101 : : static int __rte_unused
102 : : zsda_admin_q_stop(const struct rte_pci_device *pci_dev)
103 : : {
104 : : uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
105 : : int ret;
106 : :
107 : : ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_STOP_RESP, ZSDA_RESP_INVALID);
108 : : ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_STOP, ZSDA_Q_STOP);
109 : :
110 : : ret = zsda_check_write(mmio_base + ZSDA_ADMIN_Q_STOP_RESP,
111 : : ZSDA_RESP_VALID);
112 : :
113 : : if (ret)
114 : : ZSDA_LOG(INFO, "Failed! zsda_admin q stop");
115 : :
116 : : return ret;
117 : : }
118 : :
119 : : static int __rte_unused
120 : : zsda_admin_q_clear(const struct rte_pci_device *pci_dev)
121 : : {
122 : : uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
123 : : int ret;
124 : :
125 : : ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_CLR_RESP, ZSDA_RESP_INVALID);
126 : : ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_CLR, ZSDA_RESP_VALID);
127 : :
128 : : ret = zsda_check_write(mmio_base + ZSDA_ADMIN_Q_CLR_RESP,
129 : : ZSDA_RESP_VALID);
130 : :
131 : : if (ret)
132 : : ZSDA_LOG(INFO, "Failed! zsda_admin q clear");
133 : :
134 : : return ret;
135 : : }
136 : :
137 : : static int
138 : : zsda_single_queue_start(uint8_t *mmio_base, const uint8_t id)
139 : : {
140 : 0 : uint8_t *addr_start = mmio_base + ZSDA_IO_Q_START + (4 * id);
141 : :
142 : : ZSDA_CSR_WRITE32(addr_start, ZSDA_Q_START);
143 : 0 : return zsda_check_write(addr_start, ZSDA_Q_START);
144 : : }
145 : :
146 : : static int
147 : 0 : zsda_single_queue_stop(uint8_t *mmio_base, const uint8_t id)
148 : : {
149 : : int ret;
150 : 0 : uint8_t *addr_stop = mmio_base + ZSDA_IO_Q_STOP + (4 * id);
151 : 0 : uint8_t *addr_resp = mmio_base + ZSDA_IO_Q_STOP_RESP + (4 * id);
152 : :
153 : : ZSDA_CSR_WRITE32(addr_resp, ZSDA_RESP_INVALID);
154 : : ZSDA_CSR_WRITE32(addr_stop, ZSDA_Q_STOP);
155 : :
156 : 0 : ret = zsda_check_write(addr_resp, ZSDA_RESP_VALID);
157 : : ZSDA_CSR_WRITE32(addr_resp, ZSDA_RESP_INVALID);
158 : :
159 : 0 : return ret;
160 : : }
161 : :
162 : : static int
163 : 0 : zsda_single_queue_clear(uint8_t *mmio_base, const uint8_t id)
164 : : {
165 : : int ret;
166 : 0 : uint8_t *addr_clear = mmio_base + ZSDA_IO_Q_CLR + (4 * id);
167 : 0 : uint8_t *addr_resp = mmio_base + ZSDA_IO_Q_CLR_RESP + (4 * id);
168 : :
169 : : ZSDA_CSR_WRITE32(addr_resp, ZSDA_RESP_INVALID);
170 : : ZSDA_CSR_WRITE32(addr_clear, ZSDA_CLEAR_VALID);
171 : 0 : ret = zsda_check_write(addr_resp, ZSDA_RESP_VALID);
172 : : ZSDA_CSR_WRITE32(addr_clear, ZSDA_CLEAR_INVALID);
173 : :
174 : 0 : return ret;
175 : : }
176 : :
177 : : int
178 : 0 : zsda_queue_start(const struct rte_pci_device *pci_dev)
179 : : {
180 : 0 : uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
181 : : uint8_t id;
182 : : int ret = ZSDA_SUCCESS;
183 : :
184 [ # # ]: 0 : for (id = 0; id < zsda_num_used_qps; id++)
185 : 0 : ret |= zsda_single_queue_start(mmio_base, id);
186 : :
187 : 0 : return ret;
188 : : }
189 : :
190 : : int
191 : 0 : zsda_queue_stop(const struct rte_pci_device *pci_dev)
192 : : {
193 : 0 : uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
194 : : uint8_t id;
195 : : int ret = ZSDA_SUCCESS;
196 : :
197 [ # # ]: 0 : for (id = 0; id < zsda_num_used_qps; id++)
198 : 0 : ret |= zsda_single_queue_stop(mmio_base, id);
199 : :
200 : 0 : return ret;
201 : : }
202 : :
203 : : static int
204 : : zsda_queue_clear(const struct rte_pci_device *pci_dev)
205 : : {
206 : 0 : uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
207 : : uint8_t id;
208 : : int ret = ZSDA_SUCCESS;
209 : :
210 [ # # ]: 0 : for (id = 0; id < zsda_num_used_qps; id++)
211 : 0 : ret |= zsda_single_queue_clear(mmio_base, id);
212 : :
213 : : return ret;
214 : : }
215 : :
216 : : static uint32_t
217 : : zsda_reg_8_set(void *addr, const uint8_t val0, const uint8_t val1,
218 : : const uint8_t val2, const uint8_t val3)
219 : : {
220 : : uint8_t val[4];
221 : :
222 : 0 : val[0] = val0;
223 : 0 : val[1] = val1;
224 : 0 : val[2] = val2;
225 : 0 : val[3] = val3;
226 : 0 : ZSDA_CSR_WRITE32(addr, *(uint32_t *)val);
227 : : return *(uint32_t *)val;
228 : : }
229 : :
230 : : static uint8_t
231 : : zsda_reg_8_get(void *addr, const int offset)
232 : : {
233 : : uint32_t val = ZSDA_CSR_READ32(addr);
234 : :
235 : 0 : return *(((uint8_t *)&val) + offset);
236 : : }
237 : :
238 : : static inline uint32_t
239 : : zsda_modulo_32(uint32_t data, uint32_t modulo_mask)
240 : : {
241 : 0 : return (data) & (modulo_mask);
242 : : }
243 : : static inline uint16_t
244 : : zsda_modulo_16(uint16_t data, uint16_t modulo_mask)
245 : : {
246 : 0 : return (data) & (modulo_mask);
247 : : }
248 : : static inline uint8_t
249 : : zsda_modulo_8(uint8_t data, uint8_t modulo_mask)
250 : : {
251 : 0 : return (data) & (modulo_mask);
252 : : }
253 : :
254 : : static int
255 : 0 : zsda_admin_msg_send(const struct rte_pci_device *pci_dev, void *req,
256 : : const uint32_t len)
257 : : {
258 : 0 : uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
259 : : uint8_t wq_flag;
260 : : uint8_t crc;
261 : : uint16_t admin_db;
262 : : uint32_t retry = ZSDA_TIME_NUM;
263 : : int i;
264 : : uint16_t db;
265 : : int repeat = sizeof(struct zsda_admin_req) / sizeof(uint32_t);
266 : :
267 [ # # ]: 0 : if (len > ADMIN_BUF_DATA_LEN)
268 : : return -EINVAL;
269 : :
270 [ # # ]: 0 : for (i = 0; i < repeat; i++) {
271 : 0 : ZSDA_CSR_WRITE32(((uint32_t *)(mmio_base + ZSDA_ADMIN_WQ) + i),
272 : : *((uint32_t *)req + i));
273 : : }
274 : :
275 : : crc = zsda_crc8((uint8_t *)req, ADMIN_BUF_DATA_LEN);
276 : : zsda_reg_8_set(mmio_base + ZSDA_ADMIN_WQ_BASE7, crc, ADMIN_VER, MAGIC_SEND, 0);
277 : 0 : rte_delay_us_sleep(ZSDA_TIME_SLEEP_US);
278 : : rte_wmb();
279 : :
280 : : admin_db = ZSDA_CSR_READ32(mmio_base + ZSDA_ADMIN_WQ_TAIL);
281 : : db = zsda_modulo_32(admin_db, 0x1ff);
282 : : ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_WQ_TAIL, db);
283 : :
284 : : do {
285 : 0 : rte_delay_us_sleep(ZSDA_TIME_SLEEP_US);
286 : : wq_flag = zsda_reg_8_get(mmio_base + ZSDA_ADMIN_WQ_BASE7, 2);
287 [ # # ]: 0 : if (wq_flag == MAGIC_RECV)
288 : : break;
289 : :
290 : 0 : retry--;
291 [ # # ]: 0 : if (!retry) {
292 : 0 : ZSDA_LOG(ERR, "wq_flag 0x%X", wq_flag);
293 : : zsda_reg_8_set(mmio_base + ZSDA_ADMIN_WQ_BASE7, 0, crc,
294 : : ADMIN_VER, 0);
295 : 0 : return -EIO;
296 : : }
297 : : } while (1);
298 : :
299 : : return ZSDA_SUCCESS;
300 : : }
301 : :
302 : : static int
303 : 0 : zsda_admin_msg_recv(const struct rte_pci_device *pci_dev, void *resp,
304 : : const uint32_t len)
305 : : {
306 : 0 : uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
307 : : uint8_t cq_flag;
308 : : uint32_t retry = ZSDA_TIME_NUM;
309 : : uint8_t crc;
310 : 0 : uint8_t buf[ADMIN_BUF_TOTAL_LEN] = {0};
311 : : uint32_t i;
312 : :
313 [ # # ]: 0 : if (len > ADMIN_BUF_DATA_LEN)
314 : : return -EINVAL;
315 : :
316 : : do {
317 : 0 : rte_delay_us_sleep(ZSDA_TIME_SLEEP_US);
318 : :
319 : : cq_flag = zsda_reg_8_get(mmio_base + ZSDA_ADMIN_CQ_BASE7, 2);
320 [ # # ]: 0 : if (cq_flag == MAGIC_SEND)
321 : : break;
322 : :
323 : 0 : retry--;
324 [ # # ]: 0 : if (!retry)
325 : : return -EIO;
326 : : } while (1);
327 : :
328 [ # # ]: 0 : for (i = 0; i < len; i++)
329 : 0 : buf[i] = ZSDA_CSR_READ8(mmio_base + ZSDA_ADMIN_CQ + i);
330 : :
331 : : crc = ZSDA_CSR_READ8(mmio_base + ZSDA_ADMIN_CQ_CRC);
332 : : rte_rmb();
333 : : ZSDA_CSR_WRITE8(mmio_base + ZSDA_ADMIN_CQ_FLAG, MAGIC_RECV);
334 [ # # ]: 0 : if (crc != zsda_crc8(buf, ADMIN_BUF_DATA_LEN)) {
335 : 0 : ZSDA_LOG(ERR, "[%d] Failed! crc error!", __LINE__);
336 : 0 : return -EIO;
337 : : }
338 : :
339 : 0 : memcpy(resp, buf, len);
340 : :
341 : 0 : return ZSDA_SUCCESS;
342 : : }
343 : :
344 : : static int
345 : : zsda_admin_msg_init(const struct rte_pci_device *pci_dev)
346 : : {
347 : 0 : uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
348 : :
349 : : zsda_reg_8_set(mmio_base + ZSDA_ADMIN_WQ_BASE7, 0, 0, MAGIC_RECV, 0);
350 : : zsda_reg_8_set(mmio_base + ZSDA_ADMIN_CQ_BASE7, 0, 0, MAGIC_RECV, 0);
351 : : return 0;
352 : : }
353 : :
354 : : static void
355 : : zsda_queue_head_tail_set(const struct zsda_pci_device *zsda_pci_dev,
356 : : const uint8_t qid)
357 : : {
358 : 0 : struct rte_pci_device *pci_dev =
359 : 0 : zsda_devs[zsda_pci_dev->zsda_dev_id].pci_dev;
360 : 0 : uint8_t *mmio_base = pci_dev->mem_resource[0].addr;
361 : :
362 : 0 : ZSDA_CSR_WRITE32(mmio_base + IO_DB_INITIAL_CONFIG + (qid * 4),
363 : : SET_HEAD_INTI);
364 : : }
365 : :
366 : : static int
367 : 0 : zsda_queue_cfg_by_id_get(const struct zsda_pci_device *zsda_pci_dev,
368 : : const uint8_t qid, struct qinfo *qcfg)
369 : : {
370 : 0 : struct zsda_admin_req_qcfg req = {0};
371 : 0 : struct zsda_admin_resp_qcfg resp = {0};
372 : : int ret;
373 : 0 : struct rte_pci_device *pci_dev =
374 : 0 : zsda_devs[zsda_pci_dev->zsda_dev_id].pci_dev;
375 : :
376 [ # # ]: 0 : if (qid >= MAX_QPS_ON_FUNCTION) {
377 : 0 : ZSDA_LOG(ERR, "qid beyond limit!");
378 : 0 : return ZSDA_FAILED;
379 : : }
380 : :
381 : : zsda_admin_msg_init(pci_dev);
382 : 0 : req.msg_type = ZSDA_ADMIN_QUEUE_CFG_REQ;
383 : 0 : req.qid = qid;
384 : :
385 : 0 : ret = zsda_admin_msg_send(pci_dev, &req, sizeof(req));
386 [ # # ]: 0 : if (ret) {
387 : 0 : ZSDA_LOG(ERR, "Failed! Send msg");
388 : 0 : return ret;
389 : : }
390 : :
391 : 0 : ret = zsda_admin_msg_recv(pci_dev, &resp, sizeof(resp));
392 [ # # ]: 0 : if (ret) {
393 : 0 : ZSDA_LOG(ERR, "Failed! Receive msg");
394 : 0 : return ret;
395 : : }
396 : :
397 : 0 : *qcfg = resp.qcfg;
398 : :
399 : 0 : return ZSDA_SUCCESS;
400 : : }
401 : :
402 : : static int
403 : 0 : zsda_queue_cfg_get(struct zsda_pci_device *zsda_pci_dev)
404 : : {
405 : : uint8_t i;
406 : : uint32_t index;
407 : : enum zsda_service_type type;
408 : 0 : struct zsda_qp_hw *zsda_hw_qps = zsda_pci_dev->zsda_hw_qps;
409 : 0 : struct qinfo qcfg = {0};
410 : : int ret = ZSDA_FAILED;
411 : :
412 [ # # ]: 0 : for (i = 0; i < zsda_num_used_qps; i++) {
413 : 0 : zsda_queue_head_tail_set(zsda_pci_dev, i);
414 : 0 : ret = zsda_queue_cfg_by_id_get(zsda_pci_dev, i, &qcfg);
415 : 0 : type = qcfg.q_type;
416 [ # # ]: 0 : if (ret) {
417 : 0 : ZSDA_LOG(ERR, "get queue cfg!");
418 : 0 : return ret;
419 : : }
420 [ # # ]: 0 : if (type >= ZSDA_SERVICE_INVALID)
421 : 0 : continue;
422 : :
423 : 0 : index = zsda_pci_dev->zsda_qp_hw_num[type];
424 : 0 : zsda_hw_qps[type].data[index].used = true;
425 : 0 : zsda_hw_qps[type].data[index].tx_ring_num = i;
426 : 0 : zsda_hw_qps[type].data[index].rx_ring_num = i;
427 : 0 : zsda_hw_qps[type].data[index].tx_msg_size =
428 : 0 : zsda_qp_hw_ring_size[type].tx_msg_size;
429 : 0 : zsda_hw_qps[type].data[index].rx_msg_size =
430 : 0 : zsda_qp_hw_ring_size[type].rx_msg_size;
431 : :
432 : 0 : zsda_pci_dev->zsda_qp_hw_num[type]++;
433 : : }
434 : :
435 : : return ret;
436 : : }
437 : :
438 : : static int
439 : 0 : zsda_flr_unmask_set(const struct zsda_pci_device *zsda_pci_dev)
440 : : {
441 : 0 : struct zsda_admin_req_qcfg req = {0};
442 : 0 : struct zsda_admin_resp_qcfg resp = {0};
443 : :
444 : : int ret = 0;
445 : 0 : struct rte_pci_device *pci_dev =
446 : 0 : zsda_devs[zsda_pci_dev->zsda_dev_id].pci_dev;
447 : :
448 : : zsda_admin_msg_init(pci_dev);
449 : :
450 : 0 : req.msg_type = ZSDA_FLR_SET_FUNCTION;
451 : :
452 : 0 : ret = zsda_admin_msg_send(pci_dev, &req, sizeof(req));
453 [ # # ]: 0 : if (ret) {
454 : 0 : ZSDA_LOG(ERR, "Failed! Send msg");
455 : 0 : return ret;
456 : : }
457 : :
458 : 0 : ret = zsda_admin_msg_recv(pci_dev, &resp, sizeof(resp));
459 [ # # ]: 0 : if (ret) {
460 : 0 : ZSDA_LOG(ERR, "Failed! Receive msg");
461 : 0 : return ret;
462 : : }
463 : :
464 : : return ZSDA_SUCCESS;
465 : : }
466 : :
467 : : static uint16_t
468 : : zsda_num_qps_get(const struct zsda_pci_device *zsda_pci_dev,
469 : : const enum zsda_service_type service)
470 : : {
471 : : uint16_t qp_hw_num = 0;
472 : :
473 : : if (service < ZSDA_SERVICE_INVALID)
474 : 0 : qp_hw_num = zsda_pci_dev->zsda_qp_hw_num[service];
475 : : return qp_hw_num;
476 : : }
477 : :
478 : : struct zsda_num_qps zsda_nb_qps;
479 : : static void
480 : : zsda_nb_qps_get(const struct zsda_pci_device *zsda_pci_dev)
481 : : {
482 : 0 : zsda_nb_qps.encomp =
483 : : zsda_num_qps_get(zsda_pci_dev, ZSDA_SERVICE_COMPRESSION);
484 : 0 : zsda_nb_qps.decomp =
485 : : zsda_num_qps_get(zsda_pci_dev, ZSDA_SERVICE_DECOMPRESSION);
486 : 0 : zsda_nb_qps.encrypt =
487 : : zsda_num_qps_get(zsda_pci_dev, ZSDA_SERVICE_CRYPTO_ENCRY);
488 : 0 : zsda_nb_qps.decrypt =
489 : : zsda_num_qps_get(zsda_pci_dev, ZSDA_SERVICE_CRYPTO_DECRY);
490 : 0 : zsda_nb_qps.hash =
491 : : zsda_num_qps_get(zsda_pci_dev, ZSDA_SERVICE_HASH_ENCODE);
492 : : }
493 : :
494 : : int
495 : 0 : zsda_queue_init(struct zsda_pci_device *zsda_pci_dev)
496 : : {
497 : : int ret;
498 : :
499 : 0 : zsda_num_used_qps = zsda_used_qps_num_get(zsda_pci_dev->pci_dev);
500 : 0 : zsda_num_used_qps++;
501 : :
502 : 0 : ret = zsda_admin_q_start(zsda_pci_dev->pci_dev);
503 [ # # ]: 0 : if (ret) {
504 : 0 : ZSDA_LOG(ERR, "Failed! admin q start");
505 : 0 : return ret;
506 : : }
507 : :
508 : 0 : ret = zsda_queue_clear(zsda_pci_dev->pci_dev);
509 [ # # ]: 0 : if (ret) {
510 : 0 : ZSDA_LOG(ERR, "Failed! used zsda_io q clear");
511 : 0 : return ret;
512 : : }
513 : :
514 : 0 : ret = zsda_queue_cfg_get(zsda_pci_dev);
515 [ # # ]: 0 : if (ret) {
516 : 0 : ZSDA_LOG(ERR, "Failed! zsda_queue_cfg_get");
517 : 0 : return ret;
518 : : }
519 : :
520 : 0 : ret = zsda_flr_unmask_set(zsda_pci_dev);
521 [ # # ]: 0 : if (ret) {
522 : 0 : ZSDA_LOG(ERR, "Failed! zsda_flr_unmask_set");
523 : 0 : return ret;
524 : : }
525 : :
526 : : zsda_nb_qps_get(zsda_pci_dev);
527 : :
528 : 0 : return ret;
529 : : }
530 : :
531 : : struct zsda_qp_hw *
532 : 0 : zsda_qps_hw_per_service(struct zsda_pci_device *zsda_pci_dev,
533 : : enum zsda_service_type type)
534 : : {
535 : : struct zsda_qp_hw *qp_hw = NULL;
536 : :
537 [ # # ]: 0 : if (type < ZSDA_SERVICE_INVALID)
538 : 0 : qp_hw = &(zsda_pci_dev->zsda_hw_qps[type]);
539 : :
540 : 0 : return qp_hw;
541 : : }
542 : :
543 : : static const struct rte_memzone *
544 : 0 : zsda_queue_dma_zone_reserve(const char *queue_name,
545 : : const unsigned int queue_size,
546 : : const unsigned int socket_id)
547 : : {
548 : : const struct rte_memzone *mz;
549 : :
550 : 0 : mz = rte_memzone_lookup(queue_name);
551 [ # # ]: 0 : if (mz != 0) {
552 [ # # # # ]: 0 : if (((size_t)queue_size <= mz->len) &&
553 : 0 : ((socket_id == (SOCKET_ID_ANY & 0xffff)) ||
554 [ # # ]: 0 : (socket_id == (mz->socket_id & 0xffff)))) {
555 : 0 : ZSDA_LOG(DEBUG,
556 : : "re-use memzone already allocated for %s",
557 : : queue_name);
558 : 0 : return mz;
559 : : }
560 : 0 : ZSDA_LOG(ERR, "Failed! queue_name exist");
561 : 0 : return NULL;
562 : : }
563 : :
564 : 0 : mz = rte_memzone_reserve_aligned(queue_name, queue_size,
565 : 0 : (int)(socket_id & 0xfff),
566 : : RTE_MEMZONE_IOVA_CONTIG, queue_size);
567 : :
568 : 0 : return mz;
569 : : }
570 : :
571 : : static int
572 : 0 : zsda_queue_create(const uint8_t dev_id, struct zsda_queue *queue,
573 : : const struct zsda_qp_config *qp_conf, const uint8_t dir)
574 : : {
575 : : void *io_addr;
576 : : const struct rte_memzone *qp_mz;
577 : 0 : struct qinfo qcfg = {0};
578 : :
579 [ # # ]: 0 : uint16_t desc_size = ((dir == RING_DIR_TX) ? qp_conf->hw->tx_msg_size
580 : 0 : : qp_conf->hw->rx_msg_size);
581 : 0 : unsigned int queue_size_bytes = qp_conf->nb_descriptors * desc_size;
582 : :
583 [ # # ]: 0 : queue->hw_queue_number =
584 : 0 : ((dir == RING_DIR_TX) ? qp_conf->hw->tx_ring_num
585 : 0 : : qp_conf->hw->rx_ring_num);
586 : :
587 : 0 : struct rte_pci_device *pci_dev = zsda_devs[dev_id].pci_dev;
588 : 0 : struct zsda_pci_device *zsda_dev =
589 : 0 : (struct zsda_pci_device *)zsda_devs[dev_id].mz->addr;
590 : :
591 : 0 : zsda_queue_cfg_by_id_get(zsda_dev, queue->hw_queue_number, &qcfg);
592 : :
593 [ # # ]: 0 : if (dir == RING_DIR_TX)
594 : 0 : snprintf(queue->memz_name, sizeof(queue->memz_name),
595 : 0 : "%s_%d_%s_%s_%d", pci_dev->driver->driver.name, dev_id,
596 : 0 : qp_conf->service_str, "qptxmem",
597 : 0 : queue->hw_queue_number);
598 : : else
599 : 0 : snprintf(queue->memz_name, sizeof(queue->memz_name),
600 : 0 : "%s_%d_%s_%s_%d", pci_dev->driver->driver.name, dev_id,
601 : 0 : qp_conf->service_str, "qprxmem",
602 : 0 : queue->hw_queue_number);
603 : :
604 : 0 : qp_mz = zsda_queue_dma_zone_reserve(queue->memz_name, queue_size_bytes,
605 : : rte_socket_id());
606 [ # # ]: 0 : if (qp_mz == NULL) {
607 : 0 : ZSDA_LOG(ERR, "Failed! qp_mz is NULL");
608 : 0 : return -ENOMEM;
609 : : }
610 : :
611 : 0 : queue->base_addr = qp_mz->addr;
612 : 0 : queue->base_phys_addr = qp_mz->iova;
613 : 0 : queue->modulo_mask = MAX_NUM_OPS;
614 : 0 : queue->msg_size = desc_size;
615 : :
616 [ # # ]: 0 : queue->head = (dir == RING_DIR_TX) ? qcfg.wq_head : qcfg.cq_head;
617 [ # # ]: 0 : queue->tail = (dir == RING_DIR_TX) ? qcfg.wq_tail : qcfg.cq_tail;
618 : :
619 [ # # ]: 0 : if ((queue->head == 0) && (queue->tail == 0))
620 : 0 : qcfg.cycle += 1;
621 : :
622 : 0 : queue->valid = qcfg.cycle & (ZSDA_MAX_CYCLE - 1);
623 : 0 : queue->queue_size = ZSDA_MAX_DESC;
624 : 0 : queue->cycle_size = ZSDA_MAX_CYCLE;
625 : 0 : queue->io_addr = pci_dev->mem_resource[0].addr;
626 : :
627 [ # # ]: 0 : memset(queue->base_addr, 0x0, queue_size_bytes);
628 : 0 : io_addr = pci_dev->mem_resource[0].addr;
629 : :
630 [ # # ]: 0 : if (dir == RING_DIR_TX)
631 : 0 : ZSDA_CSR_WQ_RING_BASE(io_addr, queue->hw_queue_number,
632 : : queue->base_phys_addr);
633 : : else
634 : 0 : ZSDA_CSR_CQ_RING_BASE(io_addr, queue->hw_queue_number,
635 : : queue->base_phys_addr);
636 : :
637 : : return 0;
638 : : }
639 : :
640 : : static int
641 : 0 : zsda_cookie_init(const uint8_t dev_id, struct zsda_qp *qp,
642 : : const uint16_t queue_pair_id,
643 : : const struct zsda_qp_config *zsda_qp_conf)
644 : : {
645 : : char op_cookie_pool_name[RTE_RING_NAMESIZE];
646 : : uint16_t i;
647 : 0 : enum zsda_service_type type = zsda_qp_conf->service_type;
648 : :
649 [ # # ]: 0 : if (zsda_qp_conf->nb_descriptors != ZSDA_MAX_DESC)
650 : 0 : ZSDA_LOG(ERR, "Can't create qp for %u descriptors",
651 : : zsda_qp_conf->nb_descriptors);
652 : :
653 : 0 : qp->srv[type].nb_descriptors = zsda_qp_conf->nb_descriptors;
654 : :
655 : 0 : qp->srv[type].op_cookies = rte_zmalloc_socket(
656 : : "zsda PMD op cookie pointer",
657 : 0 : zsda_qp_conf->nb_descriptors *
658 : : sizeof(*qp->srv[type].op_cookies),
659 : 0 : RTE_CACHE_LINE_SIZE, zsda_qp_conf->socket_id);
660 : :
661 [ # # ]: 0 : if (qp->srv[type].op_cookies == NULL) {
662 : 0 : ZSDA_LOG(ERR, "Failed! op_cookies is NULL");
663 : 0 : return -ENOMEM;
664 : : }
665 : :
666 : 0 : snprintf(op_cookie_pool_name, RTE_RING_NAMESIZE, "ZSDA%d_cks_%s_qp%hu",
667 : 0 : dev_id, zsda_qp_conf->service_str, queue_pair_id);
668 : :
669 : 0 : qp->srv[type].op_cookie_pool = rte_mempool_lookup(op_cookie_pool_name);
670 [ # # ]: 0 : if (qp->srv[type].op_cookie_pool == NULL)
671 : 0 : qp->srv[type].op_cookie_pool = rte_mempool_create(
672 : 0 : op_cookie_pool_name, qp->srv[type].nb_descriptors,
673 : 0 : zsda_qp_conf->cookie_size, 64, 0, NULL, NULL, NULL,
674 : 0 : NULL, (int)(rte_socket_id() & 0xfff), 0);
675 [ # # ]: 0 : if (!qp->srv[type].op_cookie_pool) {
676 : 0 : ZSDA_LOG(ERR, "Failed! op_cookie_pool is NULL");
677 : 0 : goto exit;
678 : : }
679 : :
680 [ # # ]: 0 : for (i = 0; i < qp->srv[type].nb_descriptors; i++) {
681 [ # # ]: 0 : if (rte_mempool_get(qp->srv[type].op_cookie_pool,
682 [ # # ]: 0 : &qp->srv[type].op_cookies[i])) {
683 : 0 : ZSDA_LOG(ERR, "ZSDA PMD Cannot get op_cookie");
684 : 0 : goto exit;
685 : : }
686 : 0 : memset(qp->srv[type].op_cookies[i], 0,
687 : 0 : zsda_qp_conf->cookie_size);
688 : : }
689 : : return ZSDA_SUCCESS;
690 : :
691 : 0 : exit:
692 : :
693 : 0 : rte_mempool_free(qp->srv[type].op_cookie_pool);
694 : 0 : rte_free(qp->srv[type].op_cookies);
695 : :
696 : 0 : return -EFAULT;
697 : : }
698 : :
699 : : static int
700 : 0 : zsda_queue_pair_setup(const uint8_t dev_id, struct zsda_qp *qp,
701 : : const uint16_t queue_pair_id,
702 : : const struct zsda_qp_config *zsda_qp_conf)
703 : : {
704 : 0 : struct rte_pci_device *pci_dev = zsda_devs[dev_id].pci_dev;
705 : : int ret;
706 : 0 : enum zsda_service_type type = zsda_qp_conf->service_type;
707 : :
708 [ # # ]: 0 : if (type >= ZSDA_SERVICE_INVALID) {
709 : 0 : ZSDA_LOG(ERR, "Failed! service type");
710 : 0 : return -EINVAL;
711 : : }
712 : :
713 [ # # ]: 0 : if (pci_dev->mem_resource[0].addr == NULL) {
714 : 0 : ZSDA_LOG(ERR, "Failed! mem_resource[0].addr is NULL");
715 : 0 : return -EINVAL;
716 : : }
717 : :
718 [ # # ]: 0 : if (zsda_queue_create(dev_id, &(qp->srv[type].tx_q), zsda_qp_conf,
719 : : RING_DIR_TX) != 0) {
720 : 0 : ZSDA_LOG(ERR, "Failed! zsda_queue_create tx");
721 : 0 : return -EFAULT;
722 : : }
723 : :
724 [ # # ]: 0 : if (zsda_queue_create(dev_id, &(qp->srv[type].rx_q), zsda_qp_conf,
725 : : RING_DIR_RX) != 0) {
726 : 0 : ZSDA_LOG(ERR, "Failed! zsda_queue_create rx");
727 : 0 : zsda_queue_delete(&(qp->srv[type].tx_q));
728 : 0 : return -EFAULT;
729 : : }
730 : :
731 : 0 : ret = zsda_cookie_init(dev_id, qp, queue_pair_id, zsda_qp_conf);
732 [ # # ]: 0 : if (ret) {
733 : 0 : zsda_queue_delete(&(qp->srv[type].tx_q));
734 : 0 : zsda_queue_delete(&(qp->srv[type].rx_q));
735 : : qp->srv[type].used = false;
736 : : }
737 : 0 : qp->srv[type].used = true;
738 : 0 : return ret;
739 : : }
740 : :
741 : : static int
742 : 0 : zsda_common_qp_setup(uint8_t zsda_dev_id, struct zsda_qp *qp,
743 : : const uint16_t queue_pair_id, const struct zsda_qp_config *conf)
744 : : {
745 : : uint16_t i;
746 : : int ret;
747 : : rte_iova_t cookie_phys_addr;
748 : :
749 : 0 : ret = zsda_queue_pair_setup(zsda_dev_id, qp, queue_pair_id, conf);
750 [ # # ]: 0 : if (ret)
751 : : return ret;
752 : :
753 [ # # ]: 0 : for (i = 0; i < qp->srv[conf->service_type].nb_descriptors; i++) {
754 : 0 : struct zsda_op_cookie *cookie =
755 : 0 : qp->srv[conf->service_type].op_cookies[i];
756 : : cookie_phys_addr = rte_mempool_virt2iova(cookie);
757 : :
758 : 0 : cookie->comp_head_phys_addr = cookie_phys_addr +
759 : : offsetof(struct zsda_op_cookie, comp_head);
760 : :
761 : 0 : cookie->sgl_src_phys_addr = cookie_phys_addr +
762 : : offsetof(struct zsda_op_cookie, sgl_src);
763 : :
764 : 0 : cookie->sgl_dst_phys_addr = cookie_phys_addr +
765 : : offsetof(struct zsda_op_cookie, sgl_dst);
766 : : }
767 : : return ret;
768 : : }
769 : :
770 : : int
771 : 0 : zsda_task_queue_setup(struct zsda_pci_device *zsda_pci_dev,
772 : : struct zsda_qp *qp, struct task_queue_info *task_q_info)
773 : : {
774 : 0 : enum zsda_service_type type = task_q_info->type;
775 : : struct zsda_qp_config conf;
776 : : int ret;
777 : : struct zsda_qp_hw *qp_hw;
778 : 0 : const uint16_t qp_id = task_q_info->qp_id;
779 : :
780 : 0 : qp_hw = zsda_qps_hw_per_service(zsda_pci_dev, type);
781 : 0 : conf.hw = qp_hw->data + qp_id;
782 : 0 : conf.service_type = type;
783 : 0 : conf.cookie_size = sizeof(struct zsda_op_cookie);
784 : 0 : conf.nb_descriptors = task_q_info->nb_des;
785 : 0 : conf.socket_id = task_q_info->socket_id;
786 : 0 : conf.service_str = task_q_info->service_str;
787 : :
788 : 0 : ret = zsda_common_qp_setup(zsda_pci_dev->zsda_dev_id, qp, qp_id, &conf);
789 : 0 : qp->srv[type].rx_cb = task_q_info->rx_cb;
790 : 0 : qp->srv[type].tx_cb = task_q_info->tx_cb;
791 : 0 : qp->srv[type].match = task_q_info->match;
792 : :
793 : 0 : return ret;
794 : : }
795 : :
796 : : static int
797 : : zsda_free_cookie_find(const struct zsda_queue *queue, void **op_cookie,
798 : : uint16_t *idx)
799 : : {
800 : 0 : uint16_t old_tail = queue->tail;
801 : : uint16_t tail = queue->tail;
802 : : struct zsda_op_cookie *cookie;
803 : :
804 : : do {
805 : 0 : cookie = op_cookie[tail];
806 [ # # ]: 0 : if (!cookie->used) {
807 : 0 : *idx = tail & (queue->queue_size - 1);
808 : : return ZSDA_SUCCESS;
809 : : }
810 : 0 : tail = zsda_modulo_16(tail++, queue->modulo_mask);
811 [ # # ]: 0 : } while (old_tail != tail);
812 : :
813 : : return -EINVAL;
814 : : }
815 : :
816 : : static int
817 : 0 : zsda_enqueue(void *op, struct zsda_qp *qp)
818 : : {
819 : : uint16_t new_tail;
820 : : enum zsda_service_type type;
821 : : void **op_cookie;
822 : : int ret = ZSDA_SUCCESS;
823 : : struct zsda_queue *queue;
824 : :
825 [ # # ]: 0 : for (type = 0; type < ZSDA_SERVICE_INVALID; type++) {
826 [ # # ]: 0 : if (qp->srv[type].used) {
827 [ # # ]: 0 : if (!qp->srv[type].match(op))
828 : 0 : continue;
829 : 0 : queue = &qp->srv[type].tx_q;
830 : 0 : op_cookie = qp->srv[type].op_cookies;
831 : :
832 : : if (zsda_free_cookie_find(queue, op_cookie,
833 : : &new_tail)) {
834 : : ret = -EBUSY;
835 : : break;
836 : : }
837 : 0 : ret = qp->srv[type].tx_cb(op, queue, op_cookie,
838 : : new_tail);
839 [ # # ]: 0 : if (ret) {
840 : 0 : qp->srv[type].stats.enqueue_err_count++;
841 : 0 : ZSDA_LOG(ERR, "Failed! config wqe");
842 : 0 : break;
843 : : }
844 : 0 : qp->srv[type].stats.enqueued_count++;
845 : :
846 : 0 : queue->tail = zsda_modulo_16(new_tail + 1,
847 : 0 : queue->queue_size - 1);
848 : :
849 [ # # ]: 0 : if (new_tail > queue->tail)
850 : 0 : queue->valid =
851 : 0 : zsda_modulo_8(queue->valid + 1,
852 : 0 : (uint8_t)(queue->cycle_size - 1));
853 : :
854 : 0 : queue->pushed_wqe++;
855 : 0 : break;
856 : : }
857 : : }
858 : :
859 : 0 : return ret;
860 : : }
861 : :
862 : : static void
863 : 0 : zsda_tx_tail_write(struct zsda_queue *queue)
864 : : {
865 [ # # ]: 0 : if (queue->pushed_wqe)
866 : 0 : WRITE_CSR_WQ_TAIL(queue->io_addr, queue->hw_queue_number,
867 : : queue->tail);
868 : :
869 : 0 : queue->pushed_wqe = 0;
870 : 0 : }
871 : :
872 : : uint16_t
873 : 0 : zsda_enqueue_burst(struct zsda_qp *qp, void **ops, const uint16_t nb_ops)
874 : : {
875 : : int ret = ZSDA_SUCCESS;
876 : : enum zsda_service_type type;
877 : : uint16_t i;
878 : : uint16_t nb_send = 0;
879 : : void *op;
880 : :
881 [ # # ]: 0 : if (nb_ops > ZSDA_MAX_DESC) {
882 : 0 : ZSDA_LOG(ERR, "Enqueue number bigger than %d", ZSDA_MAX_DESC);
883 : 0 : return 0;
884 : : }
885 : :
886 [ # # ]: 0 : for (i = 0; i < nb_ops; i++) {
887 : 0 : op = ops[i];
888 : 0 : ret = zsda_enqueue(op, qp);
889 [ # # ]: 0 : if (ret < 0)
890 : : break;
891 : 0 : nb_send++;
892 : : }
893 : :
894 [ # # ]: 0 : for (type = 0; type < ZSDA_SERVICE_INVALID; type++)
895 [ # # ]: 0 : if (qp->srv[type].used)
896 : 0 : zsda_tx_tail_write(&qp->srv[type].tx_q);
897 : :
898 : : return nb_send;
899 : : }
900 : :
901 : : static void
902 : 0 : zsda_dequeue(struct qp_srv *srv, void **ops, const uint16_t nb_ops, uint16_t *nb)
903 : : {
904 : : uint16_t head;
905 : : struct zsda_cqe *cqe;
906 : : struct zsda_queue *queue = &srv->rx_q;
907 : : struct zsda_op_cookie *cookie;
908 : 0 : head = queue->head;
909 : :
910 [ # # ]: 0 : while (*nb < nb_ops) {
911 : 0 : cqe = (struct zsda_cqe *)(
912 : 0 : (uint8_t *)queue->base_addr + head * queue->msg_size);
913 : :
914 [ # # ]: 0 : if (!CQE_VALID(cqe->err1))
915 : : break;
916 : 0 : cookie = srv->op_cookies[cqe->sid];
917 : :
918 : 0 : ops[*nb] = cookie->op;
919 [ # # ]: 0 : if (srv->rx_cb(cookie, cqe) == ZSDA_SUCCESS)
920 : 0 : srv->stats.dequeued_count++;
921 : : else {
922 : 0 : ZSDA_LOG(ERR,
923 : : "ERR! Cqe, opcode 0x%x, sid 0x%x, "
924 : : "tx_real_length 0x%x, err0 0x%x, err1 0x%x",
925 : : cqe->op_code, cqe->sid, cqe->tx_real_length,
926 : : cqe->err0, cqe->err1);
927 : 0 : srv->stats.dequeue_err_count++;
928 : : }
929 : 0 : (*nb)++;
930 : 0 : cookie->used = false;
931 : :
932 : 0 : head = zsda_modulo_16(head + 1, queue->modulo_mask);
933 : 0 : queue->head = head;
934 : 0 : WRITE_CSR_CQ_HEAD(queue->io_addr, queue->hw_queue_number, head);
935 : : memset(cqe, 0x0, sizeof(struct zsda_cqe));
936 : : }
937 : 0 : }
938 : :
939 : : uint16_t
940 : 0 : zsda_dequeue_burst(struct zsda_qp *qp, void **ops, const uint16_t nb_ops)
941 : : {
942 : 0 : uint16_t nb = 0;
943 : : uint32_t type = 0;
944 : : struct qp_srv *srv;
945 : :
946 [ # # ]: 0 : for (type = 0; type < ZSDA_SERVICE_INVALID; type++) {
947 [ # # ]: 0 : if (!qp->srv[type].used)
948 : 0 : continue;
949 : 0 : srv = &qp->srv[type];
950 : 0 : zsda_dequeue(srv, ops, nb_ops, &nb);
951 [ # # ]: 0 : if (nb >= nb_ops)
952 : : return nb_ops;
953 : : }
954 : 0 : return nb;
955 : : }
|