When using the null driver it is useful to be able to
provide a set of mbufs to be received on the interface.
Add an option to specify a ring that the driver can poll to
provide the set of packets that have been received.  Add a
similar ring for the tx side where the packets that are being
transmitted can be stored, so the user can see what was sent.

Signed-off-by: Paul Atkins <patkins at brocade.com>
---
 drivers/net/null/rte_eth_null.c |   91 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 88 insertions(+), 3 deletions(-)

diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 9483d6a..176f477 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -47,6 +47,8 @@
 #define ETH_NULL_PACKET_SIZE_ARG       "size"
 #define ETH_NULL_PACKET_COPY_ARG       "copy"
 #define ETH_NULL_ETH_ADDR_ARG          "eth_addr"
+#define ETH_NULL_RX_RING               "rx_ring"
+#define ETH_NULL_TX_RING               "tx_ring"

 static unsigned default_packet_size = 64;
 static unsigned default_packet_copy;
@@ -56,6 +58,8 @@ static const char *valid_arguments[] = {
        ETH_NULL_PACKET_SIZE_ARG,
        ETH_NULL_PACKET_COPY_ARG,
        ETH_NULL_ETH_ADDR_ARG,
+       ETH_NULL_RX_RING,
+       ETH_NULL_TX_RING,
        NULL
 };

@@ -76,6 +80,8 @@ struct pmd_internals {
        unsigned packet_size;
        unsigned packet_copy;
        struct ether_addr eth_addr;
+       struct rte_ring *rx_ring;
+       struct rte_ring *tx_ring;
        unsigned numa_node;

        unsigned nb_rx_queues;
@@ -158,6 +164,22 @@ eth_null_copy_rx(void *q, struct rte_mbuf **bufs, uint16_t 
nb_bufs)
 }

 static uint16_t
+eth_null_copy_rx_from_ring(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
+{
+       int i;
+       struct null_queue *h = q;
+
+       if ((q == NULL) || (bufs == NULL) || (nb_bufs == 0))
+               return 0;
+
+       i = rte_ring_mc_dequeue_burst(h->internals->rx_ring, (void **)bufs,
+                                     nb_bufs);
+       rte_atomic64_add(&h->rx_pkts, 1);
+
+       return i;
+}
+
+static uint16_t
 eth_null_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
 {
        int i;
@@ -196,6 +218,23 @@ eth_null_copy_tx(void *q, struct rte_mbuf **bufs, uint16_t 
nb_bufs)
        return i;
 }

+static uint16_t
+eth_null_copy_tx_to_ring(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
+{
+       int i;
+       struct null_queue *h = q;
+
+       if ((q == NULL) || (bufs == NULL) || (nb_bufs == 0))
+               return 0;
+
+       i = rte_ring_enqueue_burst(h->internals->tx_ring, (void **)bufs,
+                                  nb_bufs);
+
+       rte_atomic64_add(&h->tx_pkts, 1);
+
+       return i;
+}
+
 static int
 eth_dev_configure(struct rte_eth_dev *dev) {
        struct pmd_internals *internals;
@@ -495,7 +534,11 @@ eth_dev_null_create_internal(const char *name,
                             const unsigned numa_node,
                             unsigned packet_size,
                             unsigned packet_copy,
-                            struct ether_addr eth_addr)
+                            struct ether_addr eth_addr,
+                            struct rte_ring *rx_ring,
+                            struct rte_ring *tx_ring
+
+       )
 {
        const unsigned nb_rx_queues = 1;
        const unsigned nb_tx_queues = 1;
@@ -546,6 +589,8 @@ eth_dev_null_create_internal(const char *name,
        internals->packet_size = packet_size;
        internals->packet_copy = packet_copy;
        internals->eth_addr = eth_addr;
+       internals->rx_ring = rx_ring;
+       internals->tx_ring = tx_ring;
        internals->numa_node = numa_node;

        internals->flow_type_rss_offloads =  ETH_RSS_PROTO_MASK;
@@ -580,6 +625,10 @@ eth_dev_null_create_internal(const char *name,
                eth_dev->rx_pkt_burst = eth_null_rx;
                eth_dev->tx_pkt_burst = eth_null_tx;
        }
+       if (rx_ring)
+               eth_dev->rx_pkt_burst = eth_null_copy_rx_from_ring;
+       if (tx_ring)
+               eth_dev->tx_pkt_burst = eth_null_copy_tx_to_ring;

        return 0;

@@ -597,7 +646,8 @@ eth_dev_null_create(const char *name,
                unsigned packet_copy)
 {
        return eth_dev_null_create_internal(name, numa_node, packet_size,
-                                           packet_copy, default_eth_addr);
+                                           packet_copy, default_eth_addr,
+                                           NULL, NULL);
 }

 static inline int
@@ -645,6 +695,23 @@ get_eth_addr_arg(const char *key __rte_unused,
                                       sizeof(struct ether_addr));
 }

+static inline int
+get_ring_arg(const char *key __rte_unused,
+            const char *value, void *extra_args)
+{
+       const char *a = value;
+       struct rte_ring **ring = extra_args;
+
+       if ((value == NULL) || (extra_args == NULL))
+               return -EINVAL;
+
+       *ring = rte_ring_create(a, 64, SOCKET_ID_ANY, 0);
+       if (*ring == NULL)
+               return -1;
+
+       return 0;
+}
+
 static int
 rte_pmd_null_devinit(const char *name, const char *params)
 {
@@ -652,6 +719,8 @@ rte_pmd_null_devinit(const char *name, const char *params)
        unsigned packet_size = default_packet_size;
        unsigned packet_copy = default_packet_copy;
        struct ether_addr eth_addr = default_eth_addr;
+       struct rte_ring *rx_ring = NULL;
+       struct rte_ring *tx_ring = NULL;
        struct rte_kvargs *kvlist = NULL;
        int ret;

@@ -691,6 +760,21 @@ rte_pmd_null_devinit(const char *name, const char *params)
                                goto free_kvlist;
                }

+               if (rte_kvargs_count(kvlist, ETH_NULL_RX_RING) == 1) {
+                       ret = rte_kvargs_process(kvlist,
+                                                ETH_NULL_RX_RING,
+                                                &get_ring_arg, &rx_ring);
+                       if (ret < 0)
+                               goto free_kvlist;
+               }
+
+               if (rte_kvargs_count(kvlist, ETH_NULL_TX_RING) == 1) {
+                       ret = rte_kvargs_process(kvlist,
+                                                ETH_NULL_TX_RING,
+                                                &get_ring_arg, &tx_ring);
+                       if (ret < 0)
+                               goto free_kvlist;
+               }
        }

        RTE_LOG(INFO, PMD, "Configure pmd_null: packet size is %d, "
@@ -698,7 +782,8 @@ rte_pmd_null_devinit(const char *name, const char *params)
                        packet_copy ? "enabled" : "disabled");

        ret = eth_dev_null_create_internal(name, numa_node, packet_size,
-                                          packet_copy, eth_addr);
+                                          packet_copy, eth_addr, rx_ring,
+                                          tx_ring);

 free_kvlist:
        if (kvlist)
-- 
1.7.10.4

Reply via email to