net/hns3: fix copyright date
[dpdk.git] / drivers / crypto / virtio / virtio_cryptodev.c
index 596a237..1822f21 100644 (file)
 #include "virtio_cryptodev.h"
 #include "virtqueue.h"
 #include "virtio_crypto_algs.h"
-
-int virtio_crypto_logtype_init;
-int virtio_crypto_logtype_session;
-int virtio_crypto_logtype_rx;
-int virtio_crypto_logtype_tx;
-int virtio_crypto_logtype_driver;
+#include "virtio_crypto_capabilities.h"
 
 static int virtio_crypto_dev_configure(struct rte_cryptodev *dev,
                struct rte_cryptodev_config *config);
@@ -29,11 +24,13 @@ static void virtio_crypto_dev_stop(struct rte_cryptodev *dev);
 static int virtio_crypto_dev_close(struct rte_cryptodev *dev);
 static void virtio_crypto_dev_info_get(struct rte_cryptodev *dev,
                struct rte_cryptodev_info *dev_info);
+static void virtio_crypto_dev_stats_get(struct rte_cryptodev *dev,
+               struct rte_cryptodev_stats *stats);
+static void virtio_crypto_dev_stats_reset(struct rte_cryptodev *dev);
 static int virtio_crypto_qp_setup(struct rte_cryptodev *dev,
                uint16_t queue_pair_id,
                const struct rte_cryptodev_qp_conf *qp_conf,
-               int socket_id,
-               struct rte_mempool *session_pool);
+               int socket_id);
 static int virtio_crypto_qp_release(struct rte_cryptodev *dev,
                uint16_t queue_pair_id);
 static void virtio_crypto_dev_free_mbufs(struct rte_cryptodev *dev);
@@ -55,6 +52,11 @@ static const struct rte_pci_id pci_id_virtio_crypto_map[] = {
        { .vendor_id = 0, /* sentinel */ },
 };
 
+static const struct rte_cryptodev_capabilities virtio_capabilities[] = {
+       VIRTIO_SYM_CAPABILITIES,
+       RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
+};
+
 uint8_t cryptodev_virtio_driver_id;
 
 #define NUM_ENTRY_SYM_CREATE_SESSION 4
