From: Fiona Trahe Date: Wed, 13 Jun 2018 12:14:02 +0000 (+0200) Subject: crypto/qat: add PCI device struct X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=b2c862d80e93be569b4a7aafeb0b7849d68692c8;p=dpdk.git crypto/qat: add PCI device struct - Added struct qat_pci_device to use internally in QAT PMD to avoid dependencies on rte_cryptodev or rte_compressdev - Added a global array of these - Restructured probe/release to separate QAT common init/clear from crypto pmd create/destroy. - In QAT common part allocated a qat_pci_device and populated it - Removed meaningless check in probe for RTE_PROC_PRIMARY Signed-off-by: Fiona Trahe --- diff --git a/drivers/crypto/qat/qat_device.c b/drivers/crypto/qat/qat_device.c index cdf4f70589..75af1e8bc9 100644 --- a/drivers/crypto/qat/qat_device.c +++ b/drivers/crypto/qat/qat_device.c @@ -20,6 +20,10 @@ struct qat_gen_hw_data qp_gen_config[] = { }, }; + +static struct qat_pci_device qat_pci_devices[QAT_MAX_PCI_DEVICES]; +static int qat_nb_pci_devices; + int qat_dev_config(__rte_unused struct rte_cryptodev *dev, __rte_unused struct rte_cryptodev_config *config) { @@ -72,3 +76,126 @@ void qat_dev_info_get(struct rte_cryptodev *dev, info->pci_dev = RTE_DEV_TO_PCI(dev->device); } } + + +static struct qat_pci_device * +qat_pci_get_dev(uint8_t dev_id) +{ + return &qat_pci_devices[dev_id]; +} +static struct qat_pci_device * +qat_pci_get_named_dev(const char *name) +{ + struct qat_pci_device *dev; + unsigned int i; + + if (name == NULL) + return NULL; + + for (i = 0; i < QAT_MAX_PCI_DEVICES; i++) { + dev = &qat_pci_devices[i]; + + if ((dev->attached == QAT_ATTACHED) && + (strcmp(dev->name, name) == 0)) + return dev; + } + + return NULL; +} + +static uint8_t +qat_pci_find_free_device_index(void) +{ + uint8_t dev_id; + + for (dev_id = 0; dev_id < QAT_MAX_PCI_DEVICES; dev_id++) { + if (qat_pci_devices[dev_id].attached == QAT_DETACHED) + break; + } + return dev_id; +} + +struct qat_pci_device * +qat_get_qat_dev_from_pci_dev(struct rte_pci_device *pci_dev) +{ + char name[QAT_DEV_NAME_MAX_LEN]; + + rte_pci_device_name(&pci_dev->addr, name, sizeof(name)); + + return qat_pci_get_named_dev(name); +} + +struct qat_pci_device * +qat_pci_device_allocate(struct rte_pci_device *pci_dev) +{ + struct qat_pci_device *qat_dev; + uint8_t qat_dev_id; + char name[QAT_DEV_NAME_MAX_LEN]; + + rte_pci_device_name(&pci_dev->addr, name, sizeof(name)); + + if (qat_pci_get_named_dev(name) != NULL) { + PMD_DRV_LOG(ERR, "QAT device with name %s already allocated!", + name); + return NULL; + } + + qat_dev_id = qat_pci_find_free_device_index(); + if (qat_dev_id == QAT_MAX_PCI_DEVICES) { + PMD_DRV_LOG(ERR, "Reached maximum number of QAT devices"); + return NULL; + } + + qat_dev = qat_pci_get_dev(qat_dev_id); + snprintf(qat_dev->name, QAT_DEV_NAME_MAX_LEN, "%s", name); + qat_dev->pci_dev = pci_dev; + switch (qat_dev->pci_dev->id.device_id) { + case 0x0443: + qat_dev->qat_dev_gen = QAT_GEN1; + break; + case 0x37c9: + case 0x19e3: + case 0x6f55: + qat_dev->qat_dev_gen = QAT_GEN2; + break; + default: + PMD_DRV_LOG(ERR, "Invalid dev_id, can't determine generation"); + return NULL; + } + + rte_spinlock_init(&qat_dev->arb_csr_lock); + + qat_dev->attached = QAT_ATTACHED; + + qat_nb_pci_devices++; + + PMD_DRV_LOG(DEBUG, "QAT device %d allocated, total QATs %d", + qat_dev_id, qat_nb_pci_devices); + + return qat_dev; +} + +int +qat_pci_device_release(struct rte_pci_device *pci_dev) +{ + struct qat_pci_device *qat_dev; + char name[QAT_DEV_NAME_MAX_LEN]; + + if (pci_dev == NULL) + return -EINVAL; + + rte_pci_device_name(&pci_dev->addr, name, sizeof(name)); + qat_dev = qat_pci_get_named_dev(name); + if (qat_dev != NULL) { + + /* Check that there are no service devs still on pci device */ + if (qat_dev->sym_dev != NULL) + return -EBUSY; + + qat_dev->attached = QAT_DETACHED; + qat_nb_pci_devices--; + } + PMD_DRV_LOG(DEBUG, "QAT device %s released, total QATs %d", + name, qat_nb_pci_devices); + return 0; +} diff --git a/drivers/crypto/qat/qat_device.h b/drivers/crypto/qat/qat_device.h index 0983e3c2e0..d83ad632c0 100644 --- a/drivers/crypto/qat/qat_device.h +++ b/drivers/crypto/qat/qat_device.h @@ -11,15 +11,58 @@ #include "adf_transport_access_macros.h" #include "qat_qp.h" + +#define QAT_DETACHED (0) +#define QAT_ATTACHED (1) + +#define QAT_MAX_PCI_DEVICES 48 +#define QAT_DEV_NAME_MAX_LEN 64 + + extern uint8_t cryptodev_qat_driver_id; extern int qat_sym_qp_release(struct rte_cryptodev *dev, uint16_t queue_pair_id); -/** private data structure for each QAT device. - * In this context a QAT device is a device offering only one service, - * so there can be more than 1 device on a pci_dev (VF), - * one for symmetric crypto, one for compression +/* + * This struct holds all the data about a QAT pci device + * including data about all services it supports. + * It contains + * - hw_data + * - config data + * - runtime data + */ +struct qat_pci_device { + + /* data used by all services */ + char name[QAT_DEV_NAME_MAX_LEN]; + /**< Name of qat pci device */ + struct rte_pci_device *pci_dev; + /**< PCI information. */ + enum qat_device_gen qat_dev_gen; + /**< QAT device generation */ + rte_spinlock_t arb_csr_lock; + /* protects accesses to the arbiter CSR */ + __extension__ + uint8_t attached : 1; + /**< Flag indicating the device is attached */ + + /* data relating to symmetric crypto service */ + struct qat_pmd_private *sym_dev; + /**< link back to cryptodev private data */ + unsigned int max_nb_sym_queue_pairs; + /**< Max number of queue pairs supported by device */ + + /* data relating to compression service */ + + /* data relating to asymmetric crypto service */ + +}; + +/** private data structure for a QAT device. + * This QAT device is a device offering only symmetric crypto service, + * there can be one of these on each qat_pci_device (VF), + * in future there may also be private data structures for other services. */ struct qat_pmd_private { unsigned int max_nb_queue_pairs; @@ -34,6 +77,8 @@ struct qat_pmd_private { /**< PCI information. */ uint8_t dev_id; /**< Device ID for this instance */ + struct qat_pci_device *qat_dev; + /**< The qat pci device hosting the service */ }; struct qat_gen_hw_data { @@ -51,4 +96,11 @@ int qat_dev_close(struct rte_cryptodev *dev); void qat_dev_info_get(struct rte_cryptodev *dev, struct rte_cryptodev_info *info); +struct qat_pci_device * +qat_pci_device_allocate(struct rte_pci_device *pci_dev); +int +qat_pci_device_release(struct rte_pci_device *pci_dev); +struct qat_pci_device * +qat_get_qat_dev_from_pci_dev(struct rte_pci_device *pci_dev); + #endif /* _QAT_DEVICE_H_ */ diff --git a/drivers/crypto/qat/rte_qat_cryptodev.c b/drivers/crypto/qat/rte_qat_cryptodev.c index fe19b18b65..6ab870cad0 100644 --- a/drivers/crypto/qat/rte_qat_cryptodev.c +++ b/drivers/crypto/qat/rte_qat_cryptodev.c @@ -69,17 +69,28 @@ static const struct rte_pci_id pci_id_qat_map[] = { {.device_id = 0}, }; + + static int -crypto_qat_create(const char *name, struct rte_pci_device *pci_dev, - struct rte_cryptodev_pmd_init_params *init_params) +qat_sym_dev_create(struct qat_pci_device *qat_pci_dev) { + struct rte_cryptodev_pmd_init_params init_params = { + .name = "", + .socket_id = qat_pci_dev->pci_dev->device.numa_node, + .private_data_size = sizeof(struct qat_pmd_private), + .max_nb_sessions = RTE_QAT_PMD_MAX_NB_SESSIONS + }; + char name[RTE_CRYPTODEV_NAME_MAX_LEN]; struct rte_cryptodev *cryptodev; struct qat_pmd_private *internals; - PMD_INIT_FUNC_TRACE(); + snprintf(name, RTE_CRYPTODEV_NAME_MAX_LEN, "%s_%s", + qat_pci_dev->name, "sym"); + PMD_DRV_LOG(DEBUG, "Creating QAT SYM device %s", name); + + cryptodev = rte_cryptodev_pmd_create(name, + &qat_pci_dev->pci_dev->device, &init_params); - cryptodev = rte_cryptodev_pmd_create(name, &pci_dev->device, - init_params); if (cryptodev == NULL) return -ENODEV; @@ -95,7 +106,10 @@ crypto_qat_create(const char *name, struct rte_pci_device *pci_dev, RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER; internals = cryptodev->data->dev_private; - internals->max_nb_sessions = init_params->max_nb_sessions; + internals->qat_dev = qat_pci_dev; + qat_pci_dev->sym_dev = internals; + + internals->max_nb_sessions = init_params.max_nb_sessions; internals->pci_dev = RTE_DEV_TO_PCI(cryptodev->device); internals->dev_id = cryptodev->data->dev_id; switch (internals->pci_dev->id.device_id) { @@ -111,68 +125,120 @@ crypto_qat_create(const char *name, struct rte_pci_device *pci_dev, break; default: PMD_DRV_LOG(ERR, - "Invalid dev_id, can't determine capabilities"); + "Invalid dev_id, can't determine capabilities"); break; } - /* - * For secondary processes, we don't initialise any further as primary - * has already done this work. Only check we don't need a different - * RX function - */ - if (rte_eal_process_type() != RTE_PROC_PRIMARY) { - PMD_DRV_LOG(DEBUG, "Device already initialised by primary process"); return 0; - } +} + +static int +qat_sym_dev_destroy(struct qat_pci_device *qat_pci_dev) +{ + struct rte_cryptodev *cryptodev; + + if (qat_pci_dev == NULL) + return -ENODEV; + if (qat_pci_dev->sym_dev == NULL) + return 0; + + /* free crypto device */ + cryptodev = rte_cryptodev_pmd_get_dev(qat_pci_dev->sym_dev->dev_id); + rte_cryptodev_pmd_destroy(cryptodev); + qat_pci_dev->sym_dev = NULL; + + return 0; +} + +static int +qat_comp_dev_create(struct qat_pci_device *qat_pci_dev __rte_unused) +{ + return 0; +} + +static int +qat_comp_dev_destroy(struct qat_pci_device *qat_pci_dev __rte_unused) +{ + return 0; +} +static int +qat_asym_dev_create(struct qat_pci_device *qat_pci_dev __rte_unused) +{ return 0; } -static int crypto_qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, +static int +qat_asym_dev_destroy(struct qat_pci_device *qat_pci_dev __rte_unused) +{ + return 0; +} + +static int +qat_pci_dev_destroy(struct qat_pci_device *qat_pci_dev, struct rte_pci_device *pci_dev) { - struct rte_cryptodev_pmd_init_params init_params = { - .name = "", - .socket_id = pci_dev->device.numa_node, - .private_data_size = sizeof(struct qat_pmd_private), - .max_nb_sessions = RTE_QAT_PMD_MAX_NB_SESSIONS - }; - char name[RTE_CRYPTODEV_NAME_MAX_LEN]; + qat_sym_dev_destroy(qat_pci_dev); + qat_comp_dev_destroy(qat_pci_dev); + qat_asym_dev_destroy(qat_pci_dev); + return qat_pci_device_release(pci_dev); +} + +static int qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, + struct rte_pci_device *pci_dev) +{ + int ret = 0; + struct qat_pci_device *qat_pci_dev; PMD_DRV_LOG(DEBUG, "Found QAT device at %02x:%02x.%x", pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function); - rte_pci_device_name(&pci_dev->addr, name, sizeof(name)); + qat_pci_dev = qat_pci_device_allocate(pci_dev); + if (qat_pci_dev == NULL) + return -ENODEV; + + ret = qat_sym_dev_create(qat_pci_dev); + if (ret != 0) + goto error_out; + + ret = qat_comp_dev_create(qat_pci_dev); + if (ret != 0) + goto error_out; + + ret = qat_asym_dev_create(qat_pci_dev); + if (ret != 0) + goto error_out; + + return 0; + +error_out: + qat_pci_dev_destroy(qat_pci_dev, pci_dev); + return ret; - return crypto_qat_create(name, pci_dev, &init_params); } -static int crypto_qat_pci_remove(struct rte_pci_device *pci_dev) +static int qat_pci_remove(struct rte_pci_device *pci_dev) { - struct rte_cryptodev *cryptodev; - char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN]; + struct qat_pci_device *qat_pci_dev; if (pci_dev == NULL) return -EINVAL; - rte_pci_device_name(&pci_dev->addr, cryptodev_name, - sizeof(cryptodev_name)); + qat_pci_dev = qat_get_qat_dev_from_pci_dev(pci_dev); + if (qat_pci_dev == NULL) + return 0; - cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name); - if (cryptodev == NULL) - return -ENODEV; + return qat_pci_dev_destroy(qat_pci_dev, pci_dev); - /* free crypto device */ - return rte_cryptodev_pmd_destroy(cryptodev); } static struct rte_pci_driver rte_qat_pmd = { .id_table = pci_id_qat_map, .drv_flags = RTE_PCI_DRV_NEED_MAPPING, - .probe = crypto_qat_pci_probe, - .remove = crypto_qat_pci_remove + .probe = qat_pci_probe, + .remove = qat_pci_remove }; static struct cryptodev_driver qat_crypto_drv;