crypto/octeontx2: enable CPT to share QP with ethdev

Adding the infrastructure to save one opaque pointer in idev and
implement the consumer-producer in the PMDs which uses it accordingly.

Signed-off-by: Ankur Dwivedi <adwivedi@marvell.com>
Signed-off-by: Anoob Joseph <anoobj@marvell.com>
Signed-off-by: Archana Muniganti <marchana@marvell.com>
Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
This commit is contained in:
Anoob Joseph 2020-02-04 16:47:17 +05:30 committed by Akhil Goyal
parent bb810fd64d
commit 3fe4d07d16
7 changed files with 178 additions and 21 deletions

View File

@ -2,12 +2,16 @@
* Copyright(C) 2020 Marvell International Ltd.
*/
#include <rte_atomic.h>
#include <rte_bus_pci.h>
#include <rte_ethdev.h>
#include <rte_spinlock.h>
#include "otx2_common.h"
#include "otx2_sec_idev.h"
static struct otx2_sec_idev_cfg sec_cfg[OTX2_MAX_INLINE_PORTS];
/**
* @internal
* Check if rte_eth_dev is security offload capable otx2_eth_dev
@ -26,3 +30,91 @@ otx2_eth_dev_is_sec_capable(struct rte_eth_dev *eth_dev)
return 0;
}
int
otx2_sec_idev_cfg_init(int port_id)
{
struct otx2_sec_idev_cfg *cfg;
int i;
cfg = &sec_cfg[port_id];
cfg->tx_cpt_idx = 0;
rte_spinlock_init(&cfg->tx_cpt_lock);
for (i = 0; i < OTX2_MAX_CPT_QP_PER_PORT; i++) {
cfg->tx_cpt[i].qp = NULL;
rte_atomic16_set(&cfg->tx_cpt[i].ref_cnt, 0);
}
return 0;
}
int
otx2_sec_idev_tx_cpt_qp_add(uint16_t port_id, struct otx2_cpt_qp *qp)
{
struct otx2_sec_idev_cfg *cfg;
int i, ret;
if (qp == NULL || port_id > OTX2_MAX_INLINE_PORTS)
return -EINVAL;
cfg = &sec_cfg[port_id];
/* Find a free slot to save CPT LF */
rte_spinlock_lock(&cfg->tx_cpt_lock);
for (i = 0; i < OTX2_MAX_CPT_QP_PER_PORT; i++) {
if (cfg->tx_cpt[i].qp == NULL) {
cfg->tx_cpt[i].qp = qp;
ret = 0;
goto unlock;
}
}
ret = -EINVAL;
unlock:
rte_spinlock_unlock(&cfg->tx_cpt_lock);
return ret;
}
int
otx2_sec_idev_tx_cpt_qp_remove(struct otx2_cpt_qp *qp)
{
struct otx2_sec_idev_cfg *cfg;
uint16_t port_id;
int i, ret;
if (qp == NULL)
return -EINVAL;
for (port_id = 0; port_id < OTX2_MAX_INLINE_PORTS; port_id++) {
cfg = &sec_cfg[port_id];
rte_spinlock_lock(&cfg->tx_cpt_lock);
for (i = 0; i < OTX2_MAX_CPT_QP_PER_PORT; i++) {
if (cfg->tx_cpt[i].qp != qp)
continue;
/* Don't free if the QP is in use by any sec session */
if (rte_atomic16_read(&cfg->tx_cpt[i].ref_cnt)) {
ret = -EBUSY;
} else {
cfg->tx_cpt[i].qp = NULL;
ret = 0;
}
goto unlock;
}
rte_spinlock_unlock(&cfg->tx_cpt_lock);
}
return -ENOENT;
unlock:
rte_spinlock_unlock(&cfg->tx_cpt_lock);
return ret;
}

View File

@ -7,6 +7,27 @@
#include <rte_ethdev.h>
#define OTX2_MAX_CPT_QP_PER_PORT 64
#define OTX2_MAX_INLINE_PORTS 64
struct otx2_cpt_qp;
struct otx2_sec_idev_cfg {
struct {
struct otx2_cpt_qp *qp;
rte_atomic16_t ref_cnt;
} tx_cpt[OTX2_MAX_CPT_QP_PER_PORT];
uint16_t tx_cpt_idx;
rte_spinlock_t tx_cpt_lock;
};
uint8_t otx2_eth_dev_is_sec_capable(struct rte_eth_dev *eth_dev);
int otx2_sec_idev_cfg_init(int port_id);
int otx2_sec_idev_tx_cpt_qp_add(uint16_t port_id, struct otx2_cpt_qp *qp);
int otx2_sec_idev_tx_cpt_qp_remove(struct otx2_cpt_qp *qp);
#endif /* _OTX2_SEC_IDEV_H_ */

View File

