ethdev: move egress metadata to dynamic field
[dpdk.git] / lib / librte_ethdev / rte_ethdev.c
index e79de30..652c369 100644 (file)
@@ -10,6 +10,7 @@
 #include <string.h>
 #include <stdarg.h>
 #include <errno.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <inttypes.h>
 #include <netinet/in.h>
 #include <rte_spinlock.h>
 #include <rte_string_fns.h>
 #include <rte_kvargs.h>
+#include <rte_class.h>
+#include <rte_ether.h>
 
-#include "rte_ether.h"
 #include "rte_ethdev.h"
 #include "rte_ethdev_driver.h"
 #include "ethdev_profile.h"
+#include "ethdev_private.h"
 
-static int ethdev_logtype;
-
-#define ethdev_log(level, fmt, ...) \
-       rte_log(RTE_LOG_ ## level, ethdev_logtype, fmt "\n", ## __VA_ARGS__)
+int rte_eth_dev_logtype;
 
 static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";
 struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
-static uint8_t eth_dev_last_created_port;
 
 /* spinlock for eth device callbacks */
 static rte_spinlock_t rte_eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER;
@@ -124,10 +123,12 @@ static const struct {
        RTE_RX_OFFLOAD_BIT2STR(VLAN_FILTER),
        RTE_RX_OFFLOAD_BIT2STR(VLAN_EXTEND),
        RTE_RX_OFFLOAD_BIT2STR(JUMBO_FRAME),
-       RTE_RX_OFFLOAD_BIT2STR(CRC_STRIP),
        RTE_RX_OFFLOAD_BIT2STR(SCATTER),
        RTE_RX_OFFLOAD_BIT2STR(TIMESTAMP),
        RTE_RX_OFFLOAD_BIT2STR(SECURITY),
+       RTE_RX_OFFLOAD_BIT2STR(KEEP_CRC),
+       RTE_RX_OFFLOAD_BIT2STR(SCTP_CKSUM),
+       RTE_RX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM),
 };
 
 #undef RTE_RX_OFFLOAD_BIT2STR
@@ -157,6 +158,9 @@ static const struct {
        RTE_TX_OFFLOAD_BIT2STR(MULTI_SEGS),
        RTE_TX_OFFLOAD_BIT2STR(MBUF_FAST_FREE),
        RTE_TX_OFFLOAD_BIT2STR(SECURITY),
+       RTE_TX_OFFLOAD_BIT2STR(UDP_TNL_TSO),
+       RTE_TX_OFFLOAD_BIT2STR(IP_TNL_TSO),
+       RTE_TX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM),
 };
 
 #undef RTE_TX_OFFLOAD_BIT2STR
@@ -181,12 +185,151 @@ enum {
        STAT_QMAP_RX
 };
 
+int
+rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
+{
+       int ret;
+       struct rte_devargs devargs = {.args = NULL};
+       const char *bus_param_key;
+       char *bus_str = NULL;
+       char *cls_str = NULL;
+       int str_size;
+
+       memset(iter, 0, sizeof(*iter));
+
+       /*
+        * The devargs string may use various syntaxes:
+        *   - 0000:08:00.0,representor=[1-3]
+        *   - pci:0000:06:00.0,representor=[0,5]
+        *   - class=eth,mac=00:11:22:33:44:55
+        * A new syntax is in development (not yet supported):
+        *   - bus=X,paramX=x/class=Y,paramY=y/driver=Z,paramZ=z
+        */
+
+       /*
+        * Handle pure class filter (i.e. without any bus-level argument),
+        * from future new syntax.
+        * rte_devargs_parse() is not yet supporting the new syntax,
+        * that's why this simple case is temporarily parsed here.
+        */
+#define iter_anybus_str "class=eth,"
+       if (strncmp(devargs_str, iter_anybus_str,
+                       strlen(iter_anybus_str)) == 0) {
+               iter->cls_str = devargs_str + strlen(iter_anybus_str);
+               goto end;
+       }
+
+       /* Split bus, device and parameters. */
+       ret = rte_devargs_parse(&devargs, devargs_str);
+       if (ret != 0)
+               goto error;
+
+       /*
+        * Assume parameters of old syntax can match only at ethdev level.
+        * Extra parameters will be ignored, thanks to "+" prefix.
+        */
+       str_size = strlen(devargs.args) + 2;
+       cls_str = malloc(str_size);
+       if (cls_str == NULL) {
+               ret = -ENOMEM;
+               goto error;
+       }
+       ret = snprintf(cls_str, str_size, "+%s", devargs.args);
+       if (ret != str_size - 1) {
+               ret = -EINVAL;
+               goto error;
+       }
+       iter->cls_str = cls_str;
+       free(devargs.args); /* allocated by rte_devargs_parse() */
+       devargs.args = NULL;
+
+       iter->bus = devargs.bus;
+       if (iter->bus->dev_iterate == NULL) {
+               ret = -ENOTSUP;
+               goto error;
+       }
+
+       /* Convert bus args to new syntax for use with new API dev_iterate. */
+       if (strcmp(iter->bus->name, "vdev") == 0) {
+               bus_param_key = "name";
+       } else if (strcmp(iter->bus->name, "pci") == 0) {
+               bus_param_key = "addr";
+       } else {
+               ret = -ENOTSUP;
+               goto error;
+       }
+       str_size = strlen(bus_param_key) + strlen(devargs.name) + 2;
+       bus_str = malloc(str_size);
+       if (bus_str == NULL) {
+               ret = -ENOMEM;
+               goto error;
+       }
+       ret = snprintf(bus_str, str_size, "%s=%s",
+                       bus_param_key, devargs.name);
+       if (ret != str_size - 1) {
+               ret = -EINVAL;
+               goto error;
+       }
+       iter->bus_str = bus_str;
+
+end:
+       iter->cls = rte_class_find_by_name("eth");
+       return 0;
+
+error:
+       if (ret == -ENOTSUP)
+               RTE_LOG(ERR, EAL, "Bus %s does not support iterating.\n",
+                               iter->bus->name);
+       free(devargs.args);
+       free(bus_str);
+       free(cls_str);
+       return ret;
+}
+
+uint16_t
+rte_eth_iterator_next(struct rte_dev_iterator *iter)
+{
+       if (iter->cls == NULL) /* invalid ethdev iterator */
+               return RTE_MAX_ETHPORTS;
+
+       do { /* loop to try all matching rte_device */
+               /* If not pure ethdev filter and */
+               if (iter->bus != NULL &&
+                               /* not in middle of rte_eth_dev iteration, */
+                               iter->class_device == NULL) {
+                       /* get next rte_device to try. */
+                       iter->device = iter->bus->dev_iterate(
+                                       iter->device, iter->bus_str, iter);
+                       if (iter->device == NULL)
+                               break; /* no more rte_device candidate */
+               }
+               /* A device is matching bus part, need to check ethdev part. */
+               iter->class_device = iter->cls->dev_iterate(
+                               iter->class_device, iter->cls_str, iter);
+               if (iter->class_device != NULL)
+                       return eth_dev_to_id(iter->class_device); /* match */
+       } while (iter->bus != NULL); /* need to try next rte_device */
+
+       /* No more ethdev port to iterate. */
+       rte_eth_iterator_cleanup(iter);
+       return RTE_MAX_ETHPORTS;
+}
+
+void
+rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
+{
+       if (iter->bus_str == NULL)
+               return; /* nothing to free in pure class filter */
+       free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
+       free(RTE_CAST_FIELD(iter, cls_str, char *)); /* workaround const */
+       memset(iter, 0, sizeof(*iter));
+}
+
 uint16_t
 rte_eth_find_next(uint16_t port_id)
 {
        while (port_id < RTE_MAX_ETHPORTS &&
-              rte_eth_devices[port_id].state != RTE_ETH_DEV_ATTACHED &&
-              rte_eth_devices[port_id].state != RTE_ETH_DEV_REMOVED)
+                       rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED)
                port_id++;
 
        if (port_id >= RTE_MAX_ETHPORTS)
@@ -195,6 +338,34 @@ rte_eth_find_next(uint16_t port_id)
        return port_id;
 }
 
+/*
+ * Macro to iterate over all valid ports for internal usage.
+ * Note: RTE_ETH_FOREACH_DEV is different because filtering owned ports.
+ */
+#define RTE_ETH_FOREACH_VALID_DEV(port_id) \
+       for (port_id = rte_eth_find_next(0); \
+            port_id < RTE_MAX_ETHPORTS; \
+            port_id = rte_eth_find_next(port_id + 1))
+
+uint16_t
+rte_eth_find_next_of(uint16_t port_id, const struct rte_device *parent)
+{
+       port_id = rte_eth_find_next(port_id);
+       while (port_id < RTE_MAX_ETHPORTS &&
+                       rte_eth_devices[port_id].device != parent)
+               port_id = rte_eth_find_next(port_id + 1);
+
+       return port_id;
+}
+
+uint16_t
+rte_eth_find_next_sibling(uint16_t port_id, uint16_t ref_port_id)
+{
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(ref_port_id, RTE_MAX_ETHPORTS);
+       return rte_eth_find_next_of(port_id,
+                       rte_eth_devices[ref_port_id].device);
+}
+
 static void
 rte_eth_dev_shared_data_prepare(void)
 {
@@ -227,19 +398,41 @@ rte_eth_dev_shared_data_prepare(void)
        rte_spinlock_unlock(&rte_eth_shared_data_lock);
 }
 
-struct rte_eth_dev *
-rte_eth_dev_allocated(const char *name)
+static bool
+is_allocated(const struct rte_eth_dev *ethdev)
+{
+       return ethdev->data->name[0] != '\0';
+}
+
+static struct rte_eth_dev *
+_rte_eth_dev_allocated(const char *name)
 {
        unsigned i;
 
        for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
-               if ((rte_eth_devices[i].state == RTE_ETH_DEV_ATTACHED) &&
+               if (rte_eth_devices[i].data != NULL &&
                    strcmp(rte_eth_devices[i].data->name, name) == 0)
                        return &rte_eth_devices[i];
        }
        return NULL;
 }
 
+struct rte_eth_dev *
+rte_eth_dev_allocated(const char *name)
+{
+       struct rte_eth_dev *ethdev;
+
+       rte_eth_dev_shared_data_prepare();
+
+       rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
+
+       ethdev = _rte_eth_dev_allocated(name);
+
+       rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock);
+
+       return ethdev;
+}
+
 static uint16_t
 rte_eth_dev_find_free_port(void)
 {
@@ -262,9 +455,6 @@ eth_dev_get(uint16_t port_id)
        struct rte_eth_dev *eth_dev = &rte_eth_devices[port_id];
 
        eth_dev->data = &rte_eth_dev_shared_data->data[port_id];
-       eth_dev->state = RTE_ETH_DEV_ATTACHED;
-
-       eth_dev_last_created_port = port_id;
 
        return eth_dev;
 }
@@ -274,36 +464,46 @@ rte_eth_dev_allocate(const char *name)
 {
        uint16_t port_id;
        struct rte_eth_dev *eth_dev = NULL;
+       size_t name_len;
+
+       name_len = strnlen(name, RTE_ETH_NAME_MAX_LEN);
+       if (name_len == 0) {
+               RTE_ETHDEV_LOG(ERR, "Zero length Ethernet device name\n");
+               return NULL;
+       }
+
+       if (name_len >= RTE_ETH_NAME_MAX_LEN) {
+               RTE_ETHDEV_LOG(ERR, "Ethernet device name is too long\n");
+               return NULL;
+       }
 
        rte_eth_dev_shared_data_prepare();
 
        /* Synchronize port creation between primary and secondary threads. */
        rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
-       port_id = rte_eth_dev_find_free_port();
-       if (port_id == RTE_MAX_ETHPORTS) {
-               ethdev_log(ERR, "Reached maximum number of Ethernet ports");
+       if (_rte_eth_dev_allocated(name) != NULL) {
+               RTE_ETHDEV_LOG(ERR,
+                       "Ethernet device with name %s already allocated\n",
+                       name);
                goto unlock;
        }
 
-       if (rte_eth_dev_allocated(name) != NULL) {
-               ethdev_log(ERR,
-                       "Ethernet Device with name %s already allocated!",
-                       name);
+       port_id = rte_eth_dev_find_free_port();
+       if (port_id == RTE_MAX_ETHPORTS) {
+               RTE_ETHDEV_LOG(ERR,
+                       "Reached maximum number of Ethernet ports\n");
                goto unlock;
        }
 
        eth_dev = eth_dev_get(port_id);
-       snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
+       strlcpy(eth_dev->data->name, name, sizeof(eth_dev->data->name));
        eth_dev->data->port_id = port_id;
-       eth_dev->data->mtu = ETHER_MTU;
+       eth_dev->data->mtu = RTE_ETHER_MTU;
 
 unlock:
        rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock);
 
-       if (eth_dev != NULL)
-               _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_NEW, NULL);
-
        return eth_dev;
 }
 
@@ -328,8 +528,8 @@ rte_eth_dev_attach_secondary(const char *name)
                        break;
        }
        if (i == RTE_MAX_ETHPORTS) {
-               RTE_PMD_DEBUG_TRACE(
-                       "device %s is not driven by the primary process\n",
+               RTE_ETHDEV_LOG(ERR,
+                       "Device %s is not driven by the primary process\n",
                        name);
        } else {
                eth_dev = eth_dev_get(i);
@@ -348,16 +548,25 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
 
        rte_eth_dev_shared_data_prepare();
 
+       if (eth_dev->state != RTE_ETH_DEV_UNUSED)
+               _rte_eth_dev_callback_process(eth_dev,
+                               RTE_ETH_EVENT_DESTROY, NULL);
+
        rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
        eth_dev->state = RTE_ETH_DEV_UNUSED;
 
-       memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data));
+       if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+               rte_free(eth_dev->data->rx_queues);
+               rte_free(eth_dev->data->tx_queues);
+               rte_free(eth_dev->data->mac_addrs);
+               rte_free(eth_dev->data->hash_mac_addrs);
+               rte_free(eth_dev->data->dev_private);
+               memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data));
+       }
 
        rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock);
 
-       _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_DESTROY, NULL);
-
        return 0;
 }
 
@@ -375,29 +584,23 @@ static int
 rte_eth_is_valid_owner_id(uint64_t owner_id)
 {
        if (owner_id == RTE_ETH_DEV_NO_OWNER ||
-           rte_eth_dev_shared_data->next_owner_id <= owner_id) {
-               RTE_PMD_DEBUG_TRACE("Invalid owner_id=%016"PRIX64".\n", owner_id);
+           rte_eth_dev_shared_data->next_owner_id <= owner_id)
                return 0;
-       }
        return 1;
 }
 
 uint64_t
 rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
 {
+       port_id = rte_eth_find_next(port_id);
        while (port_id < RTE_MAX_ETHPORTS &&
-              ((rte_eth_devices[port_id].state != RTE_ETH_DEV_ATTACHED &&
-              rte_eth_devices[port_id].state != RTE_ETH_DEV_REMOVED) ||
-              rte_eth_devices[port_id].data->owner.id != owner_id))
-               port_id++;
-
-       if (port_id >= RTE_MAX_ETHPORTS)
-               return RTE_MAX_ETHPORTS;
+                       rte_eth_devices[port_id].data->owner.id != owner_id)
+               port_id = rte_eth_find_next(port_id + 1);
 
        return port_id;
 }
 
