f44e716377
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>
184 lines
3.5 KiB
C
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;
|
|
}
|