ethdev: add device flag to bypass auto-filled queue xstats
[dpdk.git] / drivers / net / bonding / rte_eth_bond_pmd.c
index a994c9a..057b1ad 100644 (file)
@@ -21,8 +21,8 @@
 #include <rte_string_fns.h>
 
 #include "rte_eth_bond.h"
-#include "rte_eth_bond_private.h"
-#include "rte_eth_bond_8023ad_private.h"
+#include "eth_bond_private.h"
+#include "eth_bond_8023ad_private.h"
 
 #define REORDER_PERIOD_MS 10
 #define DEFAULT_POLLING_INTERVAL_10_MS (10)
@@ -69,7 +69,7 @@ bond_ethdev_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
        struct bond_rx_queue *bd_rx_q = (struct bond_rx_queue *)queue;
        internals = bd_rx_q->dev_private;
        slave_count = internals->active_slave_count;
-       active_slave = internals->active_slave;
+       active_slave = bd_rx_q->active_slave;
 
        for (i = 0; i < slave_count && nb_pkts; i++) {
                uint16_t num_rx_slave;
@@ -86,8 +86,8 @@ bond_ethdev_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
                        active_slave = 0;
        }
 
-       if (++internals->active_slave >= slave_count)
-               internals->active_slave = 0;
+       if (++bd_rx_q->active_slave >= slave_count)
+               bd_rx_q->active_slave = 0;
        return num_rx_total;
 }
 
