mlx4: allow operation in secondary processes
[dpdk.git] / drivers / net / virtio / virtio_rxtx.c
index 4fd7546..5770fa2 100644 (file)
@@ -53,6 +53,7 @@
 
 #include "virtio_logs.h"
 #include "virtio_ethdev.h"
+#include "virtio_pci.h"
 #include "virtqueue.h"
 #include "virtio_rxtx.h"
 
 #define  VIRTIO_DUMP_PACKET(m, len) do { } while (0)
 #endif
 
+
+#define VIRTIO_SIMPLE_FLAGS ((uint32_t)ETH_TXQ_FLAGS_NOMULTSEGS | \
+       ETH_TXQ_FLAGS_NOOFFLOADS)
+
 static int use_simple_rxtx;
 
 static void
@@ -432,6 +437,9 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
        vq->mpool = mp;
 
        dev->data->rx_queues[queue_idx] = vq;
+
+       virtio_rxq_vec_setup(vq);
+
        return 0;
 }
 
@@ -456,6 +464,7 @@ virtio_dev_tx_queue_setup(struct rte_eth_dev *dev,
                        const struct rte_eth_txconf *tx_conf)
 {
        uint8_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_TQ_QUEUE_IDX;
+       struct virtio_hw *hw = dev->data->dev_private;
        struct virtqueue *vq;
        uint16_t tx_free_thresh;
        int ret;
@@ -468,6 +477,15 @@ virtio_dev_tx_queue_setup(struct rte_eth_dev *dev,
                return -EINVAL;
        }
 
+       /* Use simple rx/tx func if single segment and no offloads */
+       if ((tx_conf->txq_flags & VIRTIO_SIMPLE_FLAGS) == VIRTIO_SIMPLE_FLAGS &&
+            !vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
+               PMD_INIT_LOG(INFO, "Using simple rx/tx path");
+               dev->tx_pkt_burst = virtio_xmit_pkts_simple;
+               dev->rx_pkt_burst = virtio_recv_pkts_vec;
+               use_simple_rxtx = 1;
+       }
+
        ret = virtio_dev_queue_setup(dev, VTNET_TQ, queue_idx, vtpci_queue_idx,
                        nb_desc, socket_id, &vq);
        if (ret < 0) {
@@ -516,6 +534,34 @@ virtio_discard_rxbuf(struct virtqueue *vq, struct rte_mbuf *m)
        }
 }
 
+static void
+virtio_update_packet_stats(struct virtqueue *vq, struct rte_mbuf *mbuf)
+{
+       uint32_t s = mbuf->pkt_len;
+       struct ether_addr *ea;
+
+       if (s == 64) {
+               vq->size_bins[1]++;
+       } else if (s > 64 && s < 1024) {
+               uint32_t bin;
+
+               /* count zeros, and offset into correct bin */
+               bin = (sizeof(s) * 8) - __builtin_clz(s) - 5;
+               vq->size_bins[bin]++;
+       } else {
+               if (s < 64)
+                       vq->size_bins[0]++;
+               else if (s < 1519)
+                       vq->size_bins[6]++;
+               else if (s >= 1519)
+                       vq->size_bins[7]++;
+       }
+
+       ea = rte_pktmbuf_mtod(mbuf, struct ether_addr *);
+       vq->multicast += is_multicast_ether_addr(ea);
+       vq->broadcast += is_broadcast_ether_addr(ea);
+}
+
 #define VIRTIO_MBUF_BURST_SZ 64
 #define DESC_PER_CACHELINE (RTE_CACHE_LINE_SIZE / sizeof(struct vring_desc))
 uint16_t
@@ -577,7 +623,9 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
                VIRTIO_DUMP_PACKET(rxm, rxm->data_len);
 
                rx_pkts[nb_rx++] = rxm;
+
                rxvq->bytes += rx_pkts[nb_rx - 1]->pkt_len;
+               virtio_update_packet_stats(rxvq, rxm);
        }
 
        rxvq->packets += nb_rx;
@@ -740,6 +788,7 @@ virtio_recv_mergeable_pkts(void *rx_queue,
                        rx_pkts[nb_rx]->data_len);
 
                rxvq->bytes += rx_pkts[nb_rx]->pkt_len;
+               virtio_update_packet_stats(rxvq, rx_pkts[nb_rx]);
                nb_rx++;
        }
 
@@ -840,6 +889,7 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
                        }
                        nb_tx++;
                        txvq->bytes += txm->pkt_len;
+                       virtio_update_packet_stats(txvq, txm);
                } else {
                        PMD_TX_LOG(ERR, "No free tx descriptors to transmit");
                        break;