@@ -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;
+}
@@ -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_ */
@@ -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,116 @@ 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_probe(struct rte_pci_driver *pci_drv __rte_unused,
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];
+ 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_asym_dev_destroy(qat_pci_dev);
+ qat_comp_dev_destroy(qat_pci_dev);
+ qat_sym_dev_destroy(qat_pci_dev);
+ qat_pci_device_release(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;
+ qat_asym_dev_destroy(qat_pci_dev);
+ qat_comp_dev_destroy(qat_pci_dev);
+ qat_sym_dev_destroy(qat_pci_dev);
+ return qat_pci_device_release(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;