@@ -303,9 +303,9 @@ rx_burst_8023ad(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts,
        memcpy(slaves, internals->active_slaves,
                        sizeof(internals->active_slaves[0]) * slave_count);
 
-       idx = internals->active_slave;
+       idx = bd_rx_q->active_slave;
        if (idx >= slave_count) {
-               internals->active_slave = 0;
+               bd_rx_q->active_slave = 0;
                idx = 0;
        }
        for (i = 0; i < slave_count && num_rx_total < nb_pkts; i++) {
@@ -367,8 +367,8 @@ rx_burst_8023ad(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts,
                        idx = 0;
        }
 
-       if (++internals->active_slave >= slave_count)
-               internals->active_slave = 0;
+       if (++bd_rx_q->active_slave >= slave_count)
+               bd_rx_q->active_slave = 0;
 
        return num_rx_total;
 }
@@ -489,9 +489,9 @@ update_client_stats(uint32_t addr, uint16_t port, uint32_t *TXorRXindicator)
 #endif
 
 static void
-mode6_debug(const char __attribute__((unused)) *info,
+mode6_debug(const char __rte_unused *info,
        struct rte_ether_hdr *eth_h, uint16_t port,
-       uint32_t __attribute__((unused)) *burstnumber)
+       uint32_t __rte_unused *burstnumber)
 {
        struct rte_ipv4_hdr *ipv4_h;
 #ifdef RTE_LIBRTE_BOND_DEBUG_ALB
@@ -534,8 +534,8 @@ mode6_debug(const char __attribute__((unused)) *info,
 static uint16_t
 bond_ethdev_rx_burst_alb(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
 {
-       struct bond_tx_queue *bd_tx_q = (struct bond_tx_queue *)queue;
-       struct bond_dev_private *internals = bd_tx_q->dev_private;
+       struct bond_rx_queue *bd_rx_q = (struct bond_rx_queue *)queue;
+       struct bond_dev_private *internals = bd_rx_q->dev_private;
        struct rte_ether_hdr *eth_h;
        uint16_t ether_type, offset;
        uint16_t nb_recv_pkts;
@@ -846,8 +846,14 @@ bandwidth_left(uint16_t port_id, uint64_t load, uint8_t update_idx,
                struct bwg_slave *bwg_slave)
 {
        struct rte_eth_link link_status;
+       int ret;
 
-       rte_eth_link_get_nowait(port_id, &link_status);
+       ret = rte_eth_link_get_nowait(port_id, &link_status);
+       if (ret < 0) {
+               RTE_BOND_LOG(ERR, "Slave (port %u) link get failed: %s",
+                            port_id, rte_strerror(-ret));
+               return;
+       }
        uint64_t link_bwg = link_status.link_speed * 1000000ULL / 8;
        if (link_bwg == 0)
                return;
@@ -1496,6 +1502,7 @@ int
 mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev)
 {
        struct bond_dev_private *internals = bonded_eth_dev->data->dev_private;
+       bool set;
        int i;
 
        /* Update slave devices MAC addresses */
@@ -1523,15 +1530,16 @@ mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev)
        case BONDING_MODE_TLB:
        case BONDING_MODE_ALB:
        default:
+               set = true;
                for (i = 0; i < internals->slave_count; i++) {
                        if (internals->slaves[i].port_id ==
                                        internals->current_primary_port) {
                                if (rte_eth_dev_default_mac_addr_set(
-                                               internals->primary_port,
+                                               internals->current_primary_port,
                                                bonded_eth_dev->data->mac_addrs)) {
                                        RTE_BOND_LOG(ERR, "Failed to update port Id %d MAC address",
                                                        internals->current_primary_port);
-                                       return -1;
+                                       set = false;
                                }
                        } else {
                                if (rte_eth_dev_default_mac_addr_set(
@@ -1539,10 +1547,11 @@ mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev)
                                                &internals->slaves[i].persisted_mac_addr)) {
                                        RTE_BOND_LOG(ERR, "Failed to update port Id %d MAC address",
                                                        internals->slaves[i].port_id);
-                                       return -1;
                                }
                        }
                }
+               if (!set)
+                       return -1;
        }
 
        return 0;
@@ -1685,7 +1694,10 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev,
        struct bond_dev_private *internals = bonded_eth_dev->data->dev_private;
 
        /* Stop slave */
-       rte_eth_dev_stop(slave_eth_dev->data->port_id);
+       errval = rte_eth_dev_stop(slave_eth_dev->data->port_id);
+       if (errval != 0)
+               RTE_BOND_LOG(ERR, "rte_eth_dev_stop: port %u, err (%d)",
+                            slave_eth_dev->data->port_id, errval);
 
        /* Enable interrupts on slave device if supported */
        if (slave_eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
@@ -1870,7 +1882,7 @@ slave_remove(struct bond_dev_private *internals,
        internals->slave_count--;
 
        /* force reconfiguration of slave interfaces */
-       _rte_eth_dev_reset(slave_eth_dev);
+       rte_eth_dev_internal_reset(slave_eth_dev);
 }
 
 static void
@@ -1915,7 +1927,7 @@ bond_ethdev_primary_set(struct bond_dev_private *internals,
                }
 }
 
-static void
+static int
 bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev);
 
 static int
@@ -2037,11 +2049,12 @@ bond_ethdev_free_queues(struct rte_eth_dev *dev)
        }
 }
 
-void
+int
 bond_ethdev_stop(struct rte_eth_dev *eth_dev)
 {
        struct bond_dev_private *internals = eth_dev->data->dev_private;
        uint16_t i;
+       int ret;
 
        if (internals->mode == BONDING_MODE_8023AD) {
                struct port *port;
@@ -2080,13 +2093,20 @@ bond_ethdev_stop(struct rte_eth_dev *eth_dev)
                                internals->active_slave_count, slave_id) !=
                                                internals->active_slave_count) {
                        internals->slaves[i].last_link_status = 0;
-                       rte_eth_dev_stop(slave_id);
+                       ret = rte_eth_dev_stop(slave_id);
+                       if (ret != 0) {
+                               RTE_BOND_LOG(ERR, "Failed to stop device on port %u",
+                                            slave_id);
+                               return ret;
+                       }
                        deactivate_slave(eth_dev, slave_id);
                }
        }
+
+       return 0;
 }
 
