e9240785f673053746e046aca8889dadf909eb6c
[dpdk.git] / drivers / common / octeontx2 / otx2_sec_idev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2020 Marvell International Ltd.
3  */
4
5 #include <rte_atomic.h>
6 #include <rte_bus_pci.h>
7 #include <rte_ethdev.h>
8 #include <rte_spinlock.h>
9
10 #include "otx2_common.h"
11 #include "otx2_sec_idev.h"
12
13 static struct otx2_sec_idev_cfg sec_cfg[OTX2_MAX_INLINE_PORTS];
14
15 /**
16  * @internal
17  * Check if rte_eth_dev is security offload capable otx2_eth_dev
18  */
19 uint8_t
20 otx2_eth_dev_is_sec_capable(struct rte_eth_dev *eth_dev)
21 {
22         struct rte_pci_device *pci_dev;
23
24         pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
25
26         if (pci_dev->id.device_id == PCI_DEVID_OCTEONTX2_RVU_PF ||
27             pci_dev->id.device_id == PCI_DEVID_OCTEONTX2_RVU_VF ||
28             pci_dev->id.device_id == PCI_DEVID_OCTEONTX2_RVU_AF_VF)
29                 return 1;
30
31         return 0;
32 }
33
34 int
35 otx2_sec_idev_cfg_init(int port_id)
36 {
37         struct otx2_sec_idev_cfg *cfg;
38         int i;
39
40         cfg = &sec_cfg[port_id];
41         cfg->tx_cpt_idx = 0;
42         rte_spinlock_init(&cfg->tx_cpt_lock);
43
44         for (i = 0; i < OTX2_MAX_CPT_QP_PER_PORT; i++) {
45                 cfg->tx_cpt[i].qp = NULL;
46                 rte_atomic16_set(&cfg->tx_cpt[i].ref_cnt, 0);
47         }
48
49         return 0;
50 }
51
52 int
53 otx2_sec_idev_tx_cpt_qp_add(uint16_t port_id, struct otx2_cpt_qp *qp)
54 {
55         struct otx2_sec_idev_cfg *cfg;
56         int i, ret;
57
58         if (qp == NULL || port_id > OTX2_MAX_INLINE_PORTS)
59                 return -EINVAL;
60
61         cfg = &sec_cfg[port_id];
62
63         /* Find a free slot to save CPT LF */
64
65         rte_spinlock_lock(&cfg->tx_cpt_lock);
66
67         for (i = 0; i < OTX2_MAX_CPT_QP_PER_PORT; i++) {
68                 if (cfg->tx_cpt[i].qp == NULL) {
69                         cfg->tx_cpt[i].qp = qp;
70                         ret = 0;
71                         goto unlock;
72                 }
73         }
74
75         ret = -EINVAL;
76
77 unlock:
78         rte_spinlock_unlock(&cfg->tx_cpt_lock);
79         return ret;
80 }
81
82 int
83 otx2_sec_idev_tx_cpt_qp_remove(struct otx2_cpt_qp *qp)
84 {
85         struct otx2_sec_idev_cfg *cfg;
86         uint16_t port_id;
87         int i, ret;
88
89         if (qp == NULL)
90                 return -EINVAL;
91
92         for (port_id = 0; port_id < OTX2_MAX_INLINE_PORTS; port_id++) {
93                 cfg = &sec_cfg[port_id];
94
95                 rte_spinlock_lock(&cfg->tx_cpt_lock);
96
97                 for (i = 0; i < OTX2_MAX_CPT_QP_PER_PORT; i++) {
98                         if (cfg->tx_cpt[i].qp != qp)
99                                 continue;
100
101                         /* Don't free if the QP is in use by any sec session */
102                         if (rte_atomic16_read(&cfg->tx_cpt[i].ref_cnt)) {
103                                 ret = -EBUSY;
104                         } else {
105                                 cfg->tx_cpt[i].qp = NULL;
106                                 ret = 0;
107                         }
108
109                         goto unlock;
110                 }
111
112                 rte_spinlock_unlock(&cfg->tx_cpt_lock);
113         }
114
115         return -ENOENT;
116
117 unlock:
118         rte_spinlock_unlock(&cfg->tx_cpt_lock);
119         return ret;
120 }