-int __rte_experimental
+int
 rte_eth_dev_owner_new(uint64_t *owner_id)
 {
        rte_eth_dev_shared_data_prepare();
@@ -414,38 +617,43 @@ static int
 _rte_eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
                       const struct rte_eth_dev_owner *new_owner)
 {
+       struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
        struct rte_eth_dev_owner *port_owner;
-       int sret;
 
-       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+       if (port_id >= RTE_MAX_ETHPORTS || !is_allocated(ethdev)) {
+               RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
+                       port_id);
+               return -ENODEV;
+       }
 
        if (!rte_eth_is_valid_owner_id(new_owner->id) &&
-           !rte_eth_is_valid_owner_id(old_owner_id))
+           !rte_eth_is_valid_owner_id(old_owner_id)) {
+               RTE_ETHDEV_LOG(ERR,
+                       "Invalid owner old_id=%016"PRIx64" new_id=%016"PRIx64"\n",
+                      old_owner_id, new_owner->id);
                return -EINVAL;
+       }
 
        port_owner = &rte_eth_devices[port_id].data->owner;
        if (port_owner->id != old_owner_id) {
-               RTE_PMD_DEBUG_TRACE("Cannot set owner to port %d already owned"
-                                   " by %s_%016"PRIX64".\n", port_id,
-                                   port_owner->name, port_owner->id);
+               RTE_ETHDEV_LOG(ERR,
+                       "Cannot set owner to port %u already owned by %s_%016"PRIX64"\n",
+                       port_id, port_owner->name, port_owner->id);
                return -EPERM;
        }
 
-       sret = snprintf(port_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN, "%s",
-                       new_owner->name);
-       if (sret < 0 || sret >= RTE_ETH_MAX_OWNER_NAME_LEN)
-               RTE_PMD_DEBUG_TRACE("Port %d owner name was truncated.\n",
-                                   port_id);
+       /* can not truncate (same structure) */
+       strlcpy(port_owner->name, new_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN);
 
        port_owner->id = new_owner->id;
 
-       RTE_PMD_DEBUG_TRACE("Port %d owner is %s_%016"PRIX64".\n", port_id,
-                           new_owner->name, new_owner->id);
+       RTE_ETHDEV_LOG(DEBUG, "Port %u owner is %s_%016"PRIx64"\n",
+               port_id, new_owner->name, new_owner->id);
 
        return 0;
 }
 
-int __rte_experimental
+int
 rte_eth_dev_owner_set(const uint16_t port_id,
                      const struct rte_eth_dev_owner *owner)
 {
@@ -461,7 +669,7 @@ rte_eth_dev_owner_set(const uint16_t port_id,
        return ret;
 }
 
-int __rte_experimental
+int
 rte_eth_dev_owner_unset(const uint16_t port_id, const uint64_t owner_id)
 {
        const struct rte_eth_dev_owner new_owner = (struct rte_eth_dev_owner)
@@ -478,41 +686,52 @@ rte_eth_dev_owner_unset(const uint16_t port_id, const uint64_t owner_id)
        return ret;
 }
 
-void __rte_experimental
+int
 rte_eth_dev_owner_delete(const uint64_t owner_id)
 {
        uint16_t port_id;
+       int ret = 0;
 
        rte_eth_dev_shared_data_prepare();
 
        rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
        if (rte_eth_is_valid_owner_id(owner_id)) {
-               RTE_ETH_FOREACH_DEV_OWNED_BY(port_id, owner_id)
-                       memset(&rte_eth_devices[port_id].data->owner, 0,
-                              sizeof(struct rte_eth_dev_owner));
-               RTE_PMD_DEBUG_TRACE("All port owners owned by %016"PRIX64
-                               " identifier have removed.\n", owner_id);
+               for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
+                       if (rte_eth_devices[port_id].data->owner.id == owner_id)
+                               memset(&rte_eth_devices[port_id].data->owner, 0,
+                                      sizeof(struct rte_eth_dev_owner));
+               RTE_ETHDEV_LOG(NOTICE,
+                       "All port owners owned by %016"PRIx64" identifier have removed\n",
+                       owner_id);
+       } else {
+               RTE_ETHDEV_LOG(ERR,
+                              "Invalid owner id=%016"PRIx64"\n",
+                              owner_id);
+               ret = -EINVAL;
        }
 
        rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock);
+
+       return ret;
 }
 
-int __rte_experimental
+int
 rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
 {
        int ret = 0;
+       struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
 
        rte_eth_dev_shared_data_prepare();
 
        rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
 
-       if (!rte_eth_dev_is_valid_port(port_id)) {
-               RTE_PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+       if (port_id >= RTE_MAX_ETHPORTS || !is_allocated(ethdev)) {
+               RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
+                       port_id);
                ret = -ENODEV;
        } else {
-               rte_memcpy(owner, &rte_eth_devices[port_id].data->owner,
-                          sizeof(*owner));
+               rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
        }
 
        rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock);
@@ -533,12 +752,6 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id)
        return rte_eth_devices[port_id].security_ctx;
 }
 
-uint16_t
-rte_eth_dev_count(void)
-{
-       return rte_eth_dev_count_avail();
-}
-
 uint16_t
 rte_eth_dev_count_avail(void)
 {
@@ -553,14 +766,13 @@ rte_eth_dev_count_avail(void)
        return count;
 }
 
-uint16_t __rte_experimental
+uint16_t
 rte_eth_dev_count_total(void)
 {
        uint16_t port, count = 0;
 
-       for (port = 0; port < RTE_MAX_ETHPORTS; port++)
-               if (rte_eth_devices[port].state != RTE_ETH_DEV_UNUSED)
-                       count++;
+       RTE_ETH_FOREACH_VALID_DEV(port)
+               count++;
 
        return count;
 }
@@ -573,7 +785,7 @@ rte_eth_dev_get_name_by_port(uint16_t port_id, char *name)
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
        if (name == NULL) {
-               RTE_PMD_DEBUG_TRACE("Null pointer is specified\n");
+               RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
                return -EINVAL;
        }
 
@@ -590,17 +802,15 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
        uint32_t pid;
 
        if (name == NULL) {
-               RTE_PMD_DEBUG_TRACE("Null pointer is specified\n");
+               RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
                return -EINVAL;
        }
 
-       for (pid = 0; pid < RTE_MAX_ETHPORTS; pid++) {
-               if (rte_eth_devices[pid].state != RTE_ETH_DEV_UNUSED &&
-                   !strcmp(name, rte_eth_dev_shared_data->data[pid].name)) {
+       RTE_ETH_FOREACH_VALID_DEV(pid)
+               if (!strcmp(name, rte_eth_dev_shared_data->data[pid].name)) {
                        *port_id = pid;
                        return 0;
                }
-       }
 
        return -ENODEV;
 }
@@ -615,87 +825,6 @@ eth_err(uint16_t port_id, int ret)
        return ret;
 }
 
-/* attach the new device, then store port_id of the device */
-int
-rte_eth_dev_attach(const char *devargs, uint16_t *port_id)
-{
-       int current = rte_eth_dev_count_total();
-       struct rte_devargs da;
-       int ret = -1;
-
-       memset(&da, 0, sizeof(da));
-
-       if ((devargs == NULL) || (port_id == NULL)) {
-               ret = -EINVAL;
-               goto err;
-       }
-
-       /* parse devargs */
-       if (rte_devargs_parse(&da, "%s", devargs))
-               goto err;
-
-       ret = rte_eal_hotplug_add(da.bus->name, da.name, da.args);
-       if (ret < 0)
-               goto err;
-
-       /* no point looking at the port count if no port exists */
-       if (!rte_eth_dev_count_total()) {
-               ethdev_log(ERR, "No port found for device (%s)", da.name);
-               ret = -1;
-               goto err;
-       }
-
-       /* if nothing happened, there is a bug here, since some driver told us
-        * it did attach a device, but did not create a port.
-        * FIXME: race condition in case of plug-out of another device
-        */
-       if (current == rte_eth_dev_count_total()) {
-               ret = -1;
-               goto err;
-       }
-
-       *port_id = eth_dev_last_created_port;
-       ret = 0;
-
-err:
-       free(da.args);
-       return ret;
-}
-
-/* detach the device, then store the name of the device */
-int
-rte_eth_dev_detach(uint16_t port_id, char *name __rte_unused)
-{
-       struct rte_device *dev;
-       struct rte_bus *bus;
-       uint32_t dev_flags;
-       int ret = -1;
-
-       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
-
-       dev_flags = rte_eth_devices[port_id].data->dev_flags;
-       if (dev_flags & RTE_ETH_DEV_BONDED_SLAVE) {
-               ethdev_log(ERR,
-                       "Port %" PRIu16 " is bonded, cannot detach", port_id);
-               return -ENOTSUP;
-       }
-
-       dev = rte_eth_devices[port_id].device;
-       if (dev == NULL)
-               return -EINVAL;
-
-       bus = rte_bus_find_by_device(dev);
-       if (bus == NULL)
-               return -ENOENT;
-
-       ret = rte_eal_hotplug_remove(bus->name, dev->name);
-       if (ret < 0)
-               return ret;
-
-       rte_eth_dev_release_port(&rte_eth_devices[port_id]);
-       return 0;
-}
-
 static int
 rte_eth_dev_rx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
 {
@@ -755,21 +884,29 @@ rte_eth_dev_rx_queue_start(uint16_t port_id, uint16_t rx_queue_id)
 
        dev = &rte_eth_devices[port_id];
        if (!dev->data->dev_started) {
-               RTE_PMD_DEBUG_TRACE(
-                   "port %d must be started before start any queue\n", port_id);
+               RTE_ETHDEV_LOG(ERR,
+                       "Port %u must be started before start any queue\n",
+                       port_id);
                return -EINVAL;
        }
 
        if (rx_queue_id >= dev->data->nb_rx_queues) {
-               RTE_PMD_DEBUG_TRACE("Invalid RX queue_id=%d\n", rx_queue_id);
+               RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
                return -EINVAL;
        }
 
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_start, -ENOTSUP);
 
+       if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) {
+               RTE_ETHDEV_LOG(INFO,
+                       "Can't start Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
+                       rx_queue_id, port_id);
+               return -EINVAL;
+       }
+
        if (dev->data->rx_queue_state[rx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) {
-               RTE_PMD_DEBUG_TRACE("Queue %" PRIu16" of device with port_id=%" PRIu8
-                       " already started\n",
+               RTE_ETHDEV_LOG(INFO,
+                       "Queue %"PRIu16" of device with port_id=%"PRIu16" already started\n",
                        rx_queue_id, port_id);
                return 0;
        }
@@ -788,15 +925,22 @@ rte_eth_dev_rx_queue_stop(uint16_t port_id, uint16_t rx_queue_id)
 
        dev = &rte_eth_devices[port_id];
        if (rx_queue_id >= dev->data->nb_rx_queues) {
-               RTE_PMD_DEBUG_TRACE("Invalid RX queue_id=%d\n", rx_queue_id);
+               RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
                return -EINVAL;
        }
 
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_stop, -ENOTSUP);
 
+       if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) {
+               RTE_ETHDEV_LOG(INFO,
+                       "Can't stop Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
+                       rx_queue_id, port_id);
+               return -EINVAL;
+       }
+
        if (dev->data->rx_queue_state[rx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) {
-               RTE_PMD_DEBUG_TRACE("Queue %" PRIu16" of device with port_id=%" PRIu8
-                       " already stopped\n",
+               RTE_ETHDEV_LOG(INFO,
+                       "Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped\n",
                        rx_queue_id, port_id);
                return 0;
        }
@@ -814,28 +958,34 @@ rte_eth_dev_tx_queue_start(uint16_t port_id, uint16_t tx_queue_id)
 
        dev = &rte_eth_devices[port_id];
        if (!dev->data->dev_started) {
-               RTE_PMD_DEBUG_TRACE(
-                   "port %d must be started before start any queue\n", port_id);
+               RTE_ETHDEV_LOG(ERR,
+                       "Port %u must be started before start any queue\n",
+                       port_id);
                return -EINVAL;
        }
 
        if (tx_queue_id >= dev->data->nb_tx_queues) {
-               RTE_PMD_DEBUG_TRACE("Invalid TX queue_id=%d\n", tx_queue_id);
+               RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
                return -EINVAL;
        }
 
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_start, -ENOTSUP);
 
+       if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) {
+               RTE_ETHDEV_LOG(INFO,
+                       "Can't start Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
+                       tx_queue_id, port_id);
+               return -EINVAL;
+       }
+
        if (dev->data->tx_queue_state[tx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) {
-               RTE_PMD_DEBUG_TRACE("Queue %" PRIu16" of device with port_id=%" PRIu8
-                       " already started\n",
+               RTE_ETHDEV_LOG(INFO,
+                       "Queue %"PRIu16" of device with port_id=%"PRIu16" already started\n",
                        tx_queue_id, port_id);
                return 0;
        }
 
-       return eth_err(port_id, dev->dev_ops->tx_queue_start(dev,
-                                                            tx_queue_id));
-
+       return eth_err(port_id, dev->dev_ops->tx_queue_start(dev, tx_queue_id));
 }
 
 int
@@ -847,15 +997,22 @@ rte_eth_dev_tx_queue_stop(uint16_t port_id, uint16_t tx_queue_id)
 
        dev = &rte_eth_devices[port_id];
        if (tx_queue_id >= dev->data->nb_tx_queues) {
-               RTE_PMD_DEBUG_TRACE("Invalid TX queue_id=%d\n", tx_queue_id);
+               RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
                return -EINVAL;
        }
 
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_stop, -ENOTSUP);
 
+       if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) {
+               RTE_ETHDEV_LOG(INFO,
+                       "Can't stop Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
+                       tx_queue_id, port_id);
+               return -EINVAL;
+       }
+
        if (dev->data->tx_queue_state[tx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) {
-               RTE_PMD_DEBUG_TRACE("Queue %" PRIu16" of device with port_id=%" PRIu8
-                       " already stopped\n",
+               RTE_ETHDEV_LOG(INFO,
+                       "Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped\n",
                        tx_queue_id, port_id);
                return 0;
        }
@@ -947,42 +1104,7 @@ rte_eth_speed_bitflag(uint32_t speed, int duplex)
        }
 }
 
-/**
- * A conversion function from rxmode bitfield API.
- */
-static void
-rte_eth_convert_rx_offload_bitfield(const struct rte_eth_rxmode *rxmode,
-                                   uint64_t *rx_offloads)
-{
-       uint64_t offloads = 0;
-
-       if (rxmode->header_split == 1)
-               offloads |= DEV_RX_OFFLOAD_HEADER_SPLIT;
-       if (rxmode->hw_ip_checksum == 1)
-               offloads |= DEV_RX_OFFLOAD_CHECKSUM;
-       if (rxmode->hw_vlan_filter == 1)
-               offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
-       if (rxmode->hw_vlan_strip == 1)
-               offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
-       if (rxmode->hw_vlan_extend == 1)
-               offloads |= DEV_RX_OFFLOAD_VLAN_EXTEND;
-       if (rxmode->jumbo_frame == 1)
-               offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
-       if (rxmode->hw_strip_crc == 1)
-               offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-       if (rxmode->enable_scatter == 1)
-               offloads |= DEV_RX_OFFLOAD_SCATTER;
-       if (rxmode->enable_lro == 1)
-               offloads |= DEV_RX_OFFLOAD_TCP_LRO;
-       if (rxmode->hw_timestamp == 1)
-               offloads |= DEV_RX_OFFLOAD_TIMESTAMP;
-       if (rxmode->security == 1)
-               offloads |= DEV_RX_OFFLOAD_SECURITY;
-
-       *rx_offloads = offloads;
-}
-
-const char * __rte_experimental
+const char *
 rte_eth_dev_rx_offload_name(uint64_t offload)
 {
        const char *name = "UNKNOWN";
@@ -998,7 +1120,7 @@ rte_eth_dev_rx_offload_name(uint64_t offload)
        return name;
 }
 
