]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/net/vmxnet3/vmxnet3_rxtx.c
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / spdk / dpdk / drivers / net / vmxnet3 / vmxnet3_rxtx.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2015 Intel Corporation
3 */
4
5 #include <sys/queue.h>
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <errno.h>
11 #include <stdint.h>
12 #include <stdarg.h>
13 #include <unistd.h>
14 #include <inttypes.h>
15
16 #include <rte_byteorder.h>
17 #include <rte_common.h>
18 #include <rte_cycles.h>
19 #include <rte_log.h>
20 #include <rte_debug.h>
21 #include <rte_interrupts.h>
22 #include <rte_pci.h>
23 #include <rte_memory.h>
24 #include <rte_memzone.h>
25 #include <rte_launch.h>
26 #include <rte_eal.h>
27 #include <rte_per_lcore.h>
28 #include <rte_lcore.h>
29 #include <rte_atomic.h>
30 #include <rte_branch_prediction.h>
31 #include <rte_mempool.h>
32 #include <rte_malloc.h>
33 #include <rte_mbuf.h>
34 #include <rte_ether.h>
35 #include <rte_ethdev_driver.h>
36 #include <rte_prefetch.h>
37 #include <rte_ip.h>
38 #include <rte_udp.h>
39 #include <rte_tcp.h>
40 #include <rte_sctp.h>
41 #include <rte_string_fns.h>
42 #include <rte_errno.h>
43 #include <rte_net.h>
44
45 #include "base/vmxnet3_defs.h"
46 #include "vmxnet3_ring.h"
47
48 #include "vmxnet3_logs.h"
49 #include "vmxnet3_ethdev.h"
50
51 #define VMXNET3_TX_OFFLOAD_MASK ( \
52 PKT_TX_VLAN_PKT | \
53 PKT_TX_L4_MASK | \
54 PKT_TX_TCP_SEG)
55
56 #define VMXNET3_TX_OFFLOAD_NOTSUP_MASK \
57 (PKT_TX_OFFLOAD_MASK ^ VMXNET3_TX_OFFLOAD_MASK)
58
59 static const uint32_t rxprod_reg[2] = {VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2};
60
61 static int vmxnet3_post_rx_bufs(vmxnet3_rx_queue_t*, uint8_t);
62 static void vmxnet3_tq_tx_complete(vmxnet3_tx_queue_t *);
63 #ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER_NOT_USED
64 static void vmxnet3_rxq_dump(struct vmxnet3_rx_queue *);
65 static void vmxnet3_txq_dump(struct vmxnet3_tx_queue *);
66 #endif
67
68 #ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER_NOT_USED
69 static void
70 vmxnet3_rxq_dump(struct vmxnet3_rx_queue *rxq)
71 {
72 uint32_t avail = 0;
73
74 if (rxq == NULL)
75 return;
76
77 PMD_RX_LOG(DEBUG,
78 "RXQ: cmd0 base : %p cmd1 base : %p comp ring base : %p.",
79 rxq->cmd_ring[0].base, rxq->cmd_ring[1].base, rxq->comp_ring.base);
80 PMD_RX_LOG(DEBUG,
81 "RXQ: cmd0 basePA : 0x%lx cmd1 basePA : 0x%lx comp ring basePA : 0x%lx.",
82 (unsigned long)rxq->cmd_ring[0].basePA,
83 (unsigned long)rxq->cmd_ring[1].basePA,
84 (unsigned long)rxq->comp_ring.basePA);
85
86 avail = vmxnet3_cmd_ring_desc_avail(&rxq->cmd_ring[0]);
87 PMD_RX_LOG(DEBUG,
88 "RXQ:cmd0: size=%u; free=%u; next2proc=%u; queued=%u",
89 (uint32_t)rxq->cmd_ring[0].size, avail,
90 rxq->comp_ring.next2proc,
91 rxq->cmd_ring[0].size - avail);
92
93 avail = vmxnet3_cmd_ring_desc_avail(&rxq->cmd_ring[1]);
94 PMD_RX_LOG(DEBUG, "RXQ:cmd1 size=%u; free=%u; next2proc=%u; queued=%u",
95 (uint32_t)rxq->cmd_ring[1].size, avail, rxq->comp_ring.next2proc,
96 rxq->cmd_ring[1].size - avail);
97
98 }
99
100 static void
101 vmxnet3_txq_dump(struct vmxnet3_tx_queue *txq)
102 {
103 uint32_t avail = 0;
104
105 if (txq == NULL)
106 return;
107
108 PMD_TX_LOG(DEBUG, "TXQ: cmd base : %p comp ring base : %p data ring base : %p.",
109 txq->cmd_ring.base, txq->comp_ring.base, txq->data_ring.base);
110 PMD_TX_LOG(DEBUG, "TXQ: cmd basePA : 0x%lx comp ring basePA : 0x%lx data ring basePA : 0x%lx.",
111 (unsigned long)txq->cmd_ring.basePA,
112 (unsigned long)txq->comp_ring.basePA,
113 (unsigned long)txq->data_ring.basePA);
114
115 avail = vmxnet3_cmd_ring_desc_avail(&txq->cmd_ring);
116 PMD_TX_LOG(DEBUG, "TXQ: size=%u; free=%u; next2proc=%u; queued=%u",
117 (uint32_t)txq->cmd_ring.size, avail,
118 txq->comp_ring.next2proc, txq->cmd_ring.size - avail);
119 }
120 #endif
121
122 static void
123 vmxnet3_tx_cmd_ring_release_mbufs(vmxnet3_cmd_ring_t *ring)
124 {
125 while (ring->next2comp != ring->next2fill) {
126 /* No need to worry about desc ownership, device is quiesced by now. */
127 vmxnet3_buf_info_t *buf_info = ring->buf_info + ring->next2comp;
128
129 if (buf_info->m) {
130 rte_pktmbuf_free(buf_info->m);
131 buf_info->m = NULL;
132 buf_info->bufPA = 0;
133 buf_info->len = 0;
134 }
135 vmxnet3_cmd_ring_adv_next2comp(ring);
136 }
137 }
138
139 static void
140 vmxnet3_rx_cmd_ring_release_mbufs(vmxnet3_cmd_ring_t *ring)
141 {
142 uint32_t i;
143
144 for (i = 0; i < ring->size; i++) {
145 /* No need to worry about desc ownership, device is quiesced by now. */
146 vmxnet3_buf_info_t *buf_info = &ring->buf_info[i];
147
148 if (buf_info->m) {
149 rte_pktmbuf_free_seg(buf_info->m);
150 buf_info->m = NULL;
151 buf_info->bufPA = 0;
152 buf_info->len = 0;
153 }
154 vmxnet3_cmd_ring_adv_next2comp(ring);
155 }
156 }
157
158 static void
159 vmxnet3_cmd_ring_release(vmxnet3_cmd_ring_t *ring)
160 {
161 rte_free(ring->buf_info);
162 ring->buf_info = NULL;
163 }
164
165 void
166 vmxnet3_dev_tx_queue_release(void *txq)
167 {
168 vmxnet3_tx_queue_t *tq = txq;
169
170 if (tq != NULL) {
171 /* Release mbufs */
172 vmxnet3_tx_cmd_ring_release_mbufs(&tq->cmd_ring);
173 /* Release the cmd_ring */
174 vmxnet3_cmd_ring_release(&tq->cmd_ring);
175 /* Release the memzone */
176 rte_memzone_free(tq->mz);
177 /* Release the queue */
178 rte_free(tq);
179 }
180 }
181
182 void
183 vmxnet3_dev_rx_queue_release(void *rxq)
184 {
185 int i;
186 vmxnet3_rx_queue_t *rq = rxq;
187
188 if (rq != NULL) {
189 /* Release mbufs */
190 for (i = 0; i < VMXNET3_RX_CMDRING_SIZE; i++)
191 vmxnet3_rx_cmd_ring_release_mbufs(&rq->cmd_ring[i]);
192
193 /* Release both the cmd_rings */
194 for (i = 0; i < VMXNET3_RX_CMDRING_SIZE; i++)
195 vmxnet3_cmd_ring_release(&rq->cmd_ring[i]);
196
197 /* Release the memzone */
198 rte_memzone_free(rq->mz);
199
200 /* Release the queue */
201 rte_free(rq);
202 }
203 }
204
205 static void
206 vmxnet3_dev_tx_queue_reset(void *txq)
207 {
208 vmxnet3_tx_queue_t *tq = txq;
209 struct vmxnet3_cmd_ring *ring = &tq->cmd_ring;
210 struct vmxnet3_comp_ring *comp_ring = &tq->comp_ring;
211 struct vmxnet3_data_ring *data_ring = &tq->data_ring;
212 int size;
213
214 if (tq != NULL) {
215 /* Release the cmd_ring mbufs */
216 vmxnet3_tx_cmd_ring_release_mbufs(&tq->cmd_ring);
217 }
218
219 /* Tx vmxnet rings structure initialization*/
220 ring->next2fill = 0;
221 ring->next2comp = 0;
222 ring->gen = VMXNET3_INIT_GEN;
223 comp_ring->next2proc = 0;
224 comp_ring->gen = VMXNET3_INIT_GEN;
225
226 size = sizeof(struct Vmxnet3_TxDesc) * ring->size;
227 size += sizeof(struct Vmxnet3_TxCompDesc) * comp_ring->size;
228 size += tq->txdata_desc_size * data_ring->size;
229
230 memset(ring->base, 0, size);
231 }
232
233 static void
234 vmxnet3_dev_rx_queue_reset(void *rxq)
235 {
236 int i;
237 vmxnet3_rx_queue_t *rq = rxq;
238 struct vmxnet3_hw *hw = rq->hw;
239 struct vmxnet3_cmd_ring *ring0, *ring1;
240 struct vmxnet3_comp_ring *comp_ring;
241 struct vmxnet3_rx_data_ring *data_ring = &rq->data_ring;
242 int size;
243
244 /* Release both the cmd_rings mbufs */
245 for (i = 0; i < VMXNET3_RX_CMDRING_SIZE; i++)
246 vmxnet3_rx_cmd_ring_release_mbufs(&rq->cmd_ring[i]);
247
248 ring0 = &rq->cmd_ring[0];
249 ring1 = &rq->cmd_ring[1];
250 comp_ring = &rq->comp_ring;
251
252 /* Rx vmxnet rings structure initialization */
253 ring0->next2fill = 0;
254 ring1->next2fill = 0;
255 ring0->next2comp = 0;
256 ring1->next2comp = 0;
257 ring0->gen = VMXNET3_INIT_GEN;
258 ring1->gen = VMXNET3_INIT_GEN;
259 comp_ring->next2proc = 0;
260 comp_ring->gen = VMXNET3_INIT_GEN;
261
262 size = sizeof(struct Vmxnet3_RxDesc) * (ring0->size + ring1->size);
263 size += sizeof(struct Vmxnet3_RxCompDesc) * comp_ring->size;
264 if (VMXNET3_VERSION_GE_3(hw) && rq->data_desc_size)
265 size += rq->data_desc_size * data_ring->size;
266
267 memset(ring0->base, 0, size);
268 }
269
270 void
271 vmxnet3_dev_clear_queues(struct rte_eth_dev *dev)
272 {
273 unsigned i;
274
275 PMD_INIT_FUNC_TRACE();
276
277 for (i = 0; i < dev->data->nb_tx_queues; i++) {
278 struct vmxnet3_tx_queue *txq = dev->data->tx_queues[i];
279
280 if (txq != NULL) {
281 txq->stopped = TRUE;
282 vmxnet3_dev_tx_queue_reset(txq);
283 }
284 }
285
286 for (i = 0; i < dev->data->nb_rx_queues; i++) {
287 struct vmxnet3_rx_queue *rxq = dev->data->rx_queues[i];
288
289 if (rxq != NULL) {
290 rxq->stopped = TRUE;
291 vmxnet3_dev_rx_queue_reset(rxq);
292 }
293 }
294 }
295
296 static int
297 vmxnet3_unmap_pkt(uint16_t eop_idx, vmxnet3_tx_queue_t *txq)
298 {
299 int completed = 0;
300 struct rte_mbuf *mbuf;
301
302 /* Release cmd_ring descriptor and free mbuf */
303 RTE_ASSERT(txq->cmd_ring.base[eop_idx].txd.eop == 1);
304
305 mbuf = txq->cmd_ring.buf_info[eop_idx].m;
306 if (mbuf == NULL)
307 rte_panic("EOP desc does not point to a valid mbuf");
308 rte_pktmbuf_free(mbuf);
309
310 txq->cmd_ring.buf_info[eop_idx].m = NULL;
311
312 while (txq->cmd_ring.next2comp != eop_idx) {
313 /* no out-of-order completion */
314 RTE_ASSERT(txq->cmd_ring.base[txq->cmd_ring.next2comp].txd.cq == 0);
315 vmxnet3_cmd_ring_adv_next2comp(&txq->cmd_ring);
316 completed++;
317 }
318
319 /* Mark the txd for which tcd was generated as completed */
320 vmxnet3_cmd_ring_adv_next2comp(&txq->cmd_ring);
321
322 return completed + 1;
323 }
324
325 static void
326 vmxnet3_tq_tx_complete(vmxnet3_tx_queue_t *txq)
327 {
328 int completed = 0;
329 vmxnet3_comp_ring_t *comp_ring = &txq->comp_ring;
330 struct Vmxnet3_TxCompDesc *tcd = (struct Vmxnet3_TxCompDesc *)
331 (comp_ring->base + comp_ring->next2proc);
332
333 while (tcd->gen == comp_ring->gen) {
334 completed += vmxnet3_unmap_pkt(tcd->txdIdx, txq);
335
336 vmxnet3_comp_ring_adv_next2proc(comp_ring);
337 tcd = (struct Vmxnet3_TxCompDesc *)(comp_ring->base +
338 comp_ring->next2proc);
339 }
340
341 PMD_TX_LOG(DEBUG, "Processed %d tx comps & command descs.", completed);
342 }
343
344 uint16_t
345 vmxnet3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
346 uint16_t nb_pkts)
347 {
348 int32_t ret;
349 uint32_t i;
350 uint64_t ol_flags;
351 struct rte_mbuf *m;
352
353 for (i = 0; i != nb_pkts; i++) {
354 m = tx_pkts[i];
355 ol_flags = m->ol_flags;
356
357 /* Non-TSO packet cannot occupy more than
358 * VMXNET3_MAX_TXD_PER_PKT TX descriptors.
359 */
360 if ((ol_flags & PKT_TX_TCP_SEG) == 0 &&
361 m->nb_segs > VMXNET3_MAX_TXD_PER_PKT) {
362 rte_errno = -EINVAL;
363 return i;
364 }
365
366 /* check that only supported TX offloads are requested. */
367 if ((ol_flags & VMXNET3_TX_OFFLOAD_NOTSUP_MASK) != 0 ||
368 (ol_flags & PKT_TX_L4_MASK) ==
369 PKT_TX_SCTP_CKSUM) {
370 rte_errno = -ENOTSUP;
371 return i;
372 }
373
374 #ifdef RTE_LIBRTE_ETHDEV_DEBUG
375 ret = rte_validate_tx_offload(m);
376 if (ret != 0) {
377 rte_errno = ret;
378 return i;
379 }
380 #endif
381 ret = rte_net_intel_cksum_prepare(m);
382 if (ret != 0) {
383 rte_errno = ret;
384 return i;
385 }
386 }
387
388 return i;
389 }
390
391 uint16_t
392 vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
393 uint16_t nb_pkts)
394 {
395 uint16_t nb_tx;
396 vmxnet3_tx_queue_t *txq = tx_queue;
397 struct vmxnet3_hw *hw = txq->hw;
398 Vmxnet3_TxQueueCtrl *txq_ctrl = &txq->shared->ctrl;
399 uint32_t deferred = rte_le_to_cpu_32(txq_ctrl->txNumDeferred);
400
401 if (unlikely(txq->stopped)) {
402 PMD_TX_LOG(DEBUG, "Tx queue is stopped.");
403 return 0;
404 }
405
406 /* Free up the comp_descriptors aggressively */
407 vmxnet3_tq_tx_complete(txq);
408
409 nb_tx = 0;
410 while (nb_tx < nb_pkts) {
411 Vmxnet3_GenericDesc *gdesc;
412 vmxnet3_buf_info_t *tbi;
413 uint32_t first2fill, avail, dw2;
414 struct rte_mbuf *txm = tx_pkts[nb_tx];
415 struct rte_mbuf *m_seg = txm;
416 int copy_size = 0;
417 bool tso = (txm->ol_flags & PKT_TX_TCP_SEG) != 0;
418 /* # of descriptors needed for a packet. */
419 unsigned count = txm->nb_segs;
420
421 avail = vmxnet3_cmd_ring_desc_avail(&txq->cmd_ring);
422 if (count > avail) {
423 /* Is command ring full? */
424 if (unlikely(avail == 0)) {
425 PMD_TX_LOG(DEBUG, "No free ring descriptors");
426 txq->stats.tx_ring_full++;
427 txq->stats.drop_total += (nb_pkts - nb_tx);
428 break;
429 }
430
431 /* Command ring is not full but cannot handle the
432 * multi-segmented packet. Let's try the next packet
433 * in this case.
434 */
435 PMD_TX_LOG(DEBUG, "Running out of ring descriptors "
436 "(avail %d needed %d)", avail, count);
437 txq->stats.drop_total++;
438 if (tso)
439 txq->stats.drop_tso++;
440 rte_pktmbuf_free(txm);
441 nb_tx++;
442 continue;
443 }
444
445 /* Drop non-TSO packet that is excessively fragmented */
446 if (unlikely(!tso && count > VMXNET3_MAX_TXD_PER_PKT)) {
447 PMD_TX_LOG(ERR, "Non-TSO packet cannot occupy more than %d tx "
448 "descriptors. Packet dropped.", VMXNET3_MAX_TXD_PER_PKT);
449 txq->stats.drop_too_many_segs++;
450 txq->stats.drop_total++;
451 rte_pktmbuf_free(txm);
452 nb_tx++;
453 continue;
454 }
455
456 if (txm->nb_segs == 1 &&
457 rte_pktmbuf_pkt_len(txm) <= txq->txdata_desc_size) {
458 struct Vmxnet3_TxDataDesc *tdd;
459
460 /* Skip empty packets */
461 if (unlikely(rte_pktmbuf_pkt_len(txm) == 0)) {
462 txq->stats.drop_total++;
463 rte_pktmbuf_free(txm);
464 nb_tx++;
465 continue;
466 }
467
468 tdd = (struct Vmxnet3_TxDataDesc *)
469 ((uint8 *)txq->data_ring.base +
470 txq->cmd_ring.next2fill *
471 txq->txdata_desc_size);
472 copy_size = rte_pktmbuf_pkt_len(txm);
473 rte_memcpy(tdd->data, rte_pktmbuf_mtod(txm, char *), copy_size);
474 }
475
476 /* use the previous gen bit for the SOP desc */
477 dw2 = (txq->cmd_ring.gen ^ 0x1) << VMXNET3_TXD_GEN_SHIFT;
478 first2fill = txq->cmd_ring.next2fill;
479 do {
480 /* Remember the transmit buffer for cleanup */
481 tbi = txq->cmd_ring.buf_info + txq->cmd_ring.next2fill;
482
483 /* NB: the following assumes that VMXNET3 maximum
484 * transmit buffer size (16K) is greater than
485 * maximum size of mbuf segment size.
486 */
487 gdesc = txq->cmd_ring.base + txq->cmd_ring.next2fill;
488
489 /* Skip empty segments */
490 if (unlikely(m_seg->data_len == 0))
491 continue;
492
493 if (copy_size) {
494 uint64 offset =
495 (uint64)txq->cmd_ring.next2fill *
496 txq->txdata_desc_size;
497 gdesc->txd.addr =
498 rte_cpu_to_le_64(txq->data_ring.basePA +
499 offset);
500 } else {
501 gdesc->txd.addr = rte_mbuf_data_iova(m_seg);
502 }
503
504 gdesc->dword[2] = dw2 | m_seg->data_len;
505 gdesc->dword[3] = 0;
506
507 /* move to the next2fill descriptor */
508 vmxnet3_cmd_ring_adv_next2fill(&txq->cmd_ring);
509
510 /* use the right gen for non-SOP desc */
511 dw2 = txq->cmd_ring.gen << VMXNET3_TXD_GEN_SHIFT;
512 } while ((m_seg = m_seg->next) != NULL);
513
514 /* set the last buf_info for the pkt */
515 tbi->m = txm;
516 /* Update the EOP descriptor */
517 gdesc->dword[3] |= VMXNET3_TXD_EOP | VMXNET3_TXD_CQ;
518
519 /* Add VLAN tag if present */
520 gdesc = txq->cmd_ring.base + first2fill;
521 if (txm->ol_flags & PKT_TX_VLAN_PKT) {
522 gdesc->txd.ti = 1;
523 gdesc->txd.tci = txm->vlan_tci;
524 }
525
526 if (tso) {
527 uint16_t mss = txm->tso_segsz;
528
529 RTE_ASSERT(mss > 0);
530
531 gdesc->txd.hlen = txm->l2_len + txm->l3_len + txm->l4_len;
532 gdesc->txd.om = VMXNET3_OM_TSO;
533 gdesc->txd.msscof = mss;
534
535 deferred += (rte_pktmbuf_pkt_len(txm) - gdesc->txd.hlen + mss - 1) / mss;
536 } else if (txm->ol_flags & PKT_TX_L4_MASK) {
537 gdesc->txd.om = VMXNET3_OM_CSUM;
538 gdesc->txd.hlen = txm->l2_len + txm->l3_len;
539
540 switch (txm->ol_flags & PKT_TX_L4_MASK) {
541 case PKT_TX_TCP_CKSUM:
542 gdesc->txd.msscof = gdesc->txd.hlen + offsetof(struct tcp_hdr, cksum);
543 break;
544 case PKT_TX_UDP_CKSUM:
545 gdesc->txd.msscof = gdesc->txd.hlen + offsetof(struct udp_hdr, dgram_cksum);
546 break;
547 default:
548 PMD_TX_LOG(WARNING, "requested cksum offload not supported %#llx",
549 txm->ol_flags & PKT_TX_L4_MASK);
550 abort();
551 }
552 deferred++;
553 } else {
554 gdesc->txd.hlen = 0;
555 gdesc->txd.om = VMXNET3_OM_NONE;
556 gdesc->txd.msscof = 0;
557 deferred++;
558 }
559
560 /* flip the GEN bit on the SOP */
561 rte_compiler_barrier();
562 gdesc->dword[2] ^= VMXNET3_TXD_GEN;
563
564 txq_ctrl->txNumDeferred = rte_cpu_to_le_32(deferred);
565 nb_tx++;
566 }
567
568 PMD_TX_LOG(DEBUG, "vmxnet3 txThreshold: %u", rte_le_to_cpu_32(txq_ctrl->txThreshold));
569
570 if (deferred >= rte_le_to_cpu_32(txq_ctrl->txThreshold)) {
571 txq_ctrl->txNumDeferred = 0;
572 /* Notify vSwitch that packets are available. */
573 VMXNET3_WRITE_BAR0_REG(hw, (VMXNET3_REG_TXPROD + txq->queue_id * VMXNET3_REG_ALIGN),
574 txq->cmd_ring.next2fill);
575 }
576
577 return nb_tx;
578 }
579
580 static inline void
581 vmxnet3_renew_desc(vmxnet3_rx_queue_t *rxq, uint8_t ring_id,
582 struct rte_mbuf *mbuf)
583 {
584 uint32_t val;
585 struct vmxnet3_cmd_ring *ring = &rxq->cmd_ring[ring_id];
586 struct Vmxnet3_RxDesc *rxd =
587 (struct Vmxnet3_RxDesc *)(ring->base + ring->next2fill);
588 vmxnet3_buf_info_t *buf_info = &ring->buf_info[ring->next2fill];
589
590 if (ring_id == 0) {
591 /* Usually: One HEAD type buf per packet
592 * val = (ring->next2fill % rxq->hw->bufs_per_pkt) ?
593 * VMXNET3_RXD_BTYPE_BODY : VMXNET3_RXD_BTYPE_HEAD;
594 */
595
596 /* We use single packet buffer so all heads here */
597 val = VMXNET3_RXD_BTYPE_HEAD;
598 } else {
599 /* All BODY type buffers for 2nd ring */
600 val = VMXNET3_RXD_BTYPE_BODY;
601 }
602
603 /*
604 * Load mbuf pointer into buf_info[ring_size]
605 * buf_info structure is equivalent to cookie for virtio-virtqueue
606 */
607 buf_info->m = mbuf;
608 buf_info->len = (uint16_t)(mbuf->buf_len - RTE_PKTMBUF_HEADROOM);
609 buf_info->bufPA = rte_mbuf_data_iova_default(mbuf);
610
611 /* Load Rx Descriptor with the buffer's GPA */
612 rxd->addr = buf_info->bufPA;
613
614 /* After this point rxd->addr MUST not be NULL */
615 rxd->btype = val;
616 rxd->len = buf_info->len;
617 /* Flip gen bit at the end to change ownership */
618 rxd->gen = ring->gen;
619
620 vmxnet3_cmd_ring_adv_next2fill(ring);
621 }
622 /*
623 * Allocates mbufs and clusters. Post rx descriptors with buffer details
624 * so that device can receive packets in those buffers.
625 * Ring layout:
626 * Among the two rings, 1st ring contains buffers of type 0 and type 1.
627 * bufs_per_pkt is set such that for non-LRO cases all the buffers required
628 * by a frame will fit in 1st ring (1st buf of type0 and rest of type1).
629 * 2nd ring contains buffers of type 1 alone. Second ring mostly be used
630 * only for LRO.
631 */
632 static int
633 vmxnet3_post_rx_bufs(vmxnet3_rx_queue_t *rxq, uint8_t ring_id)
634 {
635 int err = 0;
636 uint32_t i = 0;
637 struct vmxnet3_cmd_ring *ring = &rxq->cmd_ring[ring_id];
638
639 while (vmxnet3_cmd_ring_desc_avail(ring) > 0) {
640 struct rte_mbuf *mbuf;
641
642 /* Allocate blank mbuf for the current Rx Descriptor */
643 mbuf = rte_mbuf_raw_alloc(rxq->mp);
644 if (unlikely(mbuf == NULL)) {
645 PMD_RX_LOG(ERR, "Error allocating mbuf");
646 rxq->stats.rx_buf_alloc_failure++;
647 err = ENOMEM;
648 break;
649 }
650
651 vmxnet3_renew_desc(rxq, ring_id, mbuf);
652 i++;
653 }
654
655 /* Return error only if no buffers are posted at present */
656 if (vmxnet3_cmd_ring_desc_avail(ring) >= (ring->size - 1))
657 return -err;
658 else
659 return i;
660 }
661
662 /* MSS not provided by vmxnet3, guess one with available information */
663 static uint16_t
664 vmxnet3_guess_mss(struct vmxnet3_hw *hw, const Vmxnet3_RxCompDesc *rcd,
665 struct rte_mbuf *rxm)
666 {
667 uint32_t hlen, slen;
668 struct ipv4_hdr *ipv4_hdr;
669 struct ipv6_hdr *ipv6_hdr;
670 struct tcp_hdr *tcp_hdr;
671 char *ptr;
672
673 RTE_ASSERT(rcd->tcp);
674
675 ptr = rte_pktmbuf_mtod(rxm, char *);
676 slen = rte_pktmbuf_data_len(rxm);
677 hlen = sizeof(struct ether_hdr);
678
679 if (rcd->v4) {
680 if (unlikely(slen < hlen + sizeof(struct ipv4_hdr)))
681 return hw->mtu - sizeof(struct ipv4_hdr)
682 - sizeof(struct tcp_hdr);
683
684 ipv4_hdr = (struct ipv4_hdr *)(ptr + hlen);
685 hlen += (ipv4_hdr->version_ihl & IPV4_HDR_IHL_MASK) *
686 IPV4_IHL_MULTIPLIER;
687 } else if (rcd->v6) {
688 if (unlikely(slen < hlen + sizeof(struct ipv6_hdr)))
689 return hw->mtu - sizeof(struct ipv6_hdr) -
690 sizeof(struct tcp_hdr);
691
692 ipv6_hdr = (struct ipv6_hdr *)(ptr + hlen);
693 hlen += sizeof(struct ipv6_hdr);
694 if (unlikely(ipv6_hdr->proto != IPPROTO_TCP)) {
695 int frag;
696
697 rte_net_skip_ip6_ext(ipv6_hdr->proto, rxm,
698 &hlen, &frag);
699 }
700 }
701
702 if (unlikely(slen < hlen + sizeof(struct tcp_hdr)))
703 return hw->mtu - hlen - sizeof(struct tcp_hdr) +
704 sizeof(struct ether_hdr);
705
706 tcp_hdr = (struct tcp_hdr *)(ptr + hlen);
707 hlen += (tcp_hdr->data_off & 0xf0) >> 2;
708
709 if (rxm->udata64 > 1)
710 return (rte_pktmbuf_pkt_len(rxm) - hlen +
711 rxm->udata64 - 1) / rxm->udata64;
712 else
713 return hw->mtu - hlen + sizeof(struct ether_hdr);
714 }
715
716 /* Receive side checksum and other offloads */
717 static inline void
718 vmxnet3_rx_offload(struct vmxnet3_hw *hw, const Vmxnet3_RxCompDesc *rcd,
719 struct rte_mbuf *rxm, const uint8_t sop)
720 {
721 uint64_t ol_flags = rxm->ol_flags;
722 uint32_t packet_type = rxm->packet_type;
723
724 /* Offloads set in sop */
725 if (sop) {
726 /* Set packet type */
727 packet_type |= RTE_PTYPE_L2_ETHER;
728
729 /* Check large packet receive */
730 if (VMXNET3_VERSION_GE_2(hw) &&
731 rcd->type == VMXNET3_CDTYPE_RXCOMP_LRO) {
732 const Vmxnet3_RxCompDescExt *rcde =
733 (const Vmxnet3_RxCompDescExt *)rcd;
734
735 rxm->tso_segsz = rcde->mss;
736 rxm->udata64 = rcde->segCnt;
737 ol_flags |= PKT_RX_LRO;
738 }
739 } else { /* Offloads set in eop */
740 /* Check for RSS */
741 if (rcd->rssType != VMXNET3_RCD_RSS_TYPE_NONE) {
742 ol_flags |= PKT_RX_RSS_HASH;
743 rxm->hash.rss = rcd->rssHash;
744 }
745
746 /* Check for hardware stripped VLAN tag */
747 if (rcd->ts) {
748 ol_flags |= (PKT_RX_VLAN | PKT_RX_VLAN_STRIPPED);
749 rxm->vlan_tci = rte_le_to_cpu_16((uint16_t)rcd->tci);
750 }
751
752 /* Check packet type, checksum errors, etc. */
753 if (rcd->cnc) {
754 ol_flags |= PKT_RX_L4_CKSUM_UNKNOWN;
755 } else {
756 if (rcd->v4) {
757 packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
758
759 if (rcd->ipc)
760 ol_flags |= PKT_RX_IP_CKSUM_GOOD;
761 else
762 ol_flags |= PKT_RX_IP_CKSUM_BAD;
763
764 if (rcd->tuc) {
765 ol_flags |= PKT_RX_L4_CKSUM_GOOD;
766 if (rcd->tcp)
767 packet_type |= RTE_PTYPE_L4_TCP;
768 else
769 packet_type |= RTE_PTYPE_L4_UDP;
770 } else {
771 if (rcd->tcp) {
772 packet_type |= RTE_PTYPE_L4_TCP;
773 ol_flags |= PKT_RX_L4_CKSUM_BAD;
774 } else if (rcd->udp) {
775 packet_type |= RTE_PTYPE_L4_UDP;
776 ol_flags |= PKT_RX_L4_CKSUM_BAD;
777 }
778 }
779 } else if (rcd->v6) {
780 packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
781
782 if (rcd->tuc) {
783 ol_flags |= PKT_RX_L4_CKSUM_GOOD;
784 if (rcd->tcp)
785 packet_type |= RTE_PTYPE_L4_TCP;
786 else
787 packet_type |= RTE_PTYPE_L4_UDP;
788 } else {
789 if (rcd->tcp) {
790 packet_type |= RTE_PTYPE_L4_TCP;
791 ol_flags |= PKT_RX_L4_CKSUM_BAD;
792 } else if (rcd->udp) {
793 packet_type |= RTE_PTYPE_L4_UDP;
794 ol_flags |= PKT_RX_L4_CKSUM_BAD;
795 }
796 }
797 } else {
798 packet_type |= RTE_PTYPE_UNKNOWN;
799 }
800
801 /* Old variants of vmxnet3 do not provide MSS */
802 if ((ol_flags & PKT_RX_LRO) && rxm->tso_segsz == 0)
803 rxm->tso_segsz = vmxnet3_guess_mss(hw,
804 rcd, rxm);
805 }
806 }
807
808 rxm->ol_flags = ol_flags;
809 rxm->packet_type = packet_type;
810 }
811
812 /*
813 * Process the Rx Completion Ring of given vmxnet3_rx_queue
814 * for nb_pkts burst and return the number of packets received
815 */
816 uint16_t
817 vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
818 {
819 uint16_t nb_rx;
820 uint32_t nb_rxd, idx;
821 uint8_t ring_idx;
822 vmxnet3_rx_queue_t *rxq;
823 Vmxnet3_RxCompDesc *rcd;
824 vmxnet3_buf_info_t *rbi;
825 Vmxnet3_RxDesc *rxd;
826 struct rte_mbuf *rxm = NULL;
827 struct vmxnet3_hw *hw;
828
829 nb_rx = 0;
830 ring_idx = 0;
831 nb_rxd = 0;
832 idx = 0;
833
834 rxq = rx_queue;
835 hw = rxq->hw;
836
837 rcd = &rxq->comp_ring.base[rxq->comp_ring.next2proc].rcd;
838
839 if (unlikely(rxq->stopped)) {
840 PMD_RX_LOG(DEBUG, "Rx queue is stopped.");
841 return 0;
842 }
843
844 while (rcd->gen == rxq->comp_ring.gen) {
845 struct rte_mbuf *newm;
846
847 if (nb_rx >= nb_pkts)
848 break;
849
850 newm = rte_mbuf_raw_alloc(rxq->mp);
851 if (unlikely(newm == NULL)) {
852 PMD_RX_LOG(ERR, "Error allocating mbuf");
853 rxq->stats.rx_buf_alloc_failure++;
854 break;
855 }
856
857 idx = rcd->rxdIdx;
858 ring_idx = vmxnet3_get_ring_idx(hw, rcd->rqID);
859 rxd = (Vmxnet3_RxDesc *)rxq->cmd_ring[ring_idx].base + idx;
860 RTE_SET_USED(rxd); /* used only for assert when enabled */
861 rbi = rxq->cmd_ring[ring_idx].buf_info + idx;
862
863 PMD_RX_LOG(DEBUG, "rxd idx: %d ring idx: %d.", idx, ring_idx);
864
865 RTE_ASSERT(rcd->len <= rxd->len);
866 RTE_ASSERT(rbi->m);
867
868 /* Get the packet buffer pointer from buf_info */
869 rxm = rbi->m;
870
871 /* Clear descriptor associated buf_info to be reused */
872 rbi->m = NULL;
873 rbi->bufPA = 0;
874
875 /* Update the index that we received a packet */
876 rxq->cmd_ring[ring_idx].next2comp = idx;
877
878 /* For RCD with EOP set, check if there is frame error */
879 if (unlikely(rcd->eop && rcd->err)) {
880 rxq->stats.drop_total++;
881 rxq->stats.drop_err++;
882
883 if (!rcd->fcs) {
884 rxq->stats.drop_fcs++;
885 PMD_RX_LOG(ERR, "Recv packet dropped due to frame err.");
886 }
887 PMD_RX_LOG(ERR, "Error in received packet rcd#:%d rxd:%d",
888 (int)(rcd - (struct Vmxnet3_RxCompDesc *)
889 rxq->comp_ring.base), rcd->rxdIdx);
890 rte_pktmbuf_free_seg(rxm);
891 if (rxq->start_seg) {
892 struct rte_mbuf *start = rxq->start_seg;
893
894 rxq->start_seg = NULL;
895 rte_pktmbuf_free(start);
896 }
897 goto rcd_done;
898 }
899
900 /* Initialize newly received packet buffer */
901 rxm->port = rxq->port_id;
902 rxm->nb_segs = 1;
903 rxm->next = NULL;
904 rxm->pkt_len = (uint16_t)rcd->len;
905 rxm->data_len = (uint16_t)rcd->len;
906 rxm->data_off = RTE_PKTMBUF_HEADROOM;
907 rxm->ol_flags = 0;
908 rxm->vlan_tci = 0;
909 rxm->packet_type = 0;
910
911 /*
912 * If this is the first buffer of the received packet,
913 * set the pointer to the first mbuf of the packet
914 * Otherwise, update the total length and the number of segments
915 * of the current scattered packet, and update the pointer to
916 * the last mbuf of the current packet.
917 */
918 if (rcd->sop) {
919 RTE_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_HEAD);
920
921 if (unlikely(rcd->len == 0)) {
922 RTE_ASSERT(rcd->eop);
923
924 PMD_RX_LOG(DEBUG,
925 "Rx buf was skipped. rxring[%d][%d])",
926 ring_idx, idx);
927 rte_pktmbuf_free_seg(rxm);
928 goto rcd_done;
929 }
930
931 if (vmxnet3_rx_data_ring(hw, rcd->rqID)) {
932 uint8_t *rdd = rxq->data_ring.base +
933 idx * rxq->data_desc_size;
934
935 RTE_ASSERT(VMXNET3_VERSION_GE_3(hw));
936 rte_memcpy(rte_pktmbuf_mtod(rxm, char *),
937 rdd, rcd->len);
938 }
939
940 rxq->start_seg = rxm;
941 rxq->last_seg = rxm;
942 vmxnet3_rx_offload(hw, rcd, rxm, 1);
943 } else {
944 struct rte_mbuf *start = rxq->start_seg;
945
946 RTE_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_BODY);
947
948 if (rxm->data_len) {
949 start->pkt_len += rxm->data_len;
950 start->nb_segs++;
951
952 rxq->last_seg->next = rxm;
953 rxq->last_seg = rxm;
954 } else {
955 rte_pktmbuf_free_seg(rxm);
956 }
957 }
958
959 if (rcd->eop) {
960 struct rte_mbuf *start = rxq->start_seg;
961
962 vmxnet3_rx_offload(hw, rcd, start, 0);
963 rx_pkts[nb_rx++] = start;
964 rxq->start_seg = NULL;
965 }
966
967 rcd_done:
968 rxq->cmd_ring[ring_idx].next2comp = idx;
969 VMXNET3_INC_RING_IDX_ONLY(rxq->cmd_ring[ring_idx].next2comp,
970 rxq->cmd_ring[ring_idx].size);
971
972 /* It's time to renew descriptors */
973 vmxnet3_renew_desc(rxq, ring_idx, newm);
974 if (unlikely(rxq->shared->ctrl.updateRxProd)) {
975 VMXNET3_WRITE_BAR0_REG(hw, rxprod_reg[ring_idx] + (rxq->queue_id * VMXNET3_REG_ALIGN),
976 rxq->cmd_ring[ring_idx].next2fill);
977 }
978
979 /* Advance to the next descriptor in comp_ring */
980 vmxnet3_comp_ring_adv_next2proc(&rxq->comp_ring);
981
982 rcd = &rxq->comp_ring.base[rxq->comp_ring.next2proc].rcd;
983 nb_rxd++;
984 if (nb_rxd > rxq->cmd_ring[0].size) {
985 PMD_RX_LOG(ERR, "Used up quota of receiving packets,"
986 " relinquish control.");
987 break;
988 }
989 }
990
991 if (unlikely(nb_rxd == 0)) {
992 uint32_t avail;
993 for (ring_idx = 0; ring_idx < VMXNET3_RX_CMDRING_SIZE; ring_idx++) {
994 avail = vmxnet3_cmd_ring_desc_avail(&rxq->cmd_ring[ring_idx]);
995 if (unlikely(avail > 0)) {
996 /* try to alloc new buf and renew descriptors */
997 vmxnet3_post_rx_bufs(rxq, ring_idx);
998 }
999 }
1000 if (unlikely(rxq->shared->ctrl.updateRxProd)) {
1001 for (ring_idx = 0; ring_idx < VMXNET3_RX_CMDRING_SIZE; ring_idx++) {
1002 VMXNET3_WRITE_BAR0_REG(hw, rxprod_reg[ring_idx] + (rxq->queue_id * VMXNET3_REG_ALIGN),
1003 rxq->cmd_ring[ring_idx].next2fill);
1004 }
1005 }
1006 }
1007
1008 return nb_rx;
1009 }
1010
1011 int
1012 vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
1013 uint16_t queue_idx,
1014 uint16_t nb_desc,
1015 unsigned int socket_id,
1016 const struct rte_eth_txconf *tx_conf __rte_unused)
1017 {
1018 struct vmxnet3_hw *hw = dev->data->dev_private;
1019 const struct rte_memzone *mz;
1020 struct vmxnet3_tx_queue *txq;
1021 struct vmxnet3_cmd_ring *ring;
1022 struct vmxnet3_comp_ring *comp_ring;
1023 struct vmxnet3_data_ring *data_ring;
1024 int size;
1025
1026 PMD_INIT_FUNC_TRACE();
1027
1028 txq = rte_zmalloc("ethdev_tx_queue", sizeof(struct vmxnet3_tx_queue),
1029 RTE_CACHE_LINE_SIZE);
1030 if (txq == NULL) {
1031 PMD_INIT_LOG(ERR, "Can not allocate tx queue structure");
1032 return -ENOMEM;
1033 }
1034
1035 txq->queue_id = queue_idx;
1036 txq->port_id = dev->data->port_id;
1037 txq->shared = NULL; /* set in vmxnet3_setup_driver_shared() */
1038 txq->hw = hw;
1039 txq->qid = queue_idx;
1040 txq->stopped = TRUE;
1041 txq->txdata_desc_size = hw->txdata_desc_size;
1042
1043 ring = &txq->cmd_ring;
1044 comp_ring = &txq->comp_ring;
1045 data_ring = &txq->data_ring;
1046
1047 /* Tx vmxnet ring length should be between 512-4096 */
1048 if (nb_desc < VMXNET3_DEF_TX_RING_SIZE) {
1049 PMD_INIT_LOG(ERR, "VMXNET3 Tx Ring Size Min: %u",
1050 VMXNET3_DEF_TX_RING_SIZE);
1051 return -EINVAL;
1052 } else if (nb_desc > VMXNET3_TX_RING_MAX_SIZE) {
1053 PMD_INIT_LOG(ERR, "VMXNET3 Tx Ring Size Max: %u",
1054 VMXNET3_TX_RING_MAX_SIZE);
1055 return -EINVAL;
1056 } else {
1057 ring->size = nb_desc;
1058 ring->size &= ~VMXNET3_RING_SIZE_MASK;
1059 }
1060 comp_ring->size = data_ring->size = ring->size;
1061
1062 /* Tx vmxnet rings structure initialization*/
1063 ring->next2fill = 0;
1064 ring->next2comp = 0;
1065 ring->gen = VMXNET3_INIT_GEN;
1066 comp_ring->next2proc = 0;
1067 comp_ring->gen = VMXNET3_INIT_GEN;
1068
1069 size = sizeof(struct Vmxnet3_TxDesc) * ring->size;
1070 size += sizeof(struct Vmxnet3_TxCompDesc) * comp_ring->size;
1071 size += txq->txdata_desc_size * data_ring->size;
1072
1073 mz = rte_eth_dma_zone_reserve(dev, "txdesc", queue_idx, size,
1074 VMXNET3_RING_BA_ALIGN, socket_id);
1075 if (mz == NULL) {
1076 PMD_INIT_LOG(ERR, "ERROR: Creating queue descriptors zone");
1077 return -ENOMEM;
1078 }
1079 txq->mz = mz;
1080 memset(mz->addr, 0, mz->len);
1081
1082 /* cmd_ring initialization */
1083 ring->base = mz->addr;
1084 ring->basePA = mz->iova;
1085
1086 /* comp_ring initialization */
1087 comp_ring->base = ring->base + ring->size;
1088 comp_ring->basePA = ring->basePA +
1089 (sizeof(struct Vmxnet3_TxDesc) * ring->size);
1090
1091 /* data_ring initialization */
1092 data_ring->base = (Vmxnet3_TxDataDesc *)(comp_ring->base + comp_ring->size);
1093 data_ring->basePA = comp_ring->basePA +
1094 (sizeof(struct Vmxnet3_TxCompDesc) * comp_ring->size);
1095
1096 /* cmd_ring0 buf_info allocation */
1097 ring->buf_info = rte_zmalloc("tx_ring_buf_info",
1098 ring->size * sizeof(vmxnet3_buf_info_t), RTE_CACHE_LINE_SIZE);
1099 if (ring->buf_info == NULL) {
1100 PMD_INIT_LOG(ERR, "ERROR: Creating tx_buf_info structure");
1101 return -ENOMEM;
1102 }
1103
1104 /* Update the data portion with txq */
1105 dev->data->tx_queues[queue_idx] = txq;
1106
1107 return 0;
1108 }
1109
1110 int
1111 vmxnet3_dev_rx_queue_setup(struct rte_eth_dev *dev,
1112 uint16_t queue_idx,
1113 uint16_t nb_desc,
1114 unsigned int socket_id,
1115 __rte_unused const struct rte_eth_rxconf *rx_conf,
1116 struct rte_mempool *mp)
1117 {
1118 const struct rte_memzone *mz;
1119 struct vmxnet3_rx_queue *rxq;
1120 struct vmxnet3_hw *hw = dev->data->dev_private;
1121 struct vmxnet3_cmd_ring *ring0, *ring1, *ring;
1122 struct vmxnet3_comp_ring *comp_ring;
1123 struct vmxnet3_rx_data_ring *data_ring;
1124 int size;
1125 uint8_t i;
1126 char mem_name[32];
1127
1128 PMD_INIT_FUNC_TRACE();
1129
1130 rxq = rte_zmalloc("ethdev_rx_queue", sizeof(struct vmxnet3_rx_queue),
1131 RTE_CACHE_LINE_SIZE);
1132 if (rxq == NULL) {
1133 PMD_INIT_LOG(ERR, "Can not allocate rx queue structure");
1134 return -ENOMEM;
1135 }
1136
1137 rxq->mp = mp;
1138 rxq->queue_id = queue_idx;
1139 rxq->port_id = dev->data->port_id;
1140 rxq->shared = NULL; /* set in vmxnet3_setup_driver_shared() */
1141 rxq->hw = hw;
1142 rxq->qid1 = queue_idx;
1143 rxq->qid2 = queue_idx + hw->num_rx_queues;
1144 rxq->data_ring_qid = queue_idx + 2 * hw->num_rx_queues;
1145 rxq->data_desc_size = hw->rxdata_desc_size;
1146 rxq->stopped = TRUE;
1147
1148 ring0 = &rxq->cmd_ring[0];
1149 ring1 = &rxq->cmd_ring[1];
1150 comp_ring = &rxq->comp_ring;
1151 data_ring = &rxq->data_ring;
1152
1153 /* Rx vmxnet rings length should be between 256-4096 */
1154 if (nb_desc < VMXNET3_DEF_RX_RING_SIZE) {
1155 PMD_INIT_LOG(ERR, "VMXNET3 Rx Ring Size Min: 256");
1156 return -EINVAL;
1157 } else if (nb_desc > VMXNET3_RX_RING_MAX_SIZE) {
1158 PMD_INIT_LOG(ERR, "VMXNET3 Rx Ring Size Max: 4096");
1159 return -EINVAL;
1160 } else {
1161 ring0->size = nb_desc;
1162 ring0->size &= ~VMXNET3_RING_SIZE_MASK;
1163 ring1->size = ring0->size;
1164 }
1165
1166 comp_ring->size = ring0->size + ring1->size;
1167 data_ring->size = ring0->size;
1168
1169 /* Rx vmxnet rings structure initialization */
1170 ring0->next2fill = 0;
1171 ring1->next2fill = 0;
1172 ring0->next2comp = 0;
1173 ring1->next2comp = 0;
1174 ring0->gen = VMXNET3_INIT_GEN;
1175 ring1->gen = VMXNET3_INIT_GEN;
1176 comp_ring->next2proc = 0;
1177 comp_ring->gen = VMXNET3_INIT_GEN;
1178
1179 size = sizeof(struct Vmxnet3_RxDesc) * (ring0->size + ring1->size);
1180 size += sizeof(struct Vmxnet3_RxCompDesc) * comp_ring->size;
1181 if (VMXNET3_VERSION_GE_3(hw) && rxq->data_desc_size)
1182 size += rxq->data_desc_size * data_ring->size;
1183
1184 mz = rte_eth_dma_zone_reserve(dev, "rxdesc", queue_idx, size,
1185 VMXNET3_RING_BA_ALIGN, socket_id);
1186 if (mz == NULL) {
1187 PMD_INIT_LOG(ERR, "ERROR: Creating queue descriptors zone");
1188 return -ENOMEM;
1189 }
1190 rxq->mz = mz;
1191 memset(mz->addr, 0, mz->len);
1192
1193 /* cmd_ring0 initialization */
1194 ring0->base = mz->addr;
1195 ring0->basePA = mz->iova;
1196
1197 /* cmd_ring1 initialization */
1198 ring1->base = ring0->base + ring0->size;
1199 ring1->basePA = ring0->basePA + sizeof(struct Vmxnet3_RxDesc) * ring0->size;
1200
1201 /* comp_ring initialization */
1202 comp_ring->base = ring1->base + ring1->size;
1203 comp_ring->basePA = ring1->basePA + sizeof(struct Vmxnet3_RxDesc) *
1204 ring1->size;
1205
1206 /* data_ring initialization */
1207 if (VMXNET3_VERSION_GE_3(hw) && rxq->data_desc_size) {
1208 data_ring->base =
1209 (uint8_t *)(comp_ring->base + comp_ring->size);
1210 data_ring->basePA = comp_ring->basePA +
1211 sizeof(struct Vmxnet3_RxCompDesc) * comp_ring->size;
1212 }
1213
1214 /* cmd_ring0-cmd_ring1 buf_info allocation */
1215 for (i = 0; i < VMXNET3_RX_CMDRING_SIZE; i++) {
1216
1217 ring = &rxq->cmd_ring[i];
1218 ring->rid = i;
1219 snprintf(mem_name, sizeof(mem_name), "rx_ring_%d_buf_info", i);
1220
1221 ring->buf_info = rte_zmalloc(mem_name,
1222 ring->size * sizeof(vmxnet3_buf_info_t),
1223 RTE_CACHE_LINE_SIZE);
1224 if (ring->buf_info == NULL) {
1225 PMD_INIT_LOG(ERR, "ERROR: Creating rx_buf_info structure");
1226 return -ENOMEM;
1227 }
1228 }
1229
1230 /* Update the data portion with rxq */
1231 dev->data->rx_queues[queue_idx] = rxq;
1232
1233 return 0;
1234 }
1235
1236 /*
1237 * Initializes Receive Unit
1238 * Load mbufs in rx queue in advance
1239 */
1240 int
1241 vmxnet3_dev_rxtx_init(struct rte_eth_dev *dev)
1242 {
1243 struct vmxnet3_hw *hw = dev->data->dev_private;
1244
1245 int i, ret;
1246 uint8_t j;
1247
1248 PMD_INIT_FUNC_TRACE();
1249
1250 for (i = 0; i < hw->num_rx_queues; i++) {
1251 vmxnet3_rx_queue_t *rxq = dev->data->rx_queues[i];
1252
1253 for (j = 0; j < VMXNET3_RX_CMDRING_SIZE; j++) {
1254 /* Passing 0 as alloc_num will allocate full ring */
1255 ret = vmxnet3_post_rx_bufs(rxq, j);
1256 if (ret <= 0) {
1257 PMD_INIT_LOG(ERR,
1258 "ERROR: Posting Rxq: %d buffers ring: %d",
1259 i, j);
1260 return -ret;
1261 }
1262 /*
1263 * Updating device with the index:next2fill to fill the
1264 * mbufs for coming packets.
1265 */
1266 if (unlikely(rxq->shared->ctrl.updateRxProd)) {
1267 VMXNET3_WRITE_BAR0_REG(hw, rxprod_reg[j] + (rxq->queue_id * VMXNET3_REG_ALIGN),
1268 rxq->cmd_ring[j].next2fill);
1269 }
1270 }
1271 rxq->stopped = FALSE;
1272 rxq->start_seg = NULL;
1273 }
1274
1275 for (i = 0; i < dev->data->nb_tx_queues; i++) {
1276 struct vmxnet3_tx_queue *txq = dev->data->tx_queues[i];
1277
1278 txq->stopped = FALSE;
1279 }
1280
1281 return 0;
1282 }
1283
1284 static uint8_t rss_intel_key[40] = {
1285 0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2,
1286 0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0,
1287 0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4,
1288 0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C,
1289 0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA,
1290 };
1291
1292 /*
1293 * Configure RSS feature
1294 */
1295 int
1296 vmxnet3_rss_configure(struct rte_eth_dev *dev)
1297 {
1298 struct vmxnet3_hw *hw = dev->data->dev_private;
1299 struct VMXNET3_RSSConf *dev_rss_conf;
1300 struct rte_eth_rss_conf *port_rss_conf;
1301 uint64_t rss_hf;
1302 uint8_t i, j;
1303
1304 PMD_INIT_FUNC_TRACE();
1305
1306 dev_rss_conf = hw->rss_conf;
1307 port_rss_conf = &dev->data->dev_conf.rx_adv_conf.rss_conf;
1308
1309 /* loading hashFunc */
1310 dev_rss_conf->hashFunc = VMXNET3_RSS_HASH_FUNC_TOEPLITZ;
1311 /* loading hashKeySize */
1312 dev_rss_conf->hashKeySize = VMXNET3_RSS_MAX_KEY_SIZE;
1313 /* loading indTableSize: Must not exceed VMXNET3_RSS_MAX_IND_TABLE_SIZE (128)*/
1314 dev_rss_conf->indTableSize = (uint16_t)(hw->num_rx_queues * 4);
1315
1316 if (port_rss_conf->rss_key == NULL) {
1317 /* Default hash key */
1318 port_rss_conf->rss_key = rss_intel_key;
1319 }
1320
1321 /* loading hashKey */
1322 memcpy(&dev_rss_conf->hashKey[0], port_rss_conf->rss_key,
1323 dev_rss_conf->hashKeySize);
1324
1325 /* loading indTable */
1326 for (i = 0, j = 0; i < dev_rss_conf->indTableSize; i++, j++) {
1327 if (j == dev->data->nb_rx_queues)
1328 j = 0;
1329 dev_rss_conf->indTable[i] = j;
1330 }
1331
1332 /* loading hashType */
1333 dev_rss_conf->hashType = 0;
1334 rss_hf = port_rss_conf->rss_hf & VMXNET3_RSS_OFFLOAD_ALL;
1335 if (rss_hf & ETH_RSS_IPV4)
1336 dev_rss_conf->hashType |= VMXNET3_RSS_HASH_TYPE_IPV4;
1337 if (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP)
1338 dev_rss_conf->hashType |= VMXNET3_RSS_HASH_TYPE_TCP_IPV4;
1339 if (rss_hf & ETH_RSS_IPV6)
1340 dev_rss_conf->hashType |= VMXNET3_RSS_HASH_TYPE_IPV6;
1341 if (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP)
1342 dev_rss_conf->hashType |= VMXNET3_RSS_HASH_TYPE_TCP_IPV6;
1343
1344 return VMXNET3_SUCCESS;
1345 }