ethdev: add device type
[dpdk.git] / lib / librte_ether / rte_ethdev.h
index aacd75b..25e0abd 100644 (file)
@@ -351,97 +351,70 @@ struct rte_eth_rss_conf {
        uint64_t rss_hf;     /**< Hash functions to apply - see below. */
 };
 
-/* Supported RSS offloads */
-/* for 1G & 10G */
-#define ETH_RSS_IPV4_SHIFT                    0
-#define ETH_RSS_IPV4_TCP_SHIFT                1
-#define ETH_RSS_IPV6_SHIFT                    2
-#define ETH_RSS_IPV6_EX_SHIFT                 3
-#define ETH_RSS_IPV6_TCP_SHIFT                4
-#define ETH_RSS_IPV6_TCP_EX_SHIFT             5
-#define ETH_RSS_IPV4_UDP_SHIFT                6
-#define ETH_RSS_IPV6_UDP_SHIFT                7
-#define ETH_RSS_IPV6_UDP_EX_SHIFT             8
-/* for 40G only */
-#define ETH_RSS_NONF_IPV4_UDP_SHIFT           31
-#define ETH_RSS_NONF_IPV4_TCP_SHIFT           33
-#define ETH_RSS_NONF_IPV4_SCTP_SHIFT          34
-#define ETH_RSS_NONF_IPV4_OTHER_SHIFT         35
-#define ETH_RSS_FRAG_IPV4_SHIFT               36
-#define ETH_RSS_NONF_IPV6_UDP_SHIFT           41
-#define ETH_RSS_NONF_IPV6_TCP_SHIFT           43
-#define ETH_RSS_NONF_IPV6_SCTP_SHIFT          44
-#define ETH_RSS_NONF_IPV6_OTHER_SHIFT         45
-#define ETH_RSS_FRAG_IPV6_SHIFT               46
-#define ETH_RSS_FCOE_OX_SHIFT                 48
-#define ETH_RSS_FCOE_RX_SHIFT                 49
-#define ETH_RSS_FCOE_OTHER_SHIFT              50
-#define ETH_RSS_L2_PAYLOAD_SHIFT              63
-
-/* for 1G & 10G */
-#define ETH_RSS_IPV4                    (1 << ETH_RSS_IPV4_SHIFT)
-#define ETH_RSS_IPV4_TCP                (1 << ETH_RSS_IPV4_TCP_SHIFT)
-#define ETH_RSS_IPV6                    (1 << ETH_RSS_IPV6_SHIFT)
-#define ETH_RSS_IPV6_EX                 (1 << ETH_RSS_IPV6_EX_SHIFT)
-#define ETH_RSS_IPV6_TCP                (1 << ETH_RSS_IPV6_TCP_SHIFT)
-#define ETH_RSS_IPV6_TCP_EX             (1 << ETH_RSS_IPV6_TCP_EX_SHIFT)
-#define ETH_RSS_IPV4_UDP                (1 << ETH_RSS_IPV4_UDP_SHIFT)
-#define ETH_RSS_IPV6_UDP                (1 << ETH_RSS_IPV6_UDP_SHIFT)
-#define ETH_RSS_IPV6_UDP_EX             (1 << ETH_RSS_IPV6_UDP_EX_SHIFT)
-/* for 40G only */
-#define ETH_RSS_NONF_IPV4_UDP           (1ULL << ETH_RSS_NONF_IPV4_UDP_SHIFT)
-#define ETH_RSS_NONF_IPV4_TCP           (1ULL << ETH_RSS_NONF_IPV4_TCP_SHIFT)
-#define ETH_RSS_NONF_IPV4_SCTP          (1ULL << ETH_RSS_NONF_IPV4_SCTP_SHIFT)
-#define ETH_RSS_NONF_IPV4_OTHER         (1ULL << ETH_RSS_NONF_IPV4_OTHER_SHIFT)
-#define ETH_RSS_FRAG_IPV4               (1ULL << ETH_RSS_FRAG_IPV4_SHIFT)
-#define ETH_RSS_NONF_IPV6_UDP           (1ULL << ETH_RSS_NONF_IPV6_UDP_SHIFT)
-#define ETH_RSS_NONF_IPV6_TCP           (1ULL << ETH_RSS_NONF_IPV6_TCP_SHIFT)
-#define ETH_RSS_NONF_IPV6_SCTP          (1ULL << ETH_RSS_NONF_IPV6_SCTP_SHIFT)
-#define ETH_RSS_NONF_IPV6_OTHER         (1ULL << ETH_RSS_NONF_IPV6_OTHER_SHIFT)
-#define ETH_RSS_FRAG_IPV6               (1ULL << ETH_RSS_FRAG_IPV6_SHIFT)
-/* FCOE relevant should not be used */
-#define ETH_RSS_FCOE_OX                 (1ULL << ETH_RSS_FCOE_OX_SHIFT)
-#define ETH_RSS_FCOE_RX                 (1ULL << ETH_RSS_FCOE_RX_SHIFT)
-#define ETH_RSS_FCOE_OTHER              (1ULL << ETH_RSS_FCOE_OTHER_SHIFT)
-#define ETH_RSS_L2_PAYLOAD              (1ULL << ETH_RSS_L2_PAYLOAD_SHIFT)
+/*
+ * The RSS offload types are defined based on flow types which are defined
+ * in rte_eth_ctrl.h. Different NIC hardwares may support different RSS offload
+ * types. The supported flow types or RSS offload types can be queried by
+ * rte_eth_dev_info_get().
+ */
+#define ETH_RSS_IPV4               (1ULL << RTE_ETH_FLOW_IPV4)
+#define ETH_RSS_FRAG_IPV4          (1ULL << RTE_ETH_FLOW_FRAG_IPV4)
+#define ETH_RSS_NONFRAG_IPV4_TCP   (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_TCP)
+#define ETH_RSS_NONFRAG_IPV4_UDP   (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_UDP)
+#define ETH_RSS_NONFRAG_IPV4_SCTP  (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP)
+#define ETH_RSS_NONFRAG_IPV4_OTHER (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER)
+#define ETH_RSS_IPV6               (1ULL << RTE_ETH_FLOW_IPV6)
+#define ETH_RSS_FRAG_IPV6          (1ULL << RTE_ETH_FLOW_FRAG_IPV6)
+#define ETH_RSS_NONFRAG_IPV6_TCP   (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_TCP)
+#define ETH_RSS_NONFRAG_IPV6_UDP   (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_UDP)
+#define ETH_RSS_NONFRAG_IPV6_SCTP  (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP)
+#define ETH_RSS_NONFRAG_IPV6_OTHER (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER)
+#define ETH_RSS_L2_PAYLOAD         (1ULL << RTE_ETH_FLOW_L2_PAYLOAD)
+#define ETH_RSS_IPV6_EX            (1ULL << RTE_ETH_FLOW_IPV6_EX)
+#define ETH_RSS_IPV6_TCP_EX        (1ULL << RTE_ETH_FLOW_IPV6_TCP_EX)
+#define ETH_RSS_IPV6_UDP_EX        (1ULL << RTE_ETH_FLOW_IPV6_UDP_EX)
 
 #define ETH_RSS_IP ( \