-const char * __rte_experimental
+const char *
 rte_eth_dev_tx_offload_name(uint64_t offload)
 {
        const char *name = "UNKNOWN";
@@ -1020,17 +1142,35 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 {
        struct rte_eth_dev *dev;
        struct rte_eth_dev_info dev_info;
-       struct rte_eth_conf local_conf = *dev_conf;
+       struct rte_eth_conf orig_conf;
        int diag;
+       int ret;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
        dev = &rte_eth_devices[port_id];
 
-       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
 
-       rte_eth_dev_info_get(port_id, &dev_info);
+       if (dev->data->dev_started) {
+               RTE_ETHDEV_LOG(ERR,
+                       "Port %u must be stopped to allow configuration\n",
+                       port_id);
+               return -EBUSY;
+       }
+
+        /* Store original config, as rollback required on failure */
+       memcpy(&orig_conf, &dev->data->dev_conf, sizeof(dev->data->dev_conf));
+
+       /*
+        * Copy the dev_conf parameter into the dev structure.
+        * rte_eth_dev_info_get() requires dev_conf, copy it before dev_info get
+        */
+       memcpy(&dev->data->dev_conf, dev_conf, sizeof(dev->data->dev_conf));
+
+       ret = rte_eth_dev_info_get(port_id, &dev_info);
+       if (ret != 0)
+               goto rollback;
 
        /* If number of queues specified by application for both Rx and Tx is
         * zero, use driver preferred values. This cannot be done individually
@@ -1048,129 +1188,121 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
        }
 
        if (nb_rx_q > RTE_MAX_QUEUES_PER_PORT) {
-               RTE_PMD_DEBUG_TRACE(
+               RTE_ETHDEV_LOG(ERR,
                        "Number of RX queues requested (%u) is greater than max supported(%d)\n",
                        nb_rx_q, RTE_MAX_QUEUES_PER_PORT);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto rollback;
        }
 
        if (nb_tx_q > RTE_MAX_QUEUES_PER_PORT) {
-               RTE_PMD_DEBUG_TRACE(
+               RTE_ETHDEV_LOG(ERR,
                        "Number of TX queues requested (%u) is greater than max supported(%d)\n",
                        nb_tx_q, RTE_MAX_QUEUES_PER_PORT);
-               return -EINVAL;
-       }
-
-       if (dev->data->dev_started) {
-               RTE_PMD_DEBUG_TRACE(
-                   "port %d must be stopped to allow configuration\n", port_id);
-               return -EBUSY;
+               ret = -EINVAL;
+               goto rollback;
        }
 
-       /*
-        * Convert between the offloads API to enable PMDs to support
-        * only one of them.
-        */
-       if (dev_conf->rxmode.ignore_offload_bitfield == 0)
-               rte_eth_convert_rx_offload_bitfield(
-                               &dev_conf->rxmode, &local_conf.rxmode.offloads);
-
-       /* Copy the dev_conf parameter into the dev structure */
-       memcpy(&dev->data->dev_conf, &local_conf, sizeof(dev->data->dev_conf));
-
        /*
         * Check that the numbers of RX and TX queues are not greater
         * than the maximum number of RX and TX queues supported by the
         * configured device.
         */
        if (nb_rx_q > dev_info.max_rx_queues) {
-               RTE_PMD_DEBUG_TRACE("ethdev port_id=%d nb_rx_queues=%d > %d\n",
-                               port_id, nb_rx_q, dev_info.max_rx_queues);
-               return -EINVAL;
+               RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u nb_rx_queues=%u > %u\n",
+                       port_id, nb_rx_q, dev_info.max_rx_queues);
+               ret = -EINVAL;
+               goto rollback;
        }
 
        if (nb_tx_q > dev_info.max_tx_queues) {
-               RTE_PMD_DEBUG_TRACE("ethdev port_id=%d nb_tx_queues=%d > %d\n",
-                               port_id, nb_tx_q, dev_info.max_tx_queues);
-               return -EINVAL;
+               RTE_ETHDEV_LOG(ERR, "Ethdev port_id=%u nb_tx_queues=%u > %u\n",
+                       port_id, nb_tx_q, dev_info.max_tx_queues);
+               ret = -EINVAL;
+               goto rollback;
        }
 
        /* Check that the device supports requested interrupts */
        if ((dev_conf->intr_conf.lsc == 1) &&
-               (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC))) {
-                       RTE_PMD_DEBUG_TRACE("driver %s does not support lsc\n",
-                                       dev->device->driver->name);
-                       return -EINVAL;
+                       (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC))) {
+               RTE_ETHDEV_LOG(ERR, "Driver %s does not support lsc\n",
+                       dev->device->driver->name);
+               ret = -EINVAL;
+               goto rollback;
        }
        if ((dev_conf->intr_conf.rmv == 1) &&
-           (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_RMV))) {
-               RTE_PMD_DEBUG_TRACE("driver %s does not support rmv\n",
-                                   dev->device->driver->name);
-               return -EINVAL;
+                       (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_RMV))) {
+               RTE_ETHDEV_LOG(ERR, "Driver %s does not support rmv\n",
+                       dev->device->driver->name);
+               ret = -EINVAL;
+               goto rollback;
        }
 
        /*
         * If jumbo frames are enabled, check that the maximum RX packet
         * length is supported by the configured device.
         */