-void
+int
 bond_ethdev_close(struct rte_eth_dev *dev)
 {
        struct bond_dev_private *internals = dev->data->dev_private;
@@ -2094,11 +2114,18 @@ bond_ethdev_close(struct rte_eth_dev *dev)
        int skipped = 0;
        struct rte_flow_error ferror;
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
        RTE_BOND_LOG(INFO, "Closing bonded device %s", dev->device->name);
        while (internals->slave_count != skipped) {
                uint16_t port_id = internals->slaves[skipped].port_id;
 
-               rte_eth_dev_stop(port_id);
+               if (rte_eth_dev_stop(port_id) != 0) {
+                       RTE_BOND_LOG(ERR, "Failed to stop device on port %u",
+                                    port_id);
+                       skipped++;
+               }
 
                if (rte_eth_bond_slave_remove(bond_port_id, port_id) != 0) {
                        RTE_BOND_LOG(ERR,
@@ -2110,6 +2137,15 @@ bond_ethdev_close(struct rte_eth_dev *dev)
        bond_flow_ops.flush(dev, &ferror);
        bond_ethdev_free_queues(dev);
        rte_bitmap_reset(internals->vlan_filter_bmp);
+       rte_bitmap_free(internals->vlan_filter_bmp);
+       rte_free(internals->vlan_filter_bmpmem);
+
+       /* Try to release mempool used in mode6. If the bond
+        * device is not mode6, free the NULL is not problem.
+        */
+       rte_mempool_free(internals->mode6.mempool);
+
+       return 0;
 }
 
 /* forward declaration */
@@ -2358,12 +2394,14 @@ bond_ethdev_slave_link_status_change_monitor(void *cb_arg)
 static int
 bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete)
 {
-       void (*link_update)(uint16_t port_id, struct rte_eth_link *eth_link);
+       int (*link_update)(uint16_t port_id, struct rte_eth_link *eth_link);
 
        struct bond_dev_private *bond_ctx;
        struct rte_eth_link slave_link;
 
+       bool one_link_update_succeeded;
        uint32_t idx;
+       int ret;
 
        bond_ctx = ethdev->data->dev_private;
 
@@ -2395,8 +2433,18 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete)
                 * packet loss will occur on this slave if transmission at rates
                 * greater than this are attempted
                 */
-               for (idx = 1; idx < bond_ctx->active_slave_count; idx++) {
-                       link_update(bond_ctx->active_slaves[0], &slave_link);
+               for (idx = 0; idx < bond_ctx->active_slave_count; idx++) {
+                       ret = link_update(bond_ctx->active_slaves[idx],
+                                         &slave_link);
+                       if (ret < 0) {
+                               ethdev->data->dev_link.link_speed =
+                                       ETH_SPEED_NUM_NONE;
+                               RTE_BOND_LOG(ERR,
+                                       "Slave (port %u) link get failed: %s",
+                                       bond_ctx->active_slaves[idx],
+                                       rte_strerror(-ret));
+                               return 0;
+                       }
 
                        if (slave_link.link_speed <
                                        ethdev->data->dev_link.link_speed)
@@ -2406,7 +2454,13 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete)
                break;
        case BONDING_MODE_ACTIVE_BACKUP:
                /* Current primary slave */
-               link_update(bond_ctx->current_primary_port, &slave_link);
+               ret = link_update(bond_ctx->current_primary_port, &slave_link);
+               if (ret < 0) {
+                       RTE_BOND_LOG(ERR, "Slave (port %u) link get failed: %s",
+                               bond_ctx->current_primary_port,
+                               rte_strerror(-ret));
+                       return 0;
+               }
 
                ethdev->data->dev_link.link_speed = slave_link.link_speed;
                break;
@@ -2415,7 +2469,8 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete)
                                bond_ctx->mode4.slave_link.link_autoneg;
                ethdev->data->dev_link.link_duplex =
                                bond_ctx->mode4.slave_link.link_duplex;
-               /* fall through to update link speed */
+               /* fall through */
+               /* to update link speed */
        case BONDING_MODE_ROUND_ROBIN:
        case BONDING_MODE_BALANCE:
        case BONDING_MODE_TLB:
@@ -2426,13 +2481,28 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete)
                 * of all the slaves
                 */
                ethdev->data->dev_link.link_speed = ETH_SPEED_NUM_NONE;
+               one_link_update_succeeded = false;
 
                for (idx = 0; idx < bond_ctx->active_slave_count; idx++) {
-                       link_update(bond_ctx->active_slaves[idx], &slave_link);
+                       ret = link_update(bond_ctx->active_slaves[idx],
+                                       &slave_link);
+                       if (ret < 0) {
+                               RTE_BOND_LOG(ERR,
+                                       "Slave (port %u) link get failed: %s",
+                                       bond_ctx->active_slaves[idx],
+                                       rte_strerror(-ret));
+                               continue;
+                       }
 
+                       one_link_update_succeeded = true;
                        ethdev->data->dev_link.link_speed +=
                                        slave_link.link_speed;
                }
+
+               if (!one_link_update_succeeded) {
+                       RTE_BOND_LOG(ERR, "All slaves link get failed");
+                       return 0;
+               }
        }
 
 
