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