-       if (local_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
-               if (dev_conf->rxmode.max_rx_pkt_len >
-                   dev_info.max_rx_pktlen) {
-                       RTE_PMD_DEBUG_TRACE("ethdev port_id=%d max_rx_pkt_len %u"
-                               " > max valid value %u\n",
-                               port_id,
-                               (unsigned)dev_conf->rxmode.max_rx_pkt_len,
-                               (unsigned)dev_info.max_rx_pktlen);
-                       return -EINVAL;
-               } else if (dev_conf->rxmode.max_rx_pkt_len < ETHER_MIN_LEN) {
-                       RTE_PMD_DEBUG_TRACE("ethdev port_id=%d max_rx_pkt_len %u"
-                               " < min valid value %u\n",
-                               port_id,
-                               (unsigned)dev_conf->rxmode.max_rx_pkt_len,
-                               (unsigned)ETHER_MIN_LEN);
-                       return -EINVAL;
+       if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
+               if (dev_conf->rxmode.max_rx_pkt_len > dev_info.max_rx_pktlen) {
+                       RTE_ETHDEV_LOG(ERR,
+                               "Ethdev port_id=%u max_rx_pkt_len %u > max valid value %u\n",
+                               port_id, dev_conf->rxmode.max_rx_pkt_len,
+                               dev_info.max_rx_pktlen);
+                       ret = -EINVAL;
+                       goto rollback;
+               } else if (dev_conf->rxmode.max_rx_pkt_len < RTE_ETHER_MIN_LEN) {
+                       RTE_ETHDEV_LOG(ERR,
+                               "Ethdev port_id=%u max_rx_pkt_len %u < min valid value %u\n",
+                               port_id, dev_conf->rxmode.max_rx_pkt_len,
+                               (unsigned int)RTE_ETHER_MIN_LEN);
+                       ret = -EINVAL;
+                       goto rollback;
                }
        } else {
-               if (dev_conf->rxmode.max_rx_pkt_len < ETHER_MIN_LEN ||
-                       dev_conf->rxmode.max_rx_pkt_len > ETHER_MAX_LEN)
+               if (dev_conf->rxmode.max_rx_pkt_len < RTE_ETHER_MIN_LEN ||
+                       dev_conf->rxmode.max_rx_pkt_len > RTE_ETHER_MAX_LEN)
                        /* Use default value */
                        dev->data->dev_conf.rxmode.max_rx_pkt_len =
-                                                       ETHER_MAX_LEN;
+                                                       RTE_ETHER_MAX_LEN;
        }
 
        /* Any requested offloading must be within its device capabilities */
-       if ((local_conf.rxmode.offloads & dev_info.rx_offload_capa) !=
-            local_conf.rxmode.offloads) {
-               ethdev_log(ERR, "ethdev port_id=%d requested Rx offloads "
-                               "0x%" PRIx64 " doesn't match Rx offloads "
-                               "capabilities 0x%" PRIx64 " in %s()\n",
-                               port_id,
-                               local_conf.rxmode.offloads,
-                               dev_info.rx_offload_capa,
-                               __func__);
-               /* Will return -EINVAL in the next release */
-       }
-       if ((local_conf.txmode.offloads & dev_info.tx_offload_capa) !=
-            local_conf.txmode.offloads) {
-               ethdev_log(ERR, "ethdev port_id=%d requested Tx offloads "
-                               "0x%" PRIx64 " doesn't match Tx offloads "
-                               "capabilities 0x%" PRIx64 " in %s()\n",
-                               port_id,
-                               local_conf.txmode.offloads,
-                               dev_info.tx_offload_capa,
-                               __func__);
-               /* Will return -EINVAL in the next release */
+       if ((dev_conf->rxmode.offloads & dev_info.rx_offload_capa) !=
+            dev_conf->rxmode.offloads) {
+               RTE_ETHDEV_LOG(ERR,
+                       "Ethdev port_id=%u requested Rx offloads 0x%"PRIx64" doesn't match Rx offloads "
+                       "capabilities 0x%"PRIx64" in %s()\n",
+                       port_id, dev_conf->rxmode.offloads,
+                       dev_info.rx_offload_capa,
+                       __func__);
+               ret = -EINVAL;
+               goto rollback;
+       }
+       if ((dev_conf->txmode.offloads & dev_info.tx_offload_capa) !=
+            dev_conf->txmode.offloads) {
+               RTE_ETHDEV_LOG(ERR,
+                       "Ethdev port_id=%u requested Tx offloads 0x%"PRIx64" doesn't match Tx offloads "
+                       "capabilities 0x%"PRIx64" in %s()\n",
+                       port_id, dev_conf->txmode.offloads,
+                       dev_info.tx_offload_capa,
+                       __func__);
+               ret = -EINVAL;
+               goto rollback;
        }
 
+       dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf =
+               rte_eth_rss_hf_refine(dev_conf->rx_adv_conf.rss_conf.rss_hf);
+
        /* Check that device supports requested rss hash functions. */
        if ((dev_info.flow_type_rss_offloads |
             dev_conf->rx_adv_conf.rss_conf.rss_hf) !=
            dev_info.flow_type_rss_offloads) {
-               RTE_PMD_DEBUG_TRACE("ethdev port_id=%d invalid rss_hf: "
-                                   "0x%"PRIx64", valid value: 0x%"PRIx64"\n",
-                                   port_id,
-                                   dev_conf->rx_adv_conf.rss_conf.rss_hf,
-                                   dev_info.flow_type_rss_offloads);
+               RTE_ETHDEV_LOG(ERR,
+                       "Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64"\n",
+                       port_id, dev_conf->rx_adv_conf.rss_conf.rss_hf,
+                       dev_info.flow_type_rss_offloads);
+               ret = -EINVAL;
+               goto rollback;
        }
 
        /*
@@ -1178,47 +1310,57 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
         */
        diag = rte_eth_dev_rx_queue_config(dev, nb_rx_q);
        if (diag != 0) {
-               RTE_PMD_DEBUG_TRACE("port%d rte_eth_dev_rx_queue_config = %d\n",
-                               port_id, diag);
-               return diag;
+               RTE_ETHDEV_LOG(ERR,
+                       "Port%u rte_eth_dev_rx_queue_config = %d\n",
+                       port_id, diag);
+               ret = diag;
+               goto rollback;
        }
 
        diag = rte_eth_dev_tx_queue_config(dev, nb_tx_q);
        if (diag != 0) {
-               RTE_PMD_DEBUG_TRACE("port%d rte_eth_dev_tx_queue_config = %d\n",
-                               port_id, diag);
+               RTE_ETHDEV_LOG(ERR,
+                       "Port%u rte_eth_dev_tx_queue_config = %d\n",
+                       port_id, diag);
                rte_eth_dev_rx_queue_config(dev, 0);
-               return diag;
+               ret = diag;
+               goto rollback;
        }
 
        diag = (*dev->dev_ops->dev_configure)(dev);
        if (diag != 0) {
-               RTE_PMD_DEBUG_TRACE("port%d dev_configure = %d\n",
-                               port_id, diag);
+               RTE_ETHDEV_LOG(ERR, "Port%u dev_configure = %d\n",
+                       port_id, diag);
                rte_eth_dev_rx_queue_config(dev, 0);
                rte_eth_dev_tx_queue_config(dev, 0);
-               return eth_err(port_id, diag);
+               ret = eth_err(port_id, diag);
+               goto rollback;
        }
 
        /* Initialize Rx profiling if enabled at compilation time. */
-       diag = __rte_eth_profile_rx_init(port_id, dev);
+       diag = __rte_eth_dev_profile_init(port_id, dev);
        if (diag != 0) {
-               RTE_PMD_DEBUG_TRACE("port%d __rte_eth_profile_rx_init = %d\n",
-                               port_id, diag);
+               RTE_ETHDEV_LOG(ERR, "Port%u __rte_eth_dev_profile_init = %d\n",
+                       port_id, diag);
                rte_eth_dev_rx_queue_config(dev, 0);
                rte_eth_dev_tx_queue_config(dev, 0);
-               return eth_err(port_id, diag);
+               ret = eth_err(port_id, diag);
+               goto rollback;
        }
 
        return 0;
+
+rollback:
+       memcpy(&dev->data->dev_conf, &orig_conf, sizeof(dev->data->dev_conf));
+
+       return ret;
 }
 
 void
 _rte_eth_dev_reset(struct rte_eth_dev *dev)
 {
        if (dev->data->dev_started) {
-               RTE_PMD_DEBUG_TRACE(
-                       "port %d must be stopped to allow reset\n",
+               RTE_ETHDEV_LOG(ERR, "Port %u must be stopped to allow reset\n",
                        dev->data->port_id);
                return;
        }
@@ -1230,19 +1372,14 @@ _rte_eth_dev_reset(struct rte_eth_dev *dev)
 }
 
 static void
-rte_eth_dev_config_restore(uint16_t port_id)
+rte_eth_dev_mac_restore(struct rte_eth_dev *dev,
+                       struct rte_eth_dev_info *dev_info)
 {
-       struct rte_eth_dev *dev;
-       struct rte_eth_dev_info dev_info;
-       struct ether_addr *addr;
+       struct rte_ether_addr *addr;
        uint16_t i;
        uint32_t pool = 0;
        uint64_t pool_mask;
 
-       dev = &rte_eth_devices[port_id];
-
-       rte_eth_dev_info_get(port_id, &dev_info);
-
        /* replay MAC address configuration including default MAC */
        addr = &dev->data->mac_addrs[0];
        if (*dev->dev_ops->mac_addr_set != NULL)
@@ -1251,11 +1388,11 @@ rte_eth_dev_config_restore(uint16_t port_id)
                (*dev->dev_ops->mac_addr_add)(dev, addr, 0, pool);
 
        if (*dev->dev_ops->mac_addr_add != NULL) {
-               for (i = 1; i < dev_info.max_mac_addrs; i++) {
+               for (i = 1; i < dev_info->max_mac_addrs; i++) {
                        addr = &dev->data->mac_addrs[i];
 
                        /* skip zero address */
-                       if (is_zero_ether_addr(addr))
+                       if (rte_is_zero_ether_addr(addr))
                                continue;
 
                        pool = 0;
@@ -1270,25 +1407,81 @@ rte_eth_dev_config_restore(uint16_t port_id)
                        } while (pool_mask);
                }
        }
+}
+
+static int
+rte_eth_dev_config_restore(struct rte_eth_dev *dev,
+                          struct rte_eth_dev_info *dev_info, uint16_t port_id)
+{
+       int ret;
+
+       if (!(*dev_info->dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR))
+               rte_eth_dev_mac_restore(dev, dev_info);
 
        /* replay promiscuous configuration */
-       if (rte_eth_promiscuous_get(port_id) == 1)
-               rte_eth_promiscuous_enable(port_id);
-       else if (rte_eth_promiscuous_get(port_id) == 0)
-               rte_eth_promiscuous_disable(port_id);
+       /*
+        * use callbacks directly since we don't need port_id check and
+        * would like to bypass the same value set
+        */
+       if (rte_eth_promiscuous_get(port_id) == 1 &&
+           *dev->dev_ops->promiscuous_enable != NULL) {
+               ret = eth_err(port_id,
+                             (*dev->dev_ops->promiscuous_enable)(dev));
+               if (ret != 0 && ret != -ENOTSUP) {
+                       RTE_ETHDEV_LOG(ERR,
+                               "Failed to enable promiscuous mode for device (port %u): %s\n",
+                               port_id, rte_strerror(-ret));
+                       return ret;
+               }
+       } else if (rte_eth_promiscuous_get(port_id) == 0 &&
+                  *dev->dev_ops->promiscuous_disable != NULL) {
+               ret = eth_err(port_id,
+                             (*dev->dev_ops->promiscuous_disable)(dev));
+               if (ret != 0 && ret != -ENOTSUP) {
+                       RTE_ETHDEV_LOG(ERR,
+                               "Failed to disable promiscuous mode for device (port %u): %s\n",
+                               port_id, rte_strerror(-ret));
+                       return ret;
+               }
+       }
 
        /* replay all multicast configuration */
-       if (rte_eth_allmulticast_get(port_id) == 1)
-               rte_eth_allmulticast_enable(port_id);
-       else if (rte_eth_allmulticast_get(port_id) == 0)
-               rte_eth_allmulticast_disable(port_id);
+       /*
+        * use callbacks directly since we don't need port_id check and
+        * would like to bypass the same value set
+        */
+       if (rte_eth_allmulticast_get(port_id) == 1 &&
+           *dev->dev_ops->allmulticast_enable != NULL) {
+               ret = eth_err(port_id,
+                             (*dev->dev_ops->allmulticast_enable)(dev));
+               if (ret != 0 && ret != -ENOTSUP) {
+                       RTE_ETHDEV_LOG(ERR,
+                               "Failed to enable allmulticast mode for device (port %u): %s\n",
+                               port_id, rte_strerror(-ret));
+                       return ret;
+               }
+       } else if (rte_eth_allmulticast_get(port_id) == 0 &&
+                  *dev->dev_ops->allmulticast_disable != NULL) {
+               ret = eth_err(port_id,
+                             (*dev->dev_ops->allmulticast_disable)(dev));
+               if (ret != 0 && ret != -ENOTSUP) {
+                       RTE_ETHDEV_LOG(ERR,
+                               "Failed to disable allmulticast mode for device (port %u): %s\n",
+                               port_id, rte_strerror(-ret));
+                       return ret;
+               }
+       }
+
+       return 0;
 }
 
 int
 rte_eth_dev_start(uint16_t port_id)
 {
        struct rte_eth_dev *dev;
+       struct rte_eth_dev_info dev_info;
        int diag;
+       int ret;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
@@ -1297,19 +1490,34 @@ rte_eth_dev_start(uint16_t port_id)
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
 
        if (dev->data->dev_started != 0) {
-               RTE_PMD_DEBUG_TRACE("Device with port_id=%" PRIu16
-                       " already started\n",
+               RTE_ETHDEV_LOG(INFO,
+                       "Device with port_id=%"PRIu16" already started\n",
                        port_id);
                return 0;
        }
 
+       ret = rte_eth_dev_info_get(port_id, &dev_info);
+       if (ret != 0)
+               return ret;
+
+       /* Lets restore MAC now if device does not support live change */
+       if (*dev_info.dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR)
+               rte_eth_dev_mac_restore(dev, &dev_info);
+
        diag = (*dev->dev_ops->dev_start)(dev);
        if (diag == 0)
                dev->data->dev_started = 1;
        else
                return eth_err(port_id, diag);
 
-       rte_eth_dev_config_restore(port_id);
+       ret = rte_eth_dev_config_restore(dev, &dev_info, port_id);
+       if (ret != 0) {
+               RTE_ETHDEV_LOG(ERR,
+                       "Error during restoring configuration for device (port %u): %s\n",
+                       port_id, rte_strerror(-ret));
+               rte_eth_dev_stop(port_id);
+               return ret;
+       }
 
        if (dev->data->dev_conf.intr_conf.lsc == 0) {
                RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
@@ -1329,8 +1537,8 @@ rte_eth_dev_stop(uint16_t port_id)
        RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_stop);
 
        if (dev->data->dev_started == 0) {
-               RTE_PMD_DEBUG_TRACE("Device with port_id=%" PRIu16
-                       " already stopped\n",
+               RTE_ETHDEV_LOG(INFO,
+                       "Device with port_id=%"PRIu16" already stopped\n",
                        port_id);
                return;
        }
@@ -1377,6 +1585,16 @@ rte_eth_dev_close(uint16_t port_id)
        dev->data->dev_started = 0;
        (*dev->dev_ops->dev_close)(dev);
 
+       /* check behaviour flag - temporary for PMD migration */
+       if ((dev->data->dev_flags & RTE_ETH_DEV_CLOSE_REMOVE) != 0) {
+               /* new behaviour: send event + reset state + free all data */
+               rte_eth_dev_release_port(dev);
+               return;
+       }
+       RTE_ETHDEV_LOG(DEBUG, "Port closing is using an old behaviour.\n"
+                       "The driver %s should migrate to the new behaviour.\n",
+                       dev->device->driver->name);
+       /* old behaviour: only free queue arrays */
        dev->data->nb_rx_queues = 0;
        rte_free(dev->data->rx_queues);
        dev->data->rx_queues = NULL;
@@ -1402,7 +1620,7 @@ rte_eth_dev_reset(uint16_t port_id)
        return eth_err(port_id, ret);
 }
 
-int __rte_experimental
+int
 rte_eth_dev_is_removed(uint16_t port_id)
 {
        struct rte_eth_dev *dev;
@@ -1442,11 +1660,15 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 
        dev = &rte_eth_devices[port_id];
        if (rx_queue_id >= dev->data->nb_rx_queues) {
-               RTE_PMD_DEBUG_TRACE("Invalid RX queue_id=%d\n", rx_queue_id);
+               RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
+               return -EINVAL;
+       }
+
+       if (mp == NULL) {
+               RTE_ETHDEV_LOG(ERR, "Invalid null mempool pointer\n");
                return -EINVAL;
        }
 
-       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_setup, -ENOTSUP);
 
        /*
@@ -1454,25 +1676,25 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
         * This value must be provided in the private data of the memory pool.
         * First check that the memory pool has a valid private data.
         */
-       rte_eth_dev_info_get(port_id, &dev_info);
+       ret = rte_eth_dev_info_get(port_id, &dev_info);
+       if (ret != 0)
+               return ret;
+
        if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
-               RTE_PMD_DEBUG_TRACE("%s private_data_size %d < %d\n",
-                               mp->name, (int) mp->private_data_size,
-                               (int) sizeof(struct rte_pktmbuf_pool_private));
+               RTE_ETHDEV_LOG(ERR, "%s private_data_size %d < %d\n",
+                       mp->name, (int)mp->private_data_size,
+                       (int)sizeof(struct rte_pktmbuf_pool_private));
                return -ENOSPC;
        }
        mbp_buf_size = rte_pktmbuf_data_room_size(mp);
 
        if ((mbp_buf_size - RTE_PKTMBUF_HEADROOM) < dev_info.min_rx_bufsize) {
-               RTE_PMD_DEBUG_TRACE("%s mbuf_data_room_size %d < %d "
-                               "(RTE_PKTMBUF_HEADROOM=%d + min_rx_bufsize(dev)"
-                               "=%d)\n",
-                               mp->name,
-                               (int)mbp_buf_size,
-                               (int)(RTE_PKTMBUF_HEADROOM +
-                                     dev_info.min_rx_bufsize),
-                               (int)RTE_PKTMBUF_HEADROOM,
-                               (int)dev_info.min_rx_bufsize);
+               RTE_ETHDEV_LOG(ERR,
+                       "%s mbuf_data_room_size %d < %d (RTE_PKTMBUF_HEADROOM=%d + min_rx_bufsize(dev)=%d)\n",
+                       mp->name, (int)mbp_buf_size,
+                       (int)(RTE_PKTMBUF_HEADROOM + dev_info.min_rx_bufsize),
+                       (int)RTE_PKTMBUF_HEADROOM,
+                       (int)dev_info.min_rx_bufsize);
                return -EINVAL;
        }
 
@@ -1488,10 +1710,9 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
                        nb_rx_desc < dev_info.rx_desc_lim.nb_min ||
                        nb_rx_desc % dev_info.rx_desc_lim.nb_align != 0) {
 
-               RTE_PMD_DEBUG_TRACE("Invalid value for nb_rx_desc(=%hu), "
-                       "should be: <= %hu, = %hu, and a product of %hu\n",
-                       nb_rx_desc,
-                       dev_info.rx_desc_lim.nb_max,
+               RTE_ETHDEV_LOG(ERR,
+                       "Invalid value for nb_rx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu\n",
+                       nb_rx_desc, dev_info.rx_desc_lim.nb_max,
                        dev_info.rx_desc_lim.nb_min,
                        dev_info.rx_desc_lim.nb_align);
                return -EINVAL;
@@ -1502,8 +1723,9 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
                        RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP))
                return -EBUSY;
 
-       if (dev->data->rx_queue_state[rx_queue_id] !=
-               RTE_ETH_QUEUE_STATE_STOPPED)
+       if (dev->data->dev_started &&
+               (dev->data->rx_queue_state[rx_queue_id] !=
+                       RTE_ETH_QUEUE_STATE_STOPPED))
                return -EBUSY;
 
        rxq = dev->data->rx_queues;
@@ -1518,14 +1740,6 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
                rx_conf = &dev_info.default_rxconf;
 
        local_conf = *rx_conf;
-       if (dev->data->dev_conf.rxmode.ignore_offload_bitfield == 0) {
-               /**
-                * Reflect port offloads to queue offloads in order for
-                * offloads to not be discarded.
-                */
-               rte_eth_convert_rx_offload_bitfield(&dev->data->dev_conf.rxmode,
-                                                   &local_conf.offloads);
-       }
 
        /*
         * If an offloading has already been enabled in
@@ -1547,16 +1761,13 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
         */
        if ((local_conf.offloads & dev_info.rx_queue_offload_capa) !=
             local_conf.offloads) {
-               ethdev_log(ERR, "Ethdev port_id=%d rx_queue_id=%d, new "
-                               "added offloads 0x%" PRIx64 " must be "
-                               "within pre-queue offload capabilities 0x%"
-                               PRIx64 " in %s()\n",
-                               port_id,
-                               rx_queue_id,
-                               local_conf.offloads,
-                               dev_info.rx_queue_offload_capa,
-                               __func__);
-               /* Will return -EINVAL in the next release */
+               RTE_ETHDEV_LOG(ERR,
+                       "Ethdev port_id=%d rx_queue_id=%d, new added offloads 0x%"PRIx64" must be "
+                       "within per-queue offload capabilities 0x%"PRIx64" in %s()\n",
+                       port_id, rx_queue_id, local_conf.offloads,
+                       dev_info.rx_queue_offload_capa,
+                       __func__);
+               return -EINVAL;
        }
 
        ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc,
@@ -1570,53 +1781,76 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
        return eth_err(port_id, ret);
 }
 
-/**
- * Convert from tx offloads to txq_flags.
- */
-static void
-rte_eth_convert_tx_offload(const uint64_t tx_offloads, uint32_t *txq_flags)
-{
-       uint32_t flags = 0;
-
-       if (!(tx_offloads & DEV_TX_OFFLOAD_MULTI_SEGS))
-               flags |= ETH_TXQ_FLAGS_NOMULTSEGS;
-       if (!(tx_offloads & DEV_TX_OFFLOAD_VLAN_INSERT))
-               flags |= ETH_TXQ_FLAGS_NOVLANOFFL;
-       if (!(tx_offloads & DEV_TX_OFFLOAD_SCTP_CKSUM))
-               flags |= ETH_TXQ_FLAGS_NOXSUMSCTP;
-       if (!(tx_offloads & DEV_TX_OFFLOAD_UDP_CKSUM))
-               flags |= ETH_TXQ_FLAGS_NOXSUMUDP;
-       if (!(tx_offloads & DEV_TX_OFFLOAD_TCP_CKSUM))
-               flags |= ETH_TXQ_FLAGS_NOXSUMTCP;
-       if (tx_offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
-               flags |= ETH_TXQ_FLAGS_NOREFCOUNT | ETH_TXQ_FLAGS_NOMULTMEMP;
-
-       *txq_flags = flags;
-}
-
-/**
- * A conversion function from txq_flags API.
- */
-static void
-rte_eth_convert_txq_flags(const uint32_t txq_flags, uint64_t *tx_offloads)
+int
+rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
+                              uint16_t nb_rx_desc,
+                              const struct rte_eth_hairpin_conf *conf)
 {
-       uint64_t offloads = 0;
+       int ret;
+       struct rte_eth_dev *dev;
+       struct rte_eth_hairpin_cap cap;
+       void **rxq;
+       int i;
+       int count;
 
-       if (!(txq_flags & ETH_TXQ_FLAGS_NOMULTSEGS))
-               offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
-       if (!(txq_flags & ETH_TXQ_FLAGS_NOVLANOFFL))
-               offloads |= DEV_TX_OFFLOAD_VLAN_INSERT;
-       if (!(txq_flags & ETH_TXQ_FLAGS_NOXSUMSCTP))
-               offloads |= DEV_TX_OFFLOAD_SCTP_CKSUM;
-       if (!(txq_flags & ETH_TXQ_FLAGS_NOXSUMUDP))
-               offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
-       if (!(txq_flags & ETH_TXQ_FLAGS_NOXSUMTCP))
-               offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
-       if ((txq_flags & ETH_TXQ_FLAGS_NOREFCOUNT) &&
-           (txq_flags & ETH_TXQ_FLAGS_NOMULTMEMP))
-               offloads |= DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
-       *tx_offloads = offloads;
+       dev = &rte_eth_devices[port_id];
+       if (rx_queue_id >= dev->data->nb_rx_queues) {
+               RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
+               return -EINVAL;
+       }
+       ret = rte_eth_dev_hairpin_capability_get(port_id, &cap);
+       if (ret != 0)
+               return ret;
+       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_hairpin_queue_setup,
+                               -ENOTSUP);
+       /* if nb_rx_desc is zero use max number of desc from the driver. */
+       if (nb_rx_desc == 0)
+               nb_rx_desc = cap.max_nb_desc;
+       if (nb_rx_desc > cap.max_nb_desc) {
+               RTE_ETHDEV_LOG(ERR,
+                       "Invalid value for nb_rx_desc(=%hu), should be: <= %hu",
+                       nb_rx_desc, cap.max_nb_desc);
+               return -EINVAL;
+       }
+       if (conf->peer_count > cap.max_rx_2_tx) {
+               RTE_ETHDEV_LOG(ERR,
+                       "Invalid value for number of peers for Rx queue(=%hu), should be: <= %hu",
+                       conf->peer_count, cap.max_rx_2_tx);
+               return -EINVAL;
+       }
+       if (conf->peer_count == 0) {
+               RTE_ETHDEV_LOG(ERR,
+                       "Invalid value for number of peers for Rx queue(=%hu), should be: > 0",
+                       conf->peer_count);
+               return -EINVAL;
+       }
+       for (i = 0, count = 0; i < dev->data->nb_rx_queues &&
+            cap.max_nb_queues != UINT16_MAX; i++) {
+               if (i == rx_queue_id || rte_eth_dev_is_rx_hairpin_queue(dev, i))
+                       count++;
+       }
+       if (count > cap.max_nb_queues) {
+               RTE_ETHDEV_LOG(ERR, "To many Rx hairpin queues max is %d",
+               cap.max_nb_queues);
+               return -EINVAL;
+       }
+       if (dev->data->dev_started)
+               return -EBUSY;
+       rxq = dev->data->rx_queues;
+       if (rxq[rx_queue_id] != NULL) {
+               RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_release,
+                                       -ENOTSUP);
+               (*dev->dev_ops->rx_queue_release)(rxq[rx_queue_id]);
+               rxq[rx_queue_id] = NULL;
+       }
+       ret = (*dev->dev_ops->rx_hairpin_queue_setup)(dev, rx_queue_id,
+                                                     nb_rx_desc, conf);
+       if (ret == 0)
+               dev->data->rx_queue_state[rx_queue_id] =
+                       RTE_ETH_QUEUE_STATE_HAIRPIN;
+       return eth_err(port_id, ret);
 }
 
 int
