X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbonding%2Frte_eth_bond_api.c;h=8a000c81304d6245eb7001a37ba5f8332bd8b490;hb=6069d815bc4dd73e82396a607882fe8395e592ed;hp=e91a62340656bcf106e814e217fa0a94f02dff5a;hpb=3eb6bdd89e49db7ca1b9b5827b8aa194ecfb2e60;p=dpdk.git diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c index e91a623406..8a000c8130 100644 --- a/drivers/net/bonding/rte_eth_bond_api.c +++ b/drivers/net/bonding/rte_eth_bond_api.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,64 +44,37 @@ #define DEFAULT_POLLING_INTERVAL_10_MS (10) -int -valid_bonded_ethdev(struct rte_eth_dev *eth_dev) -{ - size_t len; - - /* Check valid pointer */ - if (eth_dev->driver->pci_drv.name == NULL || driver_name == NULL) - return -1; - - /* Check string lengths are equal */ - len = strlen(driver_name); - if (strlen(eth_dev->driver->pci_drv.name) != len) - return -1; - - /* Compare strings */ - return strncmp(eth_dev->driver->pci_drv.name, driver_name, len); -} +const char pmd_bond_driver_name[] = "rte_bond_pmd"; int -valid_port_id(uint8_t port_id) +check_for_bonded_ethdev(const struct rte_eth_dev *eth_dev) { - /* Verify that port id is valid */ - int ethdev_count = rte_eth_dev_count(); - if (port_id >= ethdev_count) { - RTE_BOND_LOG(ERR, "Port Id %d is greater than rte_eth_dev_count %d", - port_id, ethdev_count); + /* Check valid pointer */ + if (eth_dev->data->drv_name == NULL) return -1; - } - return 0; + /* return 0 if driver name matches */ + return eth_dev->data->drv_name != pmd_bond_driver_name; } int valid_bonded_port_id(uint8_t port_id) { - /* Verify that port id's are valid */ - if (valid_port_id(port_id)) + if (!rte_eth_dev_is_valid_port(port_id)) return -1; - /* Verify that bonded_port_id refers to a bonded port */ - if (valid_bonded_ethdev(&rte_eth_devices[port_id])) { - RTE_BOND_LOG(ERR, "Specified port Id %d is not a bonded eth_dev device", - port_id); - return -1; - } - - return 0; + 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 (valid_port_id(port_id)) + if (!rte_eth_dev_is_valid_port(port_id)) return -1; /* Verify that port_id refers to a non bonded port */ - if (!valid_bonded_ethdev(&rte_eth_devices[port_id])) + if (check_for_bonded_ethdev(&rte_eth_devices[port_id]) == 0) return -1; return 0; @@ -192,17 +165,12 @@ number_of_sockets(void) return ++sockets; } -const char *driver_name = "Link Bonding PMD"; - int rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) { - struct rte_pci_device *pci_dev = NULL; struct bond_dev_private *internals = NULL; struct rte_eth_dev *eth_dev = NULL; - struct eth_driver *eth_drv = NULL; - struct rte_pci_driver *pci_drv = NULL; - struct rte_pci_id *pci_id_table = NULL; + /* now do all data allocation - for eth_dev structure, dummy pci driver * and internal (private) data */ @@ -218,33 +186,6 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) goto err; } - pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, socket_id); - if (pci_dev == NULL) { - RTE_BOND_LOG(ERR, "Unable to malloc pci dev on socket"); - goto err; - } - - eth_drv = rte_zmalloc_socket(name, sizeof(*eth_drv), 0, socket_id); - if (eth_drv == NULL) { - RTE_BOND_LOG(ERR, "Unable to malloc eth_drv on socket"); - goto err; - } - - pci_drv = ð_drv->pci_drv; - - pci_id_table = rte_zmalloc_socket(name, sizeof(*pci_id_table), 0, socket_id); - if (pci_id_table == NULL) { - RTE_BOND_LOG(ERR, "Unable to malloc pci_id_table on socket"); - goto err; - } - pci_id_table->device_id = PCI_ANY_ID; - pci_id_table->subsystem_device_id = PCI_ANY_ID; - pci_id_table->vendor_id = PCI_ANY_ID; - pci_id_table->subsystem_vendor_id = PCI_ANY_ID; - - pci_drv->id_table = pci_id_table; - pci_drv->drv_flags = RTE_PCI_DRV_INTR_LSC; - internals = rte_zmalloc_socket(name, sizeof(*internals), 0, socket_id); if (internals == NULL) { RTE_BOND_LOG(ERR, "Unable to malloc internals on socket"); @@ -258,10 +199,6 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) goto err; } - pci_dev->numa_node = socket_id; - pci_drv->name = driver_name; - - eth_dev->driver = eth_drv; eth_dev->data->dev_private = internals; eth_dev->data->nb_rx_queues = (uint16_t)1; eth_dev->data->nb_tx_queues = (uint16_t)1; @@ -272,6 +209,10 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) eth_dev->data->mac_addrs = rte_zmalloc_socket(name, ETHER_ADDR_LEN, 0, socket_id); + if (eth_dev->data->mac_addrs == NULL) { + RTE_BOND_LOG(ERR, "Unable to malloc mac_addrs"); + goto err; + } eth_dev->data->dev_started = 0; eth_dev->data->promiscuous = 0; @@ -279,7 +220,12 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) eth_dev->data->all_multicast = 0; eth_dev->dev_ops = &default_dev_ops; - eth_dev->pci_dev = pci_dev; + eth_dev->data->dev_flags = RTE_ETH_DEV_INTR_LSC | + RTE_ETH_DEV_DETACHABLE; + eth_dev->driver = NULL; + eth_dev->data->kdrv = RTE_KDRV_NONE; + eth_dev->data->drv_name = pmd_bond_driver_name; + eth_dev->data->numa_node = socket_id; rte_spinlock_init(&internals->lock); @@ -302,6 +248,9 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) internals->rx_offload_capa = 0; internals->tx_offload_capa = 0; + /* Initially allow to choose any offload type */ + internals->flow_type_rss_offloads = ETH_RSS_PROTO_MASK; + memset(internals->active_slaves, 0, sizeof(internals->active_slaves)); memset(internals->slaves, 0, sizeof(internals->slaves)); @@ -316,14 +265,45 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) return eth_dev->data->port_id; err: - rte_free(pci_dev); - rte_free(pci_id_table); - rte_free(eth_drv); rte_free(internals); - + if (eth_dev != NULL) { + rte_free(eth_dev->data->mac_addrs); + rte_eth_dev_release_port(eth_dev); + } return -1; } +int +rte_eth_bond_free(const char *name) +{ + struct rte_eth_dev *eth_dev = NULL; + + /* now free all data allocation - for eth_dev structure, + * dummy pci driver and internal (private) data + */ + + /* find an ethdev entry */ + eth_dev = rte_eth_dev_allocated(name); + if (eth_dev == NULL) + return -ENODEV; + + if (eth_dev->data->dev_started == 1) { + bond_ethdev_stop(eth_dev); + bond_ethdev_close(eth_dev); + } + + eth_dev->dev_ops = NULL; + eth_dev->rx_pkt_burst = NULL; + eth_dev->tx_pkt_burst = NULL; + + rte_free(eth_dev->data->dev_private); + rte_free(eth_dev->data->mac_addrs); + + rte_eth_dev_release_port(eth_dev); + + return 0; +} + static int __eth_bond_slave_add_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id) { @@ -344,7 +324,7 @@ __eth_bond_slave_add_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id) /* Verify that new slave device is not already a slave of another * bonded device */ for (i = rte_eth_dev_count()-1; i >= 0; i--) { - if (valid_bonded_ethdev(&rte_eth_devices[i]) == 0) { + if (check_for_bonded_ethdev(&rte_eth_devices[i]) == 0) { temp_internals = rte_eth_devices[i].data->dev_private; for (j = 0; j < temp_internals->slave_count; j++) { @@ -363,9 +343,13 @@ __eth_bond_slave_add_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id) /* Add slave details to bonded device */ slave_add(internals, slave_eth_dev); - memset(&dev_info, 0, sizeof(dev_info)); rte_eth_dev_info_get(slave_port_id, &dev_info); + /* We need to store slaves reta_size to be able to synchronize RETA for all + * slave devices even if its sizes are different. + */ + internals->slaves[internals->slave_count].reta_size = dev_info.reta_size; + if (internals->slave_count < 1) { /* if MAC is not user defined then use MAC of first slave add to * bonded device */ @@ -379,9 +363,16 @@ __eth_bond_slave_add_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id) /* Make primary slave */ internals->primary_port = slave_port_id; + /* Inherit queues settings from first slave */ + internals->nb_rx_queues = slave_eth_dev->data->nb_rx_queues; + internals->nb_tx_queues = slave_eth_dev->data->nb_tx_queues; + + internals->reta_size = dev_info.reta_size; + /* Take the first dev's offload capabilities */ 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; } else { /* Check slave link properties are supported if props are set, @@ -400,8 +391,19 @@ __eth_bond_slave_add_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id) } 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; + + /* RETA size is GCD of all slaves RETA sizes, so, if all sizes will be + * the power of 2, the lower one is GCD + */ + if (internals->reta_size > dev_info.reta_size) + internals->reta_size = dev_info.reta_size; + } + bonded_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf &= + internals->flow_type_rss_offloads; + internals->slave_count++; /* Update all slave devices MACs*/ @@ -528,6 +530,8 @@ __eth_bond_slave_remove_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id) if (internals->slave_count == 0) { internals->rx_offload_capa = 0; internals->tx_offload_capa = 0; + internals->flow_type_rss_offloads = ETH_RSS_PROTO_MASK; + internals->reta_size = 0; } return 0; }