@@ -2472,34 +2542,58 @@ bond_ethdev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
        return 0;
 }
 
-static void
+static int
 bond_ethdev_stats_reset(struct rte_eth_dev *dev)
 {
        struct bond_dev_private *internals = dev->data->dev_private;
        int i;
+       int err;
+       int ret;
 
-       for (i = 0; i < internals->slave_count; i++)
-               rte_eth_stats_reset(internals->slaves[i].port_id);
+       for (i = 0, err = 0; i < internals->slave_count; i++) {
+               ret = rte_eth_stats_reset(internals->slaves[i].port_id);
+               if (ret != 0)
+                       err = ret;
+       }
+
+       return err;
 }
 
-static void
+static int
 bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
        struct bond_dev_private *internals = eth_dev->data->dev_private;
        int i;
+       int ret = 0;
+       uint16_t port_id;
 
        switch (internals->mode) {
        /* Promiscuous mode is propagated to all slaves */
        case BONDING_MODE_ROUND_ROBIN:
        case BONDING_MODE_BALANCE:
        case BONDING_MODE_BROADCAST:
-       case BONDING_MODE_8023AD:
+       case BONDING_MODE_8023AD: {
+               unsigned int slave_ok = 0;
+
                for (i = 0; i < internals->slave_count; i++) {
-                       uint16_t port_id = internals->slaves[i].port_id;
+                       port_id = internals->slaves[i].port_id;
 
-                       rte_eth_promiscuous_enable(port_id);
+                       ret = rte_eth_promiscuous_enable(port_id);
+                       if (ret != 0)
+                               RTE_BOND_LOG(ERR,
+                                       "Failed to enable promiscuous mode for port %u: %s",
+                                       port_id, rte_strerror(-ret));
+                       else
+                               slave_ok++;
                }
+               /*
+                * Report success if operation is successful on at least
+                * on one slave. Otherwise return last error code.
+                */
+               if (slave_ok > 0)
+                       ret = 0;
                break;
+       }
        /* Promiscuous mode is propagated only to primary slave */
        case BONDING_MODE_ACTIVE_BACKUP:
        case BONDING_MODE_TLB:
@@ -2508,32 +2602,58 @@ bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev)
                /* Do not touch promisc when there cannot be primary ports */
                if (internals->slave_count == 0)
                        break;
-               rte_eth_promiscuous_enable(internals->current_primary_port);
+               port_id = internals->current_primary_port;
+               ret = rte_eth_promiscuous_enable(port_id);
+               if (ret != 0)
+                       RTE_BOND_LOG(ERR,
+                               "Failed to enable promiscuous mode for port %u: %s",
+                               port_id, rte_strerror(-ret));
        }
+
+       return ret;
 }
 