@@ -1628,19 +1862,21 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
        struct rte_eth_dev_info dev_info;
        struct rte_eth_txconf local_conf;
        void **txq;
+       int ret;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
        dev = &rte_eth_devices[port_id];
        if (tx_queue_id >= dev->data->nb_tx_queues) {
-               RTE_PMD_DEBUG_TRACE("Invalid TX queue_id=%d\n", tx_queue_id);
+               RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
                return -EINVAL;
        }
 
-       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_setup, -ENOTSUP);
 
-       rte_eth_dev_info_get(port_id, &dev_info);
+       ret = rte_eth_dev_info_get(port_id, &dev_info);
+       if (ret != 0)
+               return ret;
 
        /* Use default specified by driver, if nb_tx_desc is zero */
        if (nb_tx_desc == 0) {
@@ -1652,12 +1888,11 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
        if (nb_tx_desc > dev_info.tx_desc_lim.nb_max ||
            nb_tx_desc < dev_info.tx_desc_lim.nb_min ||
            nb_tx_desc % dev_info.tx_desc_lim.nb_align != 0) {
-               RTE_PMD_DEBUG_TRACE("Invalid value for nb_tx_desc(=%hu), "
-                               "should be: <= %hu, = %hu, and a product of %hu\n",
-                               nb_tx_desc,
-                               dev_info.tx_desc_lim.nb_max,
-                               dev_info.tx_desc_lim.nb_min,
-                               dev_info.tx_desc_lim.nb_align);
+               RTE_ETHDEV_LOG(ERR,
+                       "Invalid value for nb_tx_desc(=%hu), should be: <= %hu, >= %hu, and a product of %hu\n",
+                       nb_tx_desc, dev_info.tx_desc_lim.nb_max,
+                       dev_info.tx_desc_lim.nb_min,
+                       dev_info.tx_desc_lim.nb_align);
                return -EINVAL;
        }
 
@@ -1666,8 +1901,9 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
                        RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP))
                return -EBUSY;
 
-       if (dev->data->tx_queue_state[tx_queue_id] !=
-               RTE_ETH_QUEUE_STATE_STOPPED)
+       if (dev->data->dev_started &&
+               (dev->data->tx_queue_state[tx_queue_id] !=
+                       RTE_ETH_QUEUE_STATE_STOPPED))
                return -EBUSY;
 
        txq = dev->data->tx_queues;
@@ -1681,15 +1917,7 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
        if (tx_conf == NULL)
                tx_conf = &dev_info.default_txconf;
 
-       /*
-        * Convert between the offloads API to enable PMDs to support
-        * only one of them.
-        */
        local_conf = *tx_conf;
-       if (!(tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE)) {
-               rte_eth_convert_txq_flags(tx_conf->txq_flags,
-                                         &local_conf.offloads);
-       }
 
        /*
         * If an offloading has already been enabled in
@@ -1711,22 +1939,90 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
         */
        if ((local_conf.offloads & dev_info.tx_queue_offload_capa) !=
             local_conf.offloads) {
-               ethdev_log(ERR, "Ethdev port_id=%d tx_queue_id=%d, new "
-                               "added offloads 0x%" PRIx64 " must be "
-                               "within pre-queue offload capabilities 0x%"
-                               PRIx64 " in %s()\n",
-                               port_id,
-                               tx_queue_id,
-                               local_conf.offloads,
-                               dev_info.tx_queue_offload_capa,
-                               __func__);
-               /* Will return -EINVAL in the next release */
+               RTE_ETHDEV_LOG(ERR,
+                       "Ethdev port_id=%d tx_queue_id=%d, new added offloads 0x%"PRIx64" must be "
+                       "within per-queue offload capabilities 0x%"PRIx64" in %s()\n",
+                       port_id, tx_queue_id, local_conf.offloads,
+                       dev_info.tx_queue_offload_capa,
+                       __func__);
+               return -EINVAL;
        }
 
        return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev,
                       tx_queue_id, nb_tx_desc, socket_id, &local_conf));
 }
 
+int
+rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
+                              uint16_t nb_tx_desc,
+                              const struct rte_eth_hairpin_conf *conf)
+{
+       struct rte_eth_dev *dev;
+       struct rte_eth_hairpin_cap cap;
+       void **txq;
+       int i;
+       int count;
+       int ret;
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+       dev = &rte_eth_devices[port_id];
+       if (tx_queue_id >= dev->data->nb_tx_queues) {
+               RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
+               return -EINVAL;
+       }
+       ret = rte_eth_dev_hairpin_capability_get(port_id, &cap);
+       if (ret != 0)
+               return ret;
+       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_hairpin_queue_setup,
+                               -ENOTSUP);
+       /* if nb_rx_desc is zero use max number of desc from the driver. */
+       if (nb_tx_desc == 0)
+               nb_tx_desc = cap.max_nb_desc;
+       if (nb_tx_desc > cap.max_nb_desc) {
+               RTE_ETHDEV_LOG(ERR,
+                       "Invalid value for nb_tx_desc(=%hu), should be: <= %hu",
+                       nb_tx_desc, cap.max_nb_desc);
+               return -EINVAL;
+       }
+       if (conf->peer_count > cap.max_tx_2_rx) {
+               RTE_ETHDEV_LOG(ERR,
+                       "Invalid value for number of peers for Tx queue(=%hu), should be: <= %hu",
+                       conf->peer_count, cap.max_tx_2_rx);
+               return -EINVAL;
+       }
+       if (conf->peer_count == 0) {
+               RTE_ETHDEV_LOG(ERR,
+                       "Invalid value for number of peers for Tx queue(=%hu), should be: > 0",
+                       conf->peer_count);
+               return -EINVAL;
+       }
+       for (i = 0, count = 0; i < dev->data->nb_tx_queues &&
+            cap.max_nb_queues != UINT16_MAX; i++) {
+               if (i == tx_queue_id || rte_eth_dev_is_tx_hairpin_queue(dev, i))
+                       count++;
+       }
+       if (count > cap.max_nb_queues) {
+               RTE_ETHDEV_LOG(ERR, "To many Tx hairpin queues max is %d",
+               cap.max_nb_queues);
+               return -EINVAL;
+       }
+       if (dev->data->dev_started)
+               return -EBUSY;
+       txq = dev->data->tx_queues;
+       if (txq[tx_queue_id] != NULL) {
+               RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_release,
+                                       -ENOTSUP);
+               (*dev->dev_ops->tx_queue_release)(txq[tx_queue_id]);
+               txq[tx_queue_id] = NULL;
+       }
+       ret = (*dev->dev_ops->tx_hairpin_queue_setup)
+               (dev, tx_queue_id, nb_tx_desc, conf);
+       if (ret == 0)
+               dev->data->tx_queue_state[tx_queue_id] =
+                       RTE_ETH_QUEUE_STATE_HAIRPIN;
+       return eth_err(port_id, ret);
+}
+
 void
 rte_eth_tx_buffer_drop_callback(struct rte_mbuf **pkts, uint16_t unsent,
                void *userdata __rte_unused)
@@ -1792,30 +2088,46 @@ rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
        return eth_err(port_id, ret);
 }
 
-void
+int
 rte_eth_promiscuous_enable(uint16_t port_id)
 {
        struct rte_eth_dev *dev;
+       int diag = 0;
 
-       RTE_ETH_VALID_PORTID_OR_RET(port_id);
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
 
-       RTE_FUNC_PTR_OR_RET(*dev->dev_ops->promiscuous_enable);
-       (*dev->dev_ops->promiscuous_enable)(dev);
-       dev->data->promiscuous = 1;
+       if (dev->data->promiscuous == 1)
+               return 0;
+
+       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_enable, -ENOTSUP);
+
+       diag = (*dev->dev_ops->promiscuous_enable)(dev);
+       dev->data->promiscuous = (diag == 0) ? 1 : 0;
+
+       return eth_err(port_id, diag);
 }
 
-void
+int
 rte_eth_promiscuous_disable(uint16_t port_id)
 {
        struct rte_eth_dev *dev;
+       int diag = 0;
 
-       RTE_ETH_VALID_PORTID_OR_RET(port_id);
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
 
-       RTE_FUNC_PTR_OR_RET(*dev->dev_ops->promiscuous_disable);
+       if (dev->data->promiscuous == 0)
+               return 0;
+
+       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_disable, -ENOTSUP);
+
        dev->data->promiscuous = 0;
-       (*dev->dev_ops->promiscuous_disable)(dev);
+       diag = (*dev->dev_ops->promiscuous_disable)(dev);
+       if (diag != 0)
+               dev->data->promiscuous = 1;
+
+       return eth_err(port_id, diag);
 }
 
 int
@@ -1829,30 +2141,44 @@ rte_eth_promiscuous_get(uint16_t port_id)
        return dev->data->promiscuous;
 }
 
-void
+int
 rte_eth_allmulticast_enable(uint16_t port_id)
 {
        struct rte_eth_dev *dev;
+       int diag;
 
-       RTE_ETH_VALID_PORTID_OR_RET(port_id);
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
 
-       RTE_FUNC_PTR_OR_RET(*dev->dev_ops->allmulticast_enable);
-       (*dev->dev_ops->allmulticast_enable)(dev);
-       dev->data->all_multicast = 1;
+       if (dev->data->all_multicast == 1)
+               return 0;
+
+       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->allmulticast_enable, -ENOTSUP);
+       diag = (*dev->dev_ops->allmulticast_enable)(dev);
+       dev->data->all_multicast = (diag == 0) ? 1 : 0;
+
+       return eth_err(port_id, diag);
 }
 
-void
+int
 rte_eth_allmulticast_disable(uint16_t port_id)
 {
        struct rte_eth_dev *dev;
+       int diag;
 
-       RTE_ETH_VALID_PORTID_OR_RET(port_id);
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
 
-       RTE_FUNC_PTR_OR_RET(*dev->dev_ops->allmulticast_disable);
+       if (dev->data->all_multicast == 0)
+               return 0;
+
+       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->allmulticast_disable, -ENOTSUP);
        dev->data->all_multicast = 0;
-       (*dev->dev_ops->allmulticast_disable)(dev);
+       diag = (*dev->dev_ops->allmulticast_disable)(dev);
+       if (diag != 0)
+               dev->data->all_multicast = 1;
+
+       return eth_err(port_id, diag);
 }
 
 int
@@ -1866,40 +2192,44 @@ rte_eth_allmulticast_get(uint16_t port_id)
        return dev->data->all_multicast;
 }
 
-void
+int
 rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
 {
        struct rte_eth_dev *dev;
 
-       RTE_ETH_VALID_PORTID_OR_RET(port_id);
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
 
        if (dev->data->dev_conf.intr_conf.lsc &&
            dev->data->dev_started)
                rte_eth_linkstatus_get(dev, eth_link);
        else {
-               RTE_FUNC_PTR_OR_RET(*dev->dev_ops->link_update);
+               RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
                (*dev->dev_ops->link_update)(dev, 1);
                *eth_link = dev->data->dev_link;
        }
+
+       return 0;
 }
 
-void
+int
 rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 {
        struct rte_eth_dev *dev;
 
-       RTE_ETH_VALID_PORTID_OR_RET(port_id);
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
 
        if (dev->data->dev_conf.intr_conf.lsc &&
            dev->data->dev_started)
                rte_eth_linkstatus_get(dev, eth_link);
        else {
-               RTE_FUNC_PTR_OR_RET(*dev->dev_ops->link_update);
+               RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
                (*dev->dev_ops->link_update)(dev, 0);
                *eth_link = dev->data->dev_link;
        }
+
+       return 0;
 }
 
 int
@@ -1921,12 +2251,16 @@ int
 rte_eth_stats_reset(uint16_t port_id)
 {
        struct rte_eth_dev *dev;
+       int ret;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
 
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_reset, -ENOTSUP);
-       (*dev->dev_ops->stats_reset)(dev);
+       ret = (*dev->dev_ops->stats_reset)(dev);
+       if (ret != 0)
+               return eth_err(port_id, ret);
+
        dev->data->rx_mbuf_alloc_failed = 0;
 
        return 0;
@@ -1984,19 +2318,19 @@ rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
        if (!id) {
-               RTE_PMD_DEBUG_TRACE("Error: id pointer is NULL\n");
+               RTE_ETHDEV_LOG(ERR, "Id pointer is NULL\n");
                return -ENOMEM;
        }
 
        if (!xstat_name) {
-               RTE_PMD_DEBUG_TRACE("Error: xstat_name pointer is NULL\n");
+               RTE_ETHDEV_LOG(ERR, "xstat_name pointer is NULL\n");
                return -ENOMEM;
        }
 
        /* Get count */
        cnt_xstats = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL);
        if (cnt_xstats  < 0) {
-               RTE_PMD_DEBUG_TRACE("Error: Cannot get count of xstats\n");
+               RTE_ETHDEV_LOG(ERR, "Cannot get count of xstats\n");
                return -ENODEV;
        }
 
@@ -2005,7 +2339,7 @@ rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
 
        if (cnt_xstats != rte_eth_xstats_get_names_by_id(
                        port_id, xstats_names, cnt_xstats, NULL)) {
-               RTE_PMD_DEBUG_TRACE("Error: Cannot get xstats lookup\n");
+               RTE_ETHDEV_LOG(ERR, "Cannot get xstats lookup\n");
                return -1;
        }
 
@@ -2029,9 +2363,9 @@ rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
        uint16_t num_q;
 
        for (idx = 0; idx < RTE_NB_STATS; idx++) {
-               snprintf(xstats_names[cnt_used_entries].name,
-                       sizeof(xstats_names[0].name),
-                       "%s", rte_stats_strings[idx].name);
+               strlcpy(xstats_names[cnt_used_entries].name,
+                       rte_stats_strings[idx].name,
+                       sizeof(xstats_names[0].name));
                cnt_used_entries++;
        }
        num_q = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
@@ -2128,7 +2462,7 @@ rte_eth_xstats_get_names_by_id(uint16_t port_id,
                sizeof(struct rte_eth_xstat_name));
 
        if (!xstats_names_copy) {
-               RTE_PMD_DEBUG_TRACE("ERROR: can't allocate memory");
+               RTE_ETHDEV_LOG(ERR, "Can't allocate memory\n");
                return -ENOMEM;
        }
 