-               ETH_RSS_IPV4 | \
-               ETH_RSS_IPV6 | \
-               ETH_RSS_NONF_IPV4_OTHER | \
-               ETH_RSS_FRAG_IPV4 | \
-               ETH_RSS_NONF_IPV6_OTHER | \
-               ETH_RSS_FRAG_IPV6)
+       ETH_RSS_IPV4 | \
+       ETH_RSS_FRAG_IPV4 | \
+       ETH_RSS_NONFRAG_IPV4_OTHER | \
+       ETH_RSS_IPV6 | \
+       ETH_RSS_FRAG_IPV6 | \
+       ETH_RSS_NONFRAG_IPV6_OTHER | \
+       ETH_RSS_IPV6_EX)
+
 #define ETH_RSS_UDP ( \
-               ETH_RSS_IPV4 | \
-               ETH_RSS_IPV6 | \
-               ETH_RSS_IPV4_UDP | \
-               ETH_RSS_IPV6_UDP | \
-               ETH_RSS_IPV6_UDP_EX | \
-               ETH_RSS_NONF_IPV4_UDP | \
-               ETH_RSS_NONF_IPV6_UDP)
+       ETH_RSS_NONFRAG_IPV4_UDP | \
+       ETH_RSS_NONFRAG_IPV6_UDP | \
+       ETH_RSS_IPV6_UDP_EX)
+
+#define ETH_RSS_TCP ( \
+       ETH_RSS_NONFRAG_IPV4_TCP | \
+       ETH_RSS_NONFRAG_IPV6_TCP | \
+       ETH_RSS_IPV6_TCP_EX)
+
+#define ETH_RSS_SCTP ( \
+       ETH_RSS_NONFRAG_IPV4_SCTP | \
+       ETH_RSS_NONFRAG_IPV6_SCTP)
+
 /**< Mask of valid RSS hash protocols */
 #define ETH_RSS_PROTO_MASK ( \