-static void
+static int
 bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev)
 {
        struct bond_dev_private *internals = dev->data->dev_private;
        int i;
+       int ret = 0;
+       uint16_t port_id;
 
        switch (internals->mode) {
        /* Promiscuous mode is propagated to all slaves */
        case BONDING_MODE_ROUND_ROBIN:
        case BONDING_MODE_BALANCE:
        case BONDING_MODE_BROADCAST:
-       case BONDING_MODE_8023AD:
+       case BONDING_MODE_8023AD: {
+               unsigned int slave_ok = 0;
+
                for (i = 0; i < internals->slave_count; i++) {
-                       uint16_t port_id = internals->slaves[i].port_id;
+                       port_id = internals->slaves[i].port_id;
 
                        if (internals->mode == BONDING_MODE_8023AD &&
                            bond_mode_8023ad_ports[port_id].forced_rx_flags ==
-                                       BOND_8023AD_FORCED_PROMISC)
+                                       BOND_8023AD_FORCED_PROMISC) {
+                               slave_ok++;
                                continue;
-                       rte_eth_promiscuous_disable(port_id);
+                       }
+                       ret = rte_eth_promiscuous_disable(port_id);
+                       if (ret != 0)
+                               RTE_BOND_LOG(ERR,
+                                       "Failed to disable promiscuous mode for port %u: %s",
+                                       port_id, rte_strerror(-ret));
+                       else
+                               slave_ok++;
                }
+               /*
+                * Report success if operation is successful on at least
+                * on one slave. Otherwise return last error code.
+                */
+               if (slave_ok > 0)
+                       ret = 0;
                break;
+       }
        /* Promiscuous mode is propagated only to primary slave */
        case BONDING_MODE_ACTIVE_BACKUP:
        case BONDING_MODE_TLB:
@@ -2542,28 +2662,52 @@ bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev)
                /* Do not touch promisc when there cannot be primary ports */
                if (internals->slave_count == 0)
                        break;
-               rte_eth_promiscuous_disable(internals->current_primary_port);
+               port_id = internals->current_primary_port;
+               ret = rte_eth_promiscuous_disable(port_id);
+               if (ret != 0)
+                       RTE_BOND_LOG(ERR,
+                               "Failed to disable promiscuous mode for port %u: %s",
+                               port_id, rte_strerror(-ret));
        }
+
+       return ret;
 }
 
-static void
+static int
 bond_ethdev_allmulticast_enable(struct rte_eth_dev *eth_dev)
 {
        struct bond_dev_private *internals = eth_dev->data->dev_private;
        int i;
+       int ret = 0;
+       uint16_t port_id;
 
        switch (internals->mode) {
        /* allmulti mode is propagated to all slaves */
        case BONDING_MODE_ROUND_ROBIN:
        case BONDING_MODE_BALANCE:
        case BONDING_MODE_BROADCAST:
-       case BONDING_MODE_8023AD:
+       case BONDING_MODE_8023AD: {
+               unsigned int slave_ok = 0;
+
                for (i = 0; i < internals->slave_count; i++) {
-                       uint16_t port_id = internals->slaves[i].port_id;
+                       port_id = internals->slaves[i].port_id;
 
-                       rte_eth_allmulticast_enable(port_id);
+                       ret = rte_eth_allmulticast_enable(port_id);
+                       if (ret != 0)
+                               RTE_BOND_LOG(ERR,
+                                       "Failed to enable allmulti mode for port %u: %s",
+                                       port_id, rte_strerror(-ret));
+                       else
+                               slave_ok++;
                }
+               /*
+                * Report success if operation is successful on at least
+                * on one slave. Otherwise return last error code.
+                */
+               if (slave_ok > 0)
+                       ret = 0;
                break;
+       }
        /* allmulti mode is propagated only to primary slave */
        case BONDING_MODE_ACTIVE_BACKUP:
        case BONDING_MODE_TLB:
@@ -2572,22 +2716,33 @@ bond_ethdev_allmulticast_enable(struct rte_eth_dev *eth_dev)
                /* Do not touch allmulti when there cannot be primary ports */
                if (internals->slave_count == 0)
                        break;
-               rte_eth_allmulticast_enable(internals->current_primary_port);
+               port_id = internals->current_primary_port;
+               ret = rte_eth_allmulticast_enable(port_id);
+               if (ret != 0)
+                       RTE_BOND_LOG(ERR,
+                               "Failed to enable allmulti mode for port %u: %s",
+                               port_id, rte_strerror(-ret));
        }
+
+       return ret;
 }
 
