Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2023 Mucse IC Design Ltd.
3 : : */
4 : :
5 : : #include <stdint.h>
6 : :
7 : : #include <rte_ethdev.h>
8 : : #include <rte_memzone.h>
9 : : #include <rte_mbuf.h>
10 : : #include <rte_malloc.h>
11 : :
12 : : #include "base/rnp_bdq_if.h"
13 : : #include "base/rnp_dma_regs.h"
14 : : #include "rnp_rxtx.h"
15 : : #include "rnp_logs.h"
16 : : #include "rnp.h"
17 : :
18 : : static void rnp_tx_queue_release_mbuf(struct rnp_tx_queue *txq);
19 : : static void rnp_tx_queue_sw_reset(struct rnp_tx_queue *txq);
20 : : static void rnp_tx_queue_release(void *_txq);
21 : :
22 : : static __rte_always_inline phys_addr_t
23 : : rnp_get_dma_addr(struct rnp_queue_attr *attr, struct rte_mbuf *mbuf)
24 : : {
25 : : phys_addr_t dma_addr;
26 : :
27 : 0 : dma_addr = rte_cpu_to_le_64(rte_mbuf_data_iova(mbuf));
28 [ # # # # : 0 : if (attr->sriov_st)
# # # # ]
29 : 0 : dma_addr |= (attr->sriov_st << 56);
30 : :
31 : : return dma_addr;
32 : : }
33 : :
34 : 0 : static void rnp_rx_queue_release_mbuf(struct rnp_rx_queue *rxq)
35 : : {
36 : : uint16_t i;
37 : :
38 [ # # ]: 0 : if (!rxq)
39 : : return;
40 : :
41 [ # # ]: 0 : if (rxq->sw_ring) {
42 [ # # ]: 0 : for (i = 0; i < rxq->attr.nb_desc; i++) {
43 [ # # ]: 0 : if (rxq->sw_ring[i].mbuf)
44 : : rte_pktmbuf_free_seg(rxq->sw_ring[i].mbuf);
45 : : }
46 : 0 : memset(rxq->sw_ring, 0,
47 : 0 : sizeof(rxq->sw_ring[0]) * rxq->attr.nb_desc);
48 : : }
49 : : }
50 : :
51 : 0 : static void rnp_rx_queue_release(void *_rxq)
52 : : {
53 : : struct rnp_rx_queue *rxq = (struct rnp_rx_queue *)_rxq;
54 : :
55 : 0 : PMD_INIT_FUNC_TRACE();
56 : :
57 [ # # ]: 0 : if (rxq) {
58 : 0 : rnp_rx_queue_release_mbuf(rxq);
59 : 0 : rte_memzone_free(rxq->rz);
60 : 0 : rte_free(rxq->sw_ring);
61 : 0 : rte_free(rxq);
62 : : }
63 : 0 : }
64 : :
65 : : static int
66 : : rnp_tx_queue_reset(struct rnp_eth_port *port,
67 : : struct rnp_tx_queue *txq)
68 : : {
69 : 0 : struct rnp_hw *hw = port->hw;
70 : :
71 : 0 : rnp_reset_hw_txq_op(hw, txq);
72 : :
73 : : return 0;
74 : : }
75 : :
76 : : static int
77 : 0 : rnp_rx_queue_reset(struct rnp_eth_port *port,
78 : : struct rnp_rx_queue *rxq)
79 : : {
80 : 0 : struct rte_eth_dev_data *data = port->eth_dev->data;
81 : 0 : struct rnp_eth_adapter *adapter = port->hw->back;
82 : : struct rte_eth_dev *dev = port->eth_dev;
83 : 0 : struct rnp_rxq_reset_res res = {0};
84 : 0 : uint16_t qidx = rxq->attr.queue_id;
85 : : struct rnp_tx_queue *txq = NULL;
86 : : struct rte_eth_txconf def_conf;
87 : : struct rnp_hw *hw = port->hw;
88 : : struct rte_mbuf *m_mbuf[2];
89 : : bool tx_origin_e = false;
90 : : bool tx_new = false;
91 : : uint16_t index;
92 : : int err = 0;
93 : :
94 : 0 : index = rxq->attr.index;
95 : : /* disable eth send pkts to this ring */
96 : 0 : rxq->rx_tail = RNP_E_REG_RD(hw, RNP_RXQ_HEAD(index));
97 [ # # ]: 0 : if (!rxq->rx_tail)
98 : : return 0;
99 [ # # # # ]: 0 : if (qidx < data->nb_tx_queues && data->tx_queues[qidx]) {
100 : : txq = (struct rnp_tx_queue *)data->tx_queues[qidx];
101 : : } else {
102 : : /* tx queues has been release or txq num less than rxq num */
103 : 0 : def_conf.tx_deferred_start = true;
104 : 0 : def_conf.tx_free_thresh = 32;
105 : 0 : def_conf.tx_rs_thresh = 32;
106 [ # # ]: 0 : if (dev->dev_ops->tx_queue_setup)
107 : 0 : err = dev->dev_ops->tx_queue_setup(dev, qidx,
108 : 0 : rxq->attr.nb_desc,
109 : 0 : dev->data->numa_node, &def_conf);
110 [ # # ]: 0 : if (err) {
111 : 0 : RNP_PMD_ERR("rxq[%u] reset pair txq setup fail", qidx);
112 : 0 : return err;
113 : : }
114 : 0 : txq = port->tx_queues[qidx];
115 : : tx_new = true;
116 : : }
117 [ # # # # ]: 0 : if (unlikely(rte_mempool_get_bulk(adapter->reset_pool, (void *)m_mbuf,
118 : : 2) < 0)) {
119 : 0 : RNP_PMD_LOG(WARNING, "port[%u] reset rx queue[%u] failed "
120 : : "because mbuf alloc failed",
121 : : data->port_id, qidx);
122 : 0 : return -ENOMEM;
123 : : }
124 : 0 : rnp_rxq_flow_disable(hw, index);
125 : 0 : tx_origin_e = txq->txq_started;
126 : 0 : rte_io_wmb();
127 : 0 : txq->txq_started = false;
128 [ # # ]: 0 : rte_mbuf_refcnt_set(m_mbuf[0], 1);
129 : 0 : rte_mbuf_refcnt_set(m_mbuf[1], 1);
130 : 0 : m_mbuf[0]->data_off = RTE_PKTMBUF_HEADROOM;
131 : 0 : m_mbuf[1]->data_off = RTE_PKTMBUF_HEADROOM;
132 [ # # ]: 0 : res.eth_hdr = rte_pktmbuf_mtod(m_mbuf[0], uint8_t *);
133 [ # # ]: 0 : res.rx_pkt_addr = rnp_get_dma_addr(&rxq->attr, m_mbuf[1]);
134 : 0 : res.tx_pkt_addr = rnp_get_dma_addr(&txq->attr, m_mbuf[0]);
135 : 0 : rnp_reset_hw_rxq_op(hw, rxq, txq, &res);
136 [ # # ]: 0 : if (tx_new)
137 : 0 : rnp_tx_queue_release(txq);
138 : : else
139 : 0 : txq->tx_tail = RNP_E_REG_RD(hw, RNP_TXQ_HEAD(index));
140 [ # # ]: 0 : if (!tx_new) {
141 [ # # ]: 0 : if (txq->tx_tail) {
142 : 0 : rnp_tx_queue_release_mbuf(txq);
143 : : rnp_tx_queue_reset(port, txq);
144 : 0 : rnp_tx_queue_sw_reset(txq);
145 : : }
146 : 0 : txq->txq_started = tx_origin_e;
147 : : }
148 [ # # ]: 0 : rte_mempool_put_bulk(adapter->reset_pool, (void **)m_mbuf, 2);
149 : 0 : rnp_rxq_flow_enable(hw, index);
150 : 0 : rte_io_wmb();
151 : 0 : RNP_E_REG_WR(hw, RNP_RXQ_LEN(index), rxq->attr.nb_desc);
152 : :
153 : 0 : return 0;
154 : : }
155 : :
156 : : static int
157 : 0 : rnp_alloc_rxbdr(struct rte_eth_dev *dev,
158 : : struct rnp_rx_queue *rxq,
159 : : uint16_t nb_rx_desc, int socket_id)
160 : : {
161 : : const struct rte_memzone *rz = NULL;
162 : : uint32_t size = 0;
163 : :
164 : 0 : size = (nb_rx_desc + RNP_RX_MAX_BURST_SIZE) *
165 : : sizeof(struct rnp_rxsw_entry);
166 : 0 : rxq->sw_ring = rte_zmalloc_socket("rx_swring", size,
167 : : RTE_CACHE_LINE_SIZE, socket_id);
168 [ # # ]: 0 : if (rxq->sw_ring == NULL)
169 : : return -ENOMEM;
170 : 0 : rz = rte_eth_dma_zone_reserve(dev, "rx_ring", rxq->attr.queue_id,
171 : : RNP_RX_MAX_RING_SZ, RNP_BD_RING_ALIGN, socket_id);
172 [ # # ]: 0 : if (rz == NULL) {
173 : 0 : rte_free(rxq->sw_ring);
174 : 0 : rxq->sw_ring = NULL;
175 : 0 : return -ENOMEM;
176 : : }
177 : 0 : memset(rz->addr, 0, RNP_RX_MAX_RING_SZ);
178 : 0 : rxq->rx_bdr = (struct rnp_rx_desc *)rz->addr;
179 : 0 : rxq->ring_phys_addr = rz->iova;
180 : 0 : rxq->rz = rz;
181 : :
182 : 0 : return 0;
183 : : }
184 : :
185 : : static void
186 : : rnp_rx_queue_sw_reset(struct rnp_rx_queue *rxq)
187 : : {
188 : : uint32_t size = 0;
189 : : uint32_t idx = 0;
190 : :
191 : 0 : rxq->nb_rx_free = rxq->attr.nb_desc - 1;
192 : 0 : rxq->rx_tail = 0;
193 : :
194 : 0 : size = rxq->attr.nb_desc + RNP_RX_MAX_BURST_SIZE;
195 [ # # # # ]: 0 : for (idx = 0; idx < size * sizeof(struct rnp_rx_desc); idx++)
196 : 0 : ((volatile char *)rxq->rx_bdr)[idx] = 0;
197 : : }
198 : :
199 : :
200 : 0 : int rnp_rx_queue_setup(struct rte_eth_dev *eth_dev,
201 : : uint16_t qidx,
202 : : uint16_t nb_rx_desc,
203 : : unsigned int socket_id,
204 : : const struct rte_eth_rxconf *rx_conf,
205 : : struct rte_mempool *mb_pool)
206 : : {
207 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
208 : : struct rte_eth_dev_data *data = eth_dev->data;
209 : 0 : struct rnp_hw *hw = port->hw;
210 : : struct rnp_rx_queue *rxq = NULL;
211 : : uint64_t offloads;
212 : : int err = 0;
213 : :
214 : 0 : RNP_PMD_LOG(INFO, "RXQ[%u] setup nb-desc %u", qidx, nb_rx_desc);
215 : 0 : offloads = rx_conf->offloads | data->dev_conf.rxmode.offloads;
216 [ # # ]: 0 : if (rte_is_power_of_2(nb_rx_desc) == 0) {
217 : 0 : RNP_PMD_ERR("Rxq Desc Num Must power of 2");
218 : 0 : return -EINVAL;
219 : : }
220 [ # # ]: 0 : if (nb_rx_desc > RNP_MAX_BD_COUNT)
221 : : return -EINVAL;
222 : : /* check whether queue has been created if so release it */
223 [ # # ]: 0 : if (qidx < data->nb_rx_queues &&
224 [ # # ]: 0 : data->rx_queues[qidx] != NULL) {
225 : 0 : rnp_rx_queue_release(data->rx_queues[qidx]);
226 : 0 : data->rx_queues[qidx] = NULL;
227 : : }
228 : 0 : rxq = rte_zmalloc_socket("rnp_rxq", sizeof(struct rnp_rx_queue),
229 : : RTE_CACHE_LINE_SIZE, socket_id);
230 [ # # ]: 0 : if (rxq == NULL) {
231 : 0 : RNP_PMD_ERR("Failed to allocate rx ring memory");
232 : 0 : return -ENOMEM;
233 : : }
234 : 0 : rxq->rx_offloads = offloads;
235 : : /* queue hw info */
236 : 0 : rxq->attr.index = rnp_get_dma_ring_index(port, qidx);
237 : 0 : rxq->attr.nb_desc_mask = nb_rx_desc - 1;
238 : 0 : rxq->attr.nb_desc = nb_rx_desc;
239 : 0 : rxq->attr.queue_id = qidx;
240 : : /* queue map to port hw info */
241 : 0 : rxq->attr.vf_num = hw->mbx.vf_num;
242 : 0 : rxq->attr.sriov_st = hw->mbx.sriov_st;
243 : 0 : rxq->attr.lane_id = port->attr.nr_lane;
244 : 0 : rxq->attr.port_id = data->port_id;
245 : : #define RNP_RXQ_BD_TIMEOUT (5000000)
246 [ # # ]: 0 : rxq->nodesc_tm_thresh = RNP_RXQ_BD_TIMEOUT;
247 : 0 : rxq->rx_buf_len = (uint16_t)(rte_pktmbuf_data_room_size(mb_pool) -
248 : : RTE_PKTMBUF_HEADROOM);
249 : 0 : rxq->mb_pool = mb_pool;
250 : 0 : err = rnp_alloc_rxbdr(eth_dev, rxq, nb_rx_desc, socket_id);
251 [ # # ]: 0 : if (err)
252 : 0 : goto fail;
253 : 0 : RNP_PMD_LOG(INFO, "PF[%u] dev:[%u] hw-lane[%u] rx_qid[%u] "
254 : : "hw_ridx %u socket %u",
255 : : hw->mbx.pf_num, rxq->attr.port_id,
256 : : rxq->attr.lane_id, qidx,
257 : : rxq->attr.index, socket_id);
258 [ # # ]: 0 : rxq->rx_free_thresh = (rx_conf->rx_free_thresh) ?
259 : : rx_conf->rx_free_thresh : RNP_DEFAULT_RX_FREE_THRESH;
260 [ # # ]: 0 : rxq->pthresh = (rx_conf->rx_thresh.pthresh) ?
261 : : rx_conf->rx_thresh.pthresh : RNP_RX_DESC_FETCH_TH;
262 [ # # ]: 0 : rxq->pburst = (rx_conf->rx_thresh.hthresh) ?
263 : : rx_conf->rx_thresh.hthresh : RNP_RX_DESC_FETCH_BURST;
264 : 0 : rnp_setup_rxbdr(hw, rxq);
265 [ # # ]: 0 : if (rxq->rx_tail) {
266 : 0 : err = rnp_rx_queue_reset(port, rxq);
267 [ # # ]: 0 : if (err) {
268 : 0 : RNP_PMD_ERR("PF[%u] dev:[%u] lane[%u] rx_qid[%u] "
269 : : "hw_ridx[%u] bdr setup failed",
270 : : hw->mbx.pf_num, rxq->attr.port_id,
271 : : rxq->attr.lane_id, qidx, rxq->attr.index);
272 : 0 : goto rxbd_setup_failed;
273 : : }
274 : : }
275 : : rnp_rx_queue_sw_reset(rxq);
276 : 0 : data->rx_queues[qidx] = rxq;
277 : :
278 : 0 : return 0;
279 : : rxbd_setup_failed:
280 : 0 : rte_memzone_free(rxq->rz);
281 : 0 : fail:
282 : 0 : rte_free(rxq);
283 : :
284 : 0 : return err;
285 : : }
286 : :
287 : 0 : static void rnp_tx_queue_release_mbuf(struct rnp_tx_queue *txq)
288 : : {
289 : : uint16_t i;
290 : :
291 [ # # ]: 0 : if (!txq)
292 : : return;
293 [ # # ]: 0 : if (txq->sw_ring) {
294 [ # # ]: 0 : for (i = 0; i < txq->attr.nb_desc; i++) {
295 [ # # ]: 0 : if (txq->sw_ring[i].mbuf) {
296 : : rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
297 : 0 : txq->sw_ring[i].mbuf = NULL;
298 : : }
299 : : }
300 : : }
301 : : }
302 : :
303 : 0 : static void rnp_tx_queue_release(void *_txq)
304 : : {
305 : : struct rnp_tx_queue *txq = (struct rnp_tx_queue *)_txq;
306 : :
307 : 0 : PMD_INIT_FUNC_TRACE();
308 : :
309 [ # # ]: 0 : if (txq) {
310 : 0 : rnp_tx_queue_release_mbuf(txq);
311 : :
312 : 0 : rte_memzone_free(txq->rz);
313 : 0 : rte_free(txq->sw_ring);
314 : 0 : rte_free(txq);
315 : : }
316 : 0 : }
317 : :
318 : : void
319 : 0 : rnp_dev_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
320 : : {
321 : 0 : rnp_rx_queue_release(dev->data->rx_queues[qid]);
322 : 0 : }
323 : :
324 : : void
325 : 0 : rnp_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
326 : : {
327 : 0 : rnp_tx_queue_release(dev->data->tx_queues[qid]);
328 : 0 : }
329 : :
330 : 0 : static int rnp_alloc_txbdr(struct rte_eth_dev *dev,
331 : : struct rnp_tx_queue *txq,
332 : : uint16_t nb_desc, int socket_id)
333 : : {
334 : : const struct rte_memzone *rz = NULL;
335 : : int size;
336 : :
337 : 0 : size = nb_desc * sizeof(struct rnp_txsw_entry);
338 : 0 : txq->sw_ring = rte_zmalloc_socket("tx_swq", size,
339 : : RTE_CACHE_LINE_SIZE, socket_id);
340 [ # # ]: 0 : if (txq->sw_ring == NULL)
341 : : return -ENOMEM;
342 : :
343 : 0 : rz = rte_eth_dma_zone_reserve(dev, "tx_ring", txq->attr.queue_id,
344 : : RNP_TX_MAX_RING_SZ, RNP_BD_RING_ALIGN, socket_id);
345 [ # # ]: 0 : if (rz == NULL) {
346 : 0 : rte_free(txq->sw_ring);
347 : 0 : txq->sw_ring = NULL;
348 : 0 : return -ENOMEM;
349 : : }
350 : 0 : memset(rz->addr, 0, RNP_TX_MAX_RING_SZ);
351 : 0 : txq->ring_phys_addr = rz->iova;
352 : 0 : txq->tx_bdr = rz->addr;
353 : 0 : txq->rz = rz;
354 : :
355 : 0 : return 0;
356 : : }
357 : :
358 : : static void
359 : 0 : rnp_tx_queue_sw_reset(struct rnp_tx_queue *txq)
360 : : {
361 : 0 : struct rnp_txsw_entry *sw_ring = txq->sw_ring;
362 : : uint32_t idx = 0, prev = 0;
363 : : uint32_t size = 0;
364 : :
365 : 0 : prev = (uint16_t)(txq->attr.nb_desc - 1);
366 [ # # ]: 0 : for (idx = 0; idx < txq->attr.nb_desc; idx++) {
367 : 0 : sw_ring[idx].mbuf = NULL;
368 : 0 : sw_ring[idx].last_id = idx;
369 : 0 : sw_ring[prev].next_id = idx;
370 : : prev = idx;
371 : : }
372 : 0 : txq->last_desc_cleaned = txq->attr.nb_desc - 1;
373 : 0 : txq->nb_tx_free = txq->attr.nb_desc - 1;
374 : 0 : txq->tx_next_dd = txq->tx_rs_thresh - 1;
375 : 0 : txq->tx_next_rs = txq->tx_rs_thresh - 1;
376 : 0 : txq->nb_tx_used = 0;
377 : 0 : txq->tx_tail = 0;
378 : :
379 : 0 : size = (txq->attr.nb_desc + RNP_TX_MAX_BURST_SIZE);
380 [ # # ]: 0 : for (idx = 0; idx < size * sizeof(struct rnp_tx_desc); idx++)
381 : 0 : ((volatile char *)txq->tx_bdr)[idx] = 0;
382 : 0 : }
383 : :
384 : : int
385 : 0 : rnp_tx_queue_setup(struct rte_eth_dev *dev,
386 : : uint16_t qidx, uint16_t nb_desc,
387 : : unsigned int socket_id,
388 : : const struct rte_eth_txconf *tx_conf)
389 : : {
390 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
391 : : struct rte_eth_dev_data *data = dev->data;
392 : 0 : struct rnp_hw *hw = port->hw;
393 : : struct rnp_tx_queue *txq;
394 : : uint64_t offloads = 0;
395 : : int err = 0;
396 : :
397 : 0 : PMD_INIT_FUNC_TRACE();
398 : 0 : offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
399 : 0 : RNP_PMD_INFO("TXQ[%u] setup nb-desc %u", qidx, nb_desc);
400 [ # # ]: 0 : if (rte_is_power_of_2(nb_desc) == 0) {
401 : 0 : RNP_PMD_ERR("txq Desc num must power of 2");
402 : 0 : return -EINVAL;
403 : : }
404 [ # # ]: 0 : if (nb_desc > RNP_MAX_BD_COUNT)
405 : : return -EINVAL;
406 : : /* check whether queue Has been create if so release it */
407 [ # # # # ]: 0 : if (qidx < data->nb_tx_queues && data->tx_queues[qidx]) {
408 : 0 : rnp_tx_queue_release(data->tx_queues[qidx]);
409 : 0 : data->tx_queues[qidx] = NULL;
410 : : }
411 : 0 : txq = rte_zmalloc_socket("rnp_txq", sizeof(struct rnp_tx_queue),
412 : : RTE_CACHE_LINE_SIZE, socket_id);
413 [ # # ]: 0 : if (!txq) {
414 : 0 : RNP_PMD_ERR("Failed to allocate TX ring memory");
415 : 0 : return -ENOMEM;
416 : : }
417 [ # # ]: 0 : txq->tx_rs_thresh = tx_conf->tx_rs_thresh ?
418 : : tx_conf->tx_rs_thresh : RNP_DEFAULT_TX_RS_THRESH;
419 [ # # ]: 0 : txq->tx_free_thresh = tx_conf->tx_free_thresh ?
420 : : tx_conf->tx_free_thresh : RNP_DEFAULT_TX_FREE_THRESH;
421 [ # # ]: 0 : if (txq->tx_rs_thresh > txq->tx_free_thresh) {
422 : 0 : RNP_PMD_ERR("tx_rs_thresh must be less than or "
423 : : "equal to tx_free_thresh. (tx_free_thresh=%u"
424 : : " tx_rs_thresh=%u port=%d queue=%d)",
425 : : (unsigned int)tx_conf->tx_free_thresh,
426 : : (unsigned int)tx_conf->tx_rs_thresh,
427 : : (int)data->port_id,
428 : : (int)qidx);
429 : : err = -EINVAL;
430 : 0 : goto txbd_setup_failed;
431 : : }
432 [ # # ]: 0 : if (txq->tx_rs_thresh + txq->tx_free_thresh >= nb_desc) {
433 : 0 : RNP_PMD_ERR("tx_rs_thresh + tx_free_thresh >= nb_desc"
434 : : "%d + %d >= %d", txq->tx_rs_thresh,
435 : : txq->tx_free_thresh, nb_desc);
436 : : err = -EINVAL;
437 : 0 : goto txbd_setup_failed;
438 : : }
439 [ # # ]: 0 : txq->pthresh = (tx_conf->tx_thresh.pthresh) ?
440 : : tx_conf->tx_thresh.pthresh : RNP_TX_DESC_FETCH_TH;
441 [ # # ]: 0 : txq->pburst = (tx_conf->tx_thresh.hthresh) ?
442 : : tx_conf->tx_thresh.hthresh : RNP_TX_DESC_FETCH_BURST;
443 : 0 : txq->free_mbufs = rte_zmalloc_socket("txq->free_mbufs",
444 : 0 : sizeof(struct rte_mbuf *) * txq->tx_rs_thresh,
445 : : RTE_CACHE_LINE_SIZE, socket_id);
446 : 0 : txq->attr.index = rnp_get_dma_ring_index(port, qidx);
447 : 0 : txq->attr.lane_id = port->attr.nr_lane;
448 : 0 : txq->attr.port_id = dev->data->port_id;
449 : 0 : txq->attr.nb_desc_mask = nb_desc - 1;
450 : 0 : txq->attr.vf_num = hw->mbx.vf_num;
451 : 0 : txq->attr.nb_desc = nb_desc;
452 : 0 : txq->attr.queue_id = qidx;
453 : :
454 : 0 : err = rnp_alloc_txbdr(dev, txq, nb_desc, socket_id);
455 [ # # ]: 0 : if (err)
456 : 0 : goto txbd_setup_failed;
457 : 0 : rnp_setup_txbdr(hw, txq);
458 [ # # ]: 0 : if (txq->tx_tail)
459 : 0 : rnp_reset_hw_txq_op(hw, txq);
460 : 0 : rnp_tx_queue_sw_reset(txq);
461 : 0 : RNP_PMD_LOG(INFO, "PF[%u] dev:[%u] hw-lane[%u] txq queue_id[%u] "
462 : : "dma_idx %u socket %u",
463 : : hw->mbx.pf_num, txq->attr.port_id,
464 : : txq->attr.lane_id, qidx,
465 : : txq->attr.index, socket_id);
466 [ # # ]: 0 : if (qidx < dev->data->nb_tx_queues)
467 : 0 : data->tx_queues[qidx] = txq;
468 : 0 : port->tx_queues[qidx] = txq;
469 : :
470 : 0 : txq->tx_deferred_start = tx_conf->tx_deferred_start;
471 : 0 : txq->tx_offloads = offloads;
472 : :
473 : 0 : return 0;
474 : 0 : txbd_setup_failed:
475 : :
476 : 0 : rte_free(txq);
477 : :
478 : 0 : return err;
479 : : }
480 : :
481 : 0 : int rnp_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t qidx)
482 : : {
483 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
484 : : struct rte_eth_dev_data *data = eth_dev->data;
485 : : struct rnp_tx_queue *txq;
486 : :
487 : 0 : PMD_INIT_FUNC_TRACE();
488 : 0 : txq = eth_dev->data->tx_queues[qidx];
489 [ # # ]: 0 : if (!txq) {
490 : 0 : RNP_PMD_ERR("TX queue %u is null or not setup", qidx);
491 : 0 : return -EINVAL;
492 : : }
493 [ # # ]: 0 : if (data->tx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STARTED) {
494 : 0 : txq->txq_started = 0;
495 : : /* wait for tx burst process stop traffic */
496 : 0 : rte_delay_us(10);
497 : 0 : rnp_tx_queue_release_mbuf(txq);
498 : : rnp_tx_queue_reset(port, txq);
499 : 0 : rnp_tx_queue_sw_reset(txq);
500 : 0 : data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;
501 : : }
502 : :
503 : : return 0;
504 : : }
505 : :
506 : 0 : int rnp_tx_queue_start(struct rte_eth_dev *eth_dev, uint16_t qidx)
507 : : {
508 : 0 : struct rte_eth_dev_data *data = eth_dev->data;
509 : : struct rnp_tx_queue *txq;
510 : :
511 : 0 : PMD_INIT_FUNC_TRACE();
512 : :
513 : 0 : txq = data->tx_queues[qidx];
514 [ # # ]: 0 : if (!txq) {
515 : 0 : RNP_PMD_ERR("Can't start tx queue %d it's not setup by "
516 : : "tx_queue_setup API", qidx);
517 : 0 : return -EINVAL;
518 : : }
519 [ # # ]: 0 : if (data->tx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STOPPED) {
520 : 0 : data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STARTED;
521 : 0 : txq->txq_started = 1;
522 : : }
523 : :
524 : : return 0;
525 : : }
526 : :
527 : 0 : int rnp_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t qidx)
528 : : {
529 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
530 : : struct rte_eth_dev_data *data = eth_dev->data;
531 : : bool ori_q_state[RNP_MAX_RX_QUEUE_NUM];
532 : 0 : struct rnp_hw *hw = port->hw;
533 : : struct rnp_rx_queue *rxq;
534 : : uint16_t hwrid;
535 : : uint16_t i = 0;
536 : :
537 : 0 : PMD_INIT_FUNC_TRACE();
538 : : memset(ori_q_state, 0, sizeof(ori_q_state));
539 [ # # ]: 0 : if (qidx >= data->nb_rx_queues)
540 : : return -EINVAL;
541 : 0 : rxq = data->rx_queues[qidx];
542 [ # # ]: 0 : if (!rxq) {
543 : 0 : RNP_PMD_ERR("rx queue %u is null or not setup", qidx);
544 : 0 : return -EINVAL;
545 : : }
546 [ # # ]: 0 : if (data->rx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STARTED) {
547 : 0 : hwrid = rxq->attr.index;
548 [ # # ]: 0 : for (i = 0; i < RNP_MAX_RX_QUEUE_NUM; i++) {
549 : 0 : RNP_E_REG_WR(hw, RNP_RXQ_DROP_TIMEOUT_TH(i), 16);
550 : 0 : ori_q_state[i] = RNP_E_REG_RD(hw, RNP_RXQ_START(i));
551 : 0 : RNP_E_REG_WR(hw, RNP_RXQ_START(i), 0);
552 : : }
553 : 0 : rxq->rxq_started = false;
554 : 0 : rnp_rx_queue_release_mbuf(rxq);
555 : 0 : RNP_E_REG_WR(hw, RNP_RXQ_START(hwrid), 0);
556 : 0 : rnp_rx_queue_reset(port, rxq);
557 : : rnp_rx_queue_sw_reset(rxq);
558 [ # # ]: 0 : for (i = 0; i < RNP_MAX_RX_QUEUE_NUM; i++) {
559 : 0 : RNP_E_REG_WR(hw, RNP_RXQ_DROP_TIMEOUT_TH(i),
560 : : rxq->nodesc_tm_thresh);
561 : 0 : RNP_E_REG_WR(hw, RNP_RXQ_START(i), ori_q_state[i]);
562 : : }
563 : 0 : RNP_E_REG_WR(hw, RNP_RXQ_START(hwrid), 0);
564 : 0 : data->rx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;
565 : : }
566 : :
567 : : return 0;
568 : : }
569 : :
570 : 0 : static int rnp_alloc_rxq_mbuf(struct rnp_rx_queue *rxq)
571 : : {
572 : 0 : struct rnp_rxsw_entry *rx_swbd = rxq->sw_ring;
573 : : volatile struct rnp_rx_desc *rxd;
574 : : struct rte_mbuf *mbuf = NULL;
575 : : uint64_t dma_addr;
576 : : uint16_t i;
577 : :
578 [ # # ]: 0 : for (i = 0; i < rxq->attr.nb_desc; i++) {
579 : 0 : mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
580 [ # # ]: 0 : if (!mbuf)
581 : 0 : goto rx_mb_alloc_failed;
582 [ # # ]: 0 : rx_swbd[i].mbuf = mbuf;
583 : :
584 : : rte_mbuf_refcnt_set(mbuf, 1);
585 : 0 : mbuf->next = NULL;
586 : 0 : mbuf->data_off = RTE_PKTMBUF_HEADROOM;
587 [ # # ]: 0 : mbuf->port = rxq->attr.port_id;
588 : : dma_addr = rnp_get_dma_addr(&rxq->attr, mbuf);
589 : :
590 : 0 : rxd = &rxq->rx_bdr[i];
591 : 0 : *rxd = rxq->zero_desc;
592 : 0 : rxd->d.pkt_addr = dma_addr;
593 : 0 : rxd->d.cmd = 0;
594 : : }
595 : 0 : memset(&rxq->fake_mbuf, 0x0, sizeof(rxq->fake_mbuf));
596 [ # # ]: 0 : for (i = 0; i < RNP_RX_MAX_BURST_SIZE; ++i)
597 : 0 : rxq->sw_ring[rxq->attr.nb_desc + i].mbuf = &rxq->fake_mbuf;
598 : :
599 : : return 0;
600 : : rx_mb_alloc_failed:
601 : 0 : RNP_PMD_ERR("rx queue %u alloc mbuf failed", rxq->attr.queue_id);
602 : 0 : rnp_rx_queue_release_mbuf(rxq);
603 : :
604 : 0 : return -ENOMEM;
605 : : }
606 : :
607 : 0 : int rnp_rx_queue_start(struct rte_eth_dev *eth_dev, uint16_t qidx)
608 : : {
609 : 0 : struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
610 : : struct rte_eth_dev_data *data = eth_dev->data;
611 : 0 : struct rnp_hw *hw = port->hw;
612 : : struct rnp_rx_queue *rxq;
613 : : uint16_t hwrid;
614 : :
615 : 0 : PMD_INIT_FUNC_TRACE();
616 : 0 : rxq = data->rx_queues[qidx];
617 [ # # ]: 0 : if (!rxq) {
618 : 0 : RNP_PMD_ERR("RX queue %u is Null or Not setup", qidx);
619 : 0 : return -EINVAL;
620 : : }
621 [ # # ]: 0 : if (data->rx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STOPPED) {
622 : 0 : hwrid = rxq->attr.index;
623 : : /* disable ring */
624 : 0 : rte_io_wmb();
625 : 0 : RNP_E_REG_WR(hw, RNP_RXQ_START(hwrid), 0);
626 [ # # ]: 0 : if (rnp_alloc_rxq_mbuf(rxq) != 0) {
627 : 0 : RNP_PMD_ERR("Could not alloc mbuf for queue:%d", qidx);
628 : 0 : return -ENOMEM;
629 : : }
630 : 0 : rte_io_wmb();
631 : 0 : RNP_REG_WR(rxq->rx_tailreg, 0, rxq->attr.nb_desc - 1);
632 : 0 : RNP_E_REG_WR(hw, RNP_RXQ_START(hwrid), 1);
633 : 0 : rxq->nb_rx_free = rxq->attr.nb_desc - 1;
634 : 0 : rxq->rxq_started = true;
635 : :
636 : 0 : data->rx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STARTED;
637 : : }
638 : :
639 : : return 0;
640 : : }
641 : :
642 : : struct rnp_rx_cksum_parse {
643 : : uint64_t offloads;
644 : : uint64_t packet_type;
645 : : uint16_t hw_offload;
646 : : uint64_t good;
647 : : uint64_t bad;
648 : : };
649 : :
650 : : #define RNP_RX_OFFLOAD_L4_CKSUM (RTE_ETH_RX_OFFLOAD_TCP_CKSUM | \
651 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM | \
652 : : RTE_ETH_RX_OFFLOAD_SCTP_CKSUM)
653 : : static const struct rnp_rx_cksum_parse rnp_rx_cksum_tunnel[] = {
654 : : { RTE_ETH_RX_OFFLOAD_IPV4_CKSUM | RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM,
655 : : RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_MASK, RNP_RX_L3_ERR,
656 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD, RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD
657 : : },
658 : : { RTE_ETH_RX_OFFLOAD_IPV4_CKSUM,
659 : : RTE_PTYPE_L3_IPV4, RNP_RX_IN_L3_ERR,
660 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD, RTE_MBUF_F_RX_IP_CKSUM_BAD
661 : : },
662 : : { RNP_RX_OFFLOAD_L4_CKSUM, RTE_PTYPE_L4_MASK,
663 : : RNP_RX_IN_L4_ERR | RNP_RX_SCTP_ERR,
664 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD, RTE_MBUF_F_RX_L4_CKSUM_BAD
665 : : }
666 : : };
667 : :
668 : : static const struct rnp_rx_cksum_parse rnp_rx_cksum[] = {
669 : : { RTE_ETH_RX_OFFLOAD_IPV4_CKSUM,
670 : : RTE_PTYPE_L3_IPV4, RNP_RX_L3_ERR,
671 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD, RTE_MBUF_F_RX_IP_CKSUM_BAD
672 : : },
673 : : { RNP_RX_OFFLOAD_L4_CKSUM,
674 : : RTE_PTYPE_L4_MASK, RNP_RX_L4_ERR | RNP_RX_SCTP_ERR,
675 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD, RTE_MBUF_F_RX_L4_CKSUM_BAD
676 : : }
677 : : };
678 : :
679 : : static void
680 : 0 : rnp_rx_parse_tunnel_cksum(struct rnp_rx_queue *rxq,
681 : : struct rte_mbuf *m, uint16_t cksum_cmd)
682 : : {
683 : : uint16_t idx = 0;
684 : :
685 [ # # ]: 0 : for (idx = 0; idx < RTE_DIM(rnp_rx_cksum_tunnel); idx++) {
686 [ # # ]: 0 : if (rxq->rx_offloads & rnp_rx_cksum_tunnel[idx].offloads &&
687 [ # # ]: 0 : m->packet_type & rnp_rx_cksum_tunnel[idx].packet_type) {
688 [ # # ]: 0 : if (cksum_cmd & rnp_rx_cksum_tunnel[idx].hw_offload)
689 : 0 : m->ol_flags |= rnp_rx_cksum_tunnel[idx].bad;
690 : : else
691 : 0 : m->ol_flags |= rnp_rx_cksum_tunnel[idx].good;
692 : : }
693 : : }
694 : 0 : }
695 : :
696 : : static void
697 : 0 : rnp_rx_parse_cksum(struct rnp_rx_queue *rxq,
698 : : struct rte_mbuf *m, uint16_t cksum_cmd)
699 : : {
700 : : uint16_t idx = 0;
701 : :
702 [ # # ]: 0 : for (idx = 0; idx < RTE_DIM(rnp_rx_cksum); idx++) {
703 [ # # ]: 0 : if (rxq->rx_offloads & rnp_rx_cksum[idx].offloads &&
704 [ # # ]: 0 : m->packet_type & rnp_rx_cksum[idx].packet_type) {
705 [ # # ]: 0 : if (cksum_cmd & rnp_rx_cksum[idx].hw_offload)
706 : 0 : m->ol_flags |= rnp_rx_cksum[idx].bad;
707 : : else
708 : 0 : m->ol_flags |= rnp_rx_cksum[idx].good;
709 : : }
710 : : }
711 : 0 : }
712 : :
713 : : static __rte_always_inline void
714 : : rnp_dev_rx_offload(struct rnp_rx_queue *rxq,
715 : : struct rte_mbuf *m,
716 : : volatile struct rnp_rx_desc rxbd)
717 : : {
718 : 0 : uint32_t rss = rte_le_to_cpu_32(rxbd.wb.qword0.rss_hash);
719 : 0 : uint16_t vlan_tci = rxbd.wb.qword1.vlan_tci;
720 : 0 : uint16_t cmd = rxbd.wb.qword1.cmd;
721 : :
722 [ # # # # ]: 0 : if (rxq->rx_offloads & RNP_RX_CHECKSUM_SUPPORT) {
723 [ # # # # ]: 0 : if (m->packet_type & RTE_PTYPE_TUNNEL_MASK) {
724 : 0 : rnp_rx_parse_tunnel_cksum(rxq, m, cmd);
725 : : } else {
726 [ # # # # ]: 0 : if (m->packet_type & RTE_PTYPE_L3_MASK ||
727 : : m->packet_type & RTE_PTYPE_L4_MASK)
728 : 0 : rnp_rx_parse_cksum(rxq, m, cmd);
729 : : }
730 : : }
731 [ # # # # : 0 : if (rxq->rx_offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH && rss) {
# # # # ]
732 : 0 : m->hash.rss = rss;
733 : 0 : m->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
734 : : }
735 [ # # # # ]: 0 : if (rxq->rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
736 [ # # # # ]: 0 : if (vlan_tci && cmd & RNP_RX_STRIP_VLAN) {
737 : 0 : m->ol_flags |= RTE_MBUF_F_RX_VLAN |
738 : : RTE_MBUF_F_RX_VLAN_STRIPPED;
739 : 0 : m->vlan_tci = vlan_tci;
740 : : }
741 : : }
742 : : }
743 : :
744 : : static __rte_always_inline void
745 : : rnp_dev_rx_parse(struct rnp_rx_queue *rxq,
746 : : struct rte_mbuf *m,
747 : : volatile struct rnp_rx_desc rxbd)
748 : : {
749 : 0 : uint32_t mark_data = rxbd.wb.qword0.mark_data;
750 : 0 : uint16_t vlan_tci = rxbd.wb.qword1.vlan_tci;
751 : 0 : uint32_t cmd = rxbd.wb.qword1.cmd;
752 : :
753 : : /* clear mbuf packet_type and ol_flags */
754 : 0 : m->packet_type = 0;
755 : 0 : m->ol_flags = 0;
756 : 0 : if (mark_data & RNP_RX_L3TYPE_VALID) {
757 [ # # # # ]: 0 : if (cmd & RNP_RX_L3TYPE_IPV6)
758 : 0 : m->packet_type |= RTE_PTYPE_L3_IPV6;
759 : : else
760 : 0 : m->packet_type |= RTE_PTYPE_L3_IPV4;
761 : : }
762 [ # # # # ]: 0 : if (vlan_tci)
763 : 0 : m->packet_type |= RTE_PTYPE_L2_ETHER_VLAN;
764 [ # # # # : 0 : switch (cmd & RNP_RX_L4TYPE_MASK) {
# # # # ]
765 : 0 : case RNP_RX_L4TYPE_UDP:
766 : 0 : m->packet_type |= RTE_PTYPE_L4_UDP;
767 : 0 : break;
768 : 0 : case RNP_RX_L4TYPE_TCP:
769 : 0 : m->packet_type |= RTE_PTYPE_L4_TCP;
770 : 0 : break;
771 : 0 : case RNP_RX_L4TYPE_SCTP:
772 : 0 : m->packet_type |= RTE_PTYPE_L4_SCTP;
773 : 0 : break;
774 : : }
775 [ # # # # : 0 : switch (cmd & RNP_RX_TUNNEL_MASK) {
# # ]
776 : 0 : case RNP_RX_PTYPE_VXLAN:
777 : 0 : m->packet_type |= RTE_PTYPE_TUNNEL_VXLAN;
778 : 0 : break;
779 : 0 : case RNP_RX_PTYPE_NVGRE:
780 : 0 : m->packet_type |= RTE_PTYPE_TUNNEL_NVGRE;
781 : 0 : break;
782 : : }
783 [ # # # # ]: 0 : if (!(m->packet_type & RTE_PTYPE_L2_MASK))
784 : 0 : m->packet_type |= RTE_PTYPE_L2_ETHER;
785 : : rnp_dev_rx_offload(rxq, m, rxbd);
786 : : }
787 : :
788 : : #define RNP_CACHE_FETCH_RX (4)
789 : : static __rte_always_inline int
790 : : rnp_refill_rx_ring(struct rnp_rx_queue *rxq)
791 : : {
792 : : volatile struct rnp_rx_desc *rxbd;
793 : : struct rnp_rxsw_entry *rx_swbd;
794 : : struct rte_eth_dev_data *data;
795 : : struct rte_mbuf *mb;
796 : : uint16_t j, i;
797 : : uint16_t rx_id;
798 : : int ret;
799 : :
800 : 0 : rxbd = rxq->rx_bdr + rxq->rxrearm_start;
801 : 0 : rx_swbd = &rxq->sw_ring[rxq->rxrearm_start];
802 [ # # ]: 0 : ret = rte_mempool_get_bulk(rxq->mb_pool, (void *)rx_swbd,
803 : : rxq->rx_free_thresh);
804 : 0 : data = rte_eth_devices[rxq->attr.port_id].data;
805 [ # # ]: 0 : if (unlikely(ret != 0)) {
806 [ # # ]: 0 : if (rxq->rxrearm_nb + rxq->rx_free_thresh >= rxq->attr.nb_desc) {
807 [ # # ]: 0 : for (i = 0; i < RNP_CACHE_FETCH_RX; i++) {
808 : 0 : rx_swbd[i].mbuf = &rxq->fake_mbuf;
809 : 0 : rxbd[i].d.pkt_addr = 0;
810 : 0 : rxbd[i].d.cmd = 0;
811 : : }
812 : : }
813 : 0 : data->rx_mbuf_alloc_failed += rxq->rx_free_thresh;
814 : 0 : return 0;
815 : : }
816 [ # # ]: 0 : for (j = 0; j < rxq->rx_free_thresh; ++j) {
817 : 0 : mb = rx_swbd[j].mbuf;
818 : 0 : rte_mbuf_refcnt_set(mb, 1);
819 : 0 : mb->data_off = RTE_PKTMBUF_HEADROOM;
820 : 0 : mb->port = rxq->attr.port_id;
821 : :
822 [ # # ]: 0 : rxbd[j].d.pkt_addr = rnp_get_dma_addr(&rxq->attr, mb);
823 : 0 : rxbd[j].d.cmd = 0;
824 : : }
825 : 0 : rxq->rxrearm_start += rxq->rx_free_thresh;
826 [ # # ]: 0 : if (rxq->rxrearm_start >= rxq->attr.nb_desc - 1)
827 : 0 : rxq->rxrearm_start = 0;
828 : 0 : rxq->rxrearm_nb -= rxq->rx_free_thresh;
829 : :
830 [ # # ]: 0 : rx_id = (uint16_t)((rxq->rxrearm_start == 0) ?
831 : : (rxq->attr.nb_desc - 1) : (rxq->rxrearm_start - 1));
832 : : rte_wmb();
833 : 0 : RNP_REG_WR(rxq->rx_tailreg, 0, rx_id);
834 : :
835 : 0 : return j;
836 : : }
837 : :
838 : : static __rte_always_inline uint16_t
839 : 0 : rnp_recv_pkts(void *_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
840 : : {
841 : : struct rnp_rx_queue *rxq = (struct rnp_rx_queue *)_rxq;
842 : : struct rnp_rxsw_entry *rx_swbd;
843 : : uint32_t state_cmd[RNP_CACHE_FETCH_RX];
844 : 0 : uint32_t pkt_len[RNP_CACHE_FETCH_RX] = {0};
845 : : volatile struct rnp_rx_desc *rxbd;
846 : : struct rte_mbuf *nmb;
847 : : int nb_dd, nb_rx = 0;
848 : : int i, j;
849 : :
850 [ # # # # ]: 0 : if (unlikely(!rxq->rxq_started || !rxq->rx_link))
851 : : return 0;
852 : 0 : nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, RNP_CACHE_FETCH_RX);
853 : 0 : rxbd = &rxq->rx_bdr[rxq->rx_tail];
854 : 0 : rte_prefetch0(rxbd);
855 [ # # ]: 0 : if (rxq->rxrearm_nb > rxq->rx_free_thresh)
856 : : rnp_refill_rx_ring(rxq);
857 : :
858 [ # # ]: 0 : if (!(rxbd->wb.qword1.cmd & RNP_CMD_DD))
859 : : return 0;
860 : :
861 : 0 : rx_swbd = &rxq->sw_ring[rxq->rx_tail];
862 [ # # ]: 0 : for (i = 0; i < nb_pkts;
863 : 0 : i += RNP_CACHE_FETCH_RX, rxbd += RNP_CACHE_FETCH_RX,
864 : 0 : rx_swbd += RNP_CACHE_FETCH_RX) {
865 [ # # ]: 0 : for (j = 0; j < RNP_CACHE_FETCH_RX; j++)
866 : 0 : state_cmd[j] = rxbd[j].wb.qword1.cmd;
867 : : rte_atomic_thread_fence(rte_memory_order_acquire);
868 : :
869 [ # # ]: 0 : for (nb_dd = 0; nb_dd < RNP_CACHE_FETCH_RX &&
870 [ # # ]: 0 : (state_cmd[nb_dd] & rte_cpu_to_le_16(RNP_CMD_DD));
871 : 0 : nb_dd++)
872 : : ;
873 [ # # ]: 0 : for (j = 0; j < nb_dd; j++)
874 : 0 : pkt_len[j] = rxbd[j].wb.qword1.lens;
875 : :
876 [ # # ]: 0 : for (j = 0; j < nb_dd; ++j) {
877 : 0 : nmb = rx_swbd[j].mbuf;
878 : :
879 : 0 : nmb->data_off = RTE_PKTMBUF_HEADROOM;
880 : 0 : nmb->port = rxq->attr.port_id;
881 : 0 : nmb->data_len = pkt_len[j];
882 : 0 : nmb->pkt_len = pkt_len[j];
883 : 0 : nmb->packet_type = 0;
884 : 0 : nmb->ol_flags = 0;
885 : 0 : nmb->nb_segs = 1;
886 : :
887 [ # # ]: 0 : rnp_dev_rx_parse(rxq, nmb, rxbd[j]);
888 : 0 : rxq->stats.ibytes += nmb->data_len;
889 : : }
890 [ # # ]: 0 : for (j = 0; j < nb_dd; ++j) {
891 : 0 : rx_pkts[i + j] = rx_swbd[j].mbuf;
892 : 0 : rx_swbd[j].mbuf = NULL;
893 : : }
894 : :
895 : 0 : nb_rx += nb_dd;
896 : 0 : rxq->nb_rx_free -= nb_dd;
897 [ # # ]: 0 : if (nb_dd != RNP_CACHE_FETCH_RX)
898 : : break;
899 : : }
900 : 0 : rxq->stats.ipackets += nb_rx;
901 : 0 : rxq->rx_tail = (rxq->rx_tail + nb_rx) & rxq->attr.nb_desc_mask;
902 : 0 : rxq->rxrearm_nb = rxq->rxrearm_nb + nb_rx;
903 : :
904 : 0 : return nb_rx;
905 : : }
906 : :
907 : : static __rte_always_inline int
908 : : rnp_clean_tx_ring(struct rnp_tx_queue *txq)
909 : : {
910 : : volatile struct rnp_tx_desc *txbd;
911 : : struct rnp_txsw_entry *tx_swbd;
912 : : struct rte_mbuf *m;
913 : : uint16_t next_dd;
914 : : uint16_t i;
915 : :
916 : 0 : txbd = &txq->tx_bdr[txq->tx_next_dd];
917 [ # # ]: 0 : if (!(txbd->d.cmd & RNP_CMD_DD))
918 : : return 0;
919 : 0 : *txbd = txq->zero_desc;
920 : 0 : next_dd = txq->tx_next_dd - (txq->tx_free_thresh - 1);
921 : 0 : tx_swbd = &txq->sw_ring[next_dd];
922 : :
923 [ # # ]: 0 : for (i = 0; i < txq->tx_rs_thresh; ++i, ++tx_swbd) {
924 [ # # ]: 0 : if (tx_swbd->mbuf) {
925 : : m = tx_swbd->mbuf;
926 : : rte_pktmbuf_free_seg(m);
927 : 0 : tx_swbd->mbuf = NULL;
928 : : }
929 : : }
930 : 0 : txq->nb_tx_free = (txq->nb_tx_free + txq->tx_rs_thresh);
931 : 0 : txq->tx_next_dd = (txq->tx_next_dd + txq->tx_rs_thresh) &
932 : 0 : txq->attr.nb_desc_mask;
933 : :
934 : 0 : return 0;
935 : : }
936 : :
937 : : static __rte_always_inline uint16_t
938 : 0 : rnp_xmit_simple(void *_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
939 : : {
940 : : struct rnp_tx_queue *txq = (struct rnp_tx_queue *)_txq;
941 : : volatile struct rnp_tx_desc *txbd;
942 : : struct rnp_txsw_entry *tx_swbd;
943 : : uint64_t phy;
944 : : uint16_t start;
945 : : uint16_t i;
946 : :
947 [ # # # # ]: 0 : if (unlikely(!txq->txq_started || !txq->tx_link))
948 : : return 0;
949 : :
950 [ # # ]: 0 : if (txq->nb_tx_free < txq->tx_free_thresh)
951 : : rnp_clean_tx_ring(txq);
952 : :
953 : 0 : nb_pkts = RTE_MIN(txq->nb_tx_free, nb_pkts);
954 [ # # ]: 0 : if (!nb_pkts)
955 : : return 0;
956 : : start = nb_pkts;
957 : 0 : i = txq->tx_tail;
958 : :
959 [ # # ]: 0 : while (nb_pkts--) {
960 : 0 : txbd = &txq->tx_bdr[i];
961 : 0 : tx_swbd = &txq->sw_ring[i];
962 [ # # ]: 0 : tx_swbd->mbuf = *tx_pkts++;
963 : : phy = rnp_get_dma_addr(&txq->attr, tx_swbd->mbuf);
964 : 0 : txbd->d.addr = phy;
965 [ # # ]: 0 : if (unlikely(tx_swbd->mbuf->data_len > RNP_MAC_MAXFRM_SIZE))
966 : 0 : tx_swbd->mbuf->data_len = 0;
967 : 0 : txbd->d.blen = tx_swbd->mbuf->data_len;
968 : 0 : txbd->d.cmd = RNP_CMD_EOP;
969 : :
970 : 0 : txq->stats.obytes += txbd->d.blen;
971 : 0 : i = (i + 1) & txq->attr.nb_desc_mask;
972 : : }
973 : 0 : txq->nb_tx_free -= start;
974 [ # # ]: 0 : if (txq->tx_tail + start > txq->tx_next_rs) {
975 : 0 : txbd = &txq->tx_bdr[txq->tx_next_rs];
976 : 0 : txbd->d.cmd |= RNP_CMD_RS;
977 : 0 : txq->tx_next_rs = (txq->tx_next_rs + txq->tx_rs_thresh);
978 : :
979 [ # # ]: 0 : if (txq->tx_next_rs > txq->attr.nb_desc)
980 : 0 : txq->tx_next_rs = txq->tx_rs_thresh - 1;
981 : : }
982 : 0 : txq->stats.opackets += start;
983 : 0 : txq->tx_tail = i;
984 : :
985 : : rte_wmb();
986 : 0 : RNP_REG_WR(txq->tx_tailreg, 0, i);
987 : :
988 : 0 : return start;
989 : : }
990 : :
991 : : static int
992 : 0 : rnp_rxq_bulk_alloc(struct rnp_rx_queue *rxq,
993 : : volatile struct rnp_rx_desc *rxbd,
994 : : struct rnp_rxsw_entry *rxe,
995 : : bool bulk_alloc)
996 : : {
997 : : struct rte_eth_dev_data *data;
998 : : struct rte_mbuf *nmb = NULL;
999 : : uint16_t update_tail;
1000 : :
1001 [ # # ]: 0 : if (!bulk_alloc) {
1002 : 0 : data = rte_eth_devices[rxq->attr.port_id].data;
1003 : 0 : nmb = rte_mbuf_raw_alloc(rxq->mb_pool);
1004 [ # # ]: 0 : if (unlikely(!nmb)) {
1005 : 0 : data->rx_mbuf_alloc_failed++;
1006 : 0 : return -ENOMEM;
1007 : : }
1008 : 0 : rxbd->d.pkt_addr = 0;
1009 : 0 : rxbd->d.cmd = 0;
1010 : : rxe->mbuf = NULL;
1011 [ # # ]: 0 : rxe->mbuf = nmb;
1012 : 0 : rxbd->d.pkt_addr = rnp_get_dma_addr(&rxq->attr, nmb);
1013 : : }
1014 : 0 : rxq->rxrearm_nb++;
1015 [ # # ]: 0 : if (rxq->rxrearm_nb > rxq->rx_free_thresh) {
1016 : 0 : rxq->rxrearm_nb -= rxq->rx_free_thresh;
1017 : 0 : rxq->rxrearm_start += rxq->rx_free_thresh;
1018 [ # # ]: 0 : if (rxq->rxrearm_start >= rxq->attr.nb_desc)
1019 : 0 : rxq->rxrearm_start = 0;
1020 [ # # ]: 0 : update_tail = (uint16_t)((rxq->rxrearm_start == 0) ?
1021 : : (rxq->attr.nb_desc - 1) : (rxq->rxrearm_start - 1));
1022 : 0 : rte_io_wmb();
1023 : 0 : RNP_REG_WR(rxq->rx_tailreg, 0, update_tail);
1024 : : }
1025 : :
1026 : : return 0;
1027 : : }
1028 : :
1029 : : static __rte_always_inline uint16_t
1030 : 0 : rnp_scattered_rx(void *rx_queue, struct rte_mbuf **rx_pkts,
1031 : : uint16_t nb_pkts)
1032 : : {
1033 : : struct rnp_rx_queue *rxq = (struct rnp_rx_queue *)rx_queue;
1034 : 0 : volatile struct rnp_rx_desc *bd_ring = rxq->rx_bdr;
1035 : 0 : struct rte_mbuf *first_seg = rxq->pkt_first_seg;
1036 : 0 : struct rte_mbuf *last_seg = rxq->pkt_last_seg;
1037 : 0 : struct rnp_rxsw_entry *sw_ring = rxq->sw_ring;
1038 : : volatile struct rnp_rx_desc *rxbd;
1039 : : volatile struct rnp_rx_desc rxd;
1040 : : struct rnp_rxsw_entry *rxe;
1041 : : struct rte_mbuf *rxm;
1042 : : uint16_t rx_pkt_len;
1043 : : uint16_t nb_rx = 0;
1044 : : uint16_t rx_status;
1045 : : uint16_t rx_id;
1046 : :
1047 [ # # # # ]: 0 : if (unlikely(!rxq->rxq_started || !rxq->rx_link))
1048 : : return 0;
1049 : 0 : rx_id = rxq->rx_tail;
1050 [ # # ]: 0 : while (nb_rx < nb_pkts) {
1051 : 0 : rxbd = &bd_ring[rx_id];
1052 : 0 : rx_status = rxbd->wb.qword1.cmd;
1053 [ # # ]: 0 : if (!(rx_status & rte_cpu_to_le_16(RNP_CMD_DD)))
1054 : : break;
1055 : : rte_atomic_thread_fence(rte_memory_order_acquire);
1056 : 0 : rxd = *rxbd;
1057 : 0 : rxe = &sw_ring[rx_id];
1058 : 0 : rxm = rxe->mbuf;
1059 [ # # ]: 0 : if (rnp_rxq_bulk_alloc(rxq, rxbd, rxe, false))
1060 : : break;
1061 : 0 : rx_id = (rx_id + 1) & rxq->attr.nb_desc_mask;
1062 : 0 : rte_prefetch0(sw_ring[rx_id].mbuf);
1063 [ # # ]: 0 : if ((rx_id & 0x3) == 0) {
1064 : 0 : rte_prefetch0(&bd_ring[rx_id]);
1065 : 0 : rte_prefetch0(&sw_ring[rx_id]);
1066 : : }
1067 : 0 : rx_pkt_len = rxd.wb.qword1.lens;
1068 : 0 : rxm->data_len = rx_pkt_len;
1069 : 0 : rxm->data_off = RTE_PKTMBUF_HEADROOM;
1070 [ # # ]: 0 : if (!first_seg) {
1071 : : /* first segment pkt */
1072 : : first_seg = rxm;
1073 : 0 : first_seg->nb_segs = 1;
1074 : 0 : first_seg->pkt_len = rx_pkt_len;
1075 : : } else {
1076 : : /* follow-up segment pkt */
1077 : 0 : first_seg->pkt_len =
1078 : 0 : (uint16_t)(first_seg->pkt_len + rx_pkt_len);
1079 : 0 : first_seg->nb_segs++;
1080 : 0 : last_seg->next = rxm;
1081 : : }
1082 [ # # ]: 0 : if (!(rx_status & rte_cpu_to_le_16(RNP_CMD_EOP))) {
1083 : : last_seg = rxm;
1084 : 0 : continue;
1085 : : }
1086 : 0 : rxm->next = NULL;
1087 [ # # ]: 0 : first_seg->port = rxq->attr.port_id;
1088 : : rnp_dev_rx_parse(rxq, first_seg, rxd);
1089 : 0 : rxq->stats.ibytes += first_seg->pkt_len;
1090 : : /* this the end of packet the large pkt has been recv finish */
1091 : 0 : rte_prefetch0(RTE_PTR_ADD(first_seg->buf_addr,
1092 : : first_seg->data_off));
1093 : 0 : rx_pkts[nb_rx++] = first_seg;
1094 : : first_seg = NULL;
1095 : : }
1096 : : /* update sw record point */
1097 : 0 : rxq->stats.ipackets += nb_rx;
1098 : 0 : rxq->rx_tail = rx_id;
1099 : 0 : rxq->pkt_first_seg = first_seg;
1100 : 0 : rxq->pkt_last_seg = last_seg;
1101 : :
1102 : 0 : return nb_rx;
1103 : : }
1104 : :
1105 : : static __rte_always_inline uint16_t
1106 : : rnp_multiseg_clean_txq(struct rnp_tx_queue *txq)
1107 : : {
1108 : 0 : uint16_t last_desc_cleaned = txq->last_desc_cleaned;
1109 : 0 : struct rnp_txsw_entry *sw_ring = txq->sw_ring;
1110 : : volatile struct rnp_tx_desc *txbd;
1111 : : uint16_t desc_to_clean_to;
1112 : : uint16_t nb_tx_to_clean;
1113 : :
1114 : 0 : desc_to_clean_to = (uint16_t)(last_desc_cleaned + txq->tx_rs_thresh);
1115 : 0 : desc_to_clean_to = desc_to_clean_to & (txq->attr.nb_desc - 1);
1116 : :
1117 : 0 : desc_to_clean_to = sw_ring[desc_to_clean_to].last_id;
1118 : 0 : txbd = &txq->tx_bdr[desc_to_clean_to];
1119 [ # # # # ]: 0 : if (!(txbd->d.cmd & RNP_CMD_DD))
1120 : : return txq->nb_tx_free;
1121 : :
1122 [ # # # # ]: 0 : if (last_desc_cleaned > desc_to_clean_to)
1123 : 0 : nb_tx_to_clean = (uint16_t)((txq->attr.nb_desc -
1124 : : last_desc_cleaned) + desc_to_clean_to);
1125 : : else
1126 : 0 : nb_tx_to_clean = (uint16_t)(desc_to_clean_to -
1127 : : last_desc_cleaned);
1128 : :
1129 : 0 : txbd->d.cmd = 0;
1130 : :
1131 : 0 : txq->last_desc_cleaned = desc_to_clean_to;
1132 : 0 : txq->nb_tx_free = (uint16_t)(txq->nb_tx_free + nb_tx_to_clean);
1133 : :
1134 : 0 : return txq->nb_tx_free;
1135 : : }
1136 : : static inline uint32_t
1137 : : rnp_cal_tso_seg(struct rte_mbuf *mbuf)
1138 : : {
1139 : : uint32_t hdr_len;
1140 : :
1141 : 0 : hdr_len = mbuf->l2_len + mbuf->l3_len + mbuf->l4_len;
1142 : :
1143 : 0 : hdr_len += (mbuf->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) ?
1144 [ # # # # ]: 0 : mbuf->outer_l2_len + mbuf->outer_l3_len : 0;
1145 : :
1146 [ # # # # ]: 0 : return (mbuf->tso_segsz) ? mbuf->tso_segsz : hdr_len;
1147 : : }
1148 : :
1149 : : static inline bool
1150 : 0 : rnp_need_ctrl_desc(uint64_t flags)
1151 : : {
1152 : : static uint64_t mask = RTE_MBUF_F_TX_OUTER_IP_CKSUM |
1153 : : RTE_MBUF_F_TX_TCP_SEG |
1154 : : RTE_MBUF_F_TX_TUNNEL_VXLAN |
1155 : : RTE_MBUF_F_TX_TUNNEL_GRE |
1156 : : RTE_MBUF_F_TX_QINQ;
1157 : 0 : return (flags & mask) ? 1 : 0;
1158 : : }
1159 : :
1160 : : static void
1161 : 0 : rnp_build_tx_control_desc(struct rnp_tx_queue *txq,
1162 : : volatile struct rnp_tx_desc *txbd,
1163 : : struct rte_mbuf *mbuf)
1164 : : {
1165 : : struct rte_gre_hdr *gre_hdr;
1166 : : uint16_t tunnel_len = 0;
1167 : : uint64_t flags;
1168 : :
1169 : 0 : *txbd = txq->zero_desc;
1170 : : /* For outer checksum offload l2_len is
1171 : : * l2 (MAC) Header Length for non-tunneling pkt.
1172 : : * For Inner checksum offload l2_len is
1173 : : * Outer_L4_len + ... + Inner_L2_len(Inner L2 Header Len)
1174 : : * for tunneling pkt.
1175 : : */
1176 [ # # ]: 0 : if (!mbuf)
1177 : : return;
1178 : 0 : flags = mbuf->ol_flags;
1179 [ # # ]: 0 : if (flags & RTE_MBUF_F_TX_TCP_SEG) {
1180 : 0 : txbd->c.qword0.mss = rnp_cal_tso_seg(mbuf);
1181 : 0 : txbd->c.qword0.l4_len = mbuf->l4_len;
1182 : : }
1183 [ # # ]: 0 : if (flags & RTE_MBUF_F_TX_QINQ) {
1184 : 0 : txbd->c.qword0.vlan_tci = mbuf->vlan_tci;
1185 : 0 : txbd->c.qword1.cmd |= RNP_TX_QINQ_INSERT;
1186 : : }
1187 : : #define GRE_TUNNEL_KEY (4)
1188 : : #define GRE_TUNNEL_SEQ (4)
1189 [ # # # ]: 0 : switch (flags & RTE_MBUF_F_TX_TUNNEL_MASK) {
1190 : 0 : case RTE_MBUF_F_TX_TUNNEL_VXLAN:
1191 : 0 : tunnel_len = mbuf->outer_l2_len + mbuf->outer_l3_len +
1192 : : sizeof(struct rte_udp_hdr) +
1193 : : sizeof(struct rte_vxlan_hdr);
1194 : 0 : break;
1195 : 0 : case RTE_MBUF_F_TX_TUNNEL_GRE:
1196 : 0 : gre_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_gre_hdr *,
1197 : : mbuf->outer_l2_len + mbuf->outer_l3_len);
1198 : 0 : tunnel_len = mbuf->outer_l2_len + mbuf->outer_l3_len +
1199 : : sizeof(struct rte_gre_hdr);
1200 [ # # ]: 0 : if (gre_hdr->k)
1201 : 0 : tunnel_len += GRE_TUNNEL_KEY;
1202 [ # # ]: 0 : if (gre_hdr->s)
1203 : 0 : tunnel_len += GRE_TUNNEL_SEQ;
1204 : : break;
1205 : : }
1206 : 0 : txbd->c.qword0.tunnel_len = tunnel_len;
1207 : 0 : txbd->c.qword1.cmd |= RNP_CTRL_DESC;
1208 : : }
1209 : :
1210 : : static void
1211 : 0 : rnp_padding_hdr_len(volatile struct rnp_tx_desc *txbd,
1212 : : struct rte_mbuf *m)
1213 : : {
1214 : : struct rte_ether_hdr *eth_hdr = NULL;
1215 : : struct rte_vlan_hdr *vlan_hdr = NULL;
1216 : : int ethertype, l2_len;
1217 : : uint16_t l3_len = 0;
1218 : :
1219 [ # # ]: 0 : if (m->l2_len == 0) {
1220 : 0 : eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
1221 : : l2_len = RTE_ETHER_HDR_LEN;
1222 : 0 : ethertype = rte_le_to_cpu_32(eth_hdr->ether_type);
1223 [ # # ]: 0 : if (ethertype == RTE_ETHER_TYPE_VLAN) {
1224 : 0 : vlan_hdr = rte_pktmbuf_mtod_offset(m, struct rte_vlan_hdr *,
1225 : : sizeof(struct rte_ether_hdr));
1226 : : l2_len += RTE_VLAN_HLEN;
1227 : 0 : ethertype = vlan_hdr->eth_proto;
1228 : : }
1229 [ # # # ]: 0 : switch (ethertype) {
1230 : 0 : case RTE_ETHER_TYPE_IPV4:
1231 : : l3_len = sizeof(struct rte_ipv4_hdr);
1232 : 0 : break;
1233 : 0 : case RTE_ETHER_TYPE_IPV6:
1234 : : l3_len = sizeof(struct rte_ipv6_hdr);
1235 : 0 : break;
1236 : : }
1237 : : } else {
1238 : 0 : l2_len = m->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK ?
1239 [ # # ]: 0 : m->outer_l2_len : m->l2_len;
1240 : 0 : l3_len = m->l3_len;
1241 : : }
1242 : 0 : txbd->d.mac_ip_len = l2_len << RNP_TX_MAC_LEN_S;
1243 : 0 : txbd->d.mac_ip_len |= l3_len;
1244 : 0 : }
1245 : :
1246 : : static void
1247 : 0 : rnp_check_inner_eth_hdr(struct rte_mbuf *mbuf,
1248 : : volatile struct rnp_tx_desc *txbd)
1249 : : {
1250 : : struct rte_ether_hdr *eth_hdr;
1251 : : uint16_t inner_l2_offset = 0;
1252 : : struct rte_vlan_hdr *vlan_hdr;
1253 : : uint16_t ext_l2_len = 0;
1254 : : uint16_t l2_offset = 0;
1255 : : uint16_t l2_type;
1256 : :
1257 : 0 : inner_l2_offset = mbuf->outer_l2_len + mbuf->outer_l3_len +
1258 : : sizeof(struct rte_udp_hdr) +
1259 : : sizeof(struct rte_vxlan_hdr);
1260 : 0 : eth_hdr = rte_pktmbuf_mtod_offset(mbuf,
1261 : : struct rte_ether_hdr *, inner_l2_offset);
1262 : 0 : l2_type = eth_hdr->ether_type;
1263 : 0 : l2_offset = txbd->d.mac_ip_len >> RNP_TX_MAC_LEN_S;
1264 [ # # # # ]: 0 : while (l2_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN) ||
1265 : : l2_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_QINQ)) {
1266 : 0 : vlan_hdr = (struct rte_vlan_hdr *)
1267 : : ((char *)eth_hdr + l2_offset);
1268 : 0 : l2_offset += RTE_VLAN_HLEN;
1269 : 0 : ext_l2_len += RTE_VLAN_HLEN;
1270 : 0 : l2_type = vlan_hdr->eth_proto;
1271 : : }
1272 : 0 : txbd->d.mac_ip_len += (ext_l2_len << RNP_TX_MAC_LEN_S);
1273 : 0 : }
1274 : :
1275 : : #define RNP_TX_L4_OFFLOAD_ALL (RTE_MBUF_F_TX_SCTP_CKSUM | \
1276 : : RTE_MBUF_F_TX_TCP_CKSUM | \
1277 : : RTE_MBUF_F_TX_UDP_CKSUM)
1278 : : static inline void
1279 : 0 : rnp_setup_csum_offload(struct rte_mbuf *mbuf,
1280 : : volatile struct rnp_tx_desc *tx_desc)
1281 : : {
1282 : 0 : tx_desc->d.cmd |= (mbuf->ol_flags & RTE_MBUF_F_TX_IP_CKSUM) ?
1283 : 0 : RNP_TX_IP_CKSUM_EN : 0;
1284 : 0 : tx_desc->d.cmd |= (mbuf->ol_flags & RTE_MBUF_F_TX_IPV6) ?
1285 : 0 : RNP_TX_L3TYPE_IPV6 : 0;
1286 [ # # ]: 0 : tx_desc->d.cmd |= (mbuf->ol_flags & RNP_TX_L4_OFFLOAD_ALL) ?
1287 : : RNP_TX_L4CKSUM_EN : 0;
1288 [ # # # # ]: 0 : switch ((mbuf->ol_flags & RTE_MBUF_F_TX_L4_MASK)) {
1289 : 0 : case RTE_MBUF_F_TX_TCP_CKSUM:
1290 : 0 : tx_desc->d.cmd |= RNP_TX_L4TYPE_TCP;
1291 : 0 : break;
1292 : 0 : case RTE_MBUF_F_TX_UDP_CKSUM:
1293 : 0 : tx_desc->d.cmd |= RNP_TX_L4TYPE_UDP;
1294 : 0 : break;
1295 : 0 : case RTE_MBUF_F_TX_SCTP_CKSUM:
1296 : 0 : tx_desc->d.cmd |= RNP_TX_L4TYPE_SCTP;
1297 : 0 : break;
1298 : : }
1299 : 0 : tx_desc->d.mac_ip_len = mbuf->l2_len << RNP_TX_MAC_LEN_S;
1300 : 0 : tx_desc->d.mac_ip_len |= mbuf->l3_len;
1301 [ # # ]: 0 : if (mbuf->ol_flags & RTE_MBUF_F_TX_TCP_SEG) {
1302 : 0 : tx_desc->d.cmd |= RNP_TX_IP_CKSUM_EN;
1303 : 0 : tx_desc->d.cmd |= RNP_TX_L4CKSUM_EN;
1304 : 0 : tx_desc->d.cmd |= RNP_TX_L4TYPE_TCP;
1305 : 0 : tx_desc->d.cmd |= RNP_TX_TSO_EN;
1306 : : }
1307 [ # # ]: 0 : if (mbuf->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) {
1308 : : /* need inner l2 l3 lens for inner checksum offload */
1309 : 0 : tx_desc->d.mac_ip_len &= ~RNP_TX_MAC_LEN_MASK;
1310 : 0 : tx_desc->d.mac_ip_len |= RTE_ETHER_HDR_LEN << RNP_TX_MAC_LEN_S;
1311 : 0 : rnp_check_inner_eth_hdr(mbuf, tx_desc);
1312 [ # # # ]: 0 : switch (mbuf->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) {
1313 : 0 : case RTE_MBUF_F_TX_TUNNEL_VXLAN:
1314 : 0 : tx_desc->d.cmd |= RNP_TX_VXLAN_TUNNEL;
1315 : 0 : break;
1316 : 0 : case RTE_MBUF_F_TX_TUNNEL_GRE:
1317 : 0 : tx_desc->d.cmd |= RNP_TX_NVGRE_TUNNEL;
1318 : 0 : break;
1319 : : }
1320 : : }
1321 : 0 : }
1322 : :
1323 : : static void
1324 : 0 : rnp_setup_tx_offload(struct rnp_tx_queue *txq,
1325 : : volatile struct rnp_tx_desc *txbd,
1326 : : uint64_t flags, struct rte_mbuf *tx_pkt)
1327 : : {
1328 : 0 : *txbd = txq->zero_desc;
1329 : 0 : if (flags & RTE_MBUF_F_TX_L4_MASK ||
1330 [ # # ]: 0 : flags & RTE_MBUF_F_TX_TCP_SEG ||
1331 : : flags & RTE_MBUF_F_TX_IP_CKSUM)
1332 : 0 : rnp_setup_csum_offload(tx_pkt, txbd);
1333 [ # # ]: 0 : if (flags & (RTE_MBUF_F_TX_VLAN |
1334 : : RTE_MBUF_F_TX_QINQ)) {
1335 : 0 : txbd->d.cmd |= RNP_TX_VLAN_VALID;
1336 [ # # ]: 0 : txbd->d.vlan_tci = (flags & RTE_MBUF_F_TX_QINQ) ?
1337 : : tx_pkt->vlan_tci_outer : tx_pkt->vlan_tci;
1338 : 0 : txbd->d.cmd |= RNP_TX_VLAN_INSERT;
1339 : : }
1340 : 0 : }
1341 : :
1342 : : static __rte_always_inline uint16_t
1343 : 0 : rnp_multiseg_xmit_pkts(void *_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
1344 : : {
1345 : : struct rnp_tx_queue *txq = (struct rnp_tx_queue *)_txq;
1346 : : volatile struct rnp_tx_desc *txbd;
1347 : : struct rnp_txsw_entry *txe, *txn;
1348 : : struct rte_mbuf *tx_pkt, *m_seg;
1349 : : uint16_t send_pkts = 0;
1350 : : uint16_t nb_used_bd;
1351 : : uint8_t ctx_desc_use;
1352 : : uint8_t first_seg;
1353 : : uint16_t tx_last;
1354 : : uint16_t nb_tx;
1355 : : uint16_t tx_id;
1356 : :
1357 [ # # # # ]: 0 : if (unlikely(!txq->txq_started || !txq->tx_link))
1358 : : return 0;
1359 [ # # ]: 0 : if (txq->nb_tx_free < txq->tx_free_thresh)
1360 : : rnp_multiseg_clean_txq(txq);
1361 [ # # ]: 0 : if (unlikely(txq->nb_tx_free == 0))
1362 : : return 0;
1363 : 0 : tx_id = txq->tx_tail;
1364 : 0 : txbd = &txq->tx_bdr[tx_id];
1365 : 0 : txe = &txq->sw_ring[tx_id];
1366 [ # # ]: 0 : for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
1367 : 0 : tx_pkt = tx_pkts[nb_tx];
1368 : 0 : ctx_desc_use = rnp_need_ctrl_desc(tx_pkt->ol_flags);
1369 : 0 : nb_used_bd = tx_pkt->nb_segs + ctx_desc_use;
1370 : 0 : tx_last = (uint16_t)(tx_id + nb_used_bd - 1);
1371 [ # # ]: 0 : if (tx_last >= txq->attr.nb_desc)
1372 : 0 : tx_last = (uint16_t)(tx_last - txq->attr.nb_desc);
1373 [ # # ]: 0 : if (nb_used_bd > txq->nb_tx_free)
1374 [ # # ]: 0 : if (nb_used_bd > rnp_multiseg_clean_txq(txq))
1375 : : break;
1376 [ # # ]: 0 : if (ctx_desc_use) {
1377 : 0 : txbd = &txq->tx_bdr[tx_id];
1378 : 0 : txn = &txq->sw_ring[txe->next_id];
1379 [ # # ]: 0 : RTE_MBUF_PREFETCH_TO_FREE(txn->mbuf);
1380 [ # # ]: 0 : if (txe->mbuf) {
1381 : : rte_pktmbuf_free_seg(txe->mbuf);
1382 : 0 : txe->mbuf = NULL;
1383 : : }
1384 : 0 : rnp_build_tx_control_desc(txq, txbd, tx_pkt);
1385 : 0 : txe->last_id = tx_last;
1386 : 0 : tx_id = txe->next_id;
1387 : : txe = txn;
1388 : : }
1389 : : m_seg = tx_pkt;
1390 : : first_seg = 1;
1391 : : do {
1392 : 0 : txbd = &txq->tx_bdr[tx_id];
1393 : 0 : txbd->d.cmd = 0;
1394 : 0 : txn = &txq->sw_ring[txe->next_id];
1395 [ # # # # ]: 0 : if ((first_seg && m_seg->ol_flags)) {
1396 : 0 : rnp_setup_tx_offload(txq, txbd,
1397 : : m_seg->ol_flags, m_seg);
1398 [ # # ]: 0 : if (!txbd->d.mac_ip_len)
1399 : 0 : rnp_padding_hdr_len(txbd, m_seg);
1400 : : first_seg = 0;
1401 : : }
1402 [ # # ]: 0 : if (txe->mbuf) {
1403 : : rte_pktmbuf_free_seg(txe->mbuf);
1404 : : txe->mbuf = NULL;
1405 : : }
1406 : 0 : txe->mbuf = m_seg;
1407 [ # # ]: 0 : txe->last_id = tx_last;
1408 : 0 : txbd->d.addr = rnp_get_dma_addr(&txq->attr, m_seg);
1409 : 0 : txbd->d.blen = rte_cpu_to_le_32(m_seg->data_len);
1410 : 0 : txbd->d.cmd &= ~RNP_CMD_EOP;
1411 : 0 : m_seg = m_seg->next;
1412 : 0 : tx_id = txe->next_id;
1413 : : txe = txn;
1414 [ # # ]: 0 : } while (m_seg != NULL);
1415 : 0 : txq->stats.obytes += tx_pkt->pkt_len;
1416 : 0 : txbd->d.cmd |= RNP_CMD_EOP;
1417 : 0 : txq->nb_tx_used = (uint16_t)txq->nb_tx_used + nb_used_bd;
1418 : 0 : txq->nb_tx_free = (uint16_t)txq->nb_tx_free - nb_used_bd;
1419 [ # # ]: 0 : if (txq->nb_tx_used >= txq->tx_rs_thresh) {
1420 : 0 : txq->nb_tx_used = 0;
1421 : 0 : txbd->d.cmd |= RNP_CMD_RS;
1422 : : }
1423 : 0 : send_pkts++;
1424 : : }
1425 [ # # ]: 0 : if (!send_pkts)
1426 : : return 0;
1427 : 0 : txq->stats.opackets += send_pkts;
1428 : 0 : txq->tx_tail = tx_id;
1429 : :
1430 : : rte_wmb();
1431 : 0 : RNP_REG_WR(txq->tx_tailreg, 0, tx_id);
1432 : :
1433 : 0 : return send_pkts;
1434 : : }
1435 : :
1436 : : #define RNP_TX_TUNNEL_NOSUP_TSO_MASK (RTE_MBUF_F_TX_TUNNEL_MASK ^ \
1437 : : (RTE_MBUF_F_TX_TUNNEL_VXLAN | \
1438 : : RTE_MBUF_F_TX_TUNNEL_GRE))
1439 : : static inline bool
1440 : 0 : rnp_check_tx_tso_valid(struct rte_mbuf *m)
1441 : : {
1442 : 0 : uint16_t max_seg = m->nb_segs;
1443 : : uint32_t remain_len = 0;
1444 : : struct rte_mbuf *m_seg;
1445 : : uint32_t total_len = 0;
1446 : : uint32_t limit_len = 0;
1447 : : uint32_t tso = 0;
1448 : :
1449 [ # # ]: 0 : if (likely(!(m->ol_flags & RTE_MBUF_F_TX_TCP_SEG))) {
1450 : : /* non tso mode */
1451 [ # # ]: 0 : if (unlikely(m->pkt_len > RNP_MAC_MAXFRM_SIZE)) {
1452 : : return false;
1453 [ # # ]: 0 : } else if (max_seg <= RNP_TX_MAX_MTU_SEG) {
1454 : : m_seg = m;
1455 : : do {
1456 : 0 : total_len += m_seg->data_len;
1457 : 0 : m_seg = m_seg->next;
1458 [ # # ]: 0 : } while (m_seg != NULL);
1459 [ # # ]: 0 : if (total_len > RNP_MAC_MAXFRM_SIZE)
1460 : : return false;
1461 : 0 : return true;
1462 : : }
1463 : : } else {
1464 [ # # ]: 0 : if (unlikely(m->ol_flags & RNP_TX_TUNNEL_NOSUP_TSO_MASK))
1465 : : return false;
1466 [ # # ]: 0 : if (max_seg > RNP_TX_MAX_MTU_SEG)
1467 : : return false;
1468 : : tso = rnp_cal_tso_seg(m);
1469 : : m_seg = m;
1470 : : do {
1471 : 0 : remain_len = RTE_MAX(remain_len, m_seg->data_len % tso);
1472 : 0 : m_seg = m_seg->next;
1473 [ # # ]: 0 : } while (m_seg != NULL);
1474 : : /* TSO will remain bytes because of tso
1475 : : * in this situation must refer the worst condition
1476 : : */
1477 : 0 : limit_len = remain_len * max_seg + tso;
1478 : :
1479 [ # # ]: 0 : if (limit_len > RNP_MAX_TSO_PKT)
1480 : 0 : return false;
1481 : : }
1482 : :
1483 : : return true;
1484 : : }
1485 : :
1486 : : static inline int
1487 : 0 : rnp_net_cksum_flags_prepare(struct rte_mbuf *m, uint64_t ol_flags)
1488 : : {
1489 : : struct rte_ipv4_hdr *ipv4_hdr = NULL;
1490 : 0 : uint64_t inner_l3_offset = m->l2_len;
1491 : : struct rte_ipv6_hdr *ipv6_hdr;
1492 : : struct rte_sctp_hdr *sctp_hdr;
1493 : : struct rte_tcp_hdr *tcp_hdr;
1494 : : struct rte_udp_hdr *udp_hdr;
1495 : :
1496 [ # # ]: 0 : if (!(ol_flags & (RTE_MBUF_F_TX_IP_CKSUM |
1497 : : RTE_MBUF_F_TX_L4_MASK |
1498 : : RTE_MBUF_F_TX_TCP_SEG)))
1499 : : return 0;
1500 [ # # ]: 0 : if (ol_flags & (RTE_MBUF_F_TX_OUTER_IPV4 | RTE_MBUF_F_TX_OUTER_IPV6)) {
1501 [ # # ]: 0 : if ((ol_flags & RTE_MBUF_F_TX_L4_MASK) ==
1502 : 0 : RTE_MBUF_F_TX_TCP_CKSUM ||
1503 [ # # ]: 0 : (ol_flags & RTE_MBUF_F_TX_TCP_SEG)) {
1504 : : /* hardware must require out-ip cksum is zero
1505 : : * when vxlan-tso enable
1506 : : */
1507 : 0 : ipv4_hdr = rte_pktmbuf_mtod_offset(m,
1508 : : struct rte_ipv4_hdr *, m->outer_l2_len);
1509 : 0 : ipv4_hdr->hdr_checksum = 0;
1510 : : }
1511 : 0 : inner_l3_offset += m->outer_l2_len + m->outer_l3_len;
1512 : : }
1513 [ # # ]: 0 : if (unlikely(rte_pktmbuf_data_len(m) <
1514 : : inner_l3_offset + m->l3_len + m->l4_len))
1515 : : return -ENOTSUP;
1516 [ # # ]: 0 : if (ol_flags & RTE_MBUF_F_TX_IPV4) {
1517 : 0 : ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv4_hdr *,
1518 : : inner_l3_offset);
1519 [ # # ]: 0 : if (ol_flags & RTE_MBUF_F_TX_IP_CKSUM)
1520 : 0 : ipv4_hdr->hdr_checksum = 0;
1521 : : }
1522 [ # # ]: 0 : if ((ol_flags & RTE_MBUF_F_TX_L4_MASK) == RTE_MBUF_F_TX_UDP_CKSUM) {
1523 [ # # ]: 0 : if (ol_flags & RTE_MBUF_F_TX_IPV4) {
1524 : 0 : ipv4_hdr = rte_pktmbuf_mtod_offset(m,
1525 : : struct rte_ipv4_hdr *, inner_l3_offset);
1526 : 0 : udp_hdr = (struct rte_udp_hdr *)((char *)ipv4_hdr +
1527 : : m->l3_len);
1528 : 0 : udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum(ipv4_hdr,
1529 : : ol_flags);
1530 : : } else {
1531 : 0 : ipv6_hdr = rte_pktmbuf_mtod_offset(m,
1532 : : struct rte_ipv6_hdr *, inner_l3_offset);
1533 : : /* non-TSO udp */
1534 : 0 : udp_hdr = rte_pktmbuf_mtod_offset(m,
1535 : : struct rte_udp_hdr *,
1536 : : inner_l3_offset + m->l3_len);
1537 : 0 : udp_hdr->dgram_cksum = rte_ipv6_phdr_cksum(ipv6_hdr,
1538 : : ol_flags);
1539 : : }
1540 [ # # ]: 0 : } else if ((ol_flags & RTE_MBUF_F_TX_L4_MASK) == RTE_MBUF_F_TX_TCP_CKSUM ||
1541 [ # # ]: 0 : (ol_flags & RTE_MBUF_F_TX_TCP_SEG)) {
1542 [ # # ]: 0 : if (ol_flags & RTE_MBUF_F_TX_IPV4) {
1543 : : /* non-TSO tcp or TSO */
1544 : 0 : ipv4_hdr = rte_pktmbuf_mtod_offset(m,
1545 : : struct rte_ipv4_hdr *, inner_l3_offset);
1546 : 0 : tcp_hdr = (struct rte_tcp_hdr *)((char *)ipv4_hdr + m->l3_len);
1547 : 0 : tcp_hdr->cksum = rte_ipv4_phdr_cksum(ipv4_hdr,
1548 : : ol_flags);
1549 : : } else {
1550 : 0 : ipv6_hdr = rte_pktmbuf_mtod_offset(m,
1551 : : struct rte_ipv6_hdr *, inner_l3_offset);
1552 : : /* non-TSO tcp or TSO */
1553 : 0 : tcp_hdr = rte_pktmbuf_mtod_offset(m,
1554 : : struct rte_tcp_hdr *,
1555 : : inner_l3_offset + m->l3_len);
1556 : 0 : tcp_hdr->cksum = rte_ipv6_phdr_cksum(ipv6_hdr,
1557 : : ol_flags);
1558 : : }
1559 [ # # ]: 0 : } else if ((ol_flags & RTE_MBUF_F_TX_L4_MASK) == RTE_MBUF_F_TX_SCTP_CKSUM) {
1560 [ # # ]: 0 : if (ol_flags & RTE_MBUF_F_TX_IPV4) {
1561 : 0 : ipv4_hdr = rte_pktmbuf_mtod_offset(m,
1562 : : struct rte_ipv4_hdr *, inner_l3_offset);
1563 : 0 : sctp_hdr = (struct rte_sctp_hdr *)((char *)ipv4_hdr +
1564 : : m->l3_len);
1565 : : /* SCTP-cksm implement CRC32 */
1566 : 0 : sctp_hdr->cksum = 0;
1567 : : } else {
1568 : 0 : ipv6_hdr = rte_pktmbuf_mtod_offset(m,
1569 : : struct rte_ipv6_hdr *, inner_l3_offset);
1570 : : /* NON-TSO SCTP */
1571 : 0 : sctp_hdr = rte_pktmbuf_mtod_offset(m,
1572 : : struct rte_sctp_hdr *,
1573 : : inner_l3_offset + m->l3_len);
1574 : 0 : sctp_hdr->cksum = 0;
1575 : : }
1576 : : }
1577 [ # # ]: 0 : if (ol_flags & RTE_MBUF_F_TX_IP_CKSUM && !(ol_flags &
1578 : : (RTE_MBUF_F_TX_L4_MASK | RTE_MBUF_F_TX_TCP_SEG))) {
1579 : : /* the hardware L4 is follow on l3 checksum.
1580 : : * when ol_flags set hw L3, sw l4 checksum offload,
1581 : : * we must prepare pseudo header to avoid
1582 : : * the l4 Checksum error
1583 : : */
1584 [ # # ]: 0 : if (ol_flags & RTE_MBUF_F_TX_IPV4) {
1585 : 0 : ipv4_hdr = rte_pktmbuf_mtod_offset(m,
1586 : : struct rte_ipv4_hdr *, inner_l3_offset);
1587 [ # # # ]: 0 : switch (ipv4_hdr->next_proto_id) {
1588 : 0 : case IPPROTO_UDP:
1589 : 0 : udp_hdr = (struct rte_udp_hdr *)((char *)ipv4_hdr +
1590 : : m->l3_len);
1591 : 0 : udp_hdr->dgram_cksum =
1592 : 0 : rte_ipv4_phdr_cksum(ipv4_hdr, ol_flags);
1593 : 0 : break;
1594 : 0 : case IPPROTO_TCP:
1595 : 0 : tcp_hdr = (struct rte_tcp_hdr *)((char *)ipv4_hdr +
1596 : : m->l3_len);
1597 : 0 : tcp_hdr->cksum = rte_ipv4_phdr_cksum(ipv4_hdr,
1598 : : ol_flags);
1599 : 0 : break;
1600 : : default:
1601 : : break;
1602 : : }
1603 : : } else {
1604 : 0 : ipv6_hdr = rte_pktmbuf_mtod_offset(m,
1605 : : struct rte_ipv6_hdr *, inner_l3_offset);
1606 [ # # # ]: 0 : switch (ipv6_hdr->proto) {
1607 : 0 : case IPPROTO_UDP:
1608 : 0 : udp_hdr = (struct rte_udp_hdr *)((char *)ipv6_hdr +
1609 : : m->l3_len);
1610 : 0 : udp_hdr->dgram_cksum =
1611 : 0 : rte_ipv6_phdr_cksum(ipv6_hdr, ol_flags);
1612 : 0 : break;
1613 : 0 : case IPPROTO_TCP:
1614 : 0 : tcp_hdr = (struct rte_tcp_hdr *)((char *)ipv6_hdr +
1615 : : m->l3_len);
1616 : 0 : tcp_hdr->cksum = rte_ipv6_phdr_cksum(ipv6_hdr,
1617 : : ol_flags);
1618 : 0 : break;
1619 : : default:
1620 : : break;
1621 : : }
1622 : : }
1623 : : }
1624 : :
1625 : : return 0;
1626 : : }
1627 : :
1628 : : static uint16_t
1629 : 0 : rnp_tx_pkt_prepare(void *tx_queue,
1630 : : struct rte_mbuf **tx_pkts,
1631 : : uint16_t nb_pkts)
1632 : : {
1633 : : struct rnp_tx_queue *txq = (struct rnp_tx_queue *)tx_queue;
1634 : : struct rte_mbuf *m;
1635 : : int i, ret;
1636 : :
1637 : 0 : PMD_INIT_FUNC_TRACE();
1638 [ # # ]: 0 : for (i = 0; i < nb_pkts; i++) {
1639 : 0 : m = tx_pkts[i];
1640 [ # # ]: 0 : if (unlikely(!rnp_check_tx_tso_valid(m))) {
1641 : 0 : txq->stats.errors++;
1642 : 0 : rte_errno = EINVAL;
1643 : 0 : return i;
1644 : : }
1645 [ # # ]: 0 : if (m->nb_segs > 10) {
1646 : 0 : txq->stats.errors++;
1647 : 0 : rte_errno = EINVAL;
1648 : 0 : return i;
1649 : : }
1650 : : #ifdef RTE_ETHDEV_DEBUG_TX
1651 : : ret = rte_validate_tx_offload(m);
1652 : : if (ret != 0) {
1653 : : rte_errno = -ret;
1654 : : return i;
1655 : : }
1656 : : #endif
1657 : 0 : ret = rnp_net_cksum_flags_prepare(m, m->ol_flags);
1658 [ # # ]: 0 : if (ret != 0) {
1659 : 0 : rte_errno = -ret;
1660 : 0 : return i;
1661 : : }
1662 : : }
1663 : :
1664 : 0 : return i;
1665 : : }
1666 : :
1667 : : static int
1668 : : rnp_check_rx_simple_valid(struct rte_eth_dev *dev)
1669 : : {
1670 : 0 : uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
1671 : :
1672 [ # # ]: 0 : if (dev->data->scattered_rx || rx_offloads & RTE_ETH_RX_OFFLOAD_SCATTER)
1673 : : return -ENOTSUP;
1674 : : return 0;
1675 : : }
1676 : :
1677 [ # # ]: 0 : int rnp_rx_func_select(struct rte_eth_dev *dev)
1678 : : {
1679 : : bool simple_allowed = false;
1680 : :
1681 : : simple_allowed = rnp_check_rx_simple_valid(dev) == 0;
1682 : : if (simple_allowed)
1683 : 0 : dev->rx_pkt_burst = rnp_recv_pkts;
1684 : : else
1685 : 0 : dev->rx_pkt_burst = rnp_scattered_rx;
1686 : :
1687 : 0 : return 0;
1688 : : }
1689 : :
1690 : : static int
1691 : : rnp_check_tx_simple_valid(struct rte_eth_dev *dev, struct rnp_tx_queue *txq)
1692 : : {
1693 : 0 : uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
1694 : :
1695 : 0 : tx_offloads |= txq->tx_offloads;
1696 : 0 : if (tx_offloads != RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)
1697 : : return -ENOTSUP;
1698 [ # # ]: 0 : if (dev->data->scattered_rx)
1699 : 0 : return -ENOTSUP;
1700 : :
1701 : : return 0;
1702 : : }
1703 : :
1704 : 0 : int rnp_tx_func_select(struct rte_eth_dev *dev)
1705 : : {
1706 : : bool simple_allowed = false;
1707 : : struct rnp_tx_queue *txq;
1708 : : int idx = 0;
1709 : :
1710 [ # # ]: 0 : for (idx = 0; idx < dev->data->nb_tx_queues; idx++) {
1711 [ # # ]: 0 : txq = dev->data->tx_queues[idx];
1712 : 0 : simple_allowed = rnp_check_tx_simple_valid(dev, txq) == 0;
1713 : : }
1714 [ # # ]: 0 : if (simple_allowed) {
1715 : 0 : dev->tx_pkt_burst = rnp_xmit_simple;
1716 : : } else {
1717 : 0 : dev->tx_pkt_burst = rnp_multiseg_xmit_pkts;
1718 : 0 : dev->tx_pkt_prepare = rnp_tx_pkt_prepare;
1719 : : }
1720 : :
1721 : 0 : return 0;
1722 : : }
1723 : :
1724 : : void
1725 : 0 : rnp_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
1726 : : struct rte_eth_rxq_info *qinfo)
1727 : : {
1728 : : struct rnp_rx_queue *rxq;
1729 : :
1730 : 0 : rxq = dev->data->rx_queues[queue_id];
1731 [ # # ]: 0 : if (!rxq)
1732 : : return;
1733 : 0 : qinfo->mp = rxq->mb_pool;
1734 : 0 : qinfo->scattered_rx = dev->data->scattered_rx;
1735 : 0 : qinfo->queue_state = rxq->rxq_started;
1736 : 0 : qinfo->nb_desc = rxq->attr.nb_desc;
1737 : 0 : qinfo->rx_buf_size = rxq->rx_buf_len;
1738 : :
1739 : 0 : qinfo->conf.rx_deferred_start = rxq->rx_deferred_start;
1740 : 0 : qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
1741 : 0 : qinfo->conf.rx_thresh.pthresh = rxq->pthresh;
1742 : 0 : qinfo->conf.rx_thresh.hthresh = rxq->pburst;
1743 : 0 : qinfo->conf.offloads = rxq->rx_offloads;
1744 : : }
1745 : :
1746 : : void
1747 : 0 : rnp_tx_queue_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
1748 : : struct rte_eth_txq_info *qinfo)
1749 : : {
1750 : : struct rnp_tx_queue *txq;
1751 : :
1752 : 0 : txq = dev->data->tx_queues[queue_id];
1753 [ # # ]: 0 : if (!txq)
1754 : : return;
1755 : 0 : qinfo->queue_state = txq->txq_started;
1756 : 0 : qinfo->nb_desc = txq->attr.nb_desc;
1757 : :
1758 : 0 : qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
1759 : 0 : qinfo->conf.tx_free_thresh = txq->tx_free_thresh;
1760 : 0 : qinfo->conf.tx_rs_thresh = txq->tx_rs_thresh;
1761 : 0 : qinfo->conf.tx_thresh.pthresh = txq->pthresh;
1762 : 0 : qinfo->conf.tx_thresh.hthresh = txq->pburst;
1763 : 0 : qinfo->conf.offloads = txq->tx_offloads;
1764 : : }
1765 : :
1766 : : static const struct {
1767 : : eth_rx_burst_t pkt_burst;
1768 : : const char *info;
1769 : : } rnp_rx_burst_infos[] = {
1770 : : { rnp_scattered_rx, "Scalar Scattered" },
1771 : : { rnp_recv_pkts, "Scalar" },
1772 : : };
1773 : :
1774 : : static const struct {
1775 : : eth_tx_burst_t pkt_burst;
1776 : : const char *info;
1777 : : } rnp_tx_burst_infos[] = {
1778 : : { rnp_xmit_simple, "Scalar Simple" },
1779 : : { rnp_multiseg_xmit_pkts, "Scalar" },
1780 : : };
1781 : :
1782 : : int
1783 : 0 : rnp_rx_burst_mode_get(struct rte_eth_dev *dev,
1784 : : __rte_unused uint16_t queue_id,
1785 : : struct rte_eth_burst_mode *mode)
1786 : : {
1787 : 0 : eth_rx_burst_t pkt_burst = dev->rx_pkt_burst;
1788 : : int ret = -EINVAL;
1789 : : unsigned int i;
1790 : :
1791 [ # # ]: 0 : for (i = 0; i < RTE_DIM(rnp_rx_burst_infos); ++i) {
1792 [ # # ]: 0 : if (pkt_burst == rnp_rx_burst_infos[i].pkt_burst) {
1793 : 0 : snprintf(mode->info, sizeof(mode->info), "%s",
1794 : 0 : rnp_rx_burst_infos[i].info);
1795 : : ret = 0;
1796 : 0 : break;
1797 : : }
1798 : : }
1799 : :
1800 : 0 : return ret;
1801 : : }
1802 : :
1803 : : int
1804 : 0 : rnp_tx_burst_mode_get(struct rte_eth_dev *dev,
1805 : : __rte_unused uint16_t queue_id,
1806 : : struct rte_eth_burst_mode *mode)
1807 : : {
1808 : 0 : eth_tx_burst_t pkt_burst = dev->tx_pkt_burst;
1809 : : int ret = -EINVAL;
1810 : : unsigned int i;
1811 : :
1812 [ # # ]: 0 : for (i = 0; i < RTE_DIM(rnp_tx_burst_infos); ++i) {
1813 [ # # ]: 0 : if (pkt_burst == rnp_tx_burst_infos[i].pkt_burst) {
1814 : 0 : snprintf(mode->info, sizeof(mode->info), "%s",
1815 : 0 : rnp_tx_burst_infos[i].info);
1816 : : ret = 0;
1817 : 0 : break;
1818 : : }
1819 : : }
1820 : :
1821 : 0 : return ret;
1822 : : }
|