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 : :
87 [ # # ]: 0 : while (pkts_n) {
88 : 0 : uint32_t idx = rq_ci & wqe_m;
89 : 0 : volatile struct xsc_wqe_data_seg *wqe =
90 : 0 : &((volatile struct xsc_wqe_data_seg *)rxq->wqes)[idx << sge_n];
91 : :
92 : 0 : seg = (*rxq->elts)[idx];
93 : : rte_prefetch0(cqe);
94 : : rte_prefetch0(wqe);
95 : :
96 : 0 : rep = rte_mbuf_raw_alloc(seg->pool);
97 [ # # ]: 0 : if (unlikely(rep == NULL)) {
98 : 0 : ++rxq->stats.rx_nombuf;
99 : 0 : break;
100 : : }
101 : :
102 : : if (!pkt) {
103 [ # # ]: 0 : if (valid_cqe_num) {
104 : 0 : cqe = cqe + 1;
105 : : len = cqe_msg_len;
106 : : valid_cqe_num = 0;
107 [ # # # # ]: 0 : } else if ((rxq->cq_ci % 2 == 0) && (pkts_n > 1)) {
108 : 0 : cq_ci_two = (rxq->cq_ci & rxq->cqe_m) / 2;
109 : 0 : cqe_u64 = &(*rxq->cqes_u64)[cq_ci_two];
110 : : cqe = (volatile struct xsc_cqe *)cqe_u64;
111 : 0 : len = xsc_rx_poll_len(rxq, cqe);
112 [ # # ]: 0 : if (len > 0) {
113 : 0 : cqe_msg_len = xsc_rx_poll_len(rxq, cqe + 1);
114 [ # # ]: 0 : if (cqe_msg_len > 0)
115 : : valid_cqe_num = 1;
116 : : }
117 : : } else {
118 : 0 : cqe = &(*rxq->cqes)[rxq->cq_ci & rxq->cqe_m];
119 : 0 : len = xsc_rx_poll_len(rxq, cqe);
120 : : }
121 : :
122 [ # # ]: 0 : if (!len) {
123 : : rte_mbuf_raw_free(rep);
124 : : break;
125 : : }
126 : :
127 [ # # ]: 0 : if (len > rte_pktmbuf_data_len(seg)) {
128 : : rte_mbuf_raw_free(rep);
129 : : pkt = NULL;
130 : 0 : ++rq_ci;
131 : 0 : continue;
132 : : }
133 : :
134 : : pkt = seg;
135 [ # # ]: 0 : pkt->ol_flags &= RTE_MBUF_F_EXTERNAL;
136 : : xsc_cq_to_mbuf(rxq, pkt, cqe);
137 : :
138 [ # # ]: 0 : if (rxq->crc_present)
139 : 0 : len -= RTE_ETHER_CRC_LEN;
140 [ # # ]: 0 : rte_pktmbuf_pkt_len(pkt) = len;
141 : : }
142 : :
143 : : xsc_pkt_info_sync(rep, seg);
144 : 0 : (*rxq->elts)[idx] = rep;
145 : :
146 : : /* Fill wqe */
147 : 0 : wqe->va = rte_cpu_to_le_64(rte_pktmbuf_iova(rep));
148 : 0 : rte_pktmbuf_data_len(seg) = len;
149 : 0 : nb_bytes += rte_pktmbuf_pkt_len(pkt);
150 : :
151 : 0 : *(pkts++) = pkt;
152 : : pkt = NULL;
153 : 0 : --pkts_n;
154 : 0 : ++nb_pkts;
155 : 0 : ++rq_ci;
156 : : }
157 : :
158 [ # # # # ]: 0 : if (unlikely(nb_pkts == 0 && rq_ci == rxq->rq_ci))
159 : : return 0;
160 : :
161 : 0 : rxq->rq_ci = rq_ci;
162 : 0 : rxq->nb_rx_hold += nb_pkts;
163 : :
164 [ # # ]: 0 : if (rxq->nb_rx_hold >= rxq->rx_free_thresh) {
165 : 0 : union xsc_cq_doorbell cq_db = {
166 : : .cq_data = 0
167 : : };
168 : 0 : cq_db.next_cid = rxq->cq_ci;
169 : 0 : cq_db.cq_num = rxq->cqn;
170 : :
171 : 0 : union xsc_recv_doorbell rq_db = {
172 : : .recv_data = 0
173 : : };
174 : 0 : rq_db.next_pid = (rxq->rq_ci << sge_n);
175 : 0 : rq_db.qp_num = rxq->qpn;
176 : :
177 : 0 : rte_write32(rte_cpu_to_le_32(cq_db.cq_data), rxq->cq_db);
178 : 0 : rte_write32(rte_cpu_to_le_32(rq_db.recv_data), rxq->rq_db);
179 : 0 : rxq->nb_rx_hold = 0;
180 : : }
181 : :
182 : 0 : rxq->stats.rx_pkts += nb_pkts;
183 : 0 : rxq->stats.rx_bytes += nb_bytes;
184 : :
185 : 0 : return nb_pkts;
186 : : }
187 : :
188 : : static void
189 : 0 : xsc_rxq_initialize(struct xsc_dev *xdev, struct xsc_rxq_data *rxq_data)
190 : : {
191 : 0 : const uint32_t wqe_n = rxq_data->wqe_s;
192 : : uint32_t i;
193 : : uint32_t seg_len = 0;
194 : : struct xsc_hwinfo *hwinfo = &xdev->hwinfo;
195 [ # # ]: 0 : uint32_t rx_ds_num = hwinfo->recv_seg_num;
196 : : uint32_t log2ds = rte_log2_u32(rx_ds_num);
197 : : uintptr_t addr;
198 : : struct rte_mbuf *mbuf;
199 : : void *jumbo_buffer_pa = xdev->jumbo_buffer_pa;
200 : 0 : void *jumbo_buffer_va = xdev->jumbo_buffer_va;
201 : : volatile struct xsc_wqe_data_seg *seg;
202 : : volatile struct xsc_wqe_data_seg *seg_next;
203 : :
204 [ # # ]: 0 : for (i = 0; (i != wqe_n); ++i) {
205 : 0 : mbuf = (*rxq_data->elts)[i];
206 [ # # ]: 0 : seg = &((volatile struct xsc_wqe_data_seg *)rxq_data->wqes)[i * rx_ds_num];
207 : 0 : addr = (uintptr_t)rte_pktmbuf_iova(mbuf);
208 [ # # ]: 0 : if (rx_ds_num == 1)
209 : : seg_len = XSC_MAX_RECV_LEN;
210 : : else
211 : 0 : seg_len = rte_pktmbuf_data_len(mbuf);
212 : 0 : *seg = (struct xsc_wqe_data_seg){
213 : : .va = rte_cpu_to_le_64(addr),
214 : : .seg_len = rte_cpu_to_le_32(seg_len),
215 : : .lkey = 0,
216 : : };
217 : :
218 [ # # ]: 0 : if (rx_ds_num != 1) {
219 : : seg_next = seg + 1;
220 [ # # ]: 0 : if (jumbo_buffer_va == NULL) {
221 : 0 : jumbo_buffer_pa = rte_malloc(NULL, XSC_MAX_RECV_LEN, 0);
222 [ # # ]: 0 : if (jumbo_buffer_pa == NULL) {
223 : : /* Rely on mtu */
224 : 0 : seg->seg_len = XSC_MAX_RECV_LEN;
225 : 0 : PMD_DRV_LOG(ERR, "Failed to malloc jumbo_buffer");
226 : 0 : continue;
227 : : } else {
228 : 0 : jumbo_buffer_va =
229 : 0 : (void *)rte_malloc_virt2iova(jumbo_buffer_pa);
230 [ # # ]: 0 : if ((rte_iova_t)jumbo_buffer_va == RTE_BAD_IOVA) {
231 : 0 : seg->seg_len = XSC_MAX_RECV_LEN;
232 : 0 : PMD_DRV_LOG(ERR, "Failed to turn jumbo_buffer");
233 : 0 : continue;
234 : : }
235 : : }
236 : 0 : xdev->jumbo_buffer_pa = jumbo_buffer_pa;
237 : 0 : xdev->jumbo_buffer_va = jumbo_buffer_va;
238 : : }
239 : 0 : *seg_next = (struct xsc_wqe_data_seg){
240 : 0 : .va = rte_cpu_to_le_64((uint64_t)jumbo_buffer_va),
241 : 0 : .seg_len = rte_cpu_to_le_32(XSC_MAX_RECV_LEN - seg_len),
242 : : .lkey = 0,
243 : : };
244 : : }
245 : : }
246 : :
247 : 0 : rxq_data->rq_ci = wqe_n;
248 : 0 : rxq_data->sge_n = log2ds;
249 : :
250 : 0 : union xsc_recv_doorbell recv_db = {
251 : : .recv_data = 0
252 : : };
253 : :
254 : 0 : recv_db.next_pid = wqe_n << log2ds;
255 : 0 : recv_db.qp_num = rxq_data->qpn;
256 : 0 : rte_write32(rte_cpu_to_le_32(recv_db.recv_data), rxq_data->rq_db);
257 : 0 : }
258 : :
259 : : static int
260 : 0 : xsc_rss_qp_create(struct xsc_ethdev_priv *priv, int port_id)
261 : : {
262 : : struct xsc_cmd_create_multiqp_mbox_in *in;
263 : : struct xsc_cmd_create_qp_request *req;
264 : : struct xsc_cmd_create_multiqp_mbox_out *out;
265 : : uint8_t log_ele;
266 : : uint64_t iova;
267 : : int wqe_n;
268 : : int in_len, out_len, cmd_len;
269 : : int entry_total_len, entry_len;
270 : : uint8_t log_rq_sz, log_sq_sz = 0;
271 : : uint32_t wqe_total_len;
272 : : int j, ret;
273 : : uint16_t i, pa_num;
274 : : int rqn_base;
275 : : struct xsc_rxq_data *rxq_data;
276 : 0 : struct xsc_dev *xdev = priv->xdev;
277 : : struct xsc_hwinfo *hwinfo = &xdev->hwinfo;
278 [ # # ]: 0 : char name[RTE_ETH_NAME_MAX_LEN] = { 0 };
279 : : void *cmd_buf;
280 : :
281 : : rxq_data = xsc_rxq_get(priv, 0);
282 : : if (rxq_data == NULL)
283 : : return -EINVAL;
284 : :
285 : : log_ele = rte_log2_u32(sizeof(struct xsc_wqe_data_seg));
286 : 0 : wqe_n = rxq_data->wqe_s;
287 [ # # ]: 0 : log_rq_sz = rte_log2_u32(wqe_n * hwinfo->recv_seg_num);
288 : 0 : wqe_total_len = 1 << (log_rq_sz + log_sq_sz + log_ele);
289 : :
290 : 0 : pa_num = (wqe_total_len + XSC_PAGE_SIZE - 1) / XSC_PAGE_SIZE;
291 : 0 : entry_len = sizeof(struct xsc_cmd_create_qp_request) + sizeof(uint64_t) * pa_num;
292 : 0 : entry_total_len = entry_len * priv->num_rq;
293 : :
294 : 0 : in_len = sizeof(struct xsc_cmd_create_multiqp_mbox_in) + entry_total_len;
295 : 0 : out_len = sizeof(struct xsc_cmd_create_multiqp_mbox_out) + entry_total_len;
296 : 0 : cmd_len = RTE_MAX(in_len, out_len);
297 : 0 : cmd_buf = malloc(cmd_len);
298 [ # # ]: 0 : if (cmd_buf == NULL) {
299 : 0 : rte_errno = ENOMEM;
300 : 0 : PMD_DRV_LOG(ERR, "Alloc rss qp create cmd memory failed");
301 : 0 : goto error;
302 : : }
303 : :
304 : : in = cmd_buf;
305 : : memset(in, 0, cmd_len);
306 [ # # ]: 0 : in->qp_num = rte_cpu_to_be_16((uint16_t)priv->num_rq);
307 : 0 : in->qp_type = XSC_QUEUE_TYPE_RAW;
308 [ # # ]: 0 : in->req_len = rte_cpu_to_be_32(cmd_len);
309 : :
310 [ # # ]: 0 : for (i = 0; i < priv->num_rq; i++) {
311 [ # # ]: 0 : rxq_data = xsc_rxq_get(priv, i);
312 : : if (rxq_data == NULL) {
313 : 0 : rte_errno = EINVAL;
314 : 0 : goto error;
315 : : }
316 : :
317 : 0 : req = (struct xsc_cmd_create_qp_request *)(&in->data[0] + entry_len * i);
318 : 0 : req->input_qpn = rte_cpu_to_be_16(0); /* useless for eth */
319 [ # # ]: 0 : req->pa_num = rte_cpu_to_be_16(pa_num);
320 : 0 : req->qp_type = XSC_QUEUE_TYPE_RAW;
321 : 0 : req->log_rq_sz = log_rq_sz;
322 [ # # ]: 0 : req->cqn_recv = rte_cpu_to_be_16((uint16_t)rxq_data->cqn);
323 : 0 : req->cqn_send = req->cqn_recv;
324 [ # # ]: 0 : req->glb_funcid = rte_cpu_to_be_16((uint16_t)hwinfo->func_id);
325 : : /* Alloc pas addr */
326 : : snprintf(name, sizeof(name), "wqe_mem_rx_%d_%d", port_id, i);
327 : 0 : rxq_data->rq_pas = rte_memzone_reserve_aligned(name,
328 : 0 : (XSC_PAGE_SIZE * pa_num),
329 : : SOCKET_ID_ANY,
330 : : 0, XSC_PAGE_SIZE);
331 [ # # ]: 0 : if (rxq_data->rq_pas == NULL) {
332 : 0 : rte_errno = ENOMEM;
333 : 0 : PMD_DRV_LOG(ERR, "Alloc rxq pas memory failed");
334 : 0 : goto error;
335 : : }
336 : :
337 : 0 : iova = rxq_data->rq_pas->iova;
338 [ # # ]: 0 : for (j = 0; j < pa_num; j++)
339 [ # # ]: 0 : req->pas[j] = rte_cpu_to_be_64(iova + j * XSC_PAGE_SIZE);
340 : : }
341 : :
342 : 0 : in->hdr.opcode = rte_cpu_to_be_16(XSC_CMD_OP_CREATE_MULTI_QP);
343 : : out = cmd_buf;
344 : 0 : ret = xsc_dev_mailbox_exec(xdev, in, in_len, out, out_len);
345 [ # # # # ]: 0 : if (ret != 0 || out->hdr.status != 0) {
346 : 0 : PMD_DRV_LOG(ERR,
347 : : "Create rss rq failed, port id=%d, qp_num=%d, ret=%d, out.status=%u",
348 : : port_id, priv->num_rq, ret, out->hdr.status);
349 : 0 : rte_errno = ENOEXEC;
350 : 0 : goto error;
351 : : }
352 [ # # ]: 0 : rqn_base = rte_be_to_cpu_32(out->qpn_base) & 0xffffff;
353 : :
354 [ # # ]: 0 : for (i = 0; i < priv->num_rq; i++) {
355 [ # # ]: 0 : rxq_data = xsc_rxq_get(priv, i);
356 : : if (rxq_data == NULL) {
357 : 0 : rte_errno = EINVAL;
358 : 0 : goto error;
359 : : }
360 : :
361 : 0 : rxq_data->wqes = rxq_data->rq_pas->addr;
362 [ # # ]: 0 : if (!xsc_dev_is_vf(xdev))
363 : 0 : rxq_data->rq_db = (uint32_t *)((uint8_t *)xdev->bar_addr +
364 : : XSC_PF_RX_DB_ADDR);
365 : : else
366 : 0 : rxq_data->rq_db = (uint32_t *)((uint8_t *)xdev->bar_addr +
367 : : XSC_VF_RX_DB_ADDR);
368 : :
369 : 0 : rxq_data->qpn = rqn_base + i;
370 : 0 : xsc_dev_modify_qp_status(xdev, rxq_data->qpn, 1, XSC_CMD_OP_RTR2RTS_QP);
371 : 0 : xsc_rxq_initialize(xdev, rxq_data);
372 : 0 : rxq_data->cq_ci = 0;
373 : 0 : priv->dev_data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
374 : 0 : PMD_DRV_LOG(INFO, "Port %d create rx qp, wqe_s:%d, wqe_n:%d, qp_db=%p, qpn:%u",
375 : : port_id,
376 : : rxq_data->wqe_s, rxq_data->wqe_n,
377 : : rxq_data->rq_db, rxq_data->qpn);
378 : : }
379 : :
380 : 0 : free(cmd_buf);
381 : 0 : return 0;
382 : :
383 : 0 : error:
384 : 0 : free(cmd_buf);
385 : 0 : return -rte_errno;
386 : : }
387 : :
388 : : int
389 : 0 : xsc_rxq_rss_obj_new(struct xsc_ethdev_priv *priv, uint16_t port_id)
390 : : {
391 : : int ret;
392 : : uint32_t i;
393 : 0 : struct xsc_dev *xdev = priv->xdev;
394 : : struct xsc_rxq_data *rxq_data;
395 : 0 : struct xsc_rx_cq_params cq_params = {0};
396 : 0 : struct xsc_rx_cq_info cq_info = {0};
397 : :
398 : : /* Create CQ */
399 [ # # ]: 0 : for (i = 0; i < priv->num_rq; ++i) {
400 [ # # ]: 0 : rxq_data = xsc_rxq_get(priv, i);
401 : : if (rxq_data == NULL)
402 : : return -EINVAL;
403 : :
404 : : memset(&cq_params, 0, sizeof(cq_params));
405 : : memset(&cq_info, 0, sizeof(cq_info));
406 : 0 : cq_params.port_id = rxq_data->port_id;
407 : 0 : cq_params.qp_id = rxq_data->idx;
408 : 0 : cq_params.wqe_s = rxq_data->wqe_s;
409 : :
410 : 0 : ret = xsc_dev_rx_cq_create(xdev, &cq_params, &cq_info);
411 [ # # ]: 0 : if (ret) {
412 : 0 : PMD_DRV_LOG(ERR, "Port %u rxq %u create cq fail", port_id, i);
413 : 0 : rte_errno = errno;
414 : 0 : goto error;
415 : : }
416 : :
417 : 0 : rxq_data->cq = cq_info.cq;
418 : 0 : rxq_data->cqe_n = cq_info.cqe_n;
419 : 0 : rxq_data->cqe_s = 1 << rxq_data->cqe_n;
420 : 0 : rxq_data->cqe_m = rxq_data->cqe_s - 1;
421 : 0 : rxq_data->cqes = cq_info.cqes;
422 : 0 : rxq_data->cq_db = cq_info.cq_db;
423 : 0 : rxq_data->cqn = cq_info.cqn;
424 : :
425 : 0 : PMD_DRV_LOG(INFO, "Port %u create rx cq, cqe_s:%d, cqe_n:%d, cq_db=%p, cqn:%u",
426 : : port_id,
427 : : rxq_data->cqe_s, rxq_data->cqe_n,
428 : : rxq_data->cq_db, rxq_data->cqn);
429 : : }
430 : :
431 : 0 : ret = xsc_rss_qp_create(priv, port_id);
432 [ # # ]: 0 : if (ret != 0) {
433 : 0 : PMD_DRV_LOG(ERR, "Port %u rss rxq create fail", port_id);
434 : 0 : goto error;
435 : : }
436 : : return 0;
437 : :
438 : 0 : error:
439 : 0 : return -rte_errno;
440 : : }
441 : :
442 : : int
443 : 0 : xsc_rxq_elts_alloc(struct xsc_rxq_data *rxq_data)
444 : : {
445 : 0 : uint32_t elts_s = rxq_data->wqe_s;
446 : : struct rte_mbuf *mbuf;
447 : : uint32_t i;
448 : :
449 [ # # ]: 0 : for (i = 0; (i != elts_s); ++i) {
450 : 0 : mbuf = rte_pktmbuf_alloc(rxq_data->mp);
451 [ # # ]: 0 : if (mbuf == NULL) {
452 : 0 : PMD_DRV_LOG(ERR, "Port %u rxq %u empty mbuf pool",
453 : : rxq_data->port_id, rxq_data->idx);
454 : 0 : rte_errno = ENOMEM;
455 : 0 : goto error;
456 : : }
457 : :
458 : 0 : mbuf->port = rxq_data->port_id;
459 : 0 : mbuf->nb_segs = 1;
460 : 0 : rte_pktmbuf_data_len(mbuf) = mbuf->buf_len - mbuf->data_off;
461 : 0 : rte_pktmbuf_pkt_len(mbuf) = rte_pktmbuf_data_len(mbuf);
462 : 0 : (*rxq_data->elts)[i] = mbuf;
463 : : }
464 : :
465 : : return 0;
466 : : error:
467 : : elts_s = i;
468 [ # # ]: 0 : for (i = 0; (i != elts_s); ++i) {
469 [ # # ]: 0 : if ((*rxq_data->elts)[i] != NULL)
470 : : rte_pktmbuf_free_seg((*rxq_data->elts)[i]);
471 : 0 : (*rxq_data->elts)[i] = NULL;
472 : : }
473 : :
474 : 0 : PMD_DRV_LOG(ERR, "Port %u rxq %u start failed, free elts",
475 : : rxq_data->port_id, rxq_data->idx);
476 : :
477 : 0 : return -rte_errno;
478 : : }
479 : :
480 : : void
481 : 0 : xsc_rxq_elts_free(struct xsc_rxq_data *rxq_data)
482 : : {
483 : : uint16_t i;
484 : :
485 [ # # ]: 0 : if (rxq_data->elts == NULL)
486 : : return;
487 [ # # ]: 0 : for (i = 0; i != rxq_data->wqe_s; ++i) {
488 [ # # ]: 0 : if ((*rxq_data->elts)[i] != NULL)
489 : : rte_pktmbuf_free_seg((*rxq_data->elts)[i]);
490 : 0 : (*rxq_data->elts)[i] = NULL;
491 : : }
492 : :
493 : 0 : PMD_DRV_LOG(DEBUG, "Port %u rxq %u free elts", rxq_data->port_id, rxq_data->idx);
494 : : }
495 : :
496 : : void
497 : 0 : xsc_rxq_rss_obj_release(struct xsc_dev *xdev, struct xsc_rxq_data *rxq_data)
498 : : {
499 : 0 : struct xsc_cmd_destroy_qp_mbox_in in = { .hdr = { 0 } };
500 : 0 : struct xsc_cmd_destroy_qp_mbox_out out = { .hdr = { 0 } };
501 : : int ret, in_len, out_len;
502 : 0 : uint32_t qpn = rxq_data->qpn;
503 : :
504 : 0 : xsc_dev_modify_qp_status(xdev, qpn, 1, XSC_CMD_OP_QP_2RST);
505 : :
506 : : in_len = sizeof(struct xsc_cmd_destroy_qp_mbox_in);
507 : : out_len = sizeof(struct xsc_cmd_destroy_qp_mbox_out);
508 : 0 : in.hdr.opcode = rte_cpu_to_be_16(XSC_CMD_OP_DESTROY_QP);
509 [ # # ]: 0 : in.qpn = rte_cpu_to_be_32(rxq_data->qpn);
510 : :
511 : 0 : ret = xsc_dev_mailbox_exec(xdev, &in, in_len, &out, out_len);
512 [ # # # # ]: 0 : if (ret != 0 || out.hdr.status != 0) {
513 : 0 : PMD_DRV_LOG(ERR,
514 : : "Release rss rq failed, port id=%d, qid=%d, err=%d, out.status=%u",
515 : : rxq_data->port_id, rxq_data->idx, ret, out.hdr.status);
516 : 0 : rte_errno = ENOEXEC;
517 : 0 : return;
518 : : }
519 : :
520 : 0 : rte_memzone_free(rxq_data->rq_pas);
521 : :
522 [ # # ]: 0 : if (rxq_data->cq != NULL)
523 : 0 : xsc_dev_destroy_cq(xdev, rxq_data->cq);
524 : 0 : rxq_data->cq = NULL;
525 : : }
|