LCOV - code coverage report
Current view: top level - drivers/net/bonding - rte_eth_bond_api.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 415 0.0 %
Date: 2024-02-14 00:53:57 Functions: 0 33 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 258 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2010-2017 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <string.h>
       6                 :            : 
       7                 :            : #include <rte_mbuf.h>
       8                 :            : #include <rte_malloc.h>
       9                 :            : #include <ethdev_driver.h>
      10                 :            : #include <rte_tcp.h>
      11                 :            : #include <bus_vdev_driver.h>
      12                 :            : #include <rte_kvargs.h>
      13                 :            : 
      14                 :            : #include "rte_eth_bond.h"
      15                 :            : #include "eth_bond_private.h"
      16                 :            : #include "eth_bond_8023ad_private.h"
      17                 :            : 
      18                 :            : int
      19                 :          0 : check_for_bonding_ethdev(const struct rte_eth_dev *eth_dev)
      20                 :            : {
      21                 :            :         /* Check valid pointer */
      22         [ #  # ]:          0 :         if (eth_dev == NULL ||
      23         [ #  # ]:          0 :                 eth_dev->device == NULL ||
      24         [ #  # ]:          0 :                 eth_dev->device->driver == NULL ||
      25         [ #  # ]:          0 :                 eth_dev->device->driver->name == NULL)
      26                 :            :                 return -1;
      27                 :            : 
      28                 :            :         /* return 0 if driver name matches */
      29                 :          0 :         return eth_dev->device->driver->name != pmd_bond_drv.driver.name;
      30                 :            : }
      31                 :            : 
      32                 :            : int
      33                 :          0 : valid_bonding_port_id(uint16_t port_id)
      34                 :            : {
      35         [ #  # ]:          0 :         RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
      36                 :          0 :         return check_for_bonding_ethdev(&rte_eth_devices[port_id]);
      37                 :            : }
      38                 :            : 
      39                 :            : int
      40                 :          0 : check_for_main_bonding_ethdev(const struct rte_eth_dev *eth_dev)
      41                 :            : {
      42                 :            :         int i;
      43                 :            :         struct bond_dev_private *internals;
      44                 :            : 
      45         [ #  # ]:          0 :         if (check_for_bonding_ethdev(eth_dev) != 0)
      46                 :            :                 return 0;
      47                 :            : 
      48                 :          0 :         internals = eth_dev->data->dev_private;
      49                 :            : 
      50                 :            :         /* Check if any of member devices is a bonding device */
      51         [ #  # ]:          0 :         for (i = 0; i < internals->member_count; i++)
      52         [ #  # ]:          0 :                 if (valid_bonding_port_id(internals->members[i].port_id) == 0)
      53                 :            :                         return 1;
      54                 :            : 
      55                 :            :         return 0;
      56                 :            : }
      57                 :            : 
      58                 :            : int
      59                 :          0 : valid_member_port_id(struct bond_dev_private *internals, uint16_t member_port_id)
      60                 :            : {
      61         [ #  # ]:          0 :         RTE_ETH_VALID_PORTID_OR_ERR_RET(member_port_id, -1);
      62                 :            : 
      63                 :            :         /* Verify that member_port_id refers to a non bonding port */
      64         [ #  # ]:          0 :         if (check_for_bonding_ethdev(&rte_eth_devices[member_port_id]) == 0 &&
      65         [ #  # ]:          0 :                         internals->mode == BONDING_MODE_8023AD) {
      66                 :          0 :                 RTE_BOND_LOG(ERR, "Cannot add member to bonding device in 802.3ad"
      67                 :            :                                 " mode as member is also a bonding device, only "
      68                 :            :                                 "physical devices can be support in this mode.");
      69                 :          0 :                 return -1;
      70                 :            :         }
      71                 :            : 
      72         [ #  # ]:          0 :         if (internals->port_id == member_port_id) {
      73                 :          0 :                 RTE_BOND_LOG(ERR,
      74                 :            :                         "Cannot add the bonding device itself as its member.");
      75                 :          0 :                 return -1;
      76                 :            :         }
      77                 :            : 
      78                 :            :         return 0;
      79                 :            : }
      80                 :            : 
      81                 :            : void
      82                 :          0 : activate_member(struct rte_eth_dev *eth_dev, uint16_t port_id)
      83                 :            : {
      84                 :          0 :         struct bond_dev_private *internals = eth_dev->data->dev_private;
      85                 :          0 :         uint16_t active_count = internals->active_member_count;
      86                 :            : 
      87         [ #  # ]:          0 :         if (internals->mode == BONDING_MODE_8023AD)
      88                 :          0 :                 bond_mode_8023ad_activate_member(eth_dev, port_id);
      89                 :            : 
      90                 :          0 :         if (internals->mode == BONDING_MODE_TLB
      91         [ #  # ]:          0 :                         || internals->mode == BONDING_MODE_ALB) {
      92                 :            : 
      93                 :          0 :                 internals->tlb_members_order[active_count] = port_id;
      94                 :            :         }
      95                 :            : 
      96                 :            :         RTE_ASSERT(internals->active_member_count <
      97                 :            :                         (RTE_DIM(internals->active_members) - 1));
      98                 :            : 
      99                 :          0 :         internals->active_members[internals->active_member_count] = port_id;
     100                 :          0 :         internals->active_member_count++;
     101                 :            : 
     102         [ #  # ]:          0 :         if (internals->mode == BONDING_MODE_TLB)
     103                 :          0 :                 bond_tlb_activate_member(internals);
     104         [ #  # ]:          0 :         if (internals->mode == BONDING_MODE_ALB)
     105                 :          0 :                 bond_mode_alb_client_list_upd(eth_dev);
     106                 :          0 : }
     107                 :            : 
     108                 :            : void
     109                 :          0 : deactivate_member(struct rte_eth_dev *eth_dev, uint16_t port_id)
     110                 :            : {
     111                 :            :         uint16_t member_pos;
     112                 :          0 :         struct bond_dev_private *internals = eth_dev->data->dev_private;
     113                 :          0 :         uint16_t active_count = internals->active_member_count;
     114                 :            : 
     115         [ #  # ]:          0 :         if (internals->mode == BONDING_MODE_8023AD) {
     116                 :          0 :                 bond_mode_8023ad_stop(eth_dev);
     117                 :          0 :                 bond_mode_8023ad_deactivate_member(eth_dev, port_id);
     118                 :          0 :         } else if (internals->mode == BONDING_MODE_TLB
     119         [ #  # ]:          0 :                         || internals->mode == BONDING_MODE_ALB)
     120                 :          0 :                 bond_tlb_disable(internals);
     121                 :            : 
     122                 :          0 :         member_pos = find_member_by_id(internals->active_members, active_count,
     123                 :            :                         port_id);
     124                 :            : 
     125                 :            :         /*
     126                 :            :          * If member was not at the end of the list
     127                 :            :          * shift active members up active array list.
     128                 :            :          */
     129         [ #  # ]:          0 :         if (member_pos < active_count) {
     130                 :          0 :                 active_count--;
     131                 :          0 :                 memmove(internals->active_members + member_pos,
     132                 :          0 :                                 internals->active_members + member_pos + 1,
     133                 :          0 :                                 (active_count - member_pos) *
     134                 :            :                                         sizeof(internals->active_members[0]));
     135                 :            :         }
     136                 :            : 
     137                 :            :         RTE_ASSERT(active_count < RTE_DIM(internals->active_members));
     138                 :          0 :         internals->active_member_count = active_count;
     139                 :            : 
     140         [ #  # ]:          0 :         if (eth_dev->data->dev_started) {
     141         [ #  # ]:          0 :                 if (internals->mode == BONDING_MODE_8023AD) {
     142                 :          0 :                         bond_mode_8023ad_start(eth_dev);
     143         [ #  # ]:          0 :                 } else if (internals->mode == BONDING_MODE_TLB) {
     144                 :          0 :                         bond_tlb_enable(internals);
     145         [ #  # ]:          0 :                 } else if (internals->mode == BONDING_MODE_ALB) {
     146                 :          0 :                         bond_tlb_enable(internals);
     147                 :          0 :                         bond_mode_alb_client_list_upd(eth_dev);
     148                 :            :                 }
     149                 :            :         }
     150                 :          0 : }
     151                 :            : 
     152                 :            : int
     153                 :          0 : rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id)
     154                 :            : {
     155                 :            :         struct bond_dev_private *internals;
     156                 :            :         struct rte_eth_dev *bond_dev;
     157                 :            :         char devargs[52];
     158                 :            :         int ret;
     159                 :            : 
     160         [ #  # ]:          0 :         if (name == NULL) {
     161                 :          0 :                 RTE_BOND_LOG(ERR, "Invalid name specified");
     162                 :          0 :                 return -EINVAL;
     163                 :            :         }
     164                 :            : 
     165         [ #  # ]:          0 :         ret = snprintf(devargs, sizeof(devargs),
     166                 :            :                 "driver=net_bonding,mode=%d,socket_id=%d", mode, socket_id);
     167         [ #  # ]:          0 :         if (ret < 0 || ret >= (int)sizeof(devargs))
     168                 :            :                 return -ENOMEM;
     169                 :            : 
     170                 :          0 :         ret = rte_vdev_init(name, devargs);
     171         [ #  # ]:          0 :         if (ret)
     172                 :            :                 return ret;
     173                 :            : 
     174                 :          0 :         bond_dev = rte_eth_dev_get_by_name(name);
     175                 :            :         RTE_ASSERT(bond_dev);
     176                 :            : 
     177                 :            :         /*
     178                 :            :          * To make bond_ethdev_configure() happy we need to free the
     179                 :            :          * internals->kvlist here.
     180                 :            :          *
     181                 :            :          * Also see comment in bond_ethdev_configure().
     182                 :            :          */
     183                 :          0 :         internals = bond_dev->data->dev_private;
     184                 :          0 :         rte_kvargs_free(internals->kvlist);
     185                 :          0 :         internals->kvlist = NULL;
     186                 :            : 
     187                 :          0 :         return bond_dev->data->port_id;
     188                 :            : }
     189                 :            : 
     190                 :            : int
     191                 :          0 : rte_eth_bond_free(const char *name)
     192                 :            : {
     193                 :          0 :         return rte_vdev_uninit(name);
     194                 :            : }
     195                 :            : 
     196                 :            : static int
     197                 :          0 : member_vlan_filter_set(uint16_t bonding_port_id, uint16_t member_port_id)
     198                 :            : {
     199                 :            :         struct rte_eth_dev *bonding_eth_dev;
     200                 :            :         struct bond_dev_private *internals;
     201                 :            :         int found;
     202                 :            :         int res = 0;
     203                 :          0 :         uint64_t slab = 0;
     204                 :          0 :         uint32_t pos = 0;
     205                 :            :         uint16_t first;
     206                 :            : 
     207                 :          0 :         bonding_eth_dev = &rte_eth_devices[bonding_port_id];
     208         [ #  # ]:          0 :         if ((bonding_eth_dev->data->dev_conf.rxmode.offloads &
     209                 :            :                         RTE_ETH_RX_OFFLOAD_VLAN_FILTER) == 0)
     210                 :            :                 return 0;
     211                 :            : 
     212                 :          0 :         internals = bonding_eth_dev->data->dev_private;
     213                 :          0 :         found = rte_bitmap_scan(internals->vlan_filter_bmp, &pos, &slab);
     214                 :          0 :         first = pos;
     215                 :            : 
     216         [ #  # ]:          0 :         if (!found)
     217                 :            :                 return 0;
     218                 :            : 
     219                 :            :         do {
     220                 :            :                 uint32_t i;
     221                 :            :                 uint64_t mask;
     222                 :            : 
     223                 :          0 :                 for (i = 0, mask = 1;
     224         [ #  # ]:          0 :                      i < RTE_BITMAP_SLAB_BIT_SIZE;
     225                 :          0 :                      i ++, mask <<= 1) {
     226         [ #  # ]:          0 :                         if (unlikely(slab & mask)) {
     227                 :          0 :                                 uint16_t vlan_id = pos + i;
     228                 :            : 
     229                 :          0 :                                 res = rte_eth_dev_vlan_filter(member_port_id,
     230                 :            :                                                               vlan_id, 1);
     231                 :            :                         }
     232                 :            :                 }
     233                 :          0 :                 found = rte_bitmap_scan(internals->vlan_filter_bmp,
     234                 :            :                                         &pos, &slab);
     235   [ #  #  #  #  :          0 :         } while (found && first != pos && res == 0);
                   #  # ]
     236                 :            : 
     237                 :            :         return res;
     238                 :            : }
     239                 :            : 
     240                 :            : static int
     241                 :          0 : member_rte_flow_prepare(uint16_t member_id, struct bond_dev_private *internals)
     242                 :            : {
     243                 :            :         struct rte_flow *flow;
     244                 :            :         struct rte_flow_error ferror;
     245                 :          0 :         uint16_t member_port_id = internals->members[member_id].port_id;
     246                 :            : 
     247         [ #  # ]:          0 :         if (internals->flow_isolated_valid != 0) {
     248         [ #  # ]:          0 :                 if (rte_eth_dev_stop(member_port_id) != 0) {
     249                 :          0 :                         RTE_BOND_LOG(ERR, "Failed to stop device on port %u",
     250                 :            :                                      member_port_id);
     251                 :          0 :                         return -1;
     252                 :            :                 }
     253                 :            : 
     254         [ #  # ]:          0 :                 if (rte_flow_isolate(member_port_id, internals->flow_isolated,
     255                 :            :                     &ferror)) {
     256         [ #  # ]:          0 :                         RTE_BOND_LOG(ERR, "rte_flow_isolate failed for member"
     257                 :            :                                      " %d: %s", member_id, ferror.message ?
     258                 :            :                                      ferror.message : "(no stated reason)");
     259                 :          0 :                         return -1;
     260                 :            :                 }
     261                 :            :         }
     262         [ #  # ]:          0 :         TAILQ_FOREACH(flow, &internals->flow_list, next) {
     263                 :          0 :                 flow->flows[member_id] = rte_flow_create(member_port_id,
     264                 :          0 :                                                         flow->rule.attr,
     265                 :          0 :                                                         flow->rule.pattern,
     266                 :          0 :                                                         flow->rule.actions,
     267                 :            :                                                         &ferror);
     268         [ #  # ]:          0 :                 if (flow->flows[member_id] == NULL) {
     269         [ #  # ]:          0 :                         RTE_BOND_LOG(ERR, "Cannot create flow for member"
     270                 :            :                                      " %d: %s", member_id,
     271                 :            :                                      ferror.message ? ferror.message :
     272                 :            :                                      "(no stated reason)");
     273                 :            :                         /* Destroy successful bond flows from the member */
     274         [ #  # ]:          0 :                         TAILQ_FOREACH(flow, &internals->flow_list, next) {
     275         [ #  # ]:          0 :                                 if (flow->flows[member_id] != NULL) {
     276                 :          0 :                                         rte_flow_destroy(member_port_id,
     277                 :            :                                                          flow->flows[member_id],
     278                 :            :                                                          &ferror);
     279                 :          0 :                                         flow->flows[member_id] = NULL;
     280                 :            :                                 }
     281                 :            :                         }
     282                 :            :                         return -1;
     283                 :            :                 }
     284                 :            :         }
     285                 :            :         return 0;
     286                 :            : }
     287                 :            : 
     288                 :            : static void
     289                 :          0 : eth_bond_member_inherit_dev_info_rx_first(struct bond_dev_private *internals,
     290                 :            :                                          const struct rte_eth_dev_info *di)
     291                 :            : {
     292                 :          0 :         struct rte_eth_rxconf *rxconf_i = &internals->default_rxconf;
     293                 :            : 
     294                 :          0 :         internals->reta_size = di->reta_size;
     295                 :          0 :         internals->rss_key_len = di->hash_key_size;
     296                 :            : 
     297                 :            :         /* Inherit Rx offload capabilities from the first member device */
     298                 :          0 :         internals->rx_offload_capa = di->rx_offload_capa;
     299                 :          0 :         internals->rx_queue_offload_capa = di->rx_queue_offload_capa;
     300                 :          0 :         internals->flow_type_rss_offloads = di->flow_type_rss_offloads;
     301                 :            : 
     302                 :            :         /* Inherit maximum Rx packet size from the first member device */
     303                 :          0 :         internals->candidate_max_rx_pktlen = di->max_rx_pktlen;
     304                 :            : 
     305                 :            :         /* Inherit default Rx queue settings from the first member device */
     306                 :          0 :         memcpy(rxconf_i, &di->default_rxconf, sizeof(*rxconf_i));
     307                 :            : 
     308                 :            :         /*
     309                 :            :          * Turn off descriptor prefetch and writeback by default for all
     310                 :            :          * member devices. Applications may tweak this setting if need be.
     311                 :            :          */
     312                 :          0 :         rxconf_i->rx_thresh.pthresh = 0;
     313                 :          0 :         rxconf_i->rx_thresh.hthresh = 0;
     314                 :          0 :         rxconf_i->rx_thresh.wthresh = 0;
     315                 :            : 
     316                 :            :         /* Setting this to zero should effectively enable default values */
     317                 :          0 :         rxconf_i->rx_free_thresh = 0;
     318                 :            : 
     319                 :            :         /* Disable deferred start by default for all member devices */
     320                 :          0 :         rxconf_i->rx_deferred_start = 0;
     321                 :          0 : }
     322                 :            : 
     323                 :            : static void
     324                 :            : eth_bond_member_inherit_dev_info_tx_first(struct bond_dev_private *internals,
     325                 :            :                                          const struct rte_eth_dev_info *di)
     326                 :            : {
     327                 :          0 :         struct rte_eth_txconf *txconf_i = &internals->default_txconf;
     328                 :            : 
     329                 :            :         /* Inherit Tx offload capabilities from the first member device */
     330                 :          0 :         internals->tx_offload_capa = di->tx_offload_capa;
     331                 :          0 :         internals->tx_queue_offload_capa = di->tx_queue_offload_capa;
     332                 :            : 
     333                 :            :         /* Inherit default Tx queue settings from the first member device */
     334                 :            :         memcpy(txconf_i, &di->default_txconf, sizeof(*txconf_i));
     335                 :            : 
     336                 :            :         /*
     337                 :            :          * Turn off descriptor prefetch and writeback by default for all
     338                 :            :          * member devices. Applications may tweak this setting if need be.
     339                 :            :          */
     340                 :          0 :         txconf_i->tx_thresh.pthresh = 0;
     341                 :          0 :         txconf_i->tx_thresh.hthresh = 0;
     342                 :          0 :         txconf_i->tx_thresh.wthresh = 0;
     343                 :            : 
     344                 :            :         /*
     345                 :            :          * Setting these parameters to zero assumes that default
     346                 :            :          * values will be configured implicitly by member devices.
     347                 :            :          */
     348                 :          0 :         txconf_i->tx_free_thresh = 0;
     349                 :          0 :         txconf_i->tx_rs_thresh = 0;
     350                 :            : 
     351                 :            :         /* Disable deferred start by default for all member devices */
     352                 :          0 :         txconf_i->tx_deferred_start = 0;
     353                 :            : }
     354                 :            : 
     355                 :            : static void
     356                 :          0 : eth_bond_member_inherit_dev_info_rx_next(struct bond_dev_private *internals,
     357                 :            :                                         const struct rte_eth_dev_info *di)
     358                 :            : {
     359                 :            :         struct rte_eth_rxconf *rxconf_i = &internals->default_rxconf;
     360                 :            :         const struct rte_eth_rxconf *rxconf = &di->default_rxconf;
     361                 :            : 
     362                 :          0 :         internals->rx_offload_capa &= di->rx_offload_capa;
     363                 :          0 :         internals->rx_queue_offload_capa &= di->rx_queue_offload_capa;
     364                 :          0 :         internals->flow_type_rss_offloads &= di->flow_type_rss_offloads;
     365                 :            : 
     366                 :            :         /*
     367                 :            :          * If at least one member device suggests enabling this
     368                 :            :          * setting by default, enable it for all member devices
     369                 :            :          * since disabling it may not be necessarily supported.
     370                 :            :          */
     371         [ #  # ]:          0 :         if (rxconf->rx_drop_en == 1)
     372                 :          0 :                 rxconf_i->rx_drop_en = 1;
     373                 :            : 
     374                 :            :         /*
     375                 :            :          * Adding a new member device may cause some of previously inherited
     376                 :            :          * offloads to be withdrawn from the internal rx_queue_offload_capa
     377                 :            :          * value. Thus, the new internal value of default Rx queue offloads
     378                 :            :          * has to be masked by rx_queue_offload_capa to make sure that only
     379                 :            :          * commonly supported offloads are preserved from both the previous
     380                 :            :          * value and the value being inherited from the new member device.
     381                 :            :          */
     382                 :          0 :         rxconf_i->offloads = (rxconf_i->offloads | rxconf->offloads) &
     383                 :            :                              internals->rx_queue_offload_capa;
     384                 :            : 
     385                 :            :         /*
     386                 :            :          * RETA size is GCD of all members RETA sizes, so, if all sizes will be
     387                 :            :          * the power of 2, the lower one is GCD
     388                 :            :          */
     389         [ #  # ]:          0 :         if (internals->reta_size > di->reta_size)
     390                 :          0 :                 internals->reta_size = di->reta_size;
     391         [ #  # ]:          0 :         if (internals->rss_key_len > di->hash_key_size) {
     392                 :          0 :                 RTE_BOND_LOG(WARNING, "member has different rss key size, "
     393                 :            :                                 "configuring rss may fail");
     394                 :          0 :                 internals->rss_key_len = di->hash_key_size;
     395                 :            :         }
     396                 :            : 
     397         [ #  # ]:          0 :         if (!internals->max_rx_pktlen &&
     398         [ #  # ]:          0 :             di->max_rx_pktlen < internals->candidate_max_rx_pktlen)
     399                 :          0 :                 internals->candidate_max_rx_pktlen = di->max_rx_pktlen;
     400                 :          0 : }
     401                 :            : 
     402                 :            : static void
     403                 :            : eth_bond_member_inherit_dev_info_tx_next(struct bond_dev_private *internals,
     404                 :            :                                         const struct rte_eth_dev_info *di)
     405                 :            : {
     406                 :            :         struct rte_eth_txconf *txconf_i = &internals->default_txconf;
     407                 :            :         const struct rte_eth_txconf *txconf = &di->default_txconf;
     408                 :            : 
     409                 :          0 :         internals->tx_offload_capa &= di->tx_offload_capa;
     410                 :          0 :         internals->tx_queue_offload_capa &= di->tx_queue_offload_capa;
     411                 :            : 
     412                 :            :         /*
     413                 :            :          * Adding a new member device may cause some of previously inherited
     414                 :            :          * offloads to be withdrawn from the internal tx_queue_offload_capa
     415                 :            :          * value. Thus, the new internal value of default Tx queue offloads
     416                 :            :          * has to be masked by tx_queue_offload_capa to make sure that only
     417                 :            :          * commonly supported offloads are preserved from both the previous
     418                 :            :          * value and the value being inherited from the new member device.
     419                 :            :          */
     420                 :          0 :         txconf_i->offloads = (txconf_i->offloads | txconf->offloads) &
     421                 :            :                              internals->tx_queue_offload_capa;
     422                 :            : }
     423                 :            : 
     424                 :            : static void
     425                 :            : eth_bond_member_inherit_desc_lim_first(struct rte_eth_desc_lim *bond_desc_lim,
     426                 :            :                 const struct rte_eth_desc_lim *member_desc_lim)
     427                 :            : {
     428                 :            :         memcpy(bond_desc_lim, member_desc_lim, sizeof(*bond_desc_lim));
     429                 :          0 : }
     430                 :            : 
     431                 :            : static int
     432                 :          0 : eth_bond_member_inherit_desc_lim_next(struct rte_eth_desc_lim *bond_desc_lim,
     433                 :            :                 const struct rte_eth_desc_lim *member_desc_lim)
     434                 :            : {
     435                 :          0 :         bond_desc_lim->nb_max = RTE_MIN(bond_desc_lim->nb_max,
     436                 :            :                                         member_desc_lim->nb_max);
     437                 :          0 :         bond_desc_lim->nb_min = RTE_MAX(bond_desc_lim->nb_min,
     438                 :            :                                         member_desc_lim->nb_min);
     439                 :          0 :         bond_desc_lim->nb_align = RTE_MAX(bond_desc_lim->nb_align,
     440                 :            :                                           member_desc_lim->nb_align);
     441                 :            : 
     442   [ #  #  #  # ]:          0 :         if (bond_desc_lim->nb_min > bond_desc_lim->nb_max ||
     443                 :            :             bond_desc_lim->nb_align > bond_desc_lim->nb_max) {
     444                 :          0 :                 RTE_BOND_LOG(ERR, "Failed to inherit descriptor limits");
     445                 :          0 :                 return -EINVAL;
     446                 :            :         }
     447                 :            : 
     448                 :            :         /* Treat maximum number of segments equal to 0 as unspecified */
     449         [ #  # ]:          0 :         if (member_desc_lim->nb_seg_max != 0 &&
     450   [ #  #  #  # ]:          0 :             (bond_desc_lim->nb_seg_max == 0 ||
     451                 :            :              member_desc_lim->nb_seg_max < bond_desc_lim->nb_seg_max))
     452                 :          0 :                 bond_desc_lim->nb_seg_max = member_desc_lim->nb_seg_max;
     453         [ #  # ]:          0 :         if (member_desc_lim->nb_mtu_seg_max != 0 &&
     454   [ #  #  #  # ]:          0 :             (bond_desc_lim->nb_mtu_seg_max == 0 ||
     455                 :            :              member_desc_lim->nb_mtu_seg_max < bond_desc_lim->nb_mtu_seg_max))
     456                 :          0 :                 bond_desc_lim->nb_mtu_seg_max = member_desc_lim->nb_mtu_seg_max;
     457                 :            : 
     458                 :            :         return 0;
     459                 :            : }
     460                 :            : 
     461                 :            : static int
     462                 :          0 : __eth_bond_member_add_lock_free(uint16_t bonding_port_id, uint16_t member_port_id)
     463                 :            : {
     464                 :            :         struct rte_eth_dev *bonding_eth_dev, *member_eth_dev;
     465                 :            :         struct bond_dev_private *internals;
     466                 :            :         struct rte_eth_link link_props;
     467                 :            :         struct rte_eth_dev_info dev_info;
     468                 :            :         int ret;
     469                 :            : 
     470                 :          0 :         bonding_eth_dev = &rte_eth_devices[bonding_port_id];
     471                 :          0 :         internals = bonding_eth_dev->data->dev_private;
     472                 :            : 
     473         [ #  # ]:          0 :         if (valid_member_port_id(internals, member_port_id) != 0)
     474                 :            :                 return -1;
     475                 :            : 
     476                 :          0 :         member_eth_dev = &rte_eth_devices[member_port_id];
     477         [ #  # ]:          0 :         if (member_eth_dev->data->dev_flags & RTE_ETH_DEV_BONDING_MEMBER) {
     478                 :          0 :                 RTE_BOND_LOG(ERR, "Member device is already a member of a bonding device");
     479                 :          0 :                 return -1;
     480                 :            :         }
     481                 :            : 
     482                 :          0 :         ret = rte_eth_dev_info_get(member_port_id, &dev_info);
     483         [ #  # ]:          0 :         if (ret != 0) {
     484                 :          0 :                 RTE_BOND_LOG(ERR,
     485                 :            :                         "%s: Error during getting device (port %u) info: %s\n",
     486                 :            :                         __func__, member_port_id, strerror(-ret));
     487                 :            : 
     488                 :          0 :                 return ret;
     489                 :            :         }
     490         [ #  # ]:          0 :         if (dev_info.max_rx_pktlen < internals->max_rx_pktlen) {
     491                 :          0 :                 RTE_BOND_LOG(ERR, "Member (port %u) max_rx_pktlen too small",
     492                 :            :                              member_port_id);
     493                 :          0 :                 return -1;
     494                 :            :         }
     495                 :            : 
     496                 :          0 :         member_add(internals, member_eth_dev);
     497                 :            : 
     498                 :            :         /* We need to store members reta_size to be able to synchronize RETA for all
     499                 :            :          * member devices even if its sizes are different.
     500                 :            :          */
     501                 :          0 :         internals->members[internals->member_count].reta_size = dev_info.reta_size;
     502                 :            : 
     503         [ #  # ]:          0 :         if (internals->member_count < 1) {
     504                 :            :                 /*
     505                 :            :                  * if MAC is not user defined then use MAC of first member add to
     506                 :            :                  * bonding device.
     507                 :            :                  */
     508         [ #  # ]:          0 :                 if (!internals->user_defined_mac) {
     509         [ #  # ]:          0 :                         if (mac_address_set(bonding_eth_dev,
     510                 :          0 :                                             member_eth_dev->data->mac_addrs)) {
     511                 :          0 :                                 RTE_BOND_LOG(ERR, "Failed to set MAC address");
     512                 :          0 :                                 return -1;
     513                 :            :                         }
     514                 :            :                 }
     515                 :            : 
     516                 :            :                 /* Make primary member */
     517                 :          0 :                 internals->primary_port = member_port_id;
     518                 :          0 :                 internals->current_primary_port = member_port_id;
     519                 :            : 
     520                 :          0 :                 internals->speed_capa = dev_info.speed_capa;
     521                 :            : 
     522                 :            :                 /* Inherit queues settings from first member */
     523                 :          0 :                 internals->nb_rx_queues = member_eth_dev->data->nb_rx_queues;
     524                 :          0 :                 internals->nb_tx_queues = member_eth_dev->data->nb_tx_queues;
     525                 :            : 
     526                 :          0 :                 eth_bond_member_inherit_dev_info_rx_first(internals, &dev_info);
     527                 :            :                 eth_bond_member_inherit_dev_info_tx_first(internals, &dev_info);
     528                 :            : 
     529                 :          0 :                 eth_bond_member_inherit_desc_lim_first(&internals->rx_desc_lim,
     530                 :            :                                                       &dev_info.rx_desc_lim);
     531                 :          0 :                 eth_bond_member_inherit_desc_lim_first(&internals->tx_desc_lim,
     532                 :            :                                                       &dev_info.tx_desc_lim);
     533                 :            :         } else {
     534                 :            :                 int ret;
     535                 :            : 
     536                 :          0 :                 internals->speed_capa &= dev_info.speed_capa;
     537                 :          0 :                 eth_bond_member_inherit_dev_info_rx_next(internals, &dev_info);
     538                 :            :                 eth_bond_member_inherit_dev_info_tx_next(internals, &dev_info);
     539                 :            : 
     540                 :          0 :                 ret = eth_bond_member_inherit_desc_lim_next(&internals->rx_desc_lim,
     541                 :            :                                                         &dev_info.rx_desc_lim);
     542         [ #  # ]:          0 :                 if (ret != 0)
     543                 :            :                         return ret;
     544                 :            : 
     545                 :          0 :                 ret = eth_bond_member_inherit_desc_lim_next(&internals->tx_desc_lim,
     546                 :            :                                                         &dev_info.tx_desc_lim);
     547         [ #  # ]:          0 :                 if (ret != 0)
     548                 :            :                         return ret;
     549                 :            :         }
     550                 :            : 
     551                 :            :         /* Bond mode Broadcast & 8023AD don't support MBUF_FAST_FREE offload. */
     552         [ #  # ]:          0 :         if (internals->mode == BONDING_MODE_8023AD ||
     553                 :            :             internals->mode == BONDING_MODE_BROADCAST)
     554                 :          0 :                 internals->tx_offload_capa &= ~RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
     555                 :            : 
     556                 :          0 :         bonding_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf &=
     557                 :          0 :                         internals->flow_type_rss_offloads;
     558                 :            : 
     559         [ #  # ]:          0 :         if (member_rte_flow_prepare(internals->member_count, internals) != 0) {
     560                 :          0 :                 RTE_BOND_LOG(ERR, "Failed to prepare new member flows: port=%d",
     561                 :            :                              member_port_id);
     562                 :          0 :                 return -1;
     563                 :            :         }
     564                 :            : 
     565                 :            :         /* Add additional MAC addresses to the member */
     566         [ #  # ]:          0 :         if (member_add_mac_addresses(bonding_eth_dev, member_port_id) != 0) {
     567                 :          0 :                 RTE_BOND_LOG(ERR, "Failed to add mac address(es) to member %hu",
     568                 :            :                                 member_port_id);
     569                 :          0 :                 return -1;
     570                 :            :         }
     571                 :            : 
     572                 :          0 :         internals->member_count++;
     573                 :            : 
     574         [ #  # ]:          0 :         if (bonding_eth_dev->data->dev_started) {
     575         [ #  # ]:          0 :                 if (member_configure(bonding_eth_dev, member_eth_dev) != 0) {
     576                 :          0 :                         internals->member_count--;
     577                 :          0 :                         RTE_BOND_LOG(ERR, "rte_bond_members_configure: port=%d",
     578                 :            :                                         member_port_id);
     579                 :          0 :                         return -1;
     580                 :            :                 }
     581         [ #  # ]:          0 :                 if (member_start(bonding_eth_dev, member_eth_dev) != 0) {
     582                 :          0 :                         internals->member_count--;
     583                 :          0 :                         RTE_BOND_LOG(ERR, "rte_bond_members_start: port=%d",
     584                 :            :                                         member_port_id);
     585                 :          0 :                         return -1;
     586                 :            :                 }
     587                 :            :         }
     588                 :            : 
     589                 :            :         /* Update all member devices MACs */
     590                 :          0 :         mac_address_members_update(bonding_eth_dev);
     591                 :            : 
     592                 :            :         /*
     593                 :            :          * Register link status change callback with bonding device pointer as
     594                 :            :          * argument.
     595                 :            :          */
     596                 :          0 :         rte_eth_dev_callback_register(member_port_id, RTE_ETH_EVENT_INTR_LSC,
     597                 :          0 :                         bond_ethdev_lsc_event_callback, &bonding_eth_dev->data->port_id);
     598                 :            : 
     599                 :            :         /*
     600                 :            :          * If bonding device is started then we can add the member to our active
     601                 :            :          * member array.
     602                 :            :          */
     603         [ #  # ]:          0 :         if (bonding_eth_dev->data->dev_started) {
     604                 :          0 :                 ret = rte_eth_link_get_nowait(member_port_id, &link_props);
     605         [ #  # ]:          0 :                 if (ret < 0) {
     606                 :          0 :                         rte_eth_dev_callback_unregister(member_port_id,
     607                 :            :                                         RTE_ETH_EVENT_INTR_LSC,
     608                 :            :                                         bond_ethdev_lsc_event_callback,
     609                 :          0 :                                         &bonding_eth_dev->data->port_id);
     610                 :          0 :                         internals->member_count--;
     611                 :          0 :                         RTE_BOND_LOG(ERR,
     612                 :            :                                 "Member (port %u) link get failed: %s\n",
     613                 :            :                                 member_port_id, rte_strerror(-ret));
     614                 :          0 :                         return -1;
     615                 :            :                 }
     616                 :            : 
     617         [ #  # ]:          0 :                 if (link_props.link_status == RTE_ETH_LINK_UP) {
     618         [ #  # ]:          0 :                         if (internals->active_member_count == 0 &&
     619         [ #  # ]:          0 :                             !internals->user_defined_primary_port)
     620                 :          0 :                                 bond_ethdev_primary_set(internals,
     621                 :            :                                                         member_port_id);
     622                 :            :                 }
     623                 :            :         }
     624                 :            : 
     625                 :            :         /* Add member details to bonding device */
     626                 :          0 :         member_eth_dev->data->dev_flags |= RTE_ETH_DEV_BONDING_MEMBER;
     627                 :            : 
     628                 :          0 :         member_vlan_filter_set(bonding_port_id, member_port_id);
     629                 :            : 
     630                 :          0 :         return 0;
     631                 :            : 
     632                 :            : }
     633                 :            : 
     634                 :            : int
     635                 :          0 : rte_eth_bond_member_add(uint16_t bonding_port_id, uint16_t member_port_id)
     636                 :            : {
     637                 :            :         struct rte_eth_dev *bonding_eth_dev;
     638                 :            :         struct bond_dev_private *internals;
     639                 :            : 
     640                 :            :         int retval;
     641                 :            : 
     642         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
     643                 :            :                 return -1;
     644                 :            : 
     645                 :            :         bonding_eth_dev = &rte_eth_devices[bonding_port_id];
     646                 :          0 :         internals = bonding_eth_dev->data->dev_private;
     647                 :            : 
     648         [ #  # ]:          0 :         if (valid_member_port_id(internals, member_port_id) != 0)
     649                 :            :                 return -1;
     650                 :            : 
     651                 :          0 :         rte_spinlock_lock(&internals->lock);
     652                 :            : 
     653                 :          0 :         retval = __eth_bond_member_add_lock_free(bonding_port_id, member_port_id);
     654                 :            : 
     655                 :            :         rte_spinlock_unlock(&internals->lock);
     656                 :            : 
     657                 :          0 :         return retval;
     658                 :            : }
     659                 :            : 
     660                 :            : static int
     661                 :          0 : __eth_bond_member_remove_lock_free(uint16_t bonding_port_id,
     662                 :            :                                    uint16_t member_port_id)
     663                 :            : {
     664                 :            :         struct rte_eth_dev *bonding_eth_dev;
     665                 :            :         struct bond_dev_private *internals;
     666                 :            :         struct rte_eth_dev *member_eth_dev;
     667                 :            :         struct rte_flow_error flow_error;
     668                 :            :         struct rte_flow *flow;
     669                 :            :         int i, member_idx;
     670                 :            : 
     671                 :          0 :         bonding_eth_dev = &rte_eth_devices[bonding_port_id];
     672                 :          0 :         internals = bonding_eth_dev->data->dev_private;
     673                 :            : 
     674         [ #  # ]:          0 :         if (valid_member_port_id(internals, member_port_id) < 0)
     675                 :            :                 return -1;
     676                 :            : 
     677                 :            :         /* first remove from active member list */
     678                 :          0 :         member_idx = find_member_by_id(internals->active_members,
     679                 :          0 :                 internals->active_member_count, member_port_id);
     680                 :            : 
     681         [ #  # ]:          0 :         if (member_idx < internals->active_member_count)
     682                 :          0 :                 deactivate_member(bonding_eth_dev, member_port_id);
     683                 :            : 
     684                 :            :         member_idx = -1;
     685                 :            :         /* now find in member list */
     686         [ #  # ]:          0 :         for (i = 0; i < internals->member_count; i++)
     687         [ #  # ]:          0 :                 if (internals->members[i].port_id == member_port_id) {
     688                 :            :                         member_idx = i;
     689                 :            :                         break;
     690                 :            :                 }
     691                 :            : 
     692         [ #  # ]:          0 :         if (member_idx < 0) {
     693                 :          0 :                 RTE_BOND_LOG(ERR, "Could not find member in port list, member count %u",
     694                 :            :                                 internals->member_count);
     695                 :          0 :                 return -1;
     696                 :            :         }
     697                 :            : 
     698                 :            :         /* Un-register link status change callback with bonding device pointer as
     699                 :            :          * argument*/
     700                 :          0 :         rte_eth_dev_callback_unregister(member_port_id, RTE_ETH_EVENT_INTR_LSC,
     701                 :            :                         bond_ethdev_lsc_event_callback,
     702                 :          0 :                         &rte_eth_devices[bonding_port_id].data->port_id);
     703                 :            : 
     704                 :            :         /* Restore original MAC address of member device */
     705                 :          0 :         rte_eth_dev_default_mac_addr_set(member_port_id,
     706                 :            :                         &internals->members[member_idx].persisted_mac_addr);
     707                 :            : 
     708                 :            :         /* remove additional MAC addresses from the member */
     709                 :          0 :         member_remove_mac_addresses(bonding_eth_dev, member_port_id);
     710                 :            : 
     711                 :            :         /*
     712                 :            :          * Remove bond device flows from member device.
     713                 :            :          * Note: don't restore flow isolate mode.
     714                 :            :          */
     715         [ #  # ]:          0 :         TAILQ_FOREACH(flow, &internals->flow_list, next) {
     716         [ #  # ]:          0 :                 if (flow->flows[member_idx] != NULL) {
     717                 :          0 :                         rte_flow_destroy(member_port_id, flow->flows[member_idx],
     718                 :            :                                          &flow_error);
     719                 :          0 :                         flow->flows[member_idx] = NULL;
     720                 :            :                 }
     721                 :            :         }
     722                 :            : 
     723                 :            :         /* Remove the dedicated queues flow */
     724         [ #  # ]:          0 :         if (internals->mode == BONDING_MODE_8023AD &&
     725         [ #  # ]:          0 :                 internals->mode4.dedicated_queues.enabled == 1 &&
     726         [ #  # ]:          0 :                 internals->mode4.dedicated_queues.flow[member_port_id] != NULL) {
     727                 :          0 :                 rte_flow_destroy(member_port_id,
     728                 :            :                                 internals->mode4.dedicated_queues.flow[member_port_id],
     729                 :            :                                 &flow_error);
     730                 :          0 :                 internals->mode4.dedicated_queues.flow[member_port_id] = NULL;
     731                 :            :         }
     732                 :            : 
     733                 :          0 :         member_eth_dev = &rte_eth_devices[member_port_id];
     734                 :          0 :         member_remove(internals, member_eth_dev);
     735                 :          0 :         member_eth_dev->data->dev_flags &= (~RTE_ETH_DEV_BONDING_MEMBER);
     736                 :            : 
     737                 :            :         /*  first member in the active list will be the primary by default,
     738                 :            :          *  otherwise use first device in list */
     739         [ #  # ]:          0 :         if (internals->current_primary_port == member_port_id) {
     740         [ #  # ]:          0 :                 if (internals->active_member_count > 0)
     741                 :          0 :                         internals->current_primary_port = internals->active_members[0];
     742         [ #  # ]:          0 :                 else if (internals->member_count > 0)
     743                 :          0 :                         internals->current_primary_port = internals->members[0].port_id;
     744                 :            :                 else
     745                 :          0 :                         internals->primary_port = 0;
     746                 :          0 :                 mac_address_members_update(bonding_eth_dev);
     747                 :            :         }
     748                 :            : 
     749         [ #  # ]:          0 :         if (internals->active_member_count < 1) {
     750                 :            :                 /*
     751                 :            :                  * if no members are any longer attached to bonding device and MAC is not
     752                 :            :                  * user defined then clear MAC of bonding device as it will be reset
     753                 :            :                  * when a new member is added.
     754                 :            :                  */
     755   [ #  #  #  # ]:          0 :                 if (internals->member_count < 1 && !internals->user_defined_mac)
     756                 :          0 :                         memset(rte_eth_devices[bonding_port_id].data->mac_addrs, 0,
     757                 :            :                                 sizeof(*rte_eth_devices[bonding_port_id].data->mac_addrs));
     758                 :            :         }
     759         [ #  # ]:          0 :         if (internals->member_count == 0) {
     760                 :          0 :                 internals->rx_offload_capa = 0;
     761                 :          0 :                 internals->tx_offload_capa = 0;
     762                 :          0 :                 internals->rx_queue_offload_capa = 0;
     763                 :          0 :                 internals->tx_queue_offload_capa = 0;
     764                 :          0 :                 internals->flow_type_rss_offloads = RTE_ETH_RSS_PROTO_MASK;
     765                 :          0 :                 internals->reta_size = 0;
     766                 :          0 :                 internals->candidate_max_rx_pktlen = 0;
     767                 :          0 :                 internals->max_rx_pktlen = 0;
     768                 :            :         }
     769                 :            :         return 0;
     770                 :            : }
     771                 :            : 
     772                 :            : int
     773                 :          0 : rte_eth_bond_member_remove(uint16_t bonding_port_id, uint16_t member_port_id)
     774                 :            : {
     775                 :            :         struct rte_eth_dev *bonding_eth_dev;
     776                 :            :         struct bond_dev_private *internals;
     777                 :            :         int retval;
     778                 :            : 
     779         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
     780                 :            :                 return -1;
     781                 :            : 
     782                 :            :         bonding_eth_dev = &rte_eth_devices[bonding_port_id];
     783                 :          0 :         internals = bonding_eth_dev->data->dev_private;
     784                 :            : 
     785                 :          0 :         rte_spinlock_lock(&internals->lock);
     786                 :            : 
     787                 :          0 :         retval = __eth_bond_member_remove_lock_free(bonding_port_id, member_port_id);
     788                 :            : 
     789                 :            :         rte_spinlock_unlock(&internals->lock);
     790                 :            : 
     791                 :          0 :         return retval;
     792                 :            : }
     793                 :            : 
     794                 :            : int
     795                 :          0 : rte_eth_bond_mode_set(uint16_t bonding_port_id, uint8_t mode)
     796                 :            : {
     797                 :            :         struct rte_eth_dev *bonding_eth_dev;
     798                 :            : 
     799         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
     800                 :            :                 return -1;
     801                 :            : 
     802                 :          0 :         bonding_eth_dev = &rte_eth_devices[bonding_port_id];
     803                 :            : 
     804   [ #  #  #  # ]:          0 :         if (check_for_main_bonding_ethdev(bonding_eth_dev) != 0 &&
     805                 :            :                         mode == BONDING_MODE_8023AD)
     806                 :            :                 return -1;
     807                 :            : 
     808                 :          0 :         return bond_ethdev_mode_set(bonding_eth_dev, mode);
     809                 :            : }
     810                 :            : 
     811                 :            : int
     812                 :          0 : rte_eth_bond_mode_get(uint16_t bonding_port_id)
     813                 :            : {
     814                 :            :         struct bond_dev_private *internals;
     815                 :            : 
     816         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
     817                 :            :                 return -1;
     818                 :            : 
     819                 :          0 :         internals = rte_eth_devices[bonding_port_id].data->dev_private;
     820                 :            : 
     821                 :          0 :         return internals->mode;
     822                 :            : }
     823                 :            : 
     824                 :            : int
     825                 :          0 : rte_eth_bond_primary_set(uint16_t bonding_port_id, uint16_t member_port_id)
     826                 :            : {
     827                 :            :         struct bond_dev_private *internals;
     828                 :            : 
     829         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
     830                 :            :                 return -1;
     831                 :            : 
     832                 :          0 :         internals = rte_eth_devices[bonding_port_id].data->dev_private;
     833                 :            : 
     834         [ #  # ]:          0 :         if (valid_member_port_id(internals, member_port_id) != 0)
     835                 :            :                 return -1;
     836                 :            : 
     837                 :          0 :         internals->user_defined_primary_port = 1;
     838                 :          0 :         internals->primary_port = member_port_id;
     839                 :            : 
     840                 :          0 :         bond_ethdev_primary_set(internals, member_port_id);
     841                 :            : 
     842                 :          0 :         return 0;
     843                 :            : }
     844                 :            : 
     845                 :            : int
     846                 :          0 : rte_eth_bond_primary_get(uint16_t bonding_port_id)
     847                 :            : {
     848                 :            :         struct bond_dev_private *internals;
     849                 :            : 
     850         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
     851                 :            :                 return -1;
     852                 :            : 
     853                 :          0 :         internals = rte_eth_devices[bonding_port_id].data->dev_private;
     854                 :            : 
     855         [ #  # ]:          0 :         if (internals->member_count < 1)
     856                 :            :                 return -1;
     857                 :            : 
     858                 :          0 :         return internals->current_primary_port;
     859                 :            : }
     860                 :            : 
     861                 :            : int
     862                 :          0 : rte_eth_bond_members_get(uint16_t bonding_port_id, uint16_t members[],
     863                 :            :                         uint16_t len)
     864                 :            : {
     865                 :            :         struct bond_dev_private *internals;
     866                 :            :         uint16_t i;
     867                 :            : 
     868         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
     869                 :            :                 return -1;
     870                 :            : 
     871         [ #  # ]:          0 :         if (members == NULL)
     872                 :            :                 return -1;
     873                 :            : 
     874                 :          0 :         internals = rte_eth_devices[bonding_port_id].data->dev_private;
     875                 :            : 
     876         [ #  # ]:          0 :         if (internals->member_count > len)
     877                 :            :                 return -1;
     878                 :            : 
     879         [ #  # ]:          0 :         for (i = 0; i < internals->member_count; i++)
     880                 :          0 :                 members[i] = internals->members[i].port_id;
     881                 :            : 
     882                 :          0 :         return internals->member_count;
     883                 :            : }
     884                 :            : 
     885                 :            : int
     886                 :          0 : rte_eth_bond_active_members_get(uint16_t bonding_port_id, uint16_t members[],
     887                 :            :                 uint16_t len)
     888                 :            : {
     889                 :            :         struct bond_dev_private *internals;
     890                 :            : 
     891         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
     892                 :            :                 return -1;
     893                 :            : 
     894         [ #  # ]:          0 :         if (members == NULL)
     895                 :            :                 return -1;
     896                 :            : 
     897                 :          0 :         internals = rte_eth_devices[bonding_port_id].data->dev_private;
     898                 :            : 
     899         [ #  # ]:          0 :         if (internals->active_member_count > len)
     900                 :            :                 return -1;
     901                 :            : 
     902                 :          0 :         memcpy(members, internals->active_members,
     903                 :          0 :         internals->active_member_count * sizeof(internals->active_members[0]));
     904                 :            : 
     905                 :          0 :         return internals->active_member_count;
     906                 :            : }
     907                 :            : 
     908                 :            : int
     909                 :          0 : rte_eth_bond_mac_address_set(uint16_t bonding_port_id,
     910                 :            :                 struct rte_ether_addr *mac_addr)
     911                 :            : {
     912                 :            :         struct rte_eth_dev *bonding_eth_dev;
     913                 :            :         struct bond_dev_private *internals;
     914                 :            : 
     915         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
     916                 :            :                 return -1;
     917                 :            : 
     918                 :          0 :         bonding_eth_dev = &rte_eth_devices[bonding_port_id];
     919                 :          0 :         internals = bonding_eth_dev->data->dev_private;
     920                 :            : 
     921                 :            :         /* Set MAC Address of Bonding Device */
     922         [ #  # ]:          0 :         if (mac_address_set(bonding_eth_dev, mac_addr))
     923                 :            :                 return -1;
     924                 :            : 
     925                 :          0 :         internals->user_defined_mac = 1;
     926                 :            : 
     927                 :            :         /* Update all member devices MACs*/
     928         [ #  # ]:          0 :         if (internals->member_count > 0)
     929                 :          0 :                 return mac_address_members_update(bonding_eth_dev);
     930                 :            : 
     931                 :            :         return 0;
     932                 :            : }
     933                 :            : 
     934                 :            : int
     935                 :          0 : rte_eth_bond_mac_address_reset(uint16_t bonding_port_id)
     936                 :            : {
     937                 :            :         struct rte_eth_dev *bonding_eth_dev;
     938                 :            :         struct bond_dev_private *internals;
     939                 :            : 
     940         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
     941                 :            :                 return -1;
     942                 :            : 
     943                 :          0 :         bonding_eth_dev = &rte_eth_devices[bonding_port_id];
     944                 :          0 :         internals = bonding_eth_dev->data->dev_private;
     945                 :            : 
     946                 :          0 :         internals->user_defined_mac = 0;
     947                 :            : 
     948         [ #  # ]:          0 :         if (internals->member_count > 0) {
     949                 :            :                 int member_port;
     950                 :            :                 /* Get the primary member location based on the primary port
     951                 :            :                  * number as, while member_add(), we will keep the primary
     952                 :            :                  * member based on member_count,but not based on the primary port.
     953                 :            :                  */
     954         [ #  # ]:          0 :                 for (member_port = 0; member_port < internals->member_count;
     955                 :          0 :                      member_port++) {
     956                 :          0 :                         if (internals->members[member_port].port_id ==
     957         [ #  # ]:          0 :                             internals->primary_port)
     958                 :            :                                 break;
     959                 :            :                 }
     960                 :            : 
     961                 :            :                 /* Set MAC Address of Bonding Device */
     962         [ #  # ]:          0 :                 if (mac_address_set(bonding_eth_dev,
     963                 :            :                         &internals->members[member_port].persisted_mac_addr)
     964                 :            :                                 != 0) {
     965                 :          0 :                         RTE_BOND_LOG(ERR, "Failed to set MAC address on bonding device");
     966                 :          0 :                         return -1;
     967                 :            :                 }
     968                 :            :                 /* Update all member devices MAC addresses */
     969                 :          0 :                 return mac_address_members_update(bonding_eth_dev);
     970                 :            :         }
     971                 :            :         /* No need to update anything as no members present */
     972                 :            :         return 0;
     973                 :            : }
     974                 :            : 
     975                 :            : int
     976                 :          0 : rte_eth_bond_xmit_policy_set(uint16_t bonding_port_id, uint8_t policy)
     977                 :            : {
     978                 :            :         struct bond_dev_private *internals;
     979                 :            : 
     980         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
     981                 :            :                 return -1;
     982                 :            : 
     983                 :          0 :         internals = rte_eth_devices[bonding_port_id].data->dev_private;
     984                 :            : 
     985   [ #  #  #  # ]:          0 :         switch (policy) {
     986                 :          0 :         case BALANCE_XMIT_POLICY_LAYER2:
     987                 :          0 :                 internals->balance_xmit_policy = policy;
     988                 :          0 :                 internals->burst_xmit_hash = burst_xmit_l2_hash;
     989                 :          0 :                 break;
     990                 :          0 :         case BALANCE_XMIT_POLICY_LAYER23:
     991                 :          0 :                 internals->balance_xmit_policy = policy;
     992                 :          0 :                 internals->burst_xmit_hash = burst_xmit_l23_hash;
     993                 :          0 :                 break;
     994                 :          0 :         case BALANCE_XMIT_POLICY_LAYER34:
     995                 :          0 :                 internals->balance_xmit_policy = policy;
     996                 :          0 :                 internals->burst_xmit_hash = burst_xmit_l34_hash;
     997                 :          0 :                 break;
     998                 :            : 
     999                 :            :         default:
    1000                 :            :                 return -1;
    1001                 :            :         }
    1002                 :            :         return 0;
    1003                 :            : }
    1004                 :            : 
    1005                 :            : int
    1006                 :          0 : rte_eth_bond_xmit_policy_get(uint16_t bonding_port_id)
    1007                 :            : {
    1008                 :            :         struct bond_dev_private *internals;
    1009                 :            : 
    1010         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
    1011                 :            :                 return -1;
    1012                 :            : 
    1013                 :          0 :         internals = rte_eth_devices[bonding_port_id].data->dev_private;
    1014                 :            : 
    1015                 :          0 :         return internals->balance_xmit_policy;
    1016                 :            : }
    1017                 :            : 
    1018                 :            : int
    1019                 :          0 : rte_eth_bond_link_monitoring_set(uint16_t bonding_port_id, uint32_t internal_ms)
    1020                 :            : {
    1021                 :            :         struct bond_dev_private *internals;
    1022                 :            : 
    1023         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
    1024                 :            :                 return -1;
    1025                 :            : 
    1026                 :          0 :         internals = rte_eth_devices[bonding_port_id].data->dev_private;
    1027                 :          0 :         internals->link_status_polling_interval_ms = internal_ms;
    1028                 :            : 
    1029                 :          0 :         return 0;
    1030                 :            : }
    1031                 :            : 
    1032                 :            : int
    1033                 :          0 : rte_eth_bond_link_monitoring_get(uint16_t bonding_port_id)
    1034                 :            : {
    1035                 :            :         struct bond_dev_private *internals;
    1036                 :            : 
    1037         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
    1038                 :            :                 return -1;
    1039                 :            : 
    1040                 :          0 :         internals = rte_eth_devices[bonding_port_id].data->dev_private;
    1041                 :            : 
    1042                 :          0 :         return internals->link_status_polling_interval_ms;
    1043                 :            : }
    1044                 :            : 
    1045                 :            : int
    1046                 :          0 : rte_eth_bond_link_down_prop_delay_set(uint16_t bonding_port_id,
    1047                 :            :                                        uint32_t delay_ms)
    1048                 :            : 
    1049                 :            : {
    1050                 :            :         struct bond_dev_private *internals;
    1051                 :            : 
    1052         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
    1053                 :            :                 return -1;
    1054                 :            : 
    1055                 :          0 :         internals = rte_eth_devices[bonding_port_id].data->dev_private;
    1056                 :          0 :         internals->link_down_delay_ms = delay_ms;
    1057                 :            : 
    1058                 :          0 :         return 0;
    1059                 :            : }
    1060                 :            : 
    1061                 :            : int
    1062                 :          0 : rte_eth_bond_link_down_prop_delay_get(uint16_t bonding_port_id)
    1063                 :            : {
    1064                 :            :         struct bond_dev_private *internals;
    1065                 :            : 
    1066         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
    1067                 :            :                 return -1;
    1068                 :            : 
    1069                 :          0 :         internals = rte_eth_devices[bonding_port_id].data->dev_private;
    1070                 :            : 
    1071                 :          0 :         return internals->link_down_delay_ms;
    1072                 :            : }
    1073                 :            : 
    1074                 :            : int
    1075                 :          0 : rte_eth_bond_link_up_prop_delay_set(uint16_t bonding_port_id, uint32_t delay_ms)
    1076                 :            : 
    1077                 :            : {
    1078                 :            :         struct bond_dev_private *internals;
    1079                 :            : 
    1080         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
    1081                 :            :                 return -1;
    1082                 :            : 
    1083                 :          0 :         internals = rte_eth_devices[bonding_port_id].data->dev_private;
    1084                 :          0 :         internals->link_up_delay_ms = delay_ms;
    1085                 :            : 
    1086                 :          0 :         return 0;
    1087                 :            : }
    1088                 :            : 
    1089                 :            : int
    1090                 :          0 : rte_eth_bond_link_up_prop_delay_get(uint16_t bonding_port_id)
    1091                 :            : {
    1092                 :            :         struct bond_dev_private *internals;
    1093                 :            : 
    1094         [ #  # ]:          0 :         if (valid_bonding_port_id(bonding_port_id) != 0)
    1095                 :            :                 return -1;
    1096                 :            : 
    1097                 :          0 :         internals = rte_eth_devices[bonding_port_id].data->dev_private;
    1098                 :            : 
    1099                 :          0 :         return internals->link_up_delay_ms;
    1100                 :            : }

Generated by: LCOV version 1.14