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 <fiona.trahe@intel.com>
This commit is contained in:
Fiona Trahe 2018-06-13 14:14:02 +02:00 committed by Pablo de Lara
parent 571ffe236f
commit b2c862d80e
3 changed files with 286 additions and 41 deletions

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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 crypto_qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
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
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;