-static void
+static int
 bond_ethdev_allmulticast_disable(struct rte_eth_dev *eth_dev)
 {
        struct bond_dev_private *internals = eth_dev->data->dev_private;
        int i;
+       int ret = 0;
+       uint16_t port_id;
 
        switch (internals->mode) {
        /* allmulti mode is propagated to all slaves */
        case BONDING_MODE_ROUND_ROBIN:
        case BONDING_MODE_BALANCE:
        case BONDING_MODE_BROADCAST:
-       case BONDING_MODE_8023AD:
+       case BONDING_MODE_8023AD: {
+               unsigned int slave_ok = 0;
+
                for (i = 0; i < internals->slave_count; i++) {
                        uint16_t port_id = internals->slaves[i].port_id;
 
@@ -2595,9 +2750,23 @@ bond_ethdev_allmulticast_disable(struct rte_eth_dev *eth_dev)
                            bond_mode_8023ad_ports[port_id].forced_rx_flags ==
                                        BOND_8023AD_FORCED_ALLMULTI)
                                continue;
-                       rte_eth_allmulticast_disable(port_id);
+
+                       ret = rte_eth_allmulticast_disable(port_id);
+                       if (ret != 0)
+                               RTE_BOND_LOG(ERR,
+                                       "Failed to disable allmulti mode for port %u: %s",
+                                       port_id, rte_strerror(-ret));
+                       else
+                               slave_ok++;
                }
+               /*
+                * Report success if operation is successful on at least
+                * on one slave. Otherwise return last error code.
+                */
+               if (slave_ok > 0)
+                       ret = 0;
                break;
+       }
        /* allmulti mode is propagated only to primary slave */
        case BONDING_MODE_ACTIVE_BACKUP:
        case BONDING_MODE_TLB:
@@ -2606,8 +2775,15 @@ bond_ethdev_allmulticast_disable(struct rte_eth_dev *eth_dev)
                /* Do not touch allmulti when there cannot be primary ports */
                if (internals->slave_count == 0)
                        break;
-               rte_eth_allmulticast_disable(internals->current_primary_port);
+               port_id = internals->current_primary_port;
+               ret = rte_eth_allmulticast_disable(port_id);
+               if (ret != 0)
+                       RTE_BOND_LOG(ERR,
+                               "Failed to disable allmulti mode for port %u: %s",
+                               port_id, rte_strerror(-ret));
        }
+
+       return ret;
 }
 
 static void
@@ -2616,7 +2792,7 @@ bond_ethdev_delayed_lsc_propagation(void *arg)
        if (arg == NULL)
                return;
 
-       _rte_eth_dev_callback_process((struct rte_eth_dev *)arg,
+       rte_eth_dev_callback_process((struct rte_eth_dev *)arg,
                        RTE_ETH_EVENT_INTR_LSC, NULL);
 }
 
@@ -2628,6 +2804,7 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type,
        struct bond_dev_private *internals;
        struct rte_eth_link link;
        int rc = -1;
+       int ret;
 
        uint8_t lsc_flag = 0;
        int valid_slave = 0;
@@ -2668,8 +2845,11 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type,
        active_pos = find_slave_by_id(internals->active_slaves,
                        internals->active_slave_count, port_id);
 
-       rte_eth_link_get_nowait(port_id, &link);
-       if (link.link_status) {
+       ret = rte_eth_link_get_nowait(port_id, &link);
+       if (ret < 0)
+               RTE_BOND_LOG(ERR, "Slave (port %u) link get failed", port_id);
+
+       if (ret == 0 && link.link_status) {
                if (active_pos < internals->active_slave_count)
                        goto link_update;
 
@@ -2723,6 +2903,7 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type,
                                                internals->active_slaves[0]);
                        else
                                internals->current_primary_port = internals->primary_port;
+                       mac_address_slaves_update(bonded_eth_dev);
                }
        }
 
@@ -2746,7 +2927,7 @@ link_update:
                                                bond_ethdev_delayed_lsc_propagation,
                                                (void *)bonded_eth_dev);
                        else
