4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/queue.h>
45 #include <rte_byteorder.h>
46 #include <rte_common.h>
47 #include <rte_cycles.h>
49 #include <rte_debug.h>
50 #include <rte_interrupts.h>
52 #include <rte_memory.h>
53 #include <rte_memzone.h>
54 #include <rte_launch.h>
55 #include <rte_tailq.h>
57 #include <rte_per_lcore.h>
58 #include <rte_lcore.h>
59 #include <rte_atomic.h>
60 #include <rte_branch_prediction.h>
62 #include <rte_mempool.h>
63 #include <rte_malloc.h>
65 #include <rte_ether.h>
66 #include <rte_ethdev.h>
67 #include <rte_prefetch.h>
72 #include <rte_string_fns.h>
73 #include <rte_errno.h>
75 #include "vmxnet3/vmxnet3_defs.h"
76 #include "vmxnet3_ring.h"
78 #include "vmxnet3_logs.h"
79 #include "vmxnet3_ethdev.h"
82 #define RTE_MBUF_DATA_DMA_ADDR(mb) \
83 (uint64_t) ((mb)->buf_physaddr + (mb)->data_off)
85 #define RTE_MBUF_DATA_DMA_ADDR_DEFAULT(mb) \
86 (uint64_t) ((mb)->buf_physaddr + RTE_PKTMBUF_HEADROOM)
88 static uint32_t rxprod_reg[2] = {VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2};
90 static inline int vmxnet3_post_rx_bufs(vmxnet3_rx_queue_t* , uint8_t);
91 static inline void vmxnet3_tq_tx_complete(vmxnet3_tx_queue_t *);
92 #ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER_NOT_USED
93 static void vmxnet3_rxq_dump(struct vmxnet3_rx_queue *);
94 static void vmxnet3_txq_dump(struct vmxnet3_tx_queue *);
97 static inline struct rte_mbuf *
98 rte_rxmbuf_alloc(struct rte_mempool *mp)
102 m = __rte_mbuf_raw_alloc(mp);
103 __rte_mbuf_sanity_check_raw(m, 0);
107 #ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER_NOT_USED
109 vmxnet3_rxq_dump(struct vmxnet3_rx_queue *rxq)
117 "RXQ: cmd0 base : 0x%p cmd1 base : 0x%p comp ring base : 0x%p.",
118 rxq->cmd_ring[0].base, rxq->cmd_ring[1].base, rxq->comp_ring.base);
120 "RXQ: cmd0 basePA : 0x%lx cmd1 basePA : 0x%lx comp ring basePA : 0x%lx.",
121 (unsigned long)rxq->cmd_ring[0].basePA,
122 (unsigned long)rxq->cmd_ring[1].basePA,
123 (unsigned long)rxq->comp_ring.basePA);
125 avail = vmxnet3_cmd_ring_desc_avail(&rxq->cmd_ring[0]);
127 "RXQ:cmd0: size=%u; free=%u; next2proc=%u; queued=%u",
128 (uint32_t)rxq->cmd_ring[0].size, avail,
129 rxq->comp_ring.next2proc,
130 rxq->cmd_ring[0].size - avail);
132 avail = vmxnet3_cmd_ring_desc_avail(&rxq->cmd_ring[1]);
133 PMD_RX_LOG(DEBUG, "RXQ:cmd1 size=%u; free=%u; next2proc=%u; queued=%u",
134 (uint32_t)rxq->cmd_ring[1].size, avail, rxq->comp_ring.next2proc,
135 rxq->cmd_ring[1].size - avail);
140 vmxnet3_txq_dump(struct vmxnet3_tx_queue *txq)
147 PMD_TX_LOG(DEBUG, "TXQ: cmd base : 0x%p comp ring base : 0x%p.",
148 txq->cmd_ring.base, txq->comp_ring.base);
149 PMD_TX_LOG(DEBUG, "TXQ: cmd basePA : 0x%lx comp ring basePA : 0x%lx.",
150 (unsigned long)txq->cmd_ring.basePA,
151 (unsigned long)txq->comp_ring.basePA);
153 avail = vmxnet3_cmd_ring_desc_avail(&txq->cmd_ring);
154 PMD_TX_LOG(DEBUG, "TXQ: size=%u; free=%u; next2proc=%u; queued=%u",
155 (uint32_t)txq->cmd_ring.size, avail,
156 txq->comp_ring.next2proc, txq->cmd_ring.size - avail);
161 vmxnet3_cmd_ring_release_mbufs(vmxnet3_cmd_ring_t *ring)
163 while (ring->next2comp != ring->next2fill) {
164 /* No need to worry about tx desc ownership, device is quiesced by now. */
165 vmxnet3_buf_info_t *buf_info = ring->buf_info + ring->next2comp;
168 rte_pktmbuf_free(buf_info->m);
173 vmxnet3_cmd_ring_adv_next2comp(ring);
178 vmxnet3_cmd_ring_release(vmxnet3_cmd_ring_t *ring)
180 vmxnet3_cmd_ring_release_mbufs(ring);
181 rte_free(ring->buf_info);
182 ring->buf_info = NULL;
187 vmxnet3_dev_tx_queue_release(void *txq)
189 vmxnet3_tx_queue_t *tq = txq;
192 /* Release the cmd_ring */
193 vmxnet3_cmd_ring_release(&tq->cmd_ring);
198 vmxnet3_dev_rx_queue_release(void *rxq)
201 vmxnet3_rx_queue_t *rq = rxq;
204 /* Release both the cmd_rings */
205 for (i = 0; i < VMXNET3_RX_CMDRING_SIZE; i++)
206 vmxnet3_cmd_ring_release(&rq->cmd_ring[i]);
211 vmxnet3_dev_tx_queue_reset(void *txq)
213 vmxnet3_tx_queue_t *tq = txq;
214 struct vmxnet3_cmd_ring *ring = &tq->cmd_ring;
215 struct vmxnet3_comp_ring *comp_ring = &tq->comp_ring;
219 /* Release the cmd_ring mbufs */
220 vmxnet3_cmd_ring_release_mbufs(&tq->cmd_ring);
223 /* Tx vmxnet rings structure initialization*/
226 ring->gen = VMXNET3_INIT_GEN;
227 comp_ring->next2proc = 0;
228 comp_ring->gen = VMXNET3_INIT_GEN;
230 size = sizeof(struct Vmxnet3_TxDesc) * ring->size;
231 size += sizeof(struct Vmxnet3_TxCompDesc) * comp_ring->size;
233 memset(ring->base, 0, size);
237 vmxnet3_dev_rx_queue_reset(void *rxq)
240 vmxnet3_rx_queue_t *rq = rxq;
241 struct vmxnet3_cmd_ring *ring0, *ring1;
242 struct vmxnet3_comp_ring *comp_ring;
246 /* Release both the cmd_rings mbufs */
247 for (i = 0; i < VMXNET3_RX_CMDRING_SIZE; i++)
248 vmxnet3_cmd_ring_release_mbufs(&rq->cmd_ring[i]);
251 ring0 = &rq->cmd_ring[0];
252 ring1 = &rq->cmd_ring[1];
253 comp_ring = &rq->comp_ring;
255 /* Rx vmxnet rings structure initialization */
256 ring0->next2fill = 0;
257 ring1->next2fill = 0;
258 ring0->next2comp = 0;
259 ring1->next2comp = 0;
260 ring0->gen = VMXNET3_INIT_GEN;
261 ring1->gen = VMXNET3_INIT_GEN;
262 comp_ring->next2proc = 0;
263 comp_ring->gen = VMXNET3_INIT_GEN;
265 size = sizeof(struct Vmxnet3_RxDesc) * (ring0->size + ring1->size);
266 size += sizeof(struct Vmxnet3_RxCompDesc) * comp_ring->size;
268 memset(ring0->base, 0, size);
272 vmxnet3_dev_clear_queues(struct rte_eth_dev *dev)
276 PMD_INIT_FUNC_TRACE();
278 for (i = 0; i < dev->data->nb_tx_queues; i++) {
279 struct vmxnet3_tx_queue *txq = dev->data->tx_queues[i];
283 vmxnet3_dev_tx_queue_reset(txq);
287 for (i = 0; i < dev->data->nb_rx_queues; i++) {
288 struct vmxnet3_rx_queue *rxq = dev->data->rx_queues[i];
292 vmxnet3_dev_rx_queue_reset(rxq);
298 vmxnet3_tq_tx_complete(vmxnet3_tx_queue_t *txq)
301 struct rte_mbuf *mbuf;
302 vmxnet3_comp_ring_t *comp_ring = &txq->comp_ring;
303 struct Vmxnet3_TxCompDesc *tcd = (struct Vmxnet3_TxCompDesc *)
304 (comp_ring->base + comp_ring->next2proc);
306 while (tcd->gen == comp_ring->gen) {
308 /* Release cmd_ring descriptor and free mbuf */
309 #ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
310 VMXNET3_ASSERT(txq->cmd_ring.base[tcd->txdIdx].txd.eop == 1);
312 mbuf = txq->cmd_ring.buf_info[tcd->txdIdx].m;
313 if (unlikely(mbuf == NULL))
314 rte_panic("EOP desc does not point to a valid mbuf");
316 rte_pktmbuf_free(mbuf);
319 txq->cmd_ring.buf_info[tcd->txdIdx].m = NULL;
320 /* Mark the txd for which tcd was generated as completed */
321 vmxnet3_cmd_ring_adv_next2comp(&txq->cmd_ring);
323 vmxnet3_comp_ring_adv_next2proc(comp_ring);
324 tcd = (struct Vmxnet3_TxCompDesc *)(comp_ring->base +
325 comp_ring->next2proc);
329 PMD_TX_LOG(DEBUG, "Processed %d tx comps & command descs.", completed);
333 vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
337 Vmxnet3_TxDesc *txd = NULL;
338 vmxnet3_buf_info_t *tbi = NULL;
339 struct vmxnet3_hw *hw;
340 struct rte_mbuf *txm;
341 vmxnet3_tx_queue_t *txq = tx_queue;
346 PMD_TX_LOG(DEBUG, "Tx queue is stopped.");
350 /* Free up the comp_descriptors aggressively */
351 vmxnet3_tq_tx_complete(txq);
354 while (nb_tx < nb_pkts) {
356 if (vmxnet3_cmd_ring_desc_avail(&txq->cmd_ring)) {
358 txm = tx_pkts[nb_tx];
359 /* Don't support scatter packets yet, free them if met */
360 if (txm->nb_segs != 1) {
361 PMD_TX_LOG(DEBUG, "Don't support scatter packets yet, drop!");
362 rte_pktmbuf_free(tx_pkts[nb_tx]);
363 txq->stats.drop_total++;
369 /* Needs to minus ether header len */
370 if (txm->data_len > (hw->cur_mtu + ETHER_HDR_LEN)) {
371 PMD_TX_LOG(DEBUG, "Packet data_len higher than MTU");
372 rte_pktmbuf_free(tx_pkts[nb_tx]);
373 txq->stats.drop_total++;
379 txd = (Vmxnet3_TxDesc *)(txq->cmd_ring.base + txq->cmd_ring.next2fill);
381 /* Fill the tx descriptor */
382 tbi = txq->cmd_ring.buf_info + txq->cmd_ring.next2fill;
383 tbi->bufPA = RTE_MBUF_DATA_DMA_ADDR(txm);
384 txd->addr = tbi->bufPA;
385 txd->len = txm->data_len;
387 /* Mark the last descriptor as End of Packet. */
391 /* Add VLAN tag if requested */
392 if (txm->ol_flags & PKT_TX_VLAN_PKT) {
394 txd->tci = rte_cpu_to_le_16(txm->vlan_tci);
397 /* Record current mbuf for freeing it later in tx complete */
398 #ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
403 /* Set the offloading mode to default */
405 txd->om = VMXNET3_OM_NONE;
408 /* finally flip the GEN bit of the SOP desc */
409 txd->gen = txq->cmd_ring.gen;
410 txq->shared->ctrl.txNumDeferred++;
412 /* move to the next2fill descriptor */
413 vmxnet3_cmd_ring_adv_next2fill(&txq->cmd_ring);
417 PMD_TX_LOG(DEBUG, "No free tx cmd desc(s)");
418 txq->stats.drop_total += (nb_pkts - nb_tx);
423 PMD_TX_LOG(DEBUG, "vmxnet3 txThreshold: %u", txq->shared->ctrl.txThreshold);
425 if (txq->shared->ctrl.txNumDeferred >= txq->shared->ctrl.txThreshold) {
427 txq->shared->ctrl.txNumDeferred = 0;
428 /* Notify vSwitch that packets are available. */
429 VMXNET3_WRITE_BAR0_REG(hw, (VMXNET3_REG_TXPROD + txq->queue_id * VMXNET3_REG_ALIGN),
430 txq->cmd_ring.next2fill);
437 * Allocates mbufs and clusters. Post rx descriptors with buffer details
438 * so that device can receive packets in those buffers.
440 * Among the two rings, 1st ring contains buffers of type 0 and type1.
441 * bufs_per_pkt is set such that for non-LRO cases all the buffers required
442 * by a frame will fit in 1st ring (1st buf of type0 and rest of type1).
443 * 2nd ring contains buffers of type 1 alone. Second ring mostly be used
448 vmxnet3_post_rx_bufs(vmxnet3_rx_queue_t *rxq, uint8_t ring_id)
451 uint32_t i = 0, val = 0;
452 struct vmxnet3_cmd_ring *ring = &rxq->cmd_ring[ring_id];
455 /* Usually: One HEAD type buf per packet
456 * val = (ring->next2fill % rxq->hw->bufs_per_pkt) ?
457 * VMXNET3_RXD_BTYPE_BODY : VMXNET3_RXD_BTYPE_HEAD;
460 /* We use single packet buffer so all heads here */
461 val = VMXNET3_RXD_BTYPE_HEAD;
463 /* All BODY type buffers for 2nd ring */
464 val = VMXNET3_RXD_BTYPE_BODY;
467 while (vmxnet3_cmd_ring_desc_avail(ring) > 0) {
468 struct Vmxnet3_RxDesc *rxd;
469 struct rte_mbuf *mbuf;
470 vmxnet3_buf_info_t *buf_info = &ring->buf_info[ring->next2fill];
472 rxd = (struct Vmxnet3_RxDesc *)(ring->base + ring->next2fill);
474 /* Allocate blank mbuf for the current Rx Descriptor */
475 mbuf = rte_rxmbuf_alloc(rxq->mp);
476 if (unlikely(mbuf == NULL)) {
477 PMD_RX_LOG(ERR, "Error allocating mbuf in %s", __func__);
478 rxq->stats.rx_buf_alloc_failure++;
484 * Load mbuf pointer into buf_info[ring_size]
485 * buf_info structure is equivalent to cookie for virtio-virtqueue
488 buf_info->len = (uint16_t)(mbuf->buf_len -
489 RTE_PKTMBUF_HEADROOM);
490 buf_info->bufPA = RTE_MBUF_DATA_DMA_ADDR_DEFAULT(mbuf);
492 /* Load Rx Descriptor with the buffer's GPA */
493 rxd->addr = buf_info->bufPA;
495 /* After this point rxd->addr MUST not be NULL */
497 rxd->len = buf_info->len;
498 /* Flip gen bit at the end to change ownership */
499 rxd->gen = ring->gen;
501 vmxnet3_cmd_ring_adv_next2fill(ring);
505 /* Return error only if no buffers are posted at present */
506 if (vmxnet3_cmd_ring_desc_avail(ring) >= (ring->size - 1))
513 * Process the Rx Completion Ring of given vmxnet3_rx_queue
514 * for nb_pkts burst and return the number of packets received
517 vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
520 uint32_t nb_rxd, idx;
522 vmxnet3_rx_queue_t *rxq;
523 Vmxnet3_RxCompDesc *rcd;
524 vmxnet3_buf_info_t *rbi;
526 struct rte_mbuf *rxm = NULL;
527 struct vmxnet3_hw *hw;
537 rcd = &rxq->comp_ring.base[rxq->comp_ring.next2proc].rcd;
539 if (unlikely(rxq->stopped)) {
540 PMD_RX_LOG(DEBUG, "Rx queue is stopped.");
544 while (rcd->gen == rxq->comp_ring.gen) {
545 if (nb_rx >= nb_pkts)
549 ring_idx = (uint8_t)((rcd->rqID == rxq->qid1) ? 0 : 1);
550 rxd = (Vmxnet3_RxDesc *)rxq->cmd_ring[ring_idx].base + idx;
551 rbi = rxq->cmd_ring[ring_idx].buf_info + idx;
553 if (unlikely(rcd->sop != 1 || rcd->eop != 1)) {
554 rte_pktmbuf_free_seg(rbi->m);
555 PMD_RX_LOG(DEBUG, "Packet spread across multiple buffers\n)");
559 PMD_RX_LOG(DEBUG, "rxd idx: %d ring idx: %d.", idx, ring_idx);
561 #ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
562 VMXNET3_ASSERT(rcd->len <= rxd->len);
563 VMXNET3_ASSERT(rbi->m);
565 if (unlikely(rcd->len == 0)) {
566 PMD_RX_LOG(DEBUG, "Rx buf was skipped. rxring[%d][%d]\n)",
568 #ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
569 VMXNET3_ASSERT(rcd->sop && rcd->eop);
571 rte_pktmbuf_free_seg(rbi->m);
575 /* Assuming a packet is coming in a single packet buffer */
576 if (unlikely(rxd->btype != VMXNET3_RXD_BTYPE_HEAD)) {
578 "Alert : Misbehaving device, incorrect "
579 " buffer type used. iPacket dropped.");
580 rte_pktmbuf_free_seg(rbi->m);
583 #ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
584 VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_HEAD);
586 /* Get the packet buffer pointer from buf_info */
589 /* Clear descriptor associated buf_info to be reused */
593 /* Update the index that we received a packet */
594 rxq->cmd_ring[ring_idx].next2comp = idx;
596 /* For RCD with EOP set, check if there is frame error */
597 if (unlikely(rcd->err)) {
598 rxq->stats.drop_total++;
599 rxq->stats.drop_err++;
602 rxq->stats.drop_fcs++;
603 PMD_RX_LOG(ERR, "Recv packet dropped due to frame err.");
605 PMD_RX_LOG(ERR, "Error in received packet rcd#:%d rxd:%d",
606 (int)(rcd - (struct Vmxnet3_RxCompDesc *)
607 rxq->comp_ring.base), rcd->rxdIdx);
608 rte_pktmbuf_free_seg(rxm);
612 /* Check for hardware stripped VLAN tag */
614 PMD_RX_LOG(DEBUG, "Received packet with vlan ID: %d.",
616 rxm->ol_flags = PKT_RX_VLAN_PKT;
617 /* Copy vlan tag in packet buffer */
618 rxm->vlan_tci = rte_le_to_cpu_16((uint16_t)rcd->tci);
624 /* Initialize newly received packet buffer */
625 rxm->port = rxq->port_id;
628 rxm->pkt_len = (uint16_t)rcd->len;
629 rxm->data_len = (uint16_t)rcd->len;
630 rxm->data_off = RTE_PKTMBUF_HEADROOM;
632 /* Check packet type, checksum errors, etc. Only support IPv4 for now. */
634 struct ether_hdr *eth = rte_pktmbuf_mtod(rxm, struct ether_hdr *);
635 struct ipv4_hdr *ip = (struct ipv4_hdr *)(eth + 1);
637 if (((ip->version_ihl & 0xf) << 2) > (int)sizeof(struct ipv4_hdr))
638 rxm->ol_flags |= PKT_RX_IPV4_HDR_EXT;
640 rxm->ol_flags |= PKT_RX_IPV4_HDR;
644 rxm->ol_flags |= PKT_RX_IP_CKSUM_BAD;
646 if ((rcd->tcp || rcd->udp) && !rcd->tuc)
647 rxm->ol_flags |= PKT_RX_L4_CKSUM_BAD;
651 rx_pkts[nb_rx++] = rxm;
653 rxq->cmd_ring[ring_idx].next2comp = idx;
654 VMXNET3_INC_RING_IDX_ONLY(rxq->cmd_ring[ring_idx].next2comp, rxq->cmd_ring[ring_idx].size);
656 /* It's time to allocate some new buf and renew descriptors */
657 vmxnet3_post_rx_bufs(rxq, ring_idx);
658 if (unlikely(rxq->shared->ctrl.updateRxProd)) {
659 VMXNET3_WRITE_BAR0_REG(hw, rxprod_reg[ring_idx] + (rxq->queue_id * VMXNET3_REG_ALIGN),
660 rxq->cmd_ring[ring_idx].next2fill);
663 /* Advance to the next descriptor in comp_ring */
664 vmxnet3_comp_ring_adv_next2proc(&rxq->comp_ring);
666 rcd = &rxq->comp_ring.base[rxq->comp_ring.next2proc].rcd;
668 if (nb_rxd > rxq->cmd_ring[0].size) {
670 "Used up quota of receiving packets,"
671 " relinquish control.");
680 * Create memzone for device rings. malloc can't be used as the physical address is
681 * needed. If the memzone is already created, then this function returns a ptr
684 static const struct rte_memzone *
685 ring_dma_zone_reserve(struct rte_eth_dev *dev, const char *ring_name,
686 uint16_t queue_id, uint32_t ring_size, int socket_id)
688 char z_name[RTE_MEMZONE_NAMESIZE];
689 const struct rte_memzone *mz;
691 snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
692 dev->driver->pci_drv.name, ring_name,
693 dev->data->port_id, queue_id);
695 mz = rte_memzone_lookup(z_name);
699 return rte_memzone_reserve_aligned(z_name, ring_size,
700 socket_id, 0, VMXNET3_RING_BA_ALIGN);
704 vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
707 unsigned int socket_id,
708 __attribute__((unused)) const struct rte_eth_txconf *tx_conf)
710 struct vmxnet3_hw *hw = dev->data->dev_private;
711 const struct rte_memzone *mz;
712 struct vmxnet3_tx_queue *txq;
713 struct vmxnet3_cmd_ring *ring;
714 struct vmxnet3_comp_ring *comp_ring;
717 PMD_INIT_FUNC_TRACE();
719 if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOMULTSEGS) !=
720 ETH_TXQ_FLAGS_NOMULTSEGS) {
721 PMD_INIT_LOG(ERR, "TX Multi segment not support yet");
725 if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOOFFLOADS) !=
726 ETH_TXQ_FLAGS_NOOFFLOADS) {
727 PMD_INIT_LOG(ERR, "TX not support offload function yet");
731 txq = rte_zmalloc("ethdev_tx_queue", sizeof(struct vmxnet3_tx_queue), CACHE_LINE_SIZE);
733 PMD_INIT_LOG(ERR, "Can not allocate tx queue structure");
737 txq->queue_id = queue_idx;
738 txq->port_id = dev->data->port_id;
739 txq->shared = &hw->tqd_start[queue_idx];
741 txq->qid = queue_idx;
744 ring = &txq->cmd_ring;
745 comp_ring = &txq->comp_ring;
747 /* Tx vmxnet ring length should be between 512-4096 */
748 if (nb_desc < VMXNET3_DEF_TX_RING_SIZE) {
749 PMD_INIT_LOG(ERR, "VMXNET3 Tx Ring Size Min: %u",
750 VMXNET3_DEF_TX_RING_SIZE);
752 } else if (nb_desc > VMXNET3_TX_RING_MAX_SIZE) {
753 PMD_INIT_LOG(ERR, "VMXNET3 Tx Ring Size Max: %u",
754 VMXNET3_TX_RING_MAX_SIZE);
757 ring->size = nb_desc;
758 ring->size &= ~VMXNET3_RING_SIZE_MASK;
760 comp_ring->size = ring->size;
762 /* Tx vmxnet rings structure initialization*/
765 ring->gen = VMXNET3_INIT_GEN;
766 comp_ring->next2proc = 0;
767 comp_ring->gen = VMXNET3_INIT_GEN;
769 size = sizeof(struct Vmxnet3_TxDesc) * ring->size;
770 size += sizeof(struct Vmxnet3_TxCompDesc) * comp_ring->size;
772 mz = ring_dma_zone_reserve(dev, "txdesc", queue_idx, size, socket_id);
774 PMD_INIT_LOG(ERR, "ERROR: Creating queue descriptors zone");
777 memset(mz->addr, 0, mz->len);
779 /* cmd_ring initialization */
780 ring->base = mz->addr;
781 ring->basePA = mz->phys_addr;
783 /* comp_ring initialization */
784 comp_ring->base = ring->base + ring->size;
785 comp_ring->basePA = ring->basePA +
786 (sizeof(struct Vmxnet3_TxDesc) * ring->size);
788 /* cmd_ring0 buf_info allocation */
789 ring->buf_info = rte_zmalloc("tx_ring_buf_info",
790 ring->size * sizeof(vmxnet3_buf_info_t), CACHE_LINE_SIZE);
791 if (ring->buf_info == NULL) {
792 PMD_INIT_LOG(ERR, "ERROR: Creating tx_buf_info structure");
796 /* Update the data portion with txq */
797 dev->data->tx_queues[queue_idx] = txq;
803 vmxnet3_dev_rx_queue_setup(struct rte_eth_dev *dev,
806 unsigned int socket_id,
807 __attribute__((unused)) const struct rte_eth_rxconf *rx_conf,
808 struct rte_mempool *mp)
810 const struct rte_memzone *mz;
811 struct vmxnet3_rx_queue *rxq;
812 struct vmxnet3_hw *hw = dev->data->dev_private;
813 struct vmxnet3_cmd_ring *ring0, *ring1, *ring;
814 struct vmxnet3_comp_ring *comp_ring;
819 struct rte_pktmbuf_pool_private *mbp_priv;
821 PMD_INIT_FUNC_TRACE();
823 mbp_priv = (struct rte_pktmbuf_pool_private *)
824 rte_mempool_get_priv(mp);
825 buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
826 RTE_PKTMBUF_HEADROOM);
828 if (dev->data->dev_conf.rxmode.max_rx_pkt_len > buf_size) {
829 PMD_INIT_LOG(ERR, "buf_size = %u, max_pkt_len = %u, "
830 "VMXNET3 don't support scatter packets yet",
831 buf_size, dev->data->dev_conf.rxmode.max_rx_pkt_len);
835 rxq = rte_zmalloc("ethdev_rx_queue", sizeof(struct vmxnet3_rx_queue), CACHE_LINE_SIZE);
837 PMD_INIT_LOG(ERR, "Can not allocate rx queue structure");
842 rxq->queue_id = queue_idx;
843 rxq->port_id = dev->data->port_id;
844 rxq->shared = &hw->rqd_start[queue_idx];
846 rxq->qid1 = queue_idx;
847 rxq->qid2 = queue_idx + hw->num_rx_queues;
850 ring0 = &rxq->cmd_ring[0];
851 ring1 = &rxq->cmd_ring[1];
852 comp_ring = &rxq->comp_ring;
854 /* Rx vmxnet rings length should be between 256-4096 */
855 if (nb_desc < VMXNET3_DEF_RX_RING_SIZE) {
856 PMD_INIT_LOG(ERR, "VMXNET3 Rx Ring Size Min: 256");
858 } else if (nb_desc > VMXNET3_RX_RING_MAX_SIZE) {
859 PMD_INIT_LOG(ERR, "VMXNET3 Rx Ring Size Max: 4096");
862 ring0->size = nb_desc;
863 ring0->size &= ~VMXNET3_RING_SIZE_MASK;
864 ring1->size = ring0->size;
867 comp_ring->size = ring0->size + ring1->size;
869 /* Rx vmxnet rings structure initialization */
870 ring0->next2fill = 0;
871 ring1->next2fill = 0;
872 ring0->next2comp = 0;
873 ring1->next2comp = 0;
874 ring0->gen = VMXNET3_INIT_GEN;
875 ring1->gen = VMXNET3_INIT_GEN;
876 comp_ring->next2proc = 0;
877 comp_ring->gen = VMXNET3_INIT_GEN;
879 size = sizeof(struct Vmxnet3_RxDesc) * (ring0->size + ring1->size);
880 size += sizeof(struct Vmxnet3_RxCompDesc) * comp_ring->size;
882 mz = ring_dma_zone_reserve(dev, "rxdesc", queue_idx, size, socket_id);
884 PMD_INIT_LOG(ERR, "ERROR: Creating queue descriptors zone");
887 memset(mz->addr, 0, mz->len);
889 /* cmd_ring0 initialization */
890 ring0->base = mz->addr;
891 ring0->basePA = mz->phys_addr;
893 /* cmd_ring1 initialization */
894 ring1->base = ring0->base + ring0->size;
895 ring1->basePA = ring0->basePA + sizeof(struct Vmxnet3_RxDesc) * ring0->size;
897 /* comp_ring initialization */
898 comp_ring->base = ring1->base + ring1->size;
899 comp_ring->basePA = ring1->basePA + sizeof(struct Vmxnet3_RxDesc) *
902 /* cmd_ring0-cmd_ring1 buf_info allocation */
903 for (i = 0; i < VMXNET3_RX_CMDRING_SIZE; i++) {
905 ring = &rxq->cmd_ring[i];
907 snprintf(mem_name, sizeof(mem_name), "rx_ring_%d_buf_info", i);
909 ring->buf_info = rte_zmalloc(mem_name, ring->size * sizeof(vmxnet3_buf_info_t), CACHE_LINE_SIZE);
910 if (ring->buf_info == NULL) {
911 PMD_INIT_LOG(ERR, "ERROR: Creating rx_buf_info structure");
916 /* Update the data portion with rxq */
917 dev->data->rx_queues[queue_idx] = rxq;
923 * Initializes Receive Unit
924 * Load mbufs in rx queue in advance
927 vmxnet3_dev_rxtx_init(struct rte_eth_dev *dev)
929 struct vmxnet3_hw *hw = dev->data->dev_private;
934 PMD_INIT_FUNC_TRACE();
936 for (i = 0; i < hw->num_rx_queues; i++) {
937 vmxnet3_rx_queue_t *rxq = dev->data->rx_queues[i];
939 for (j = 0; j < VMXNET3_RX_CMDRING_SIZE; j++) {
940 /* Passing 0 as alloc_num will allocate full ring */
941 ret = vmxnet3_post_rx_bufs(rxq, j);
943 PMD_INIT_LOG(ERR, "ERROR: Posting Rxq: %d buffers ring: %d", i, j);
946 /* Updating device with the index:next2fill to fill the mbufs for coming packets */
947 if (unlikely(rxq->shared->ctrl.updateRxProd)) {
948 VMXNET3_WRITE_BAR0_REG(hw, rxprod_reg[j] + (rxq->queue_id * VMXNET3_REG_ALIGN),
949 rxq->cmd_ring[j].next2fill);
952 rxq->stopped = FALSE;
955 for (i = 0; i < dev->data->nb_tx_queues; i++) {
956 struct vmxnet3_tx_queue *txq = dev->data->tx_queues[i];
958 txq->stopped = FALSE;
964 static uint8_t rss_intel_key[40] = {
965 0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2,
966 0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0,
967 0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4,
968 0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C,
969 0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA,
973 * Configure RSS feature
976 vmxnet3_rss_configure(struct rte_eth_dev *dev)
978 #define VMXNET3_RSS_OFFLOAD_ALL ( \
984 struct vmxnet3_hw *hw = dev->data->dev_private;
985 struct VMXNET3_RSSConf *dev_rss_conf;
986 struct rte_eth_rss_conf *port_rss_conf;
990 PMD_INIT_FUNC_TRACE();
992 dev_rss_conf = hw->rss_conf;
993 port_rss_conf = &dev->data->dev_conf.rx_adv_conf.rss_conf;
995 /* loading hashFunc */
996 dev_rss_conf->hashFunc = VMXNET3_RSS_HASH_FUNC_TOEPLITZ;
997 /* loading hashKeySize */
998 dev_rss_conf->hashKeySize = VMXNET3_RSS_MAX_KEY_SIZE;
999 /* loading indTableSize : Must not exceed VMXNET3_RSS_MAX_IND_TABLE_SIZE (128)*/
1000 dev_rss_conf->indTableSize = (uint16_t)(hw->num_rx_queues * 4);
1002 if (port_rss_conf->rss_key == NULL) {
1003 /* Default hash key */
1004 port_rss_conf->rss_key = rss_intel_key;
1007 /* loading hashKey */
1008 memcpy(&dev_rss_conf->hashKey[0], port_rss_conf->rss_key, dev_rss_conf->hashKeySize);
1010 /* loading indTable */
1011 for (i = 0, j = 0; i < dev_rss_conf->indTableSize; i++, j++) {
1012 if (j == dev->data->nb_rx_queues)
1014 dev_rss_conf->indTable[i] = j;
1017 /* loading hashType */
1018 dev_rss_conf->hashType = 0;
1019 rss_hf = port_rss_conf->rss_hf & VMXNET3_RSS_OFFLOAD_ALL;
1020 if (rss_hf & ETH_RSS_IPV4)
1021 dev_rss_conf->hashType |= VMXNET3_RSS_HASH_TYPE_IPV4;
1022 if (rss_hf & ETH_RSS_IPV4_TCP)
1023 dev_rss_conf->hashType |= VMXNET3_RSS_HASH_TYPE_TCP_IPV4;
1024 if (rss_hf & ETH_RSS_IPV6)
1025 dev_rss_conf->hashType |= VMXNET3_RSS_HASH_TYPE_IPV6;
1026 if (rss_hf & ETH_RSS_IPV6_TCP)
1027 dev_rss_conf->hashType |= VMXNET3_RSS_HASH_TYPE_TCP_IPV6;
1029 return VMXNET3_SUCCESS;
1033 * Configure VLAN Filter feature
1036 vmxnet3_vlan_configure(struct rte_eth_dev *dev)
1039 struct vmxnet3_hw *hw = dev->data->dev_private;
1040 uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
1042 PMD_INIT_FUNC_TRACE();
1044 /* Verify if this tag is already set */
1045 for (i = 0; i < VMXNET3_VFT_SIZE; i++) {
1046 /* Filter all vlan tags out by default */
1048 /* To-Do: Provide another routine in dev_ops for user config */
1050 PMD_INIT_LOG(DEBUG, "Registering VLAN portid: %"PRIu8" tag %u",
1051 dev->data->port_id, vf_table[i]);
1054 return VMXNET3_SUCCESS;