X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fionic%2Fionic_ethdev.c;h=f58d2d3a66f2f04102955470fdbe6dc9be4a2868;hb=669c8de67c88f9d168eeab0fc93b71d63c669a73;hp=b0ae7b076b3eddcf4c9329d8ea899f288e82ce31;hpb=23bf4ddb3aff154b44da764d87d224bf0358748f;p=dpdk.git diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c index b0ae7b076b..f58d2d3a66 100644 --- a/drivers/net/ionic/ionic_ethdev.c +++ b/drivers/net/ionic/ionic_ethdev.c @@ -7,11 +7,17 @@ #include #include #include +#include #include "ionic_logs.h" #include "ionic.h" #include "ionic_dev.h" #include "ionic_mac_api.h" +#include "ionic_lif.h" +#include "ionic_ethdev.h" + +static int eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params); +static int eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev); int ionic_logtype; @@ -22,10 +28,81 @@ static const struct rte_pci_id pci_id_ionic_map[] = { { .vendor_id = 0, /* sentinel */ }, }; +static const struct eth_dev_ops ionic_eth_dev_ops = { +}; + +static int +eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params) +{ + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); + struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); + struct ionic_adapter *adapter = (struct ionic_adapter *)init_params; + int err; + + IONIC_PRINT_CALL(); + + eth_dev->dev_ops = &ionic_eth_dev_ops; + + /* Multi-process not supported, primary does initialization anyway */ + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + + rte_eth_copy_pci_info(eth_dev, pci_dev); + + lif->index = adapter->nlifs; + lif->eth_dev = eth_dev; + lif->adapter = adapter; + adapter->lifs[adapter->nlifs] = lif; + + err = ionic_lif_alloc(lif); + if (err) { + IONIC_PRINT(ERR, "Cannot allocate LIFs: %d, aborting", + err); + goto err; + } + + err = ionic_lif_init(lif); + if (err) { + IONIC_PRINT(ERR, "Cannot init LIFs: %d, aborting", err); + goto err_free_lif; + } + + IONIC_PRINT(DEBUG, "Port %u initialized", eth_dev->data->port_id); + + return 0; + +err_free_lif: + ionic_lif_free(lif); +err: + return err; +} + +static int +eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev) +{ + struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); + struct ionic_adapter *adapter = lif->adapter; + + IONIC_PRINT_CALL(); + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + + adapter->lifs[lif->index] = NULL; + + ionic_lif_deinit(lif); + ionic_lif_free(lif); + + eth_dev->dev_ops = NULL; + + return 0; +} + static int eth_ionic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct rte_pci_device *pci_dev) { + char name[RTE_ETH_NAME_MAX_LEN]; struct rte_mem_resource *resource; struct ionic_adapter *adapter; struct ionic_hw *hw; @@ -112,6 +189,38 @@ eth_ionic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, goto err_free_adapter; } + /* Configure LIFs */ + err = ionic_lif_identify(adapter); + if (err) { + IONIC_PRINT(ERR, "Cannot identify lif: %d, aborting", err); + goto err_free_adapter; + } + + /* Allocate and init LIFs */ + err = ionic_lifs_size(adapter); + if (err) { + IONIC_PRINT(ERR, "Cannot size LIFs: %d, aborting", err); + goto err_free_adapter; + } + + adapter->nlifs = 0; + for (i = 0; i < adapter->ident.dev.nlifs; i++) { + snprintf(name, sizeof(name), "net_%s_lif_%lu", + pci_dev->device.name, i); + + err = rte_eth_dev_create(&pci_dev->device, name, + sizeof(struct ionic_lif), + NULL, NULL, + eth_ionic_dev_init, adapter); + if (err) { + IONIC_PRINT(ERR, "Cannot create eth device for " + "ionic lif %s", name); + break; + } + + adapter->nlifs++; + } + return 0; err_free_adapter: @@ -123,6 +232,31 @@ err: static int eth_ionic_pci_remove(struct rte_pci_device *pci_dev __rte_unused) { + char name[RTE_ETH_NAME_MAX_LEN]; + struct ionic_adapter *adapter = NULL; + struct rte_eth_dev *eth_dev; + struct ionic_lif *lif; + uint32_t i; + + /* Adapter lookup is using (the first) eth_dev name */ + snprintf(name, sizeof(name), "net_%s_lif_0", + pci_dev->device.name); + + eth_dev = rte_eth_dev_allocated(name); + if (eth_dev) { + lif = IONIC_ETH_DEV_TO_LIF(eth_dev); + adapter = lif->adapter; + } + + if (adapter) { + for (i = 0; i < adapter->nlifs; i++) { + lif = adapter->lifs[i]; + rte_eth_dev_destroy(lif->eth_dev, eth_ionic_dev_uninit); + } + + rte_free(adapter); + } + return 0; }