ethdev: change device info get callback to return int
[dpdk.git] / drivers / net / bonding / rte_eth_bond_pmd.c
index 49e38f6..a994c9a 100644 (file)
@@ -186,7 +186,15 @@ bond_ethdev_8023ad_flow_verify(struct rte_eth_dev *bond_dev,
                return -1;
        }
 
-       rte_eth_dev_info_get(slave_port, &slave_info);
+       ret = rte_eth_dev_info_get(slave_port, &slave_info);
+       if (ret != 0) {
+               RTE_BOND_LOG(ERR,
+                       "%s: Error during getting device (port %u) info: %s\n",
+                       __func__, slave_port, strerror(-ret));
+
+               return ret;
+       }
+
        if (slave_info.max_rx_queues < bond_dev->data->nb_rx_queues ||
                        slave_info.max_tx_queues < bond_dev->data->nb_tx_queues) {
                RTE_BOND_LOG(ERR,
@@ -204,10 +212,19 @@ bond_8023ad_slow_pkt_hw_filter_supported(uint16_t port_id) {
        struct bond_dev_private *internals = bond_dev->data->dev_private;
        struct rte_eth_dev_info bond_info;
        uint16_t idx;
+       int ret;
 
        /* Verify if all slaves in bonding supports flow director and */
        if (internals->slave_count > 0) {
-               rte_eth_dev_info_get(bond_dev->data->port_id, &bond_info);
+               ret = rte_eth_dev_info_get(bond_dev->data->port_id, &bond_info);
+               if (ret != 0) {
+                       RTE_BOND_LOG(ERR,
+                               "%s: Error during getting device (port %u) info: %s\n",
+                               __func__, bond_dev->data->port_id,
+                               strerror(-ret));
+
+                       return ret;
+               }
 
                internals->mode4.dedicated_queues.rx_qid = bond_info.nb_rx_queues;
                internals->mode4.dedicated_queues.tx_qid = bond_info.nb_tx_queues;
@@ -273,7 +290,8 @@ rx_burst_8023ad(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts,
        uint16_t slave_count, idx;
 
        uint8_t collecting;  /* current slave collecting status */
-       const uint8_t promisc = internals->promiscuous_en;
+       const uint8_t promisc = rte_eth_promiscuous_get(internals->port_id);
+       const uint8_t allmulti = rte_eth_allmulticast_get(internals->port_id);
        uint8_t subtype;
        uint16_t i;
        uint16_t j;
@@ -313,8 +331,10 @@ rx_burst_8023ad(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts,
                        /* Remove packet from array if:
                         * - it is slow packet but no dedicated rxq is present,
                         * - slave is not in collecting state,
-                        * - bonding interface is not in promiscuous mode and
-                        *   packet is not multicast and address does not match,
+                        * - bonding interface is not in promiscuous mode:
+                        *   - packet is unicast and address does not match,
+                        *   - packet is multicast and bonding interface
+                        *     is not in allmulti,
                         */
                        if (unlikely(
                                (!dedicated_rxq &&
@@ -322,9 +342,11 @@ rx_burst_8023ad(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts,
                                                 bufs[j])) ||
                                !collecting ||
                                (!promisc &&
-                                !rte_is_multicast_ether_addr(&hdr->d_addr) &&
-                                !rte_is_same_ether_addr(bond_mac,
-                                                    &hdr->d_addr)))) {
+                                ((rte_is_unicast_ether_addr(&hdr->d_addr) &&
+                                  !rte_is_same_ether_addr(bond_mac,
+                                                      &hdr->d_addr)) ||
+                                 (!allmulti &&
+                                  rte_is_multicast_ether_addr(&hdr->d_addr)))))) {
 
                                if (hdr->ether_type == ether_type_slow_be) {
                                        bond_mode_8023ad_handle_slow_pkt(
@@ -1936,10 +1958,6 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
                }
        }
 
-       /* If bonded device is configure in promiscuous mode then re-apply config */
-       if (internals->promiscuous_en)
-               bond_ethdev_promiscuous_enable(eth_dev);
-
        if (internals->mode == BONDING_MODE_8023AD) {
                if (internals->mode4.dedicated_queues.enabled == 1) {
                        internals->mode4.dedicated_queues.rx_qid =
@@ -2097,10 +2115,12 @@ bond_ethdev_close(struct rte_eth_dev *dev)
 /* forward declaration */
 static int bond_ethdev_configure(struct rte_eth_dev *dev);
 
-static void
+static int
 bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
        struct bond_dev_private *internals = dev->data->dev_private;
+       struct bond_slave_details slave;
+       int ret;
 
        uint16_t max_nb_rx_queues = UINT16_MAX;
        uint16_t max_nb_tx_queues = UINT16_MAX;
@@ -2122,8 +2142,17 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                uint16_t idx;
 
                for (idx = 0; idx < internals->slave_count; idx++) {
-                       rte_eth_dev_info_get(internals->slaves[idx].port_id,
-                                       &slave_info);
+                       slave = internals->slaves[idx];
+                       ret = rte_eth_dev_info_get(slave.port_id, &slave_info);
+                       if (ret != 0) {
+                               RTE_BOND_LOG(ERR,
+                                       "%s: Error during getting device (port %u) info: %s\n",
+                                       __func__,
+                                       slave.port_id,
+                                       strerror(-ret));
+
+                               return ret;
+                       }
 
                        if (slave_info.max_rx_queues < max_nb_rx_queues)
                                max_nb_rx_queues = slave_info.max_rx_queues;
@@ -2169,6 +2198,8 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
        dev_info->flow_type_rss_offloads = internals->flow_type_rss_offloads;
 
        dev_info->reta_size = internals->reta_size;
+
+       return 0;
 }
 
 static int
@@ -2457,18 +2488,17 @@ bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev)
        struct bond_dev_private *internals = eth_dev->data->dev_private;
        int i;
 
-       internals->promiscuous_en = 1;
-
        switch (internals->mode) {
        /* Promiscuous mode is propagated to all slaves */
        case BONDING_MODE_ROUND_ROBIN:
        case BONDING_MODE_BALANCE:
        case BONDING_MODE_BROADCAST:
-               for (i = 0; i < internals->slave_count; i++)
-                       rte_eth_promiscuous_enable(internals->slaves[i].port_id);
-               break;
-       /* In mode4 promiscus mode is managed when slave is added/removed */
        case BONDING_MODE_8023AD:
+               for (i = 0; i < internals->slave_count; i++) {
+                       uint16_t port_id = internals->slaves[i].port_id;
+
+                       rte_eth_promiscuous_enable(port_id);
+               }
                break;
        /* Promiscuous mode is propagated only to primary slave */
        case BONDING_MODE_ACTIVE_BACKUP:
@@ -2488,18 +2518,21 @@ bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev)
        struct bond_dev_private *internals = dev->data->dev_private;
        int i;
 
-       internals->promiscuous_en = 0;
-
        switch (internals->mode) {
        /* Promiscuous mode is propagated to all slaves */
        case BONDING_MODE_ROUND_ROBIN:
        case BONDING_MODE_BALANCE:
        case BONDING_MODE_BROADCAST:
-               for (i = 0; i < internals->slave_count; i++)
-                       rte_eth_promiscuous_disable(internals->slaves[i].port_id);
-               break;
-       /* In mode4 promiscus mode is set managed when slave is added/removed */
        case BONDING_MODE_8023AD:
+               for (i = 0; i < internals->slave_count; i++) {
+                       uint16_t 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)
+                               continue;
+                       rte_eth_promiscuous_disable(port_id);
+               }
                break;
        /* Promiscuous mode is propagated only to primary slave */
        case BONDING_MODE_ACTIVE_BACKUP:
@@ -2513,6 +2546,70 @@ bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev)
        }
 }
 
+static void
+bond_ethdev_allmulticast_enable(struct rte_eth_dev *eth_dev)
+{
+       struct bond_dev_private *internals = eth_dev->data->dev_private;
+       int i;
+
+       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:
+               for (i = 0; i < internals->slave_count; i++) {
+                       uint16_t port_id = internals->slaves[i].port_id;
+
+                       rte_eth_allmulticast_enable(port_id);
+               }
+               break;
+       /* allmulti mode is propagated only to primary slave */
+       case BONDING_MODE_ACTIVE_BACKUP:
+       case BONDING_MODE_TLB:
+       case BONDING_MODE_ALB:
+       default:
+               /* Do not touch allmulti when there cannot be primary ports */
+               if (internals->slave_count == 0)
+                       break;
+               rte_eth_allmulticast_enable(internals->current_primary_port);
+       }
+}
+
+static void
+bond_ethdev_allmulticast_disable(struct rte_eth_dev *eth_dev)
+{
+       struct bond_dev_private *internals = eth_dev->data->dev_private;
+       int i;
+
+       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:
+               for (i = 0; i < internals->slave_count; i++) {
+                       uint16_t 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_ALLMULTI)
+                               continue;
+                       rte_eth_allmulticast_disable(port_id);
+               }
+               break;
+       /* allmulti mode is propagated only to primary slave */
+       case BONDING_MODE_ACTIVE_BACKUP:
+       case BONDING_MODE_TLB:
+       case BONDING_MODE_ALB:
+       default:
+               /* Do not touch allmulti when there cannot be primary ports */
+               if (internals->slave_count == 0)
+                       break;
+               rte_eth_allmulticast_disable(internals->current_primary_port);
+       }
+}
+
 static void
 bond_ethdev_delayed_lsc_propagation(void *arg)
 {
@@ -2907,6 +3004,8 @@ const struct eth_dev_ops default_dev_ops = {
        .stats_reset          = bond_ethdev_stats_reset,
        .promiscuous_enable   = bond_ethdev_promiscuous_enable,
        .promiscuous_disable  = bond_ethdev_promiscuous_disable,
+       .allmulticast_enable  = bond_ethdev_allmulticast_enable,
+       .allmulticast_disable = bond_ethdev_allmulticast_disable,
        .reta_update          = bond_ethdev_rss_reta_update,
        .reta_query           = bond_ethdev_rss_reta_query,
        .rss_hash_update      = bond_ethdev_rss_hash_update,