Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2025 Yunsilicon Technology Co., Ltd.
3 : : */
4 : :
5 : : #include <rte_io.h>
6 : :
7 : : #include "xsc_log.h"
8 : : #include "xsc_defs.h"
9 : : #include "xsc_dev.h"
10 : : #include "xsc_ethdev.h"
11 : : #include "xsc_cmd.h"
12 : : #include "xsc_rx.h"
13 : :
14 : : #define XSC_MAX_RECV_LEN 9800
15 : :
16 : : static inline void
17 : : xsc_cq_to_mbuf(struct xsc_rxq_data *rxq, struct rte_mbuf *pkt,
18 : : volatile struct xsc_cqe *cqe)
19 : : {
20 : : uint32_t rss_hash_res = 0;
21 : :
22 : 0 : pkt->port = rxq->port_id;
23 : 0 : if (rxq->rss_hash) {
24 : 0 : rss_hash_res = rte_be_to_cpu_32(cqe->vni);
25 [ # # ]: 0 : if (rss_hash_res) {
26 : 0 : pkt->hash.rss = rss_hash_res;
27 : 0 : pkt->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
28 : : }
29 : : }
30 : : }
31 : :
32 : : static inline int
33 : 0 : xsc_rx_poll_len(struct xsc_rxq_data *rxq, volatile struct xsc_cqe *cqe)
34 : : {
35 : : int len;
36 : :
37 : : do {
38 : : len = 0;
39 : : int ret;
40 : :
41 [ # # ]: 0 : ret = xsc_check_cqe_own(cqe, rxq->cqe_n, rxq->cq_ci);
42 [ # # ]: 0 : if (unlikely(ret != XSC_CQE_OWNER_SW)) {
43 [ # # ]: 0 : if (unlikely(ret == XSC_CQE_OWNER_ERR)) {
44 : 0 : ++rxq->stats.rx_errors;
45 : : } else {
46 : : return 0;
47 : : }
48 : : }
49 : :
50 : 0 : rxq->cq_ci += 1;
51 : 0 : len = rte_le_to_cpu_32(cqe->msg_len);
52 : 0 : return len;
53 : : } while (1);
54 : : }
55 : :
56 : : static __rte_always_inline void
57 : : xsc_pkt_info_sync(struct rte_mbuf *rep, struct rte_mbuf *seg)
58 : : {
59 : 0 : if (rep != NULL && seg != NULL) {
60 : 0 : rep->data_len = seg->data_len;
61 : 0 : rep->pkt_len = seg->pkt_len;
62 : 0 : rep->data_off = seg->data_off;
63 : 0 : rep->port = seg->port;
64 : : }
65 : : }
66 : :
67 : : uint16_t
68 : 0 : xsc_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
69 : : {
70 : : struct xsc_rxq_data *rxq = dpdk_rxq;
71 : 0 : const uint32_t wqe_m = rxq->wqe_m;
72 : 0 : const uint32_t cqe_m = rxq->cqe_m;
73 : 0 : const uint32_t sge_n = rxq->sge_n;
74 : : struct rte_mbuf *pkt = NULL;
75 : : struct rte_mbuf *seg = NULL;
76 : 0 : volatile struct xsc_cqe *cqe = &(*rxq->cqes)[rxq->cq_ci & cqe_m];
77 : : uint32_t nb_pkts = 0;
78 : : uint64_t nb_bytes = 0;
79 : 0 : uint32_t rq_ci = rxq->rq_ci;
80 : : int len = 0;
81 : : uint32_t cq_ci_two = 0;
82 : : int valid_cqe_num = 0;
83 : : int cqe_msg_len = 0;
84 : : volatile struct xsc_cqe_u64 *cqe_u64 = NULL;
85 : : struct rte_mbuf *rep;
86 : : uint16_t cq_pi;
87 : : uint16_t cqe_pkts_n = 0;
88 : :
89 [ # # ]: 0 : if (rxq->cq_pi != NULL) {
90 : 0 : cq_pi = (*(volatile uint32_t *)(rxq->cq_pi)) & 0xFFFF;
91 [ # # ]: 0 : if (cq_pi == rxq->cq_ci)
92 : : return 0;
93 : 0 : cqe_pkts_n = (uint16_t)((cq_pi - rxq->cq_ci) & 0xFFFF);
94 : 0 : pkts_n = pkts_n < cqe_pkts_n ? pkts_n : cqe_pkts_n;
95 : : }
96 : :
97 [ # # ]: 0 : while (pkts_n) {
98 : 0 : uint32_t idx = rq_ci & wqe_m;
99 : 0 : volatile struct xsc_wqe_data_seg *wqe =
100 : 0 : &((volatile struct xsc_wqe_data_seg *)rxq->wqes)[idx << sge_n];
101 : :
102 : 0 : seg = (*rxq->elts)[idx];
103 : : rte_prefetch0(cqe);
104 : : rte_prefetch0(wqe);
105 : :
106 : 0 : rep = rte_mbuf_raw_alloc(seg->pool);
107 [ # # ]: 0 : if (unlikely(rep == NULL)) {
108 : 0 : ++rxq->stats.rx_nombuf;
109 : 0 : break;
110 : : }
111 : :
112 : : if (!pkt) {
113 [ # # ]: 0 : if (valid_cqe_num) {
114 : 0 : cqe = cqe + 1;
115 : : len = cqe_msg_len;
116 : : valid_cqe_num = 0;
117 [ # # # # ]: 0 : } else if ((rxq->cq_ci % 2 == 0) && (pkts_n > 1)) {
118 : 0 : cq_ci_two = (rxq->cq_ci & rxq->cqe_m) / 2;
119 : 0 : cqe_u64 = &(*rxq->cqes_u64)[cq_ci_two];
120 : : cqe = (volatile struct xsc_cqe *)cqe_u64;
121 : 0 : len = xsc_rx_poll_len(rxq, cqe);
122 [ # # ]: 0 : if (len > 0) {
123 : 0 : cqe_msg_len = xsc_rx_poll_len(rxq, cqe + 1);
124 [ # # ]: 0 : if (cqe_msg_len > 0)
125 : : valid_cqe_num = 1;
126 : : }
127 : : } else {
128 : 0 : cqe = &(*rxq->cqes)[rxq->cq_ci & rxq->cqe_m];
129 : 0 : len = xsc_rx_poll_len(rxq, cqe);
130 : : }
131 : :
132 [ # # ]: 0 : if (!len) {
133 : : rte_mbuf_raw_free(rep);
134 : : break;
135 : : }
136 : :
137 [ # # ]: 0 : if (len > rte_pktmbuf_data_len(seg)) {
138 : : rte_mbuf_raw_free(rep);
139 : : pkt = NULL;
140 : 0 : ++rq_ci;
141 : 0 : continue;
142 : : }
143 : :
144 : : pkt = seg;
145 [ # # ]: 0 : pkt->ol_flags &= RTE_MBUF_F_EXTERNAL;
146 : : xsc_cq_to_mbuf(rxq, pkt, cqe);
147 : :
148 [ # # ]: 0 : if (rxq->crc_present)
149 : 0 : len -= RTE_ETHER_CRC_LEN;
150 [ # # ]: 0 : rte_pktmbuf_pkt_len(pkt) = len;
151 : : }
152 : :
153 : : xsc_pkt_info_sync(rep, seg);
154 : 0 : (*rxq->elts)[idx] = rep;
155 : :
156 : : /* Fill wqe */
157 : 0 : wqe->va = rte_cpu_to_le_64(rte_pktmbuf_iova(rep));
158 : 0 : rte_pktmbuf_data_len(seg) = len;
159 : 0 : nb_bytes += rte_pktmbuf_pkt_len(pkt);
160 : :
161 : 0 : *(pkts++) = pkt;
162 : : pkt = NULL;
163 : 0 : --pkts_n;
164 : 0 : ++nb_pkts;
165 : 0 : ++rq_ci;
166 : : }
167 : :
168 [ # # # # ]: 0 : if (unlikely(nb_pkts == 0 && rq_ci == rxq->rq_ci))
169 : : return 0;
170 : :
171 : 0 : rxq->rq_ci = rq_ci;
172 : 0 : rxq->nb_rx_hold += nb_pkts;
173 : :
174 [ # # ]: 0 : if (rxq->nb_rx_hold >= rxq->rx_free_thresh) {
175 : 0 : union xsc_cq_doorbell cq_db = {
176 : : .cq_data = 0
177 : : };
178 : 0 : cq_db.next_cid = rxq->cq_ci;
179 : 0 : cq_db.cq_num = rxq->cqn;
180 : :
181 : 0 : union xsc_recv_doorbell rq_db = {
182 : : .recv_data = 0
183 : : };
184 : 0 : rq_db.next_pid = (rxq->rq_ci << sge_n);
185 : 0 : rq_db.qp_num = rxq->qpn;
186 : :
187 : 0 : rte_write32(rte_cpu_to_le_32(cq_db.cq_data), rxq->cq_db);
188 : 0 : rte_write32(rte_cpu_to_le_32(rq_db.recv_data), rxq->rq_db);
189 : 0 : rxq->nb_rx_hold = 0;
190 : : }
191 : :
192 : 0 : rxq->stats.rx_pkts += nb_pkts;
193 : 0 : rxq->stats.rx_bytes += nb_bytes;
194 : :
195 : 0 : return nb_pkts;
196 : : }
197 : :
198 : : static void
199 : 0 : xsc_rxq_initialize(struct xsc_dev *xdev, struct xsc_rxq_data *rxq_data)
200 : : {
201 : 0 : const uint32_t wqe_n = rxq_data->wqe_s;
202 : : uint32_t i;
203 : : uint32_t seg_len = 0;
204 : : struct xsc_hwinfo *hwinfo = &xdev->hwinfo;
205 [ # # ]: 0 : uint32_t rx_ds_num = hwinfo->recv_seg_num;
206 : : uint32_t log2ds = rte_log2_u32(rx_ds_num);
207 : : uintptr_t addr;
208 : : struct rte_mbuf *mbuf;
209 : : void *jumbo_buffer_pa = xdev->jumbo_buffer_pa;
210 : 0 : void *jumbo_buffer_va = xdev->jumbo_buffer_va;
211 : : volatile struct xsc_wqe_data_seg *seg;
212 : : volatile struct xsc_wqe_data_seg *seg_next;
213 : :
214 [ # # ]: 0 : for (i = 0; (i != wqe_n); ++i) {
215 : 0 : mbuf = (*rxq_data->elts)[i];
216 [ # # ]: 0 : seg = &((volatile struct xsc_wqe_data_seg *)rxq_data->wqes)[i * rx_ds_num];
217 : 0 : addr = (uintptr_t)rte_pktmbuf_iova(mbuf);
218 [ # # ]: 0 : if (rx_ds_num == 1)
219 : : seg_len = XSC_MAX_RECV_LEN;
220 : : else
221 : 0 : seg_len = rte_pktmbuf_data_len(mbuf);
222 : 0 : *seg = (struct xsc_wqe_data_seg){
223 : : .va = rte_cpu_to_le_64(addr),
224 : : .seg_len = rte_cpu_to_le_32(seg_len),
225 : : .lkey = 0,
226 : : };
227 : :
228 [ # # ]: 0 : if (rx_ds_num != 1) {
229 : : seg_next = seg + 1;
230 [ # # ]: 0 : if (jumbo_buffer_va == NULL) {
231 : 0 : jumbo_buffer_pa = rte_malloc(NULL, XSC_MAX_RECV_LEN, 0);
232 [ # # ]: 0 : if (jumbo_buffer_pa == NULL) {
233 : : /* Rely on mtu */
234 : 0 : seg->seg_len = XSC_MAX_RECV_LEN;
235 : 0 : PMD_DRV_LOG(ERR, "Failed to malloc jumbo_buffer");
236 : 0 : continue;
237 : : } else {
238 : 0 : jumbo_buffer_va =
239 : 0 : (void *)rte_malloc_virt2iova(jumbo_buffer_pa);
240 [ # # ]: 0 : if ((rte_iova_t)jumbo_buffer_va == RTE_BAD_IOVA) {
241 : 0 : seg->seg_len = XSC_MAX_RECV_LEN;
242 : 0 : PMD_DRV_LOG(ERR, "Failed to turn jumbo_buffer");
243 : 0 : continue;
244 : : }
245 : : }
246 : 0 : xdev->jumbo_buffer_pa = jumbo_buffer_pa;
247 : 0 : xdev->jumbo_buffer_va = jumbo_buffer_va;
248 : : }
249 : 0 : *seg_next = (struct xsc_wqe_data_seg){
250 : 0 : .va = rte_cpu_to_le_64((uint64_t)jumbo_buffer_va),
251 : 0 : .seg_len = rte_cpu_to_le_32(XSC_MAX_RECV_LEN - seg_len),
252 : : .lkey = 0,
253 : : };
254 : : }
255 : : }
256 : :
257 : 0 : rxq_data->rq_ci = wqe_n;
258 : 0 : rxq_data->sge_n = log2ds;
259 : :
260 : 0 : union xsc_recv_doorbell recv_db = {
261 : : .recv_data = 0
262 : : };
263 : :
264 : 0 : recv_db.next_pid = wqe_n << log2ds;
265 : 0 : recv_db.qp_num = rxq_data->qpn;
266 : 0 : rte_write32(rte_cpu_to_le_32(recv_db.recv_data), rxq_data->rq_db);
267 : 0 : }
268 : :
269 : : static int
270 : 0 : xsc_alloc_qpn(struct xsc_dev *xdev, uint16_t *qpn_base, uint16_t qp_cnt)
271 : : {
272 : : int ret;
273 : 0 : struct xsc_cmd_alloc_qpn_mbox_in in = { };
274 : 0 : struct xsc_cmd_alloc_qpn_mbox_out out = { };
275 : :
276 : 0 : in.hdr.opcode = rte_cpu_to_be_16(XSC_CMD_OP_ALLOC_QPN);
277 [ # # ]: 0 : in.qp_cnt = rte_cpu_to_be_16(qp_cnt);
278 : 0 : in.qp_type = XSC_QUEUE_TYPE_RAW;
279 : :
280 : 0 : ret = xsc_dev_mailbox_exec(xdev, &in, sizeof(in), &out, sizeof(out));
281 [ # # # # ]: 0 : if (ret != 0 || out.hdr.status != 0) {
282 : 0 : PMD_DRV_LOG(ERR,
283 : : "Failed to allocate qpn, port id=%d, qp num=%d, "
284 : : "ret=%d, out.status=%u",
285 : : xdev->port_id, qp_cnt, ret, out.hdr.status);
286 : 0 : rte_errno = ENOEXEC;
287 : 0 : goto error;
288 : : }
289 : :
290 [ # # ]: 0 : *qpn_base = rte_be_to_cpu_16(out.qpn_base);
291 : 0 : return 0;
292 : :
293 : : error:
294 : 0 : return -rte_errno;
295 : : }
296 : :
297 : : static int
298 : 0 : xsc_free_qpn(struct xsc_dev *xdev, uint16_t qpn_base, uint16_t qp_cnt)
299 : : {
300 : : int ret;
301 : 0 : struct xsc_cmd_free_qpn_mbox_in in = { };
302 : 0 : struct xsc_cmd_free_qpn_mbox_out out = { };
303 : :
304 : 0 : in.hdr.opcode = rte_cpu_to_be_16(XSC_CMD_OP_FREE_QPN);
305 [ # # ]: 0 : in.qpn_base = rte_cpu_to_be_16(qpn_base);
306 [ # # ]: 0 : in.qp_cnt = rte_cpu_to_be_16(qp_cnt);
307 : 0 : in.qp_type = XSC_QUEUE_TYPE_RAW;
308 : :
309 : 0 : ret = xsc_dev_mailbox_exec(xdev, &in, sizeof(in), &out, sizeof(out));
310 [ # # # # ]: 0 : if (ret != 0 || out.hdr.status != 0) {
311 : 0 : PMD_DRV_LOG(ERR,
312 : : "Failed to free qpn, port id=%d, qpn base=%u, qp num=%d, "
313 : : "ret=%d, out.status=%u",
314 : : xdev->port_id, qpn_base, qp_cnt, ret, out.hdr.status);
315 : 0 : rte_errno = ENOEXEC;
316 : 0 : return -rte_errno;
317 : : }
318 : :
319 : : return 0;
320 : : }
321 : :
322 : : static int
323 : 0 : xsc_set_qp_info(struct xsc_dev *xdev, struct xsc_cmd_create_qp_request *qp_info, size_t pas_size)
324 : : {
325 : : int ret;
326 : : size_t in_size;
327 : : struct xsc_cmd_set_qp_info_in *in;
328 : 0 : struct xsc_cmd_set_qp_info_out out = { };
329 : :
330 : 0 : in_size = sizeof(*in) + pas_size;
331 : 0 : in = malloc(in_size);
332 [ # # ]: 0 : if (in == NULL) {
333 : 0 : rte_errno = ENOMEM;
334 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate memory for setting qp info");
335 : 0 : return -rte_errno;
336 : : }
337 : :
338 : 0 : in->hdr.opcode = rte_cpu_to_be_16(XSC_CMD_OP_SET_QP_INFO);
339 : 0 : memcpy(&in->qp_info, qp_info, sizeof(*qp_info) + pas_size);
340 : 0 : ret = xsc_dev_mailbox_exec(xdev, in, in_size, &out, sizeof(out));
341 [ # # # # ]: 0 : if (ret != 0 || out.hdr.status != 0) {
342 : 0 : PMD_DRV_LOG(ERR,
343 : : "Failed to set qp info, port id=%d, ret=%d, out.status=%u",
344 : : xdev->port_id, ret, out.hdr.status);
345 : 0 : rte_errno = ENOEXEC;
346 : 0 : goto error;
347 : : }
348 : :
349 : 0 : free(in);
350 : 0 : return 0;
351 : : error:
352 : 0 : free(in);
353 : 0 : return -rte_errno;
354 : : }
355 : :
356 : : static int
357 : 0 : xsc_unset_qp_info(struct xsc_dev *xdev, uint16_t qpn)
358 : : {
359 : : int ret;
360 : 0 : struct xsc_cmd_unset_qp_info_in in = { };
361 : 0 : struct xsc_cmd_unset_qp_info_out out = { };
362 : :
363 : 0 : in.hdr.opcode = rte_cpu_to_be_16(XSC_CMD_QP_UNSET_QP_INFO);
364 [ # # ]: 0 : in.qpn = rte_cpu_to_be_16(qpn);
365 : :
366 : 0 : ret = xsc_dev_mailbox_exec(xdev, &in, sizeof(in), &out, sizeof(out));
367 [ # # # # ]: 0 : if (ret != 0 || out.hdr.status != 0) {
368 : 0 : PMD_DRV_LOG(ERR,
369 : : "Failed to unset qp info, port id=%d, ret=%d, out.status=%u",
370 : : xdev->port_id, ret, out.hdr.status);
371 : 0 : rte_errno = ENOEXEC;
372 : 0 : return -rte_errno;
373 : : }
374 : :
375 : : return 0;
376 : : }
377 : :
378 : : static int
379 : 0 : xsc_rss_qp_create(struct xsc_ethdev_priv *priv, int port_id)
380 : : {
381 : : int ret;
382 : : int wqe_n;
383 : : int entry_total_len, entry_len;
384 : : uint32_t wqe_total_len;
385 : : uint16_t rqn_base, pa_num;
386 : : uint16_t i, j;
387 : : uint16_t set_last_no = 0;
388 : : uint8_t log_ele, log_rq_sz, log_sq_sz = 0;
389 : : uint64_t iova;
390 : : size_t pas_size;
391 : : struct xsc_rxq_data *rxq_data;
392 : 0 : struct xsc_dev *xdev = priv->xdev;
393 : : struct xsc_cmd_create_qp_request *req, *info;
394 : : struct xsc_hwinfo *hwinfo = &xdev->hwinfo;
395 : 0 : char name[RTE_ETH_NAME_MAX_LEN] = { 0 };
396 [ # # ]: 0 : uint32_t numa_node = priv->eth_dev->device->numa_node;
397 : :
398 : : rxq_data = xsc_rxq_get(priv, 0);
399 : : if (rxq_data == NULL) {
400 : 0 : rte_errno = EINVAL;
401 : 0 : return -rte_errno;
402 : : }
403 : :
404 [ # # ]: 0 : if (numa_node != rxq_data->socket)
405 : 0 : PMD_DRV_LOG(WARNING, "Port %u: rxq numa_node=%u, device numa_node=%u",
406 : : port_id, rxq_data->socket, numa_node);
407 : :
408 : : log_ele = rte_log2_u32(sizeof(struct xsc_wqe_data_seg));
409 : 0 : wqe_n = rxq_data->wqe_s;
410 [ # # ]: 0 : log_rq_sz = rte_log2_u32(wqe_n * hwinfo->recv_seg_num);
411 : 0 : wqe_total_len = 1 << (log_rq_sz + log_sq_sz + log_ele);
412 : :
413 : 0 : pa_num = (wqe_total_len + XSC_PAGE_SIZE - 1) / XSC_PAGE_SIZE;
414 : 0 : entry_len = sizeof(struct xsc_cmd_create_qp_request) + sizeof(uint64_t) * pa_num;
415 : 0 : entry_total_len = entry_len * priv->num_rq;
416 : :
417 : 0 : req = malloc(entry_total_len);
418 [ # # ]: 0 : if (req == NULL) {
419 : 0 : rte_errno = ENOMEM;
420 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc create qp request cmd memory");
421 : 0 : return -rte_errno;
422 : : }
423 : :
424 : 0 : ret = xsc_alloc_qpn(xdev, &rqn_base, priv->num_rq);
425 [ # # ]: 0 : if (ret != 0)
426 : 0 : goto alloc_qpn_fail;
427 : :
428 [ # # ]: 0 : for (i = 0; i < priv->num_rq; i++) {
429 [ # # ]: 0 : rxq_data = xsc_rxq_get(priv, i);
430 : : if (rxq_data == NULL) {
431 : 0 : rte_errno = EINVAL;
432 : 0 : goto set_qp_fail;
433 : : }
434 : :
435 : 0 : info = (struct xsc_cmd_create_qp_request *)((uint8_t *)req + entry_len * i);
436 [ # # ]: 0 : info->input_qpn = rte_cpu_to_be_16(rqn_base + i);
437 [ # # ]: 0 : info->pa_num = rte_cpu_to_be_16(pa_num);
438 : 0 : info->qp_type = XSC_QUEUE_TYPE_RAW;
439 : 0 : info->log_rq_sz = log_rq_sz;
440 [ # # ]: 0 : info->cqn_recv = rte_cpu_to_be_16((uint16_t)rxq_data->cqn);
441 : 0 : info->cqn_send = info->cqn_recv;
442 [ # # ]: 0 : info->glb_funcid = rte_cpu_to_be_16((uint16_t)hwinfo->func_id);
443 : : /* Alloc pas addr */
444 : : snprintf(name, sizeof(name), "wqe_mem_rx_%d_%d", port_id, i);
445 : 0 : rxq_data->rq_pas = rte_memzone_reserve_aligned(name,
446 : 0 : (XSC_PAGE_SIZE * pa_num),
447 : 0 : rxq_data->socket,
448 : : RTE_MEMZONE_IOVA_CONTIG,
449 : : XSC_PAGE_SIZE);
450 [ # # ]: 0 : if (rxq_data->rq_pas == NULL) {
451 : 0 : rte_errno = ENOMEM;
452 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc rxq pas memory");
453 : 0 : goto set_qp_fail;
454 : : }
455 : :
456 : 0 : iova = rxq_data->rq_pas->iova;
457 [ # # ]: 0 : for (j = 0; j < pa_num; j++)
458 [ # # ]: 0 : info->pas[j] = rte_cpu_to_be_64(iova + j * XSC_PAGE_SIZE);
459 : :
460 : 0 : pas_size = pa_num * sizeof(uint64_t);
461 : 0 : ret = xsc_set_qp_info(xdev, info, pas_size);
462 [ # # ]: 0 : if (ret != 0)
463 : 0 : goto set_qp_fail;
464 : :
465 : 0 : set_last_no++;
466 : : }
467 : :
468 [ # # ]: 0 : for (i = 0; i < priv->num_rq; i++) {
469 [ # # ]: 0 : rxq_data = xsc_rxq_get(priv, i);
470 : : if (rxq_data == NULL) {
471 : 0 : rte_errno = EINVAL;
472 : 0 : goto set_qp_fail;
473 : : }
474 : :
475 : 0 : rxq_data->wqes = rxq_data->rq_pas->addr;
476 [ # # ]: 0 : if (!xsc_dev_is_vf(xdev)) {
477 : 0 : rxq_data->rq_db = (uint32_t *)((uint8_t *)xdev->bar_addr +
478 : : XSC_PF_RX_DB_ADDR);
479 : 0 : rxq_data->cq_pi = (uint32_t *)((uint8_t *)xdev->bar_addr +
480 : 0 : XSC_PF_CQ_PID_START_ADDR + rxq_data->cqn * 4);
481 : : } else {
482 : 0 : rxq_data->rq_db = (uint32_t *)((uint8_t *)xdev->bar_addr +
483 : : XSC_VF_RX_DB_ADDR);
484 : 0 : rxq_data->cq_pi = NULL;
485 : : }
486 : :
487 : 0 : rxq_data->qpn = rqn_base + i;
488 : 0 : xsc_dev_modify_qp_status(xdev, rxq_data->qpn, 1, XSC_CMD_OP_RTR2RTS_QP);
489 : 0 : xsc_rxq_initialize(xdev, rxq_data);
490 : 0 : rxq_data->cq_ci = 0;
491 : 0 : PMD_DRV_LOG(INFO, "Port %d create rx qp, wqe_s:%d, wqe_n:%d, qp_db=%p, qpn:%u",
492 : : port_id,
493 : : rxq_data->wqe_s, rxq_data->wqe_n,
494 : : rxq_data->rq_db, rxq_data->qpn);
495 : : }
496 : :
497 : 0 : free(req);
498 : 0 : return 0;
499 : :
500 : 0 : set_qp_fail:
501 : 0 : free(req);
502 [ # # ]: 0 : for (i = 0; i < set_last_no; i++) {
503 : 0 : xsc_unset_qp_info(xdev, rqn_base + i);
504 [ # # ]: 0 : rxq_data = xsc_rxq_get(priv, i);
505 : 0 : if (rxq_data == NULL)
506 : 0 : continue;
507 : 0 : rte_memzone_free(rxq_data->rq_pas);
508 : 0 : rxq_data->rq_pas = NULL;
509 : : }
510 : :
511 : 0 : xsc_free_qpn(xdev, rqn_base, priv->num_rq);
512 : 0 : return -rte_errno;
513 : :
514 : : alloc_qpn_fail:
515 : 0 : free(req);
516 : 0 : return -rte_errno;
517 : : }
518 : :
519 : : int
520 : 0 : xsc_rxq_rss_obj_new(struct xsc_ethdev_priv *priv, uint16_t port_id)
521 : : {
522 : : int ret;
523 : : uint32_t i;
524 : 0 : struct xsc_dev *xdev = priv->xdev;
525 : : struct xsc_rxq_data *rxq_data;
526 : 0 : struct xsc_rx_cq_params cq_params = {0};
527 : 0 : struct xsc_rx_cq_info cq_info = {0};
528 : :
529 : : /* Create CQ */
530 [ # # ]: 0 : for (i = 0; i < priv->num_rq; ++i) {
531 [ # # ]: 0 : rxq_data = xsc_rxq_get(priv, i);
532 : : if (rxq_data == NULL)
533 : : return -EINVAL;
534 : :
535 : : memset(&cq_params, 0, sizeof(cq_params));
536 : : memset(&cq_info, 0, sizeof(cq_info));
537 : 0 : cq_params.port_id = rxq_data->port_id;
538 : 0 : cq_params.qp_id = rxq_data->idx;
539 : 0 : cq_params.wqe_s = rxq_data->wqe_s;
540 : 0 : cq_params.socket_id = rxq_data->socket;
541 : :
542 : 0 : ret = xsc_dev_rx_cq_create(xdev, &cq_params, &cq_info);
543 [ # # ]: 0 : if (ret) {
544 : 0 : PMD_DRV_LOG(ERR, "Port %u rxq %u create cq fail", port_id, i);
545 : 0 : rte_errno = errno;
546 : 0 : goto error;
547 : : }
548 : :
549 : 0 : rxq_data->cq = cq_info.cq;
550 : 0 : rxq_data->cqe_n = cq_info.cqe_n;
551 : 0 : rxq_data->cqe_s = 1 << rxq_data->cqe_n;
552 : 0 : rxq_data->cqe_m = rxq_data->cqe_s - 1;
553 : 0 : rxq_data->cqes = cq_info.cqes;
554 : 0 : rxq_data->cq_db = cq_info.cq_db;
555 : 0 : rxq_data->cqn = cq_info.cqn;
556 : :
557 : 0 : PMD_DRV_LOG(INFO, "Port %u create rx cq, cqe_s:%d, cqe_n:%d, cq_db=%p, cqn:%u",
558 : : port_id,
559 : : rxq_data->cqe_s, rxq_data->cqe_n,
560 : : rxq_data->cq_db, rxq_data->cqn);
561 : : }
562 : :
563 : 0 : ret = xsc_rss_qp_create(priv, port_id);
564 [ # # ]: 0 : if (ret != 0) {
565 : 0 : PMD_DRV_LOG(ERR, "Port %u rss rxq create fail", port_id);
566 : 0 : goto error;
567 : : }
568 : : return 0;
569 : :
570 : 0 : error:
571 : 0 : return -rte_errno;
572 : : }
573 : :
574 : : int
575 : 0 : xsc_rxq_elts_alloc(struct xsc_rxq_data *rxq_data)
576 : : {
577 : 0 : uint32_t elts_s = rxq_data->wqe_s;
578 : : struct rte_mbuf *mbuf;
579 : : uint32_t i;
580 : :
581 [ # # ]: 0 : for (i = 0; (i != elts_s); ++i) {
582 : 0 : mbuf = rte_pktmbuf_alloc(rxq_data->mp);
583 [ # # ]: 0 : if (mbuf == NULL) {
584 : 0 : PMD_DRV_LOG(ERR, "Port %u rxq %u empty mbuf pool",
585 : : rxq_data->port_id, rxq_data->idx);
586 : 0 : rte_errno = ENOMEM;
587 : 0 : goto error;
588 : : }
589 : :
590 : 0 : mbuf->port = rxq_data->port_id;
591 : 0 : mbuf->nb_segs = 1;
592 : 0 : rte_pktmbuf_data_len(mbuf) = mbuf->buf_len - mbuf->data_off;
593 : 0 : rte_pktmbuf_pkt_len(mbuf) = rte_pktmbuf_data_len(mbuf);
594 : 0 : (*rxq_data->elts)[i] = mbuf;
595 : : }
596 : :
597 : : return 0;
598 : : error:
599 : : elts_s = i;
600 [ # # ]: 0 : for (i = 0; (i != elts_s); ++i) {
601 [ # # ]: 0 : if ((*rxq_data->elts)[i] != NULL)
602 : : rte_pktmbuf_free_seg((*rxq_data->elts)[i]);
603 : 0 : (*rxq_data->elts)[i] = NULL;
604 : : }
605 : :
606 : 0 : PMD_DRV_LOG(ERR, "Port %u rxq %u start failed, free elts",
607 : : rxq_data->port_id, rxq_data->idx);
608 : :
609 : 0 : return -rte_errno;
610 : : }
611 : :
612 : : void
613 : 0 : xsc_rxq_elts_free(struct xsc_rxq_data *rxq_data)
614 : : {
615 : : uint16_t i;
616 : :
617 [ # # ]: 0 : if (rxq_data->elts == NULL)
618 : : return;
619 [ # # ]: 0 : for (i = 0; i != rxq_data->wqe_s; ++i) {
620 [ # # ]: 0 : if ((*rxq_data->elts)[i] != NULL)
621 : : rte_pktmbuf_free_seg((*rxq_data->elts)[i]);
622 : 0 : (*rxq_data->elts)[i] = NULL;
623 : : }
624 : :
625 : 0 : PMD_DRV_LOG(DEBUG, "Port %u rxq %u free elts", rxq_data->port_id, rxq_data->idx);
626 : : }
627 : :
628 : : void
629 : 0 : xsc_rxq_rss_obj_release(struct xsc_dev *xdev, struct xsc_rxq_data *rxq_data)
630 : : {
631 : 0 : struct xsc_cmd_destroy_qp_mbox_in in = { .hdr = { 0 } };
632 : 0 : struct xsc_cmd_destroy_qp_mbox_out out = { .hdr = { 0 } };
633 : : int ret, in_len, out_len;
634 : 0 : uint32_t qpn = rxq_data->qpn;
635 : :
636 : 0 : xsc_dev_modify_qp_status(xdev, qpn, 1, XSC_CMD_OP_QP_2RST);
637 : :
638 : : in_len = sizeof(struct xsc_cmd_destroy_qp_mbox_in);
639 : : out_len = sizeof(struct xsc_cmd_destroy_qp_mbox_out);
640 : 0 : in.hdr.opcode = rte_cpu_to_be_16(XSC_CMD_OP_DESTROY_QP);
641 [ # # ]: 0 : in.qpn = rte_cpu_to_be_32(rxq_data->qpn);
642 : :
643 : 0 : ret = xsc_dev_mailbox_exec(xdev, &in, in_len, &out, out_len);
644 [ # # # # ]: 0 : if (ret != 0 || out.hdr.status != 0) {
645 : 0 : PMD_DRV_LOG(ERR,
646 : : "Release rss rq failed, port id=%d, qid=%d, err=%d, out.status=%u",
647 : : rxq_data->port_id, rxq_data->idx, ret, out.hdr.status);
648 : 0 : rte_errno = ENOEXEC;
649 : 0 : return;
650 : : }
651 : :
652 : 0 : rte_memzone_free(rxq_data->rq_pas);
653 : :
654 [ # # ]: 0 : if (rxq_data->cq != NULL)
655 : 0 : xsc_dev_destroy_cq(xdev, rxq_data->cq);
656 : 0 : rxq_data->cq = NULL;
657 : : }
|