@@ -2156,7 +2490,7 @@ rte_eth_xstats_get_names_by_id(uint16_t port_id,
        /* Filter stats */
        for (i = 0; i < size; i++) {
                if (ids[i] >= expected_entries) {
-                       RTE_PMD_DEBUG_TRACE("ERROR: id value isn't valid\n");
+                       RTE_ETHDEV_LOG(ERR, "Id value isn't valid\n");
                        free(xstats_names_copy);
                        return -1;
                }
@@ -2341,7 +2675,7 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
        /* Filter stats */
        for (i = 0; i < size; i++) {
                if (ids[i] >= expected_entries) {
-                       RTE_PMD_DEBUG_TRACE("ERROR: id value isn't valid\n");
+                       RTE_ETHDEV_LOG(ERR, "Id value isn't valid\n");
                        return -1;
                }
                values[i] = xstats[ids[i]].value;
@@ -2402,22 +2736,20 @@ rte_eth_xstats_get(uint16_t port_id, struct rte_eth_xstat *xstats,
 }
 
 /* reset ethdev extended statistics */
-void
+int
 rte_eth_xstats_reset(uint16_t port_id)
 {
        struct rte_eth_dev *dev;
 
-       RTE_ETH_VALID_PORTID_OR_RET(port_id);
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
 
        /* implemented by the driver */
-       if (dev->dev_ops->xstats_reset != NULL) {
-               (*dev->dev_ops->xstats_reset)(dev);
-               return;
-       }
+       if (dev->dev_ops->xstats_reset != NULL)
+               return eth_err(port_id, (*dev->dev_ops->xstats_reset)(dev));
 
        /* fallback to default */
-       rte_eth_stats_reset(port_id);
+       return rte_eth_stats_reset(port_id);
 }
 
 static int
@@ -2431,6 +2763,16 @@ set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id, uint8_t stat_idx,
        dev = &rte_eth_devices[port_id];
 
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_stats_mapping_set, -ENOTSUP);
+
+       if (is_rx && (queue_id >= dev->data->nb_rx_queues))
+               return -EINVAL;
+
+       if (!is_rx && (queue_id >= dev->data->nb_tx_queues))
+               return -EINVAL;
+
+       if (stat_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
+               return -EINVAL;
+
        return (*dev->dev_ops->queue_stats_mapping_set)
                        (dev, queue_id, stat_idx, is_rx);
 }
@@ -2466,35 +2808,49 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
                                                        fw_version, fw_size));
 }
 
-void
+int
 rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 {
        struct rte_eth_dev *dev;
-       struct rte_eth_txconf *txconf;
        const struct rte_eth_desc_lim lim = {
                .nb_max = UINT16_MAX,
                .nb_min = 0,
                .nb_align = 1,
+               .nb_seg_max = UINT16_MAX,
+               .nb_mtu_seg_max = UINT16_MAX,
        };
+       int diag;
 
-       RTE_ETH_VALID_PORTID_OR_RET(port_id);
+       /*
+        * Init dev_info before port_id check since caller does not have
+        * return status and does not know if get is successful or not.
+        */
+       memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
 
-       memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
        dev_info->rx_desc_lim = lim;
        dev_info->tx_desc_lim = lim;
        dev_info->device = dev->device;
+       dev_info->min_mtu = RTE_ETHER_MIN_MTU;
+       dev_info->max_mtu = UINT16_MAX;
+
+       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
+       diag = (*dev->dev_ops->dev_infos_get)(dev, dev_info);
+       if (diag != 0) {
+               /* Cleanup already filled in device information */
+               memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
+               return eth_err(port_id, diag);
+       }
 
-       RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
-       (*dev->dev_ops->dev_infos_get)(dev, dev_info);
        dev_info->driver_name = dev->device->driver->name;
        dev_info->nb_rx_queues = dev->data->nb_rx_queues;
        dev_info->nb_tx_queues = dev->data->nb_tx_queues;
 
        dev_info->dev_flags = &dev->data->dev_flags;
-       txconf = &dev_info->default_txconf;
-       /* convert offload to txq_flags to support legacy app */
-       rte_eth_convert_tx_offload(txconf->offloads, &txconf->txq_flags);
+
+       return 0;
 }
 
 int
@@ -2523,14 +2879,16 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
        return j;
 }
 
-void
-rte_eth_macaddr_get(uint16_t port_id, struct ether_addr *mac_addr)
+int
+rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
 {
        struct rte_eth_dev *dev;
 
-       RTE_ETH_VALID_PORTID_OR_RET(port_id);
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
-       ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
+       rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
+
+       return 0;
 }
 
 
@@ -2550,12 +2908,28 @@ int
 rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu)
 {
        int ret;
+       struct rte_eth_dev_info dev_info;
        struct rte_eth_dev *dev;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mtu_set, -ENOTSUP);
 
+       /*
+        * Check if the device supports dev_infos_get, if it does not
+        * skip min_mtu/max_mtu validation here as this requires values
+        * that are populated within the call to rte_eth_dev_info_get()
+        * which relies on dev->dev_ops->dev_infos_get.
+        */
+       if (*dev->dev_ops->dev_infos_get != NULL) {
+               ret = rte_eth_dev_info_get(port_id, &dev_info);
+               if (ret != 0)
+                       return ret;
+
+               if (mtu < dev_info.min_mtu || mtu > dev_info.max_mtu)
+                       return -EINVAL;
+       }
+
        ret = (*dev->dev_ops->mtu_set)(dev, mtu);
        if (!ret)
                dev->data->mtu = mtu;
@@ -2573,13 +2947,14 @@ rte_eth_dev_vlan_filter(uint16_t port_id, uint16_t vlan_id, int on)
        dev = &rte_eth_devices[port_id];
        if (!(dev->data->dev_conf.rxmode.offloads &
              DEV_RX_OFFLOAD_VLAN_FILTER)) {
-               RTE_PMD_DEBUG_TRACE("port %d: vlan-filtering disabled\n", port_id);
+               RTE_ETHDEV_LOG(ERR, "Port %u: vlan-filtering disabled\n",
+                       port_id);
                return -ENOSYS;
        }
 
        if (vlan_id > 4095) {
-               RTE_PMD_DEBUG_TRACE("(port_id=%d) invalid vlan_id=%u > 4095\n",
-                               port_id, (unsigned) vlan_id);
+               RTE_ETHDEV_LOG(ERR, "Port_id=%u invalid vlan_id=%u > 4095\n",
+                       port_id, vlan_id);
                return -EINVAL;
        }
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_filter_set, -ENOTSUP);
@@ -2612,7 +2987,7 @@ rte_eth_dev_set_vlan_strip_on_queue(uint16_t port_id, uint16_t rx_queue_id,
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
        if (rx_queue_id >= dev->data->nb_rx_queues) {
-               RTE_PMD_DEBUG_TRACE("Invalid rx_queue_id=%d\n", port_id);
+               RTE_ETHDEV_LOG(ERR, "Invalid rx_queue_id=%u\n", rx_queue_id);
                return -EINVAL;
        }
 
@@ -2645,53 +3020,56 @@ rte_eth_dev_set_vlan_offload(uint16_t port_id, int offload_mask)
        int mask = 0;
        int cur, org = 0;
        uint64_t orig_offloads;
+       uint64_t *dev_offloads;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
 
        /* save original values in case of failure */
        orig_offloads = dev->data->dev_conf.rxmode.offloads;
+       dev_offloads = &dev->data->dev_conf.rxmode.offloads;
 
        /*check which option changed by application*/
        cur = !!(offload_mask & ETH_VLAN_STRIP_OFFLOAD);
-       org = !!(dev->data->dev_conf.rxmode.offloads &
-                DEV_RX_OFFLOAD_VLAN_STRIP);
+       org = !!(*dev_offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
        if (cur != org) {
                if (cur)
-                       dev->data->dev_conf.rxmode.offloads |=
-                               DEV_RX_OFFLOAD_VLAN_STRIP;
+                       *dev_offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
                else
-                       dev->data->dev_conf.rxmode.offloads &=
-                               ~DEV_RX_OFFLOAD_VLAN_STRIP;
+                       *dev_offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
                mask |= ETH_VLAN_STRIP_MASK;
        }
 
        cur = !!(offload_mask & ETH_VLAN_FILTER_OFFLOAD);
-       org = !!(dev->data->dev_conf.rxmode.offloads &
-                DEV_RX_OFFLOAD_VLAN_FILTER);
+       org = !!(*dev_offloads & DEV_RX_OFFLOAD_VLAN_FILTER);
        if (cur != org) {
                if (cur)
-                       dev->data->dev_conf.rxmode.offloads |=
-                               DEV_RX_OFFLOAD_VLAN_FILTER;
+                       *dev_offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
                else
-                       dev->data->dev_conf.rxmode.offloads &=
-                               ~DEV_RX_OFFLOAD_VLAN_FILTER;
+                       *dev_offloads &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
                mask |= ETH_VLAN_FILTER_MASK;
        }
 
        cur = !!(offload_mask & ETH_VLAN_EXTEND_OFFLOAD);
-       org = !!(dev->data->dev_conf.rxmode.offloads &
-                DEV_RX_OFFLOAD_VLAN_EXTEND);
+       org = !!(*dev_offloads & DEV_RX_OFFLOAD_VLAN_EXTEND);
        if (cur != org) {
                if (cur)
-                       dev->data->dev_conf.rxmode.offloads |=
-                               DEV_RX_OFFLOAD_VLAN_EXTEND;
+                       *dev_offloads |= DEV_RX_OFFLOAD_VLAN_EXTEND;
                else
-                       dev->data->dev_conf.rxmode.offloads &=
-                               ~DEV_RX_OFFLOAD_VLAN_EXTEND;
+                       *dev_offloads &= ~DEV_RX_OFFLOAD_VLAN_EXTEND;
                mask |= ETH_VLAN_EXTEND_MASK;
        }
 
+       cur = !!(offload_mask & ETH_QINQ_STRIP_OFFLOAD);
+       org = !!(*dev_offloads & DEV_RX_OFFLOAD_QINQ_STRIP);
+       if (cur != org) {
+               if (cur)
+                       *dev_offloads |= DEV_RX_OFFLOAD_QINQ_STRIP;
+               else
+                       *dev_offloads &= ~DEV_RX_OFFLOAD_QINQ_STRIP;
+               mask |= ETH_QINQ_STRIP_MASK;
+       }
+
        /*no change*/
        if (mask == 0)
                return ret;
@@ -2700,7 +3078,7 @@ rte_eth_dev_set_vlan_offload(uint16_t port_id, int offload_mask)
        ret = (*dev->dev_ops->vlan_offload_set)(dev, mask);
        if (ret) {
                /* hit an error restore  original values */
-               dev->data->dev_conf.rxmode.offloads = orig_offloads;
+               *dev_offloads = orig_offloads;
        }
 
        return eth_err(port_id, ret);
@@ -2710,23 +3088,25 @@ int
 rte_eth_dev_get_vlan_offload(uint16_t port_id)
 {
        struct rte_eth_dev *dev;
+       uint64_t *dev_offloads;
        int ret = 0;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
+       dev_offloads = &dev->data->dev_conf.rxmode.offloads;
 
-       if (dev->data->dev_conf.rxmode.offloads &
-           DEV_RX_OFFLOAD_VLAN_STRIP)
+       if (*dev_offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
                ret |= ETH_VLAN_STRIP_OFFLOAD;
 
-       if (dev->data->dev_conf.rxmode.offloads &
-           DEV_RX_OFFLOAD_VLAN_FILTER)
+       if (*dev_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
                ret |= ETH_VLAN_FILTER_OFFLOAD;
 
-       if (dev->data->dev_conf.rxmode.offloads &
-           DEV_RX_OFFLOAD_VLAN_EXTEND)
+       if (*dev_offloads & DEV_RX_OFFLOAD_VLAN_EXTEND)
                ret |= ETH_VLAN_EXTEND_OFFLOAD;
 
+       if (*dev_offloads & DEV_RX_OFFLOAD_QINQ_STRIP)
+               ret |= ETH_QINQ_STRIP_OFFLOAD;
+
        return ret;
 }
 
@@ -2761,7 +3141,7 @@ rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
-               RTE_PMD_DEBUG_TRACE("Invalid send_xon, only 0/1 allowed\n");
+               RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
                return -EINVAL;
        }
 
@@ -2778,7 +3158,7 @@ rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) {
-               RTE_PMD_DEBUG_TRACE("Invalid priority, only 0-7 allowed\n");
+               RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
                return -EINVAL;
        }
 
@@ -2819,7 +3199,7 @@ rte_eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
                return -EINVAL;
 
        if (max_rxq == 0) {
-               RTE_PMD_DEBUG_TRACE("No receive queue is available\n");
+               RTE_ETHDEV_LOG(ERR, "No receive queue is available\n");
                return -EINVAL;
        }
 
@@ -2828,8 +3208,9 @@ rte_eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
                shift = i % RTE_RETA_GROUP_SIZE;
                if ((reta_conf[idx].mask & (1ULL << shift)) &&
                        (reta_conf[idx].reta[shift] >= max_rxq)) {
-                       RTE_PMD_DEBUG_TRACE("reta_conf[%u]->reta[%u]: %u exceeds "
-                               "the maximum rxq index: %u\n", idx, shift,
+                       RTE_ETHDEV_LOG(ERR,
+                               "reta_conf[%u]->reta[%u]: %u exceeds the maximum rxq index: %u\n",
+                               idx, shift,
                                reta_conf[idx].reta[shift], max_rxq);
                        return -EINVAL;
                }
@@ -2892,17 +3273,24 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
 {
        struct rte_eth_dev *dev;
        struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, };
+       int ret;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+       ret = rte_eth_dev_info_get(port_id, &dev_info);
+       if (ret != 0)
+               return ret;
+
+       rss_conf->rss_hf = rte_eth_rss_hf_refine(rss_conf->rss_hf);
+
        dev = &rte_eth_devices[port_id];
-       rte_eth_dev_info_get(port_id, &dev_info);
        if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
            dev_info.flow_type_rss_offloads) {
-               RTE_PMD_DEBUG_TRACE("ethdev port_id=%d invalid rss_hf: "
-                                   "0x%"PRIx64", valid value: 0x%"PRIx64"\n",
-                                   port_id,
-                                   rss_conf->rss_hf,
-                                   dev_info.flow_type_rss_offloads);
+               RTE_ETHDEV_LOG(ERR,
+                       "Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64"\n",
+                       port_id, rss_conf->rss_hf,
+                       dev_info.flow_type_rss_offloads);
+               return -EINVAL;
        }
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_update, -ENOTSUP);
        return eth_err(port_id, (*dev->dev_ops->rss_hash_update)(dev,
@@ -2930,12 +3318,12 @@ rte_eth_dev_udp_tunnel_port_add(uint16_t port_id,
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        if (udp_tunnel == NULL) {
-               RTE_PMD_DEBUG_TRACE("Invalid udp_tunnel parameter\n");
+               RTE_ETHDEV_LOG(ERR, "Invalid udp_tunnel parameter\n");
                return -EINVAL;
        }
 
        if (udp_tunnel->prot_type >= RTE_TUNNEL_TYPE_MAX) {
-               RTE_PMD_DEBUG_TRACE("Invalid tunnel type\n");
+               RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n");
                return -EINVAL;
        }
 
@@ -2955,12 +3343,12 @@ rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
        dev = &rte_eth_devices[port_id];
 
        if (udp_tunnel == NULL) {
-               RTE_PMD_DEBUG_TRACE("Invalid udp_tunnel parameter\n");
+               RTE_ETHDEV_LOG(ERR, "Invalid udp_tunnel parameter\n");
                return -EINVAL;
        }
 
        if (udp_tunnel->prot_type >= RTE_TUNNEL_TYPE_MAX) {
-               RTE_PMD_DEBUG_TRACE("Invalid tunnel type\n");
+               RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n");
                return -EINVAL;
        }
 
@@ -2996,26 +3384,29 @@ rte_eth_led_off(uint16_t port_id)
  * an empty spot.
  */
 static int
-get_mac_addr_index(uint16_t port_id, const struct ether_addr *addr)
+get_mac_addr_index(uint16_t port_id, const struct rte_ether_addr *addr)
 {
        struct rte_eth_dev_info dev_info;
        struct rte_eth_dev *dev = &rte_eth_devices[port_id];
        unsigned i;
+       int ret;
 
-       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-       rte_eth_dev_info_get(port_id, &dev_info);
+       ret = rte_eth_dev_info_get(port_id, &dev_info);
+       if (ret != 0)
+               return -1;
 
        for (i = 0; i < dev_info.max_mac_addrs; i++)
-               if (memcmp(addr, &dev->data->mac_addrs[i], ETHER_ADDR_LEN) == 0)
+               if (memcmp(addr, &dev->data->mac_addrs[i],
+                               RTE_ETHER_ADDR_LEN) == 0)
                        return i;
 
        return -1;
 }
 
-static const struct ether_addr null_mac_addr;
+static const struct rte_ether_addr null_mac_addr;
 
 int
-rte_eth_dev_mac_addr_add(uint16_t port_id, struct ether_addr *addr,
+rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
                        uint32_t pool)
 {
        struct rte_eth_dev *dev;
@@ -3027,13 +3418,13 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct ether_addr *addr,
        dev = &rte_eth_devices[port_id];
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
 
-       if (is_zero_ether_addr(addr)) {
-               RTE_PMD_DEBUG_TRACE("port %d: Cannot add NULL MAC address\n",
+       if (rte_is_zero_ether_addr(addr)) {
+               RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
                        port_id);
                return -EINVAL;
        }
        if (pool >= ETH_64_POOLS) {
-               RTE_PMD_DEBUG_TRACE("pool id must be 0-%d\n", ETH_64_POOLS - 1);
+               RTE_ETHDEV_LOG(ERR, "Pool id must be 0-%d\n", ETH_64_POOLS - 1);
                return -EINVAL;
        }
 
@@ -3041,7 +3432,7 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct ether_addr *addr,
        if (index < 0) {
                index = get_mac_addr_index(port_id, &null_mac_addr);
                if (index < 0) {
-                       RTE_PMD_DEBUG_TRACE("port %d: MAC address array full\n",
+                       RTE_ETHDEV_LOG(ERR, "Port %u: MAC address array full\n",
                                port_id);
                        return -ENOSPC;
                }
@@ -3058,7 +3449,7 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct ether_addr *addr,
 
        if (ret == 0) {
                /* Update address in NIC data structure */
-               ether_addr_copy(addr, &dev->data->mac_addrs[index]);
+               rte_ether_addr_copy(addr, &dev->data->mac_addrs[index]);
 
                /* Update pool bitmap in NIC data structure */
                dev->data->mac_pool_sel[index] |= (1ULL << pool);
@@ -3068,7 +3459,7 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct ether_addr *addr,
 }
 
 int
-rte_eth_dev_mac_addr_remove(uint16_t port_id, struct ether_addr *addr)
+rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
 {
        struct rte_eth_dev *dev;
        int index;
@@ -3079,7 +3470,9 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct ether_addr *addr)
 
        index = get_mac_addr_index(port_id, addr);
        if (index == 0) {
-               RTE_PMD_DEBUG_TRACE("port %d: Cannot remove default MAC address\n", port_id);
+               RTE_ETHDEV_LOG(ERR,
+                       "Port %u: Cannot remove default MAC address\n",
+                       port_id);
                return -EADDRINUSE;
        } else if (index < 0)
                return 0;  /* Do nothing if address wasn't found */
@@ -3088,7 +3481,7 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct ether_addr *addr)
        (*dev->dev_ops->mac_addr_remove)(dev, index);
 
        /* Update address in NIC data structure */
-       ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]);
+       rte_ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]);
 
        /* reset pool bitmap */
        dev->data->mac_pool_sel[index] = 0;
@@ -3097,14 +3490,14 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct ether_addr *addr)
 }
 
 int
-rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
+rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
 {
        struct rte_eth_dev *dev;
        int ret;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
-       if (!is_valid_assigned_ether_addr(addr))
+       if (!rte_is_valid_assigned_ether_addr(addr))
                return -EINVAL;
 
        dev = &rte_eth_devices[port_id];
@@ -3115,7 +3508,7 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
                return ret;
 
        /* Update default address in NIC data structure */
-       ether_addr_copy(addr, &dev->data->mac_addrs[0]);
+       rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]);
 
        return 0;
 }
