crypto/qat: add PCI device struct
authorFiona Trahe <fiona.trahe@intel.com>
Wed, 13 Jun 2018 12:14:02 +0000 (14:14 +0200)
committerPablo de Lara <pablo.de.lara.guarch@intel.com>
Wed, 27 Jun 2018 23:25:33 +0000 (01:25 +0200)
- 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>
drivers/crypto/qat/qat_device.c
drivers/crypto/qat/qat_device.h
drivers/crypto/qat/rte_qat_cryptodev.c

index cdf4f70..75af1e8 100644 (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;
+}
index 0983e3c..d83ad63 100644 (file)
 #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_ */
index fe19b18..6ab870c 100644 (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
+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;