numam-dpdk/drivers/common/octeontx2/otx2_sec_idev.c
Anoob Joseph f44e716377 net/octeontx2: add security session operations
Adding security session operations in eth security ctx.

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>
2020-02-05 15:20:51 +01:00

184 lines
3.5 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* 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
*/
uint8_t
otx2_eth_dev_is_sec_capable(struct rte_eth_dev *eth_dev)
{
struct rte_pci_device *pci_dev;
pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
if (pci_dev->id.device_id == PCI_DEVID_OCTEONTX2_RVU_PF ||
pci_dev->id.device_id == PCI_DEVID_OCTEONTX2_RVU_VF ||
pci_dev->id.device_id == PCI_DEVID_OCTEONTX2_RVU_AF_VF)
return 1;
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;
}
int
otx2_sec_idev_tx_cpt_qp_get(uint16_t port_id, struct otx2_cpt_qp **qp)
{
struct otx2_sec_idev_cfg *cfg;
uint16_t index;
int i, ret;
if (port_id > OTX2_MAX_INLINE_PORTS || qp == NULL)
return -EINVAL;
cfg = &sec_cfg[port_id];
rte_spinlock_lock(&cfg->tx_cpt_lock);
index = cfg->tx_cpt_idx;
/* Get the next index with valid data */
for (i = 0; i < OTX2_MAX_CPT_QP_PER_PORT; i++) {
if (cfg->tx_cpt[index].qp != NULL)
break;
index = (index + 1) % OTX2_MAX_CPT_QP_PER_PORT;
}
if (i >= OTX2_MAX_CPT_QP_PER_PORT) {
ret = -EINVAL;
goto unlock;
}
*qp = cfg->tx_cpt[index].qp;
rte_atomic16_inc(&cfg->tx_cpt[index].ref_cnt);
cfg->tx_cpt_idx = (index + 1) % OTX2_MAX_CPT_QP_PER_PORT;
ret = 0;
unlock:
rte_spinlock_unlock(&cfg->tx_cpt_lock);
return ret;
}
int
otx2_sec_idev_tx_cpt_qp_put(struct otx2_cpt_qp *qp)
{
struct otx2_sec_idev_cfg *cfg;
uint16_t port_id;
int i;
if (qp == NULL)
return -EINVAL;
for (port_id = 0; port_id < OTX2_MAX_INLINE_PORTS; port_id++) {
cfg = &sec_cfg[port_id];
for (i = 0; i < OTX2_MAX_CPT_QP_PER_PORT; i++) {
if (cfg->tx_cpt[i].qp == qp) {
rte_atomic16_dec(&cfg->tx_cpt[i].ref_cnt);
return 0;
}
}
}
return -EINVAL;
}