-               ETH_RSS_IPV4 | \
-               ETH_RSS_IPV4_TCP | \
-               ETH_RSS_IPV6 | \
-               ETH_RSS_IPV6_EX | \
-               ETH_RSS_IPV6_TCP | \
-               ETH_RSS_IPV6_TCP_EX | \
-               ETH_RSS_IPV4_UDP | \
-               ETH_RSS_IPV6_UDP | \
-               ETH_RSS_IPV6_UDP_EX | \
-               ETH_RSS_NONF_IPV4_UDP | \
-               ETH_RSS_NONF_IPV4_TCP | \
-               ETH_RSS_NONF_IPV4_SCTP | \
-               ETH_RSS_NONF_IPV4_OTHER | \
-               ETH_RSS_FRAG_IPV4 | \
-               ETH_RSS_NONF_IPV6_UDP | \
-               ETH_RSS_NONF_IPV6_TCP | \
-               ETH_RSS_NONF_IPV6_SCTP | \
-               ETH_RSS_NONF_IPV6_OTHER | \
-               ETH_RSS_FRAG_IPV6 | \
-               ETH_RSS_L2_PAYLOAD)
+       ETH_RSS_IPV4 | \
+       ETH_RSS_FRAG_IPV4 | \
+       ETH_RSS_NONFRAG_IPV4_TCP | \
+       ETH_RSS_NONFRAG_IPV4_UDP | \
+       ETH_RSS_NONFRAG_IPV4_SCTP | \
+       ETH_RSS_NONFRAG_IPV4_OTHER | \
+       ETH_RSS_IPV6 | \
+       ETH_RSS_FRAG_IPV6 | \
+       ETH_RSS_NONFRAG_IPV6_TCP | \
+       ETH_RSS_NONFRAG_IPV6_UDP | \
+       ETH_RSS_NONFRAG_IPV6_SCTP | \
+       ETH_RSS_NONFRAG_IPV6_OTHER | \
+       ETH_RSS_L2_PAYLOAD | \
+       ETH_RSS_IPV6_EX | \
+       ETH_RSS_IPV6_TCP_EX | \
+       ETH_RSS_IPV6_UDP_EX)
 
 /*
  * Definitions used for redirection table entry size.
@@ -938,6 +911,8 @@ struct rte_eth_dev_info {
        uint32_t tx_offload_capa; /**< Device TX offload capabilities. */
        uint16_t reta_size;
        /**< Device redirection table size, the total number of entries. */
+       /** Bit mask of RSS offloads, the bit offset also means flow type */
+       uint64_t flow_type_rss_offloads;
        struct rte_eth_rxconf default_rxconf; /**< Default RX configuration */
        struct rte_eth_txconf default_txconf; /**< Default TX configuration */
        uint16_t vmdq_queue_base; /**< First queue ID for VMDQ pools. */
@@ -966,47 +941,6 @@ struct rte_eth_dev_callback;
 /** @internal Structure to keep track of registered callbacks */
 TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
 