@ -28,6 +28,9 @@ DPDK_20.0 {
otx2_npa_pf_func_get;
otx2_npa_set_defaults;
otx2_register_irq;
otx2_sec_idev_cfg_init;
otx2_sec_idev_tx_cpt_qp_add;
otx2_sec_idev_tx_cpt_qp_remove;
otx2_sso_pf_func_get;
otx2_sso_pf_func_set;
otx2_unregister_irq;

View File

@ -15,6 +15,7 @@
#include "cpt_mcode_defines.h"
#include "otx2_dev.h"
#include "otx2_cryptodev_qp.h"
/* CPT instruction queue length */
#define OTX2_CPT_IQ_LEN 8200
@ -135,27 +136,6 @@ enum cpt_9x_comp_e {
CPT_9X_COMP_E_LAST_ENTRY = 0x06
};
struct otx2_cpt_qp {
uint32_t id;
/**< Queue pair id */
uintptr_t base;
/**< Base address where BAR is mapped */
void *lmtline;
/**< Address of LMTLINE */
rte_iova_t lf_nq_reg;
/**< LF enqueue register address */
struct pending_queue pend_q;
/**< Pending queue */
struct rte_mempool *sess_mp;
/**< Session mempool */
struct rte_mempool *sess_mp_priv;
/**< Session private data mempool */
struct cpt_qp_meta_info meta_info;
/**< Metabuf info required to support operations on the queue pair */
rte_iova_t iq_dma_addr;
/**< Instruction queue address */
};
void otx2_cpt_err_intr_unregister(const struct rte_cryptodev *dev);
int otx2_cpt_err_intr_register(const struct rte_cryptodev *dev);

View File

@ -149,6 +149,11 @@ otx2_cpt_qp_inline_cfg(const struct rte_cryptodev *dev, struct otx2_cpt_qp *qp)
if (ret)
return ret;
/* Publish inline Tx QP to eth dev security */
ret = otx2_sec_idev_tx_cpt_qp_add(port_id, qp);
if (ret)
return ret;
return 0;
}
@ -243,6 +248,12 @@ otx2_cpt_qp_create(const struct rte_cryptodev *dev, uint16_t qp_id,
qp->lf_nq_reg = qp->base + OTX2_CPT_LF_NQ(0);
ret = otx2_sec_idev_tx_cpt_qp_remove(qp);
if (ret && (ret != -ENOENT)) {
CPT_LOG_ERR("Could not delete inline configuration");
goto mempool_destroy;
}
otx2_cpt_iq_disable(qp);
ret = otx2_cpt_qp_inline_cfg(dev, qp);
@ -276,6 +287,12 @@ otx2_cpt_qp_destroy(const struct rte_cryptodev *dev, struct otx2_cpt_qp *qp)
char name[RTE_MEMZONE_NAMESIZE];
int ret;
ret = otx2_sec_idev_tx_cpt_qp_remove(qp);
if (ret && (ret != -ENOENT)) {
CPT_LOG_ERR("Could not delete inline configuration");
return ret;
}
otx2_cpt_iq_disable(qp);
otx2_cpt_metabuf_mempool_destroy(qp);

View File

@ -0,0 +1,35 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (C) 2020 Marvell International Ltd.
*/
#ifndef _OTX2_CRYPTODEV_QP_H_
#define _OTX2_CRYPTODEV_QP_H_
#include <rte_common.h>
#include <rte_mempool.h>
#include <rte_spinlock.h>
#include "cpt_common.h"
struct otx2_cpt_qp {
uint32_t id;
/**< Queue pair id */
uintptr_t base;
/**< Base address where BAR is mapped */
void *lmtline;
/**< Address of LMTLINE */
rte_iova_t lf_nq_reg;
/**< LF enqueue register address */
struct pending_queue pend_q;
/**< Pending queue */
struct rte_mempool *sess_mp;
/**< Session mempool */
struct rte_mempool *sess_mp_priv;
/**< Session private data mempool */
struct cpt_qp_meta_info meta_info;
/**< Metabuf info required to support operations on the queue pair */
rte_iova_t iq_dma_addr;
/**< Instruction queue address */
};
#endif /* _OTX2_CRYPTODEV_QP_H_ */

View File

@ -10,9 +10,11 @@
#include <rte_security.h>
#include <rte_security_driver.h>
#include "otx2_cryptodev_qp.h"
#include "otx2_ethdev.h"
#include "otx2_ethdev_sec.h"
#include "otx2_ipsec_fp.h"
#include "otx2_sec_idev.h"
#define ETH_SEC_MAX_PKT_LEN 1450
@ -160,12 +162,19 @@ int
otx2_eth_sec_ctx_create(struct rte_eth_dev *eth_dev)
{
struct rte_security_ctx *ctx;
int ret;
ctx = rte_malloc("otx2_eth_sec_ctx",
sizeof(struct rte_security_ctx), 0);
if (ctx == NULL)
return -ENOMEM;
ret = otx2_sec_idev_cfg_init(eth_dev->data->port_id);
if (ret) {
rte_free(ctx);
return ret;
}
/* Populate ctx */
ctx->device = eth_dev;