int
valid_bonded_port_id(uint8_t port_id)
{
- if (!rte_eth_dev_is_valid_port(port_id))
- return -1;
-
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
return check_for_bonded_ethdev(&rte_eth_devices[port_id]);
}
int
valid_slave_port_id(uint8_t port_id)
{
- /* Verify that port id's are valid */
- if (!rte_eth_dev_is_valid_port(port_id))
- return -1;
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
/* Verify that port_id refers to a non bonded port */
if (check_for_bonded_ethdev(&rte_eth_devices[port_id]) == 0)
internals->tlb_slaves_order[active_count] = port_id;
}
- RTE_VERIFY(internals->active_slave_count <
+ RTE_ASSERT(internals->active_slave_count <
(RTE_DIM(internals->active_slaves) - 1));
internals->active_slaves[internals->active_slave_count] = port_id;
sizeof(internals->active_slaves[0]));
}
- RTE_VERIFY(active_count < RTE_DIM(internals->active_slaves));
+ RTE_ASSERT(active_count < RTE_DIM(internals->active_slaves));
internals->active_slave_count = active_count;
if (eth_dev->data->dev_started) {
{
struct bond_dev_private *internals = NULL;
struct rte_eth_dev *eth_dev = NULL;
+ uint32_t vlan_filter_bmp_size;
/* now do all data allocation - for eth_dev structure, dummy pci driver
* and internal (private) data
}
/* reserve an ethdev entry */
- eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL);
+ eth_dev = rte_eth_dev_allocate(name);
if (eth_dev == NULL) {
RTE_BOND_LOG(ERR, "Unable to allocate rte_eth_dev");
goto err;
internals->active_slave_count = 0;
internals->rx_offload_capa = 0;
internals->tx_offload_capa = 0;
+ internals->candidate_max_rx_pktlen = 0;
+ internals->max_rx_pktlen = 0;
/* Initially allow to choose any offload type */
internals->flow_type_rss_offloads = ETH_RSS_PROTO_MASK;
goto err;
}
+ vlan_filter_bmp_size =
+ rte_bitmap_get_memory_footprint(ETHER_MAX_VLAN_ID + 1);
+ internals->vlan_filter_bmpmem = rte_malloc(name, vlan_filter_bmp_size,
+ RTE_CACHE_LINE_SIZE);
+ if (internals->vlan_filter_bmpmem == NULL) {
+ RTE_BOND_LOG(ERR,
+ "Failed to allocate vlan bitmap for bonded device %u\n",
+ eth_dev->data->port_id);
+ goto err;
+ }
+
+ internals->vlan_filter_bmp = rte_bitmap_init(ETHER_MAX_VLAN_ID + 1,
+ internals->vlan_filter_bmpmem, vlan_filter_bmp_size);
+ if (internals->vlan_filter_bmp == NULL) {
+ RTE_BOND_LOG(ERR,
+ "Failed to init vlan bitmap for bonded device %u\n",
+ eth_dev->data->port_id);
+ rte_free(internals->vlan_filter_bmpmem);
+ goto err;
+ }
+
return eth_dev->data->port_id;
err:
eth_dev->rx_pkt_burst = NULL;
eth_dev->tx_pkt_burst = NULL;
+ internals = eth_dev->data->dev_private;
+ rte_bitmap_free(internals->vlan_filter_bmp);
+ rte_free(internals->vlan_filter_bmpmem);
rte_free(eth_dev->data->dev_private);
rte_free(eth_dev->data->mac_addrs);
return 0;
}
+static int
+slave_vlan_filter_set(uint8_t bonded_port_id, uint8_t slave_port_id)
+{
+ struct rte_eth_dev *bonded_eth_dev;
+ struct bond_dev_private *internals;
+ int found;
+ int res = 0;
+ uint64_t slab = 0;
+ uint32_t pos = 0;
+ uint16_t first;
+
+ bonded_eth_dev = &rte_eth_devices[bonded_port_id];
+ if (bonded_eth_dev->data->dev_conf.rxmode.hw_vlan_filter == 0)
+ return 0;
+
+ internals = bonded_eth_dev->data->dev_private;
+ found = rte_bitmap_scan(internals->vlan_filter_bmp, &pos, &slab);
+ first = pos;
+
+ if (!found)
+ return 0;
+
+ do {
+ uint32_t i;
+ uint64_t mask;
+
+ for (i = 0, mask = 1;
+ i < RTE_BITMAP_SLAB_BIT_SIZE;
+ i ++, mask <<= 1) {
+ if (unlikely(slab & mask)) {
+ uint16_t vlan_id = pos + i;
+
+ res = rte_eth_dev_vlan_filter(slave_port_id,
+ vlan_id, 1);
+ }
+ }
+ found = rte_bitmap_scan(internals->vlan_filter_bmp,
+ &pos, &slab);
+ } while (found && first != pos && res == 0);
+
+ return res;
+}
+
static int
__eth_bond_slave_add_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id)
{
/* Add slave details to bonded device */
slave_eth_dev->data->dev_flags |= RTE_ETH_DEV_BONDED_SLAVE;
- slave_add(internals, slave_eth_dev);
rte_eth_dev_info_get(slave_port_id, &dev_info);
+ if (dev_info.max_rx_pktlen < internals->max_rx_pktlen) {
+ RTE_BOND_LOG(ERR, "Slave (port %u) max_rx_pktlen too small",
+ slave_port_id);
+ return -1;
+ }
+
+ slave_add(internals, slave_eth_dev);
/* We need to store slaves reta_size to be able to synchronize RETA for all
* slave devices even if its sizes are different.
if (internals->slave_count < 1) {
/* if MAC is not user defined then use MAC of first slave add to
* bonded device */
- if (!internals->user_defined_mac)
- mac_address_set(bonded_eth_dev, slave_eth_dev->data->mac_addrs);
+ if (!internals->user_defined_mac) {
+ if (mac_address_set(bonded_eth_dev,
+ slave_eth_dev->data->mac_addrs)) {
+ RTE_BOND_LOG(ERR, "Failed to set MAC address");
+ return -1;
+ }
+ }
/* Inherit eth dev link properties from first slave */
link_properties_set(bonded_eth_dev,
internals->tx_offload_capa = dev_info.tx_offload_capa;
internals->flow_type_rss_offloads = dev_info.flow_type_rss_offloads;
+ /* Inherit first slave's max rx packet size */
+ internals->candidate_max_rx_pktlen = dev_info.max_rx_pktlen;
+
} else {
- /* Check slave link properties are supported if props are set,
- * all slaves must be the same */
- if (internals->link_props_set) {
- if (link_properties_valid(&(bonded_eth_dev->data->dev_link),
- &(slave_eth_dev->data->dev_link))) {
- slave_eth_dev->data->dev_flags &= (~RTE_ETH_DEV_BONDED_SLAVE);
- RTE_BOND_LOG(ERR,
- "Slave port %d link speed/duplex not supported",
- slave_port_id);
- return -1;
- }
- } else {
- link_properties_set(bonded_eth_dev,
- &(slave_eth_dev->data->dev_link));
- }
internals->rx_offload_capa &= dev_info.rx_offload_capa;
internals->tx_offload_capa &= dev_info.tx_offload_capa;
internals->flow_type_rss_offloads &= dev_info.flow_type_rss_offloads;
if (internals->reta_size > dev_info.reta_size)
internals->reta_size = dev_info.reta_size;
+ if (!internals->max_rx_pktlen &&
+ dev_info.max_rx_pktlen < internals->candidate_max_rx_pktlen)
+ internals->candidate_max_rx_pktlen = dev_info.max_rx_pktlen;
}
bonded_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf &=
activate_slave(bonded_eth_dev, slave_port_id);
}
}
+
+ slave_vlan_filter_set(bonded_port_id, slave_port_id);
+
return 0;
}
&rte_eth_devices[bonded_port_id].data->port_id);
/* Restore original MAC address of slave device */
- mac_address_set(&rte_eth_devices[slave_port_id],
+ rte_eth_dev_default_mac_addr_set(slave_port_id,
&(internals->slaves[slave_idx].persisted_mac_addr));
slave_eth_dev = &rte_eth_devices[slave_port_id];
internals->tx_offload_capa = 0;
internals->flow_type_rss_offloads = ETH_RSS_PROTO_MASK;
internals->reta_size = 0;
+ internals->candidate_max_rx_pktlen = 0;
+ internals->max_rx_pktlen = 0;
}
return 0;
}
internals->user_defined_mac = 0;
if (internals->slave_count > 0) {
+ int slave_port;
+ /* Get the primary slave location based on the primary port
+ * number as, while slave_add(), we will keep the primary
+ * slave based on slave_count,but not based on the primary port.
+ */
+ for (slave_port = 0; slave_port < internals->slave_count;
+ slave_port++) {
+ if (internals->slaves[slave_port].port_id ==
+ internals->primary_port)
+ break;
+ }
+
/* Set MAC Address of Bonded Device */
if (mac_address_set(bonded_eth_dev,
- &internals->slaves[internals->primary_port].persisted_mac_addr)
+ &internals->slaves[slave_port].persisted_mac_addr)
!= 0) {
RTE_BOND_LOG(ERR, "Failed to set MAC address on bonded device");
return -1;