-
-#define TCP_URG_FLAG 0x20
-#define TCP_UGR_FLAG 0x20
-#define TCP_ACK_FLAG 0x10
-#define TCP_PSH_FLAG 0x08
-#define TCP_RST_FLAG 0x04
-#define TCP_SYN_FLAG 0x02
-#define TCP_FIN_FLAG 0x01
-#define TCP_FLAG_ALL 0x3F
-
-/**
- *  A structure used to define a 2tuple filter.
- */
-struct rte_2tuple_filter {
-       uint16_t dst_port;        /**< big endian. */
-       uint8_t protocol;
-       uint8_t tcp_flags;
-       uint16_t priority;        /**< used when more than one filter matches. */
-       uint8_t dst_port_mask:1,  /**< if mask is 1b, means not compare. */
-               protocol_mask:1;
-};
-
-/**
- *  A structure used to define a 5tuple filter.
- */
-struct rte_5tuple_filter {
-       uint32_t dst_ip;         /**< destination IP address in big endian. */
-       uint32_t src_ip;         /**< source IP address in big endian. */
-       uint16_t dst_port;       /**< destination port in big endian. */
-       uint16_t src_port;       /**< source Port big endian. */
-       uint8_t protocol;        /**< l4 protocol. */
-       uint8_t tcp_flags;       /**< tcp flags. */
-       uint16_t priority;       /**< seven evels (001b-111b), 111b is highest,
-                                     used when more than one filter matches. */
-       uint8_t dst_ip_mask:1,   /**< if mask is 1b, do not compare dst ip. */
-               src_ip_mask:1,   /**< if mask is 1b, do not compare src ip. */
-               dst_port_mask:1, /**< if mask is 1b, do not compare dst port. */
-               src_port_mask:1, /**< if mask is 1b, do not compare src port. */
-               protocol_mask:1; /**< if mask is 1b, do not compare protocol. */
-};
-
 /*
  * Definitions of all functions exported by an Ethernet driver through the
  * the generic structure of type *eth_dev_ops* supplied in the *rte_eth_dev*
@@ -1342,34 +1276,6 @@ typedef int32_t (*bypass_ver_show_t)(struct rte_eth_dev *dev, uint32_t *ver);
 typedef int32_t (*bypass_wd_reset_t)(struct rte_eth_dev *dev);
 #endif
 
-typedef int (*eth_add_2tuple_filter_t)(struct rte_eth_dev *dev,
-                       uint16_t index, struct rte_2tuple_filter *filter,
-                       uint16_t rx_queue);
-/**< @internal Setup a new 2tuple filter rule on an Ethernet device */
-
-typedef int (*eth_remove_2tuple_filter_t)(struct rte_eth_dev *dev,
-                       uint16_t index);
-/**< @internal Remove a 2tuple filter rule on an Ethernet device */
-
-typedef int (*eth_get_2tuple_filter_t)(struct rte_eth_dev *dev,
-                       uint16_t index, struct rte_2tuple_filter *filter,
-                       uint16_t *rx_queue);
-/**< @internal Get a 2tuple filter rule on an Ethernet device */
-
-typedef int (*eth_add_5tuple_filter_t)(struct rte_eth_dev *dev,
-                       uint16_t index, struct rte_5tuple_filter *filter,
-                       uint16_t rx_queue);
-/**< @internal Setup a new 5tuple filter rule on an Ethernet device */
-
-typedef int (*eth_remove_5tuple_filter_t)(struct rte_eth_dev *dev,
-                       uint16_t index);
-/**< @internal Remove a 5tuple filter rule on an Ethernet device */
-
-typedef int (*eth_get_5tuple_filter_t)(struct rte_eth_dev *dev,
-                       uint16_t index, struct rte_5tuple_filter *filter,
-                       uint16_t *rx_queue);
-/**< @internal Get a 5tuple filter rule on an Ethernet device */
-
 typedef int (*eth_filter_ctrl_t)(struct rte_eth_dev *dev,
                                 enum rte_filter_type filter_type,
                                 enum rte_filter_op filter_op,
@@ -1472,15 +1378,61 @@ struct eth_dev_ops {
        rss_hash_update_t rss_hash_update;
        /** Get current RSS hash configuration. */
        rss_hash_conf_get_t rss_hash_conf_get;
-       eth_add_2tuple_filter_t        add_2tuple_filter;    /**< add 2tuple filter. */
-       eth_remove_2tuple_filter_t     remove_2tuple_filter; /**< remove 2tuple filter. */
-       eth_get_2tuple_filter_t        get_2tuple_filter;    /**< get 2tuple filter. */
-       eth_add_5tuple_filter_t        add_5tuple_filter;    /**< add 5tuple filter. */
-       eth_remove_5tuple_filter_t     remove_5tuple_filter; /**< remove 5tuple filter. */
-       eth_get_5tuple_filter_t        get_5tuple_filter;    /**< get 5tuple filter. */
        eth_filter_ctrl_t              filter_ctrl;          /**< common filter control*/
 };
 
+/**
+ * Function type used for callbacks for processing packets on RX and TX
+ *
+ * If configured for RX, it is called with a burst of packets that have just
+ * been received on the given port and queue. On TX, it is called with a burst
+ * of packets immediately before those packets are put onto the hardware queue
+ * for transmission.
+ *
+ * @param port
+ *   The ethernet port on which rx or tx is being performed
+ * @param queue
+ *   The queue on the ethernet port which is being used to receive or transmit
+ *   the packets.
+ * @param pkts
+ *   The burst of packets on which processing is to be done. On RX, these
+ *   packets have just been received. On TX, they are about to be transmitted.
+ * @param nb_pkts
+ *   The number of packets in the burst pointed to by "pkts"
+ * @param user_param
+ *   The arbitrary user parameter passed in by the application when the callback
+ *   was originally configured.
+ * @return
+ *   The number of packets remaining in pkts are processing.
+ *     * On RX, this will be returned to the user as the return value from
+ *       rte_eth_rx_burst.
+ *     * On TX, this will be the number of packets actually written to the NIC.
+ */
+typedef uint16_t (*rte_rxtx_callback_fn)(uint8_t port, uint16_t queue,
+       struct rte_mbuf *pkts[], uint16_t nb_pkts, void *user_param);
+
+/**
+ * @internal
+ * Structure used to hold information about the callbacks to be called for a
+ * queue on RX and TX.
+ */
+struct rte_eth_rxtx_callback {
+       struct rte_eth_rxtx_callback *next;
+       rte_rxtx_callback_fn fn;
+       void *param;
+};
+
+/*
+ * The eth device type
+ */
+enum rte_eth_dev_type {
+       RTE_ETH_DEV_UNKNOWN,    /**< unknown device type */
+       RTE_ETH_DEV_PCI,
+               /**< Physical function and Virtual function of PCI devices */
+       RTE_ETH_DEV_VIRTUAL,    /**< non hardware device */
+       RTE_ETH_DEV_MAX         /**< max value of this enum */
+};
+
 /**
  * @internal
  * The generic data structure associated with each ethernet device.
@@ -1498,7 +1450,20 @@ struct rte_eth_dev {
        const struct eth_driver *driver;/**< Driver for this device */
        struct eth_dev_ops *dev_ops;    /**< Functions exported by PMD */
        struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
-       struct rte_eth_dev_cb_list callbacks; /**< User application callbacks */
+       /** User application callbacks for NIC interrupts */
+       struct rte_eth_dev_cb_list link_intr_cbs;
+       /**
+        * User-supplied functions called from rx_burst to post-process
+        * received packets before passing them to the user
+        */
+       struct rte_eth_rxtx_callback **post_rx_burst_cbs;
+       /**
+        * User-supplied functions called from tx_burst to pre-process
+        * received packets before passing them to the driver for transmission.
+        */
+       struct rte_eth_rxtx_callback **pre_tx_burst_cbs;
+       uint8_t attached; /**< Flag indicating the port is attached */
+       enum rte_eth_dev_type dev_type; /**< Flag indicating the device type */
 };
 
 struct rte_eth_dev_sriov {
@@ -1563,7 +1528,11 @@ extern struct rte_eth_dev rte_eth_devices[];
  * Get the total number of Ethernet devices that have been successfully
  * initialized by the [matching] Ethernet driver during the PCI probing phase.
  * All devices whose port identifier is in the range
- * [0,  rte_eth_dev_count() - 1] can be operated on by network applications.
+ * [0,  rte_eth_dev_count() - 1] can be operated on by network applications
+ * immediately after invoking rte_eal_init().
+ * If the application unplugs a port using hotplug function, The enabled port
+ * numbers may be noncontiguous. In the case, the applications need to manage
+ * enabled port by themselves.
  *
  * @return
  *   - The total number of usable Ethernet devices.
@@ -1577,10 +1546,24 @@ extern uint8_t rte_eth_dev_count(void);
  * to that slot for the driver to use.
  *
  * @param      name    Unique identifier name for each Ethernet device
+ * @param      type    Device type of this Ethernet device
  * @return
  *   - Slot in the rte_dev_devices array for a new device;
  */
-struct rte_eth_dev *rte_eth_dev_allocate(const char *name);
+struct rte_eth_dev *rte_eth_dev_allocate(const char *name,
+               enum rte_eth_dev_type type);
+
+/**
+ * Function for internal use by dummy drivers primarily, e.g. ring-based
+ * driver.
+ * Release the specified ethdev port.
+ *
+ * @param eth_dev
+ * The *eth_dev* pointer is the address of the *rte_eth_dev* structure.
+ * @return
+ *   - 0 on success, negative on error
+ */
+int rte_eth_dev_release_port(struct rte_eth_dev *eth_dev);
 
 struct eth_driver;
 /**
@@ -1617,6 +1600,27 @@ struct eth_driver;
 typedef int (*eth_dev_init_t)(struct eth_driver  *eth_drv,
                              struct rte_eth_dev *eth_dev);
 
+/**
+ * @internal
+ * Finalization function of an Ethernet driver invoked for each matching
+ * Ethernet PCI device detected during the PCI closing phase.
+ *
+ * @param eth_drv
+ *   The pointer to the [matching] Ethernet driver structure supplied by
+ *   the PMD when it registered itself.
+ * @param eth_dev
+ *   The *eth_dev* pointer is the address of the *rte_eth_dev* structure
+ *   associated with the matching device and which have been [automatically]
+ *   allocated in the *rte_eth_devices* array.
+ * @return
+ *   - 0: Success, the device is properly finalized by the driver.
+ *        In particular, the driver MUST free the *dev_ops* pointer
+ *        of the *eth_dev* structure.
+ *   - <0: Error code of the device initialization failure.
+ */
+typedef int (*eth_dev_uninit_t)(const struct eth_driver  *eth_drv,
+                                 struct rte_eth_dev *eth_dev);
+
 /**
  * @internal
  * The structure associated with a PMD Ethernet driver.
@@ -1628,11 +1632,14 @@ typedef int (*eth_dev_init_t)(struct eth_driver  *eth_drv,
  *
  * - The *eth_dev_init* function invoked for each matching PCI device.
  *
+ * - The *eth_dev_uninit* function invoked for each matching PCI device.
+ *
  * - The size of the private data to allocate for each matching device.
  */
 struct eth_driver {
        struct rte_pci_driver pci_drv;    /**< The PMD is also a PCI driver. */
        eth_dev_init_t eth_dev_init;      /**< Device init function. */
+       eth_dev_uninit_t eth_dev_uninit;  /**< Device uninit function. */
        unsigned int dev_private_size;    /**< Size of device private data. */
 };
 
@@ -2352,7 +2359,23 @@ rte_eth_rx_burst(uint8_t port_id, uint16_t queue_id,
        struct rte_eth_dev *dev;
 
        dev = &rte_eth_devices[port_id];
-       return (*dev->rx_pkt_burst)(dev->data->rx_queues[queue_id], rx_pkts, nb_pkts);
+
+       nb_pkts = (*dev->rx_pkt_burst)(dev->data->rx_queues[queue_id], rx_pkts,
+                       nb_pkts);
+
+#ifdef RTE_ETHDEV_RXTX_CALLBACKS
+       struct rte_eth_rxtx_callback *cb = dev->post_rx_burst_cbs[queue_id];
+
+       if (unlikely(cb != NULL)) {
+               do {
+                       nb_pkts = cb->fn(port_id, queue_id, rx_pkts, nb_pkts,
+                                       cb->param);
+                       cb = cb->next;
+               } while (cb != NULL);
+       }
+#endif
+
+       return nb_pkts;
 }
 #endif
 
@@ -2479,6 +2502,19 @@ rte_eth_tx_burst(uint8_t port_id, uint16_t queue_id,
        struct rte_eth_dev *dev;
 
        dev = &rte_eth_devices[port_id];
+
+#ifdef RTE_ETHDEV_RXTX_CALLBACKS
+       struct rte_eth_rxtx_callback *cb = dev->pre_tx_burst_cbs[queue_id];
+
+       if (unlikely(cb != NULL)) {
+               do {
+                       nb_pkts = cb->fn(port_id, queue_id, tx_pkts, nb_pkts,
+                                       cb->param);
+                       cb = cb->next;
+               } while (cb != NULL);
+       }
+#endif
+
        return (*dev->tx_pkt_burst)(dev->data->tx_queues[queue_id], tx_pkts, nb_pkts);
 }
 #endif
@@ -3363,162 +3399,157 @@ int
 rte_eth_dev_udp_tunnel_delete(uint8_t port_id,
                              struct rte_eth_udp_tunnel *tunnel_udp);
 
-
 /**
- * Add a new 2tuple filter rule on an Ethernet device.
+ * Check whether the filter type is supported on an Ethernet device.
+ * All the supported filter types are defined in 'rte_eth_ctrl.h'.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 2tuple filter.
- * @param filter
- *   The pointer to the structure describing the 2tuple filter rule.
- *   The *rte_2tuple_filter* structure includes the values of the different
- *   fields to match: protocol, dst_port and
- *   tcp_flags if the protocol is tcp type.
- * @param rx_queue
- *   The index of the RX queue where to store RX packets matching the added
- *   2tuple filter.
+ * @param filter_type
+ *   Filter type.
  * @return
  *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 2tuple filter.
+ *   - (-ENOTSUP) if hardware doesn't support this filter type.
  *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
  */
-int rte_eth_dev_add_2tuple_filter(uint8_t port_id, uint16_t index,
-                       struct rte_2tuple_filter *filter, uint16_t rx_queue);
+int rte_eth_dev_filter_supported(uint8_t port_id, enum rte_filter_type filter_type);
 
 /**
- * remove a 2tuple filter rule on an Ethernet device.
+ * Take operations to assigned filter type on an Ethernet device.
+ * All the supported operations and filter types are defined in 'rte_eth_ctrl.h'.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 2tuple filter.
+ * @param filter_type
+ *   Filter type.
+ * @param filter_op
+ *   Type of operation.
+ * @param arg
+ *   A pointer to arguments defined specifically for the operation.
  * @return
  *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 2tuple filter.
+ *   - (-ENOTSUP) if hardware doesn't support.
  *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
+ *   - others depends on the specific operations implementation.
  */
-int rte_eth_dev_remove_2tuple_filter(uint8_t port_id, uint16_t index);
+int rte_eth_dev_filter_ctrl(uint8_t port_id, enum rte_filter_type filter_type,
+                       enum rte_filter_op filter_op, void *arg);
 
 /**
- * Get an 2tuple filter rule on an Ethernet device.
+ * Add a callback to be called on packet RX on a given port and queue.
  *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 2tuple filter.
- * @param filter
- *   A pointer to a structure of type *rte_2tuple_filter* to be filled with
- *   the information of the 2tuple filter.
- * @param rx_queue
- *   A pointer to get the queue index.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 2tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- *   - (-ENOENT) if no enabled filter in this index.
- */
-int rte_eth_dev_get_2tuple_filter(uint8_t port_id, uint16_t index,
-                       struct rte_2tuple_filter *filter, uint16_t *rx_queue);
-
-/**
- * Add a new 5tuple filter rule on an Ethernet device.
+ * This API configures a function to be called for each burst of
+ * packets received on a given NIC port queue. The return value is a pointer
+ * that can be used to later remove the callback using
+ * rte_eth_remove_rx_callback().
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 5tuple filter.
- * @param filter
- *   The pointer to the structure describing the 5tuple filter rule.
- *   The *rte_5tuple_filter* structure includes the values of the different
- *   fields to match: dst src IP, dst src port, protocol and relative masks
- * @param rx_queue
- *   The index of the RX queue where to store RX packets matching the added
- *   5tuple filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 5tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_add_5tuple_filter(uint8_t port_id, uint16_t index,
-                       struct rte_5tuple_filter *filter, uint16_t rx_queue);
-
-/**
- * remove a 5tuple filter rule on an Ethernet device.
+ * @param queue_id
+ *   The queue on the Ethernet device on which the callback is to be added.
+ * @param fn
+ *   The callback function
+ * @param user_param
+ *   A generic pointer parameter which will be passed to each invocation of the
+ *   callback function on this port and queue.
  *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 5tuple filter.
  * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 5tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
+ *   NULL on error.
+ *   On success, a pointer value which can later be used to remove the callback.
  */
-int rte_eth_dev_remove_5tuple_filter(uint8_t port_id, uint16_t index);
+void *rte_eth_add_rx_callback(uint8_t port_id, uint16_t queue_id,
+               rte_rxtx_callback_fn fn, void *user_param);
 
 /**
- * Get an 5tuple filter rule on an Ethernet device.
+ * Add a callback to be called on packet TX on a given port and queue.
+ *
+ * This API configures a function to be called for each burst of
+ * packets sent on a given NIC port queue. The return value is a pointer
+ * that can be used to later remove the callback using
+ * rte_eth_remove_tx_callback().
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 5tuple filter.
- * @param filter
- *   A pointer to a structure of type *rte_5tuple_filter* to be filled with
- *   the information of the 5tuple filter.
- * @param rx_queue
- *   A pointer to get the queue index.
+ * @param queue_id
+ *   The queue on the Ethernet device on which the callback is to be added.
+ * @param fn
+ *   The callback function
+ * @param user_param
+ *   A generic pointer parameter which will be passed to each invocation of the
+ *   callback function on this port and queue.
+ *
  * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 5tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
+ *   NULL on error.
+ *   On success, a pointer value which can later be used to remove the callback.
  */
-int rte_eth_dev_get_5tuple_filter(uint8_t port_id, uint16_t index,
-                       struct rte_5tuple_filter *filter, uint16_t *rx_queue);
+void *rte_eth_add_tx_callback(uint8_t port_id, uint16_t queue_id,
+               rte_rxtx_callback_fn fn, void *user_param);
 
 /**
- * Check whether the filter type is supported on an Ethernet device.
- * All the supported filter types are defined in 'rte_eth_ctrl.h'.
+ * Remove an RX packet callback from a given port and queue.
+ *
+ * This function is used to removed callbacks that were added to a NIC port
+ * queue using rte_eth_add_rx_callback().
+ *
+ * Note: the callback is removed from the callback list but it isn't freed
+ * since the it may still be in use. The memory for the callback can be
+ * subsequently freed back by the application by calling rte_free():
+ *
+ *  - Immediately - if the port is stopped, or the user knows that no
+ *    callbacks are in flight e.g. if called from the thread doing RX/TX
+ *    on that queue.
+ *
+ * - After a short delay - where the delay is sufficient to allow any
+ *   in-flight callbacks to complete.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
- * @param filter_type
- *   Filter type.
+ * @param queue_id
+ *   The queue on the Ethernet device from which the callback is to be removed.
+ * @param user_cb
+ *   User supplied callback created via rte_eth_add_rx_callback().
+ *
  * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support this filter type.
- *   - (-ENODEV) if *port_id* invalid.
+ *   - 0: Success. Callback was removed.
+ *   - -ENOTSUP: Callback support is not available.
+ *   - -EINVAL:  The port_id or the queue_id is out of range, or the callback
+ *               is NULL or not found for the port/queue.
  */
-int rte_eth_dev_filter_supported(uint8_t port_id, enum rte_filter_type filter_type);
+int rte_eth_remove_rx_callback(uint8_t port_id, uint16_t queue_id,
+               struct rte_eth_rxtx_callback *user_cb);
 
 /**
- * Take operations to assigned filter type on an Ethernet device.
- * All the supported operations and filter types are defined in 'rte_eth_ctrl.h'.
+ * Remove a TX packet callback from a given port and queue.
+ *
+ * This function is used to removed callbacks that were added to a NIC port
+ * queue using rte_eth_add_tx_callback().
+ *
+ * Note: the callback is removed from the callback list but it isn't freed
+ * since the it may still be in use. The memory for the callback can be
+ * subsequently freed back by the application by calling rte_free():
+ *
+ *  - Immediately - if the port is stopped, or the user knows that no
+ *    callbacks are in flight e.g. if called from the thread doing RX/TX
+ *    on that queue.
+ *
+ * - After a short delay - where the delay is sufficient to allow any
+ *   in-flight callbacks to complete.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
- * @param filter_type
- *   Filter type.
- * @param filter_op
- *   Type of operation.
- * @param arg
- *   A pointer to arguments defined specifically for the operation.
+ * @param queue_id
+ *   The queue on the Ethernet device from which the callback is to be removed.
+ * @param user_cb
+ *   User supplied callback created via rte_eth_add_tx_callback().
+ *
  * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support.
- *   - (-ENODEV) if *port_id* invalid.
- *   - others depends on the specific operations implementation.
+ *   - 0: Success. Callback was removed.
+ *   - -ENOTSUP: Callback support is not available.
+ *   - -EINVAL:  The port_id or the queue_id is out of range, or the callback
+ *               is NULL or not found for the port/queue.
  */
-int rte_eth_dev_filter_ctrl(uint8_t port_id, enum rte_filter_type filter_type,
-                       enum rte_filter_op filter_op, void *arg);
+int rte_eth_remove_tx_callback(uint8_t port_id, uint16_t queue_id,
+               struct rte_eth_rxtx_callback *user_cb);
 
 #ifdef __cplusplus
 }