-                               _rte_eth_dev_callback_process(bonded_eth_dev,
+                               rte_eth_dev_callback_process(bonded_eth_dev,
                                                RTE_ETH_EVENT_INTR_LSC,
                                                NULL);
 
@@ -2756,7 +2937,7 @@ link_update:
                                                bond_ethdev_delayed_lsc_propagation,
                                                (void *)bonded_eth_dev);
                        else
-                               _rte_eth_dev_callback_process(bonded_eth_dev,
+                               rte_eth_dev_callback_process(bonded_eth_dev,
                                                RTE_ETH_EVENT_INTR_LSC,
                                                NULL);
                }
@@ -2781,7 +2962,8 @@ bond_ethdev_rss_reta_update(struct rte_eth_dev *dev,
                return -EINVAL;
 
         /* Copy RETA table */
-       reta_count = reta_size / RTE_RETA_GROUP_SIZE;
+       reta_count = (reta_size + RTE_RETA_GROUP_SIZE - 1) /
+                       RTE_RETA_GROUP_SIZE;
 
        for (i = 0; i < reta_count; i++) {
                internals->reta_conf[i].mask = reta_conf[i].mask;
@@ -3052,7 +3234,8 @@ bond_alloc(struct rte_vdev_device *dev, uint8_t mode)
        }
 
        eth_dev->dev_ops = &default_dev_ops;
-       eth_dev->data->dev_flags = RTE_ETH_DEV_INTR_LSC;
+       eth_dev->data->dev_flags = RTE_ETH_DEV_INTR_LSC |
+                                       RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
 
        rte_spinlock_init(&internals->lock);
        rte_spinlock_init(&internals->lsc_lock);
@@ -3250,6 +3433,7 @@ bond_remove(struct rte_vdev_device *dev)
        struct rte_eth_dev *eth_dev;
        struct bond_dev_private *internals;
        const char *name;
+       int ret = 0;
 
        if (!dev)
                return -EINVAL;
@@ -3257,14 +3441,10 @@ bond_remove(struct rte_vdev_device *dev)
        name = rte_vdev_device_name(dev);
        RTE_BOND_LOG(INFO, "Uninitializing pmd_bond for %s", name);
 
-       /* now free all data allocation - for eth_dev structure,
-        * dummy pci driver and internal (private) data
-        */
-
        /* find an ethdev entry */
        eth_dev = rte_eth_dev_allocated(name);
        if (eth_dev == NULL)
-               return -ENODEV;
+               return 0; /* port already released */
 
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
                return rte_eth_dev_release_port(eth_dev);
@@ -3276,25 +3456,12 @@ bond_remove(struct rte_vdev_device *dev)
                return -EBUSY;
 
        if (eth_dev->data->dev_started == 1) {
-               bond_ethdev_stop(eth_dev);
+               ret = bond_ethdev_stop(eth_dev);
                bond_ethdev_close(eth_dev);
        }
-
-       eth_dev->dev_ops = NULL;
-       eth_dev->rx_pkt_burst = NULL;
-       eth_dev->tx_pkt_burst = NULL;
-
-       internals = eth_dev->data->dev_private;
-       /* Try to release mempool used in mode6. If the bond
-        * device is not mode6, free the NULL is not problem.
-        */
-       rte_mempool_free(internals->mode6.mempool);
-       rte_bitmap_free(internals->vlan_filter_bmp);
-       rte_free(internals->vlan_filter_bmpmem);
-
        rte_eth_dev_release_port(eth_dev);
 
-       return 0;
+       return ret;
 }
 
 /* this part will resolve the slave portids after all the other pdev and vdev
@@ -3600,11 +3767,4 @@ RTE_PMD_REGISTER_PARAM_STRING(net_bonding,
        "up_delay=<int> "
        "down_delay=<int>");
 
-int bond_logtype;
-
-RTE_INIT(bond_init_log)
-{
-       bond_logtype = rte_log_register("pmd.net.bond");
-       if (bond_logtype >= 0)
-               rte_log_set_level(bond_logtype, RTE_LOG_NOTICE);
-}
+RTE_LOG_REGISTER(bond_logtype, pmd.net.bond, NOTICE);