@@ -409,7 +411,7 @@ virtio_crypto_queue_setup(struct rte_cryptodev *dev,
         * and only accepts 32 bit page frame number.
         * Check if the allocated physical memory exceeds 16TB.
         */
-       if ((mz->phys_addr + vq->vq_ring_size - 1)
+       if ((mz->iova + vq->vq_ring_size - 1)
                                >> (VIRTIO_PCI_QUEUE_ADDR_SHIFT + 32)) {
                VIRTIO_CRYPTO_INIT_LOG_ERR("vring address shouldn't be "
                                        "above 16TB!");
@@ -418,10 +420,10 @@ virtio_crypto_queue_setup(struct rte_cryptodev *dev,
 
        memset(mz->addr, 0, sizeof(mz->len));
        vq->mz = mz;
-       vq->vq_ring_mem = mz->phys_addr;
+       vq->vq_ring_mem = mz->iova;
        vq->vq_ring_virt_mem = mz->addr;
        VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_ring_mem(physical): 0x%"PRIx64,
-                                       (uint64_t)mz->phys_addr);
+                                       (uint64_t)mz->iova);
        VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_ring_virt_mem: 0x%"PRIx64,
                                        (uint64_t)(uintptr_t)mz->addr);
 
@@ -501,28 +503,81 @@ static struct rte_cryptodev_ops virtio_crypto_dev_ops = {
        .dev_close                       = virtio_crypto_dev_close,
        .dev_infos_get                   = virtio_crypto_dev_info_get,
 
-       .stats_get                       = NULL,
-       .stats_reset                     = NULL,
+       .stats_get                       = virtio_crypto_dev_stats_get,
+       .stats_reset                     = virtio_crypto_dev_stats_reset,
 
        .queue_pair_setup                = virtio_crypto_qp_setup,
        .queue_pair_release              = virtio_crypto_qp_release,
-       .queue_pair_start                = NULL,
-       .queue_pair_stop                 = NULL,
-       .queue_pair_count                = NULL,
 
        /* Crypto related operations */
-       .session_get_size       = virtio_crypto_sym_get_session_private_size,
-       .session_configure      = virtio_crypto_sym_configure_session,
-       .session_clear          = virtio_crypto_sym_clear_session,
-       .qp_attach_session = NULL,
-       .qp_detach_session = NULL
+       .sym_session_get_size           = virtio_crypto_sym_get_session_private_size,
+       .sym_session_configure          = virtio_crypto_sym_configure_session,
+       .sym_session_clear              = virtio_crypto_sym_clear_session
 };
 
+static void
+virtio_crypto_update_stats(struct rte_cryptodev *dev,
+               struct rte_cryptodev_stats *stats)
+{
+       unsigned int i;
+       struct virtio_crypto_hw *hw = dev->data->dev_private;
+
+       PMD_INIT_FUNC_TRACE();
+
+       if (stats == NULL) {
+               VIRTIO_CRYPTO_DRV_LOG_ERR("invalid pointer");
+               return;
+       }
+
+       for (i = 0; i < hw->max_dataqueues; i++) {
+               const struct virtqueue *data_queue
+                       = dev->data->queue_pairs[i];
+               if (data_queue == NULL)
+                       continue;
+
+               stats->enqueued_count += data_queue->packets_sent_total;
+               stats->enqueue_err_count += data_queue->packets_sent_failed;
+
+               stats->dequeued_count += data_queue->packets_received_total;
+               stats->dequeue_err_count
+                       += data_queue->packets_received_failed;
+       }
+}
+
+static void
+virtio_crypto_dev_stats_get(struct rte_cryptodev *dev,
+               struct rte_cryptodev_stats *stats)
+{
+       PMD_INIT_FUNC_TRACE();
+
+       virtio_crypto_update_stats(dev, stats);
+}
+
+static void
+virtio_crypto_dev_stats_reset(struct rte_cryptodev *dev)
+{
+       unsigned int i;
+       struct virtio_crypto_hw *hw = dev->data->dev_private;
+
+       PMD_INIT_FUNC_TRACE();
+
+       for (i = 0; i < hw->max_dataqueues; i++) {
+               struct virtqueue *data_queue = dev->data->queue_pairs[i];
+               if (data_queue == NULL)
+                       continue;
+
+               data_queue->packets_sent_total = 0;
+               data_queue->packets_sent_failed = 0;
+
+               data_queue->packets_received_total = 0;
+               data_queue->packets_received_failed = 0;
+       }
+}
+
 static int
 virtio_crypto_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id,
                const struct rte_cryptodev_qp_conf *qp_conf,
-               int socket_id,
-               struct rte_mempool *session_pool __rte_unused)
+               int socket_id)
 {
        int ret;
        struct virtqueue *vq;
@@ -680,10 +735,12 @@ crypto_virtio_create(const char *name, struct rte_pci_device *pci_dev,
        cryptodev->dequeue_burst = virtio_crypto_pkt_rx_burst;
 
        cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
-               RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING;
+               RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
+               RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT;
 
        hw = cryptodev->data->dev_private;
        hw->dev_id = cryptodev->data->dev_id;
+       hw->virtio_dev_capabilities = virtio_capabilities;
 
        VIRTIO_CRYPTO_INIT_LOG_DBG("dev %d vendorID=0x%x deviceID=0x%x",
                cryptodev->data->dev_id, pci_dev->id.vendor_id,
@@ -893,7 +950,7 @@ virtio_crypto_sym_clear_session(
 
        hw = dev->data->dev_private;
        vq = hw->cvq;
-       session = (struct virtio_crypto_session *)get_session_private_data(
+       session = (struct virtio_crypto_session *)get_sym_session_private_data(
                sess, cryptodev_virtio_driver_id);
        if (session == NULL) {
                VIRTIO_CRYPTO_SESSION_LOG_ERR("Invalid session parameter");
@@ -1011,7 +1068,10 @@ virtio_crypto_sym_clear_session(
        VIRTIO_CRYPTO_SESSION_LOG_INFO("Close session %"PRIu64" successfully ",
                        session->session_id);
 
-       memset(sess, 0, sizeof(struct virtio_crypto_session));
+       memset(session, 0, sizeof(struct virtio_crypto_session));
+       struct rte_mempool *sess_mp = rte_mempool_from_obj(session);
+       set_sym_session_private_data(sess, cryptodev_virtio_driver_id, NULL);
+       rte_mempool_put(sess_mp, session);
        rte_free(malloc_virt_addr);
 }
 
@@ -1077,6 +1137,9 @@ virtio_crypto_sym_pad_cipher_param(
                struct rte_crypto_cipher_xform *cipher_xform)
 {
        switch (cipher_xform->algo) {
+       case RTE_CRYPTO_CIPHER_AES_CBC:
+               para->algo = VIRTIO_CRYPTO_CIPHER_AES_CBC;
+               break;
        default:
                VIRTIO_CRYPTO_SESSION_LOG_ERR("Crypto: Unsupported "
                                "Cipher alg %u", cipher_xform->algo);
@@ -1124,11 +1187,13 @@ virtio_crypto_sym_pad_auth_param(
        }
 
        switch (auth_xform->algo) {
+       case RTE_CRYPTO_AUTH_SHA1_HMAC:
+               *algo = VIRTIO_CRYPTO_MAC_HMAC_SHA1;
+               break;
        default:
                VIRTIO_CRYPTO_SESSION_LOG_ERR(
                        "Crypto: Undefined Hash algo %u specified",
                        auth_xform->algo);
-               *algo = VIRTIO_CRYPTO_NO_MAC;
                return -1;
        }
 
@@ -1139,7 +1204,7 @@ static int
 virtio_crypto_sym_pad_op_ctrl_req(
                struct virtio_crypto_op_ctrl_req *ctrl,
                struct rte_crypto_sym_xform *xform, bool is_chainned,
-               uint8_t **cipher_key_data, uint8_t **auth_key_data,
+               uint8_t *cipher_key_data, uint8_t *auth_key_data,
                struct virtio_crypto_session *session)
 {
        int ret;
@@ -1149,6 +1214,18 @@ virtio_crypto_sym_pad_op_ctrl_req(
        /* Get cipher xform from crypto xform chain */
        cipher_xform = virtio_crypto_get_cipher_xform(xform);
        if (cipher_xform) {
+               if (cipher_xform->key.length > VIRTIO_CRYPTO_MAX_KEY_SIZE) {
+                       VIRTIO_CRYPTO_SESSION_LOG_ERR(
+                               "cipher key size cannot be longer than %u",
+                               VIRTIO_CRYPTO_MAX_KEY_SIZE);
+                       return -1;
+               }
+               if (cipher_xform->iv.length > VIRTIO_CRYPTO_MAX_IV_SIZE) {
+                       VIRTIO_CRYPTO_SESSION_LOG_ERR(
+                               "cipher IV size cannot be longer than %u",
+                               VIRTIO_CRYPTO_MAX_IV_SIZE);
+                       return -1;
+               }
                if (is_chainned)
                        ret = virtio_crypto_sym_pad_cipher_param(
                                &ctrl->u.sym_create_session.u.chain.para
@@ -1164,7 +1241,8 @@ virtio_crypto_sym_pad_op_ctrl_req(
                        return -1;
                }
 
-               *cipher_key_data = cipher_xform->key.data;
+               memcpy(cipher_key_data, cipher_xform->key.data,
+                               cipher_xform->key.length);
 
                session->iv.offset = cipher_xform->iv.offset;
                session->iv.length = cipher_xform->iv.length;
@@ -1177,13 +1255,20 @@ virtio_crypto_sym_pad_op_ctrl_req(
                struct virtio_crypto_alg_chain_session_para *para =
                        &(ctrl->u.sym_create_session.u.chain.para);
                if (auth_xform->key.length) {
+                       if (auth_xform->key.length >
+                                       VIRTIO_CRYPTO_MAX_KEY_SIZE) {
+                               VIRTIO_CRYPTO_SESSION_LOG_ERR(
+                               "auth key size cannot be longer than %u",
+                                       VIRTIO_CRYPTO_MAX_KEY_SIZE);
+                               return -1;
+                       }
                        para->hash_mode = VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH;
                        para->u.mac_param.auth_key_len =
                                (uint32_t)auth_xform->key.length;
                        para->u.mac_param.hash_result_len =
                                auth_xform->digest_length;
-
-                       *auth_key_data = auth_xform->key.data;
+                       memcpy(auth_key_data, auth_xform->key.data,
+                                       auth_xform->key.length);
                } else {
                        para->hash_mode = VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN;
                        para->u.hash_param.hash_result_len =
@@ -1233,8 +1318,8 @@ virtio_crypto_sym_configure_session(
        struct virtio_crypto_session *session;
        struct virtio_crypto_op_ctrl_req *ctrl_req;
        enum virtio_crypto_cmd_id cmd_id;
-       uint8_t *cipher_key_data = NULL;
-       uint8_t *auth_key_data = NULL;
+       uint8_t cipher_key_data[VIRTIO_CRYPTO_MAX_KEY_SIZE] = {0};
+       uint8_t auth_key_data[VIRTIO_CRYPTO_MAX_KEY_SIZE] = {0};
        struct virtio_crypto_hw *hw;
        struct virtqueue *control_vq;
 
@@ -1278,7 +1363,7 @@ virtio_crypto_sym_configure_session(
                        = VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING;
 
                ret = virtio_crypto_sym_pad_op_ctrl_req(ctrl_req,
-                       xform, true, &cipher_key_data, &auth_key_data, session);
+                       xform, true, cipher_key_data, auth_key_data, session);
                if (ret < 0) {
                        VIRTIO_CRYPTO_SESSION_LOG_ERR(
                                "padding sym op ctrl req failed");
@@ -1296,7 +1381,7 @@ virtio_crypto_sym_configure_session(
                ctrl_req->u.sym_create_session.op_type
                        = VIRTIO_CRYPTO_SYM_OP_CIPHER;
                ret = virtio_crypto_sym_pad_op_ctrl_req(ctrl_req, xform,
-                       false, &cipher_key_data, &auth_key_data, session);
+                       false, cipher_key_data, auth_key_data, session);
                if (ret < 0) {
                        VIRTIO_CRYPTO_SESSION_LOG_ERR(
                                "padding sym op ctrl req failed");
@@ -1316,7 +1401,7 @@ virtio_crypto_sym_configure_session(
                goto error_out;
        }
 
-       set_session_private_data(sess, dev->driver_id,
+       set_sym_session_private_data(sess, dev->driver_id,
                session_private);
 
        return 0;
@@ -1335,11 +1420,11 @@ virtio_crypto_dev_info_get(struct rte_cryptodev *dev,
 
        if (info != NULL) {
                info->driver_id = cryptodev_virtio_driver_id;
-               info->pci_dev = RTE_DEV_TO_PCI(dev->device);
                info->feature_flags = dev->feature_flags;
                info->max_nb_queue_pairs = hw->max_dataqueues;
-               info->sym.max_nb_sessions =
-                       RTE_VIRTIO_CRYPTO_PMD_MAX_NB_SESSIONS;
+               /* No limit of number of sessions */
+               info->sym.max_nb_sessions = 0;
+               info->capabilities = hw->virtio_dev_capabilities;
        }
 }
 
@@ -1350,9 +1435,8 @@ crypto_virtio_pci_probe(
 {
        struct rte_cryptodev_pmd_init_params init_params = {
                .name = "",
-               .socket_id = rte_socket_id(),
-               .private_data_size = sizeof(struct virtio_crypto_hw),
-               .max_nb_sessions = RTE_VIRTIO_CRYPTO_PMD_MAX_NB_SESSIONS
+               .socket_id = pci_dev->device.numa_node,
+               .private_data_size = sizeof(struct virtio_crypto_hw)
        };
        char name[RTE_CRYPTODEV_NAME_MAX_LEN];
 
@@ -1399,31 +1483,10 @@ RTE_PMD_REGISTER_PCI(CRYPTODEV_NAME_VIRTIO_PMD, rte_virtio_crypto_driver);
 RTE_PMD_REGISTER_CRYPTO_DRIVER(virtio_crypto_drv,
        rte_virtio_crypto_driver.driver,
        cryptodev_virtio_driver_id);
-
-RTE_INIT(virtio_crypto_init_log);
-static void
-virtio_crypto_init_log(void)
-{
-       virtio_crypto_logtype_init = rte_log_register("pmd.crypto.virtio.init");
-       if (virtio_crypto_logtype_init >= 0)
-               rte_log_set_level(virtio_crypto_logtype_init, RTE_LOG_NOTICE);
-
-       virtio_crypto_logtype_session =
-               rte_log_register("pmd.crypto.virtio.session");
-       if (virtio_crypto_logtype_session >= 0)
-               rte_log_set_level(virtio_crypto_logtype_session,
-                               RTE_LOG_NOTICE);
-
-       virtio_crypto_logtype_rx = rte_log_register("pmd.crypto.virtio.rx");
-       if (virtio_crypto_logtype_rx >= 0)
-               rte_log_set_level(virtio_crypto_logtype_rx, RTE_LOG_NOTICE);
-
-       virtio_crypto_logtype_tx = rte_log_register("pmd.crypto.virtio.tx");
-       if (virtio_crypto_logtype_tx >= 0)
-               rte_log_set_level(virtio_crypto_logtype_tx, RTE_LOG_NOTICE);
-
-       virtio_crypto_logtype_driver =
-               rte_log_register("pmd.crypto.virtio.driver");
-       if (virtio_crypto_logtype_driver >= 0)
-               rte_log_set_level(virtio_crypto_logtype_driver, RTE_LOG_NOTICE);
-}
+RTE_LOG_REGISTER(virtio_crypto_logtype_init, pmd.crypto.virtio.init, NOTICE);
+RTE_LOG_REGISTER(virtio_crypto_logtype_session, pmd.crypto.virtio.session,
+                NOTICE);
+RTE_LOG_REGISTER(virtio_crypto_logtype_rx, pmd.crypto.virtio.rx, NOTICE);
+RTE_LOG_REGISTER(virtio_crypto_logtype_tx, pmd.crypto.virtio.tx, NOTICE);
+RTE_LOG_REGISTER(virtio_crypto_logtype_driver, pmd.crypto.virtio.driver,
+                NOTICE);