1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (C) 2020 Marvell International Ltd.
5 #include <rte_ethdev.h>
6 #include <rte_eventdev.h>
7 #include <rte_malloc.h>
8 #include <rte_memzone.h>
9 #include <rte_security.h>
11 #include "otx2_ethdev.h"
12 #include "otx2_ethdev_sec.h"
13 #include "otx2_ipsec_fp.h"
15 #define ETH_SEC_MAX_PKT_LEN 1450
17 struct eth_sec_tag_const {
21 uint32_t rsvd_11_0 : 12;
23 uint32_t event_type : 4;
24 uint32_t rsvd_31_24 : 8;
31 in_sa_mz_name_get(char *name, int size, uint16_t port)
33 snprintf(name, size, "otx2_ipsec_in_sadb_%u", port);
37 otx2_eth_sec_ctx_create(struct rte_eth_dev *eth_dev)
39 struct rte_security_ctx *ctx;
41 ctx = rte_malloc("otx2_eth_sec_ctx",
42 sizeof(struct rte_security_ctx), 0);
48 ctx->device = eth_dev;
51 eth_dev->security_ctx = ctx;
57 otx2_eth_sec_ctx_destroy(struct rte_eth_dev *eth_dev)
59 rte_free(eth_dev->security_ctx);
63 eth_sec_ipsec_cfg(struct rte_eth_dev *eth_dev, uint8_t tt)
65 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
66 uint16_t port = eth_dev->data->port_id;
67 struct nix_inline_ipsec_lf_cfg *req;
68 struct otx2_mbox *mbox = dev->mbox;
69 struct eth_sec_tag_const tag_const;
70 char name[RTE_MEMZONE_NAMESIZE];
71 const struct rte_memzone *mz;
73 in_sa_mz_name_get(name, RTE_MEMZONE_NAMESIZE, port);
74 mz = rte_memzone_lookup(name);
78 req = otx2_mbox_alloc_msg_nix_inline_ipsec_lf_cfg(mbox);
80 req->sa_base_addr = mz->iova;
82 req->ipsec_cfg0.tt = tt;
85 tag_const.event_type = RTE_EVENT_TYPE_ETHDEV;
86 tag_const.port = port;
87 req->ipsec_cfg0.tag_const = tag_const.u32;
89 req->ipsec_cfg0.sa_pow2_size =
90 rte_log2_u32(sizeof(struct otx2_ipsec_fp_in_sa));
91 req->ipsec_cfg0.lenm1_max = ETH_SEC_MAX_PKT_LEN - 1;
93 req->ipsec_cfg1.sa_idx_w = rte_log2_u32(dev->ipsec_in_max_spi);
94 req->ipsec_cfg1.sa_idx_max = dev->ipsec_in_max_spi - 1;
96 return otx2_mbox_process(mbox);
100 otx2_eth_sec_init(struct rte_eth_dev *eth_dev)
102 const size_t sa_width = sizeof(struct otx2_ipsec_fp_in_sa);
103 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
104 uint16_t port = eth_dev->data->port_id;
105 char name[RTE_MEMZONE_NAMESIZE];
106 const struct rte_memzone *mz;
110 RTE_BUILD_BUG_ON(sa_width < 32 || sa_width > 512 ||
111 !RTE_IS_POWER_OF_2(sa_width));
113 if (!(dev->tx_offloads & DEV_TX_OFFLOAD_SECURITY) &&
114 !(dev->rx_offloads & DEV_RX_OFFLOAD_SECURITY))
117 nb_sa = dev->ipsec_in_max_spi;
118 mz_sz = nb_sa * sa_width;
119 in_sa_mz_name_get(name, RTE_MEMZONE_NAMESIZE, port);
120 mz = rte_memzone_reserve_aligned(name, mz_sz, rte_socket_id(),
121 RTE_MEMZONE_IOVA_CONTIG, OTX2_ALIGN);
124 otx2_err("Could not allocate inbound SA DB");
128 memset(mz->addr, 0, mz_sz);
130 ret = eth_sec_ipsec_cfg(eth_dev, SSO_TT_ORDERED);
132 otx2_err("Could not configure inline IPsec");
139 otx2_err("Could not configure device for security");
140 otx2_eth_sec_fini(eth_dev);
145 otx2_eth_sec_fini(struct rte_eth_dev *eth_dev)
147 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
148 uint16_t port = eth_dev->data->port_id;
149 char name[RTE_MEMZONE_NAMESIZE];
151 if (!(dev->tx_offloads & DEV_TX_OFFLOAD_SECURITY) &&
152 !(dev->rx_offloads & DEV_RX_OFFLOAD_SECURITY))
155 in_sa_mz_name_get(name, RTE_MEMZONE_NAMESIZE, port);
156 rte_memzone_free(rte_memzone_lookup(name));