@@ -3126,26 +3519,30 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
  * an empty spot.
  */
 static int
-get_hash_mac_addr_index(uint16_t port_id, const struct ether_addr *addr)
+get_hash_mac_addr_index(uint16_t port_id, const struct rte_ether_addr *addr)
 {
        struct rte_eth_dev_info dev_info;
        struct rte_eth_dev *dev = &rte_eth_devices[port_id];
        unsigned i;
+       int ret;
+
+       ret = rte_eth_dev_info_get(port_id, &dev_info);
+       if (ret != 0)
+               return -1;
 
-       rte_eth_dev_info_get(port_id, &dev_info);
        if (!dev->data->hash_mac_addrs)
                return -1;
 
        for (i = 0; i < dev_info.max_hash_mac_addrs; i++)
                if (memcmp(addr, &dev->data->hash_mac_addrs[i],
-                       ETHER_ADDR_LEN) == 0)
+                       RTE_ETHER_ADDR_LEN) == 0)
                        return i;
 
        return -1;
 }
 
 int
-rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct ether_addr *addr,
+rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
                                uint8_t on)
 {
        int index;
@@ -3155,8 +3552,8 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct ether_addr *addr,
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
        dev = &rte_eth_devices[port_id];
-       if (is_zero_ether_addr(addr)) {
-               RTE_PMD_DEBUG_TRACE("port %d: Cannot add NULL MAC address\n",
+       if (rte_is_zero_ether_addr(addr)) {
+               RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
                        port_id);
                return -EINVAL;
        }
@@ -3168,15 +3565,16 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct ether_addr *addr,
 
        if (index < 0) {
                if (!on) {
-                       RTE_PMD_DEBUG_TRACE("port %d: the MAC address was not "
-                               "set in UTA\n", port_id);
+                       RTE_ETHDEV_LOG(ERR,
+                               "Port %u: the MAC address was not set in UTA\n",
+                               port_id);
                        return -EINVAL;
                }
 
                index = get_hash_mac_addr_index(port_id, &null_mac_addr);
                if (index < 0) {
-                       RTE_PMD_DEBUG_TRACE("port %d: MAC address array full\n",
-                                       port_id);
+                       RTE_ETHDEV_LOG(ERR, "Port %u: MAC address array full\n",
+                               port_id);
                        return -ENOSPC;
                }
        }
@@ -3186,10 +3584,10 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct ether_addr *addr,
        if (ret == 0) {
                /* Update address in NIC data structure */
                if (on)
-                       ether_addr_copy(addr,
+                       rte_ether_addr_copy(addr,
                                        &dev->data->hash_mac_addrs[index]);
                else
-                       ether_addr_copy(&null_mac_addr,
+                       rte_ether_addr_copy(&null_mac_addr,
                                        &dev->data->hash_mac_addrs[index]);
        }
 
@@ -3216,22 +3614,27 @@ int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx,
        struct rte_eth_dev *dev;
        struct rte_eth_dev_info dev_info;
        struct rte_eth_link link;
+       int ret;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+       ret = rte_eth_dev_info_get(port_id, &dev_info);
+       if (ret != 0)
+               return ret;
+
        dev = &rte_eth_devices[port_id];
-       rte_eth_dev_info_get(port_id, &dev_info);
        link = dev->data->dev_link;
 
        if (queue_idx > dev_info.max_tx_queues) {
-               RTE_PMD_DEBUG_TRACE("set queue rate limit:port %d: "
-                               "invalid queue id=%d\n", port_id, queue_idx);
+               RTE_ETHDEV_LOG(ERR,
+                       "Set queue rate limit:port %u: invalid queue id=%u\n",
+                       port_id, queue_idx);
                return -EINVAL;
        }
 
        if (tx_rate > link.link_speed) {
-               RTE_PMD_DEBUG_TRACE("set queue rate limit:invalid tx_rate=%d, "
-                               "bigger than link speed= %d\n",
+               RTE_ETHDEV_LOG(ERR,
+                       "Set queue rate limit:invalid tx_rate=%u, bigger than link speed= %d\n",
                        tx_rate, link.link_speed);
                return -EINVAL;
        }
@@ -3250,26 +3653,28 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        if (mirror_conf->rule_type == 0) {
-               RTE_PMD_DEBUG_TRACE("mirror rule type can not be 0.\n");
+               RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n");
                return -EINVAL;
        }
 
        if (mirror_conf->dst_pool >= ETH_64_POOLS) {
-               RTE_PMD_DEBUG_TRACE("Invalid dst pool, pool id must be 0-%d\n",
-                               ETH_64_POOLS - 1);
+               RTE_ETHDEV_LOG(ERR, "Invalid dst pool, pool id must be 0-%d\n",
+                       ETH_64_POOLS - 1);
                return -EINVAL;
        }
 
        if ((mirror_conf->rule_type & (ETH_MIRROR_VIRTUAL_POOL_UP |
             ETH_MIRROR_VIRTUAL_POOL_DOWN)) &&
            (mirror_conf->pool_mask == 0)) {
-               RTE_PMD_DEBUG_TRACE("Invalid mirror pool, pool mask can not be 0.\n");
+               RTE_ETHDEV_LOG(ERR,
+                       "Invalid mirror pool, pool mask can not be 0\n");
                return -EINVAL;
        }
 
        if ((mirror_conf->rule_type & ETH_MIRROR_VLAN) &&
            mirror_conf->vlan.vlan_mask == 0) {
-               RTE_PMD_DEBUG_TRACE("Invalid vlan mask, vlan mask can not be 0.\n");
+               RTE_ETHDEV_LOG(ERR,
+                       "Invalid vlan mask, vlan mask can not be 0\n");
                return -EINVAL;
        }
 
@@ -3316,7 +3721,7 @@ rte_eth_dev_callback_register(uint16_t port_id,
                return -EINVAL;
 
        if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) {
-               ethdev_log(ERR, "Invalid port_id=%d", port_id);
+               RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id);
                return -EINVAL;
        }
 
@@ -3379,7 +3784,7 @@ rte_eth_dev_callback_unregister(uint16_t port_id,
                return -EINVAL;
 
        if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) {
-               ethdev_log(ERR, "Invalid port_id=%d", port_id);
+               RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id);
                return -EINVAL;
        }
 
@@ -3453,6 +3858,10 @@ rte_eth_dev_probing_finish(struct rte_eth_dev *dev)
 {
        if (dev == NULL)
                return;
+
+       _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_NEW, NULL);
+
+       dev->state = RTE_ETH_DEV_ATTACHED;
 }
 
 int
@@ -3469,13 +3878,13 @@ rte_eth_dev_rx_intr_ctl(uint16_t port_id, int epfd, int op, void *data)
        dev = &rte_eth_devices[port_id];
 
        if (!dev->intr_handle) {
-               RTE_PMD_DEBUG_TRACE("RX Intr handle unset\n");
+               RTE_ETHDEV_LOG(ERR, "RX Intr handle unset\n");
                return -ENOTSUP;
        }
 
        intr_handle = dev->intr_handle;
        if (!intr_handle->intr_vec) {
-               RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
+               RTE_ETHDEV_LOG(ERR, "RX Intr vector unset\n");
                return -EPERM;
        }
 
@@ -3483,15 +3892,52 @@ rte_eth_dev_rx_intr_ctl(uint16_t port_id, int epfd, int op, void *data)
                vec = intr_handle->intr_vec[qid];
                rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data);
                if (rc && rc != -EEXIST) {
-                       RTE_PMD_DEBUG_TRACE("p %u q %u rx ctl error"
-                                       " op %d epfd %d vec %u\n",
-                                       port_id, qid, op, epfd, vec);
+                       RTE_ETHDEV_LOG(ERR,
+                               "p %u q %u rx ctl error op %d epfd %d vec %u\n",
+                               port_id, qid, op, epfd, vec);
                }
        }
 
        return 0;
 }
 
+int
+rte_eth_dev_rx_intr_ctl_q_get_fd(uint16_t port_id, uint16_t queue_id)
+{
+       struct rte_intr_handle *intr_handle;
+       struct rte_eth_dev *dev;
+       unsigned int efd_idx;
+       uint32_t vec;
+       int fd;
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
+
+       dev = &rte_eth_devices[port_id];
+
+       if (queue_id >= dev->data->nb_rx_queues) {
+               RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
+               return -1;
+       }
+
+       if (!dev->intr_handle) {
+               RTE_ETHDEV_LOG(ERR, "RX Intr handle unset\n");
+               return -1;
+       }
+
+       intr_handle = dev->intr_handle;
+       if (!intr_handle->intr_vec) {
+               RTE_ETHDEV_LOG(ERR, "RX Intr vector unset\n");
+               return -1;
+       }
+
+       vec = intr_handle->intr_vec[queue_id];
+       efd_idx = (vec >= RTE_INTR_VEC_RXTX_OFFSET) ?
+               (vec - RTE_INTR_VEC_RXTX_OFFSET) : vec;
+       fd = intr_handle->efds[efd_idx];
+
+       return fd;
+}
+
 const struct rte_memzone *
 rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
                         uint16_t queue_id, size_t size, unsigned align,
@@ -3499,10 +3945,15 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 {
        char z_name[RTE_MEMZONE_NAMESIZE];
        const struct rte_memzone *mz;
+       int rc;
 
-       snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-                dev->device->driver->name, ring_name,
-                dev->data->port_id, queue_id);
+       rc = snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
+                     dev->data->port_id, queue_id, ring_name);
+       if (rc >= RTE_MEMZONE_NAMESIZE) {
+               RTE_ETHDEV_LOG(ERR, "ring name too long\n");
+               rte_errno = ENAMETOOLONG;
+               return NULL;
+       }
 
        mz = rte_memzone_lookup(z_name);
        if (mz)
@@ -3512,7 +3963,7 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
                        RTE_MEMZONE_IOVA_CONTIG, align);
 }
 
-int __rte_experimental
+int
 rte_eth_dev_create(struct rte_device *device, const char *name,
        size_t priv_data_size,
        ethdev_bus_specific_init ethdev_bus_specific_init,
@@ -3526,10 +3977,8 @@ rte_eth_dev_create(struct rte_device *device, const char *name,
 
        if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
                ethdev = rte_eth_dev_allocate(name);
-               if (!ethdev) {
-                       retval = -ENODEV;
-                       goto probe_failed;
-               }
+               if (!ethdev)
+                       return -ENODEV;
 
                if (priv_data_size) {
                        ethdev->data->dev_private = rte_zmalloc_socket(
@@ -3547,8 +3996,7 @@ rte_eth_dev_create(struct rte_device *device, const char *name,
                if (!ethdev) {
                        RTE_LOG(ERR, EAL, "secondary process attach failed, "
                                "ethdev doesn't exist");
-                       retval = -ENODEV;
-                       goto probe_failed;
+                       return  -ENODEV;
                }
        }
 
@@ -3572,17 +4020,13 @@ rte_eth_dev_create(struct rte_device *device, const char *name,
        rte_eth_dev_probing_finish(ethdev);
 
        return retval;
-probe_failed:
-       /* free ports private data if primary process */
-       if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-               rte_free(ethdev->data->dev_private);
 
+probe_failed:
        rte_eth_dev_release_port(ethdev);
-
        return retval;
 }
 
-int  __rte_experimental
+int
 rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
        ethdev_uninit_t ethdev_uninit)
 {
@@ -3593,16 +4037,10 @@ rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
                return -ENODEV;
 
        RTE_FUNC_PTR_OR_ERR_RET(*ethdev_uninit, -EINVAL);
-       if (ethdev_uninit) {
-               ret = ethdev_uninit(ethdev);
-               if (ret)
-                       return ret;
-       }
 
-       if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-               rte_free(ethdev->data->dev_private);
-
-       ethdev->data->dev_private = NULL;
+       ret = ethdev_uninit(ethdev);
+       if (ret)
+               return ret;
 
        return rte_eth_dev_release_port(ethdev);
 }
@@ -3620,27 +4058,27 @@ rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id,
 
        dev = &rte_eth_devices[port_id];
        if (queue_id >= dev->data->nb_rx_queues) {
-               RTE_PMD_DEBUG_TRACE("Invalid RX queue_id=%u\n", queue_id);
+               RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
                return -EINVAL;
        }
 
        if (!dev->intr_handle) {
-               RTE_PMD_DEBUG_TRACE("RX Intr handle unset\n");
+               RTE_ETHDEV_LOG(ERR, "RX Intr handle unset\n");
                return -ENOTSUP;
        }
 
        intr_handle = dev->intr_handle;
        if (!intr_handle->intr_vec) {
-               RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
+               RTE_ETHDEV_LOG(ERR, "RX Intr vector unset\n");
                return -EPERM;
        }
 
        vec = intr_handle->intr_vec[queue_id];
        rc = rte_intr_rx_ctl(intr_handle, epfd, op, vec, data);
        if (rc && rc != -EEXIST) {
-               RTE_PMD_DEBUG_TRACE("p %u q %u rx ctl error"
-                               " op %d epfd %d vec %u\n",
-                               port_id, queue_id, op, epfd, vec);
+               RTE_ETHDEV_LOG(ERR,
+                       "p %u q %u rx ctl error op %d epfd %d vec %u\n",
+                       port_id, queue_id, op, epfd, vec);
                return rc;
        }
 
@@ -3714,12 +4152,19 @@ rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id,
        rte_errno = ENOTSUP;
        return NULL;
 #endif
+       struct rte_eth_dev *dev;
+
        /* check input parameters */
        if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL ||
                    queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) {
                rte_errno = EINVAL;
                return NULL;
        }
+       dev = &rte_eth_devices[port_id];
+       if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) {
+               rte_errno = EINVAL;
+               return NULL;
+       }
        struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0);
 
        if (cb == NULL) {
@@ -3791,6 +4236,8 @@ rte_eth_add_tx_callback(uint16_t port_id, uint16_t queue_id,
        rte_errno = ENOTSUP;
        return NULL;
 #endif
+       struct rte_eth_dev *dev;
+
        /* check input parameters */
        if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL ||
                    queue_id >= rte_eth_devices[port_id].data->nb_tx_queues) {
@@ -3798,6 +4245,12 @@ rte_eth_add_tx_callback(uint16_t port_id, uint16_t queue_id,
                return NULL;
        }
 
+       dev = &rte_eth_devices[port_id];
+       if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) {
+               rte_errno = EINVAL;
+               return NULL;
+       }
+
        struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0);
 
        if (cb == NULL) {
@@ -3907,7 +4360,14 @@ rte_eth_rx_queue_info_get(uint16_t port_id, uint16_t queue_id,
 
        dev = &rte_eth_devices[port_id];
        if (queue_id >= dev->data->nb_rx_queues) {
-               RTE_PMD_DEBUG_TRACE("Invalid RX queue_id=%d\n", queue_id);
+               RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
+               return -EINVAL;
+       }
+
+       if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) {
+               RTE_ETHDEV_LOG(INFO,
+                       "Can't get hairpin Rx queue %"PRIu16" info of device with port_id=%"PRIu16"\n",
+                       queue_id, port_id);
                return -EINVAL;
        }
 
@@ -3923,7 +4383,6 @@ rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id,
        struct rte_eth_txq_info *qinfo)
 {
        struct rte_eth_dev *dev;
-       struct rte_eth_txconf *txconf = &qinfo->conf;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
@@ -3932,7 +4391,14 @@ rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id,
 
        dev = &rte_eth_devices[port_id];
        if (queue_id >= dev->data->nb_tx_queues) {
-               RTE_PMD_DEBUG_TRACE("Invalid TX queue_id=%d\n", queue_id);
+               RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id);
+               return -EINVAL;
+       }
+
+       if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) {
+               RTE_ETHDEV_LOG(INFO,
+                       "Can't get hairpin Tx queue %"PRIu16" info of device with port_id=%"PRIu16"\n",
+                       queue_id, port_id);
                return -EINVAL;
        }
 
@@ -3940,15 +4406,61 @@ rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id,
 
        memset(qinfo, 0, sizeof(*qinfo));
        dev->dev_ops->txq_info_get(dev, queue_id, qinfo);
-       /* convert offload to txq_flags to support legacy app */
-       rte_eth_convert_tx_offload(txconf->offloads, &txconf->txq_flags);
 
        return 0;
 }
 
+int
+rte_eth_rx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
+                         struct rte_eth_burst_mode *mode)
+{
+       struct rte_eth_dev *dev;
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+       if (mode == NULL)
+               return -EINVAL;
+
+       dev = &rte_eth_devices[port_id];
+
+       if (queue_id >= dev->data->nb_rx_queues) {
+               RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
+               return -EINVAL;
+       }
+
+       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_burst_mode_get, -ENOTSUP);
+       memset(mode, 0, sizeof(*mode));
+       return eth_err(port_id,
+                      dev->dev_ops->rx_burst_mode_get(dev, queue_id, mode));
+}
+
+int
+rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
+                         struct rte_eth_burst_mode *mode)
+{
+       struct rte_eth_dev *dev;
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+       if (mode == NULL)
+               return -EINVAL;
+
+       dev = &rte_eth_devices[port_id];
+
+       if (queue_id >= dev->data->nb_tx_queues) {
+               RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id);
+               return -EINVAL;
+       }
+
+       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_burst_mode_get, -ENOTSUP);
+       memset(mode, 0, sizeof(*mode));
+       return eth_err(port_id,
+                      dev->dev_ops->tx_burst_mode_get(dev, queue_id, mode));
+}
+
 int
 rte_eth_dev_set_mc_addr_list(uint16_t port_id,
-                            struct ether_addr *mc_addr_set,
+                            struct rte_ether_addr *mc_addr_set,
                             uint32_t nb_mc_addr)
 {
        struct rte_eth_dev *dev;
@@ -4052,6 +4564,18 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
                                                                timestamp));
 }
 
+int
+rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
+{
+       struct rte_eth_dev *dev;
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+       dev = &rte_eth_devices[port_id];
+
+       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP);
+       return eth_err(port_id, (*dev->dev_ops->read_clock)(dev, clock));
+}
+
 int
 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 {
@@ -4100,7 +4624,7 @@ rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info)
        return eth_err(port_id, (*dev->dev_ops->set_eeprom)(dev, info));
 }
 
-int __rte_experimental
+int
 rte_eth_dev_get_module_info(uint16_t port_id,
                            struct rte_eth_dev_module_info *modinfo)
 {
@@ -4113,7 +4637,7 @@ rte_eth_dev_get_module_info(uint16_t port_id,
        return (*dev->dev_ops->get_module_info)(dev, modinfo);
 }
 
-int __rte_experimental
+int
 rte_eth_dev_get_module_eeprom(uint16_t port_id,
                              struct rte_dev_eeprom_info *info)
 {
@@ -4149,12 +4673,12 @@ rte_eth_dev_l2_tunnel_eth_type_conf(uint16_t port_id,
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        if (l2_tunnel == NULL) {
-               RTE_PMD_DEBUG_TRACE("Invalid l2_tunnel parameter\n");
+               RTE_ETHDEV_LOG(ERR, "Invalid l2_tunnel parameter\n");
                return -EINVAL;
        }
 
        if (l2_tunnel->l2_tunnel_type >= RTE_TUNNEL_TYPE_MAX) {
-               RTE_PMD_DEBUG_TRACE("Invalid tunnel type\n");
+               RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n");
                return -EINVAL;
        }
 
@@ -4176,17 +4700,17 @@ rte_eth_dev_l2_tunnel_offload_set(uint16_t port_id,
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
        if (l2_tunnel == NULL) {
-               RTE_PMD_DEBUG_TRACE("Invalid l2_tunnel parameter\n");
+               RTE_ETHDEV_LOG(ERR, "Invalid l2_tunnel parameter\n");
                return -EINVAL;
        }
 
        if (l2_tunnel->l2_tunnel_type >= RTE_TUNNEL_TYPE_MAX) {
-               RTE_PMD_DEBUG_TRACE("Invalid tunnel type.\n");
+               RTE_ETHDEV_LOG(ERR, "Invalid tunnel type\n");
                return -EINVAL;
        }
 
        if (mask == 0) {
-               RTE_PMD_DEBUG_TRACE("Mask should have a value.\n");
+               RTE_ETHDEV_LOG(ERR, "Mask should have a value\n");
                return -EINVAL;
        }
 
@@ -4215,15 +4739,14 @@ rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id,
                                 uint16_t *nb_rx_desc,
                                 uint16_t *nb_tx_desc)
 {
-       struct rte_eth_dev *dev;
        struct rte_eth_dev_info dev_info;
+       int ret;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
-       dev = &rte_eth_devices[port_id];
-       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
-
-       rte_eth_dev_info_get(port_id, &dev_info);
+       ret = rte_eth_dev_info_get(port_id, &dev_info);
+       if (ret != 0)
+               return ret;
 
        if (nb_rx_desc != NULL)
                rte_eth_dev_adjust_nb_desc(nb_rx_desc, &dev_info.rx_desc_lim);
@@ -4234,6 +4757,38 @@ rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id,
        return 0;
 }
 
+int
+rte_eth_dev_hairpin_capability_get(uint16_t port_id,
+                                  struct rte_eth_hairpin_cap *cap)
+{
+       struct rte_eth_dev *dev;
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+
+       dev = &rte_eth_devices[port_id];
+       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP);
+       memset(cap, 0, sizeof(*cap));
+       return eth_err(port_id, (*dev->dev_ops->hairpin_cap_get)(dev, cap));
+}
+
+int
+rte_eth_dev_is_rx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+       if (dev->data->rx_queue_state[queue_id] ==
+           RTE_ETH_QUEUE_STATE_HAIRPIN)
+               return 1;
+       return 0;
+}
+
+int
+rte_eth_dev_is_tx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+       if (dev->data->tx_queue_state[queue_id] ==
+           RTE_ETH_QUEUE_STATE_HAIRPIN)
+               return 1;
+       return 0;
+}
+
 int
 rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
 {
@@ -4265,11 +4820,11 @@ enum rte_eth_switch_domain_state {
  * RTE_MAX_ETHPORTS elements as there cannot be more active switch domains than
  * ethdev ports in a single process.
  */
-struct rte_eth_dev_switch {
+static struct rte_eth_dev_switch {
        enum rte_eth_switch_domain_state state;
 } rte_eth_switch_domains[RTE_MAX_ETHPORTS];
 
-int __rte_experimental
+int
 rte_eth_switch_domain_alloc(uint16_t *domain_id)
 {
        unsigned int i;
@@ -4290,7 +4845,7 @@ rte_eth_switch_domain_alloc(uint16_t *domain_id)
        return -ENOSPC;
 }
 
-int __rte_experimental
+int
 rte_eth_switch_domain_free(uint16_t domain_id)
 {
        if (domain_id == RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID ||
@@ -4306,8 +4861,6 @@ rte_eth_switch_domain_free(uint16_t domain_id)
        return 0;
 }
 
-typedef int (*rte_eth_devargs_callback_t)(char *str, void *data);
-
 static int
 rte_eth_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in)
 {
@@ -4372,90 +4925,7 @@ rte_eth_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in)
        }
 }
 
-static int
-rte_eth_devargs_parse_list(char *str, rte_eth_devargs_callback_t callback,
-       void *data)
-{
-       char *str_start;
-       int state;
-       int result;
-
-       if (*str != '[')
-               /* Single element, not a list */
-               return callback(str, data);
-
-       /* Sanity check, then strip the brackets */
-       str_start = &str[strlen(str) - 1];
-       if (*str_start != ']') {
-               RTE_LOG(ERR, EAL, "(%s): List does not end with ']'", str);
-               return -EINVAL;
-       }
-       str++;
-       *str_start = '\0';
-
-       /* Process list elements */
-       state = 0;
-       while (1) {
-               if (state == 0) {
-                       if (*str == '\0')
-                               break;
-                       if (*str != ',') {
-                               str_start = str;
-                               state = 1;
-                       }
-               } else if (state == 1) {
-                       if (*str == ',' || *str == '\0') {
-                               if (str > str_start) {
-                                       /* Non-empty string fragment */
-                                       *str = '\0';
-                                       result = callback(str_start, data);
-                                       if (result < 0)
-                                               return result;
-                               }
-                               state = 0;
-                       }
-               }
-               str++;
-       }
-       return 0;
-}
-
-static int
-rte_eth_devargs_process_range(char *str, uint16_t *list, uint16_t *len_list,
-       const uint16_t max_list)
-{
-       uint16_t lo, hi, val;
-       int result;
-
-       result = sscanf(str, "%hu-%hu", &lo, &hi);
-       if (result == 1) {
-               if (*len_list >= max_list)
-                       return -ENOMEM;
-               list[(*len_list)++] = lo;
-       } else if (result == 2) {
-               if (lo >= hi || lo > RTE_MAX_ETHPORTS || hi > RTE_MAX_ETHPORTS)
-                       return -EINVAL;
-               for (val = lo; val <= hi; val++) {
-                       if (*len_list >= max_list)
-                               return -ENOMEM;
-                       list[(*len_list)++] = val;
-               }
-       } else
-               return -EINVAL;
-       return 0;
-}
-
-
-static int
-rte_eth_devargs_parse_representor_ports(char *str, void *data)
-{
-       struct rte_eth_devargs *eth_da = data;
-
-       return rte_eth_devargs_process_range(str, eth_da->representor_ports,
-               &eth_da->nb_representor_ports, RTE_MAX_ETHPORTS);
-}
-
-int __rte_experimental
+int
 rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da)
 {
        struct rte_kvargs args;
@@ -4487,11 +4957,9 @@ parse_cleanup:
        return result;
 }
 
-RTE_INIT(ethdev_init_log);
-static void
-ethdev_init_log(void)
+RTE_INIT(ethdev_init_log)
 {
-       ethdev_logtype = rte_log_register("lib.ethdev");
-       if (ethdev_logtype >= 0)
-               rte_log_set_level(ethdev_logtype, RTE_LOG_INFO);
+       rte_eth_dev_logtype = rte_log_register("lib.ethdev");
+       if (rte_eth_dev_logtype >= 0)
+               rte_log_set_level(rte_eth_dev_logtype, RTE_LOG_INFO);
 }