1e9dcd831SSlava Shwartsman /*-
2e23731dbSKonstantin Belousov * Copyright (c) 2023 NVIDIA corporation & affiliates.
3e9dcd831SSlava Shwartsman *
4e23731dbSKonstantin Belousov * Redistribution and use in source and binary forms, with or without
5e23731dbSKonstantin Belousov * modification, are permitted provided that the following conditions
6e23731dbSKonstantin Belousov * are met:
7e23731dbSKonstantin Belousov * 1. Redistributions of source code must retain the above copyright
8e23731dbSKonstantin Belousov * notice, this list of conditions and the following disclaimer.
9e23731dbSKonstantin Belousov * 2. Redistributions in binary form must reproduce the above copyright
10e23731dbSKonstantin Belousov * notice, this list of conditions and the following disclaimer in the
11e23731dbSKonstantin Belousov * documentation and/or other materials provided with the distribution.
12e9dcd831SSlava Shwartsman *
13e23731dbSKonstantin Belousov * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14e23731dbSKonstantin Belousov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15e23731dbSKonstantin Belousov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16e23731dbSKonstantin Belousov * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17e23731dbSKonstantin Belousov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18e23731dbSKonstantin Belousov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19e23731dbSKonstantin Belousov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20e23731dbSKonstantin Belousov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21e23731dbSKonstantin Belousov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22e23731dbSKonstantin Belousov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23e23731dbSKonstantin Belousov * SUCH DAMAGE.
24e9dcd831SSlava Shwartsman *
25e9dcd831SSlava Shwartsman */
26e9dcd831SSlava Shwartsman
27e9dcd831SSlava Shwartsman #ifndef __MLX5_ACCEL_IPSEC_H__
28e9dcd831SSlava Shwartsman #define __MLX5_ACCEL_IPSEC_H__
29e9dcd831SSlava Shwartsman
30e23731dbSKonstantin Belousov #include <sys/mbuf.h>
31e9dcd831SSlava Shwartsman #include <dev/mlx5/driver.h>
32e23731dbSKonstantin Belousov #include <dev/mlx5/qp.h>
33e23731dbSKonstantin Belousov #include <dev/mlx5/mlx5_core/mlx5_core.h>
34e23731dbSKonstantin Belousov #include <dev/mlx5/mlx5_en/en.h>
35e23731dbSKonstantin Belousov #include <dev/mlx5/mlx5_lib/aso.h>
36e9dcd831SSlava Shwartsman
37e23731dbSKonstantin Belousov #define MLX5E_IPSEC_SADB_RX_BITS 10
38e23731dbSKonstantin Belousov #define MLX5_IPSEC_METADATA_MARKER(ipsec_metadata) ((ipsec_metadata >> 31) & 0x1)
39e23731dbSKonstantin Belousov
40*205263acSAriel Ehrenberg #define VLAN_NONE 0xfff
41*205263acSAriel Ehrenberg
42e23731dbSKonstantin Belousov struct mlx5e_priv;
43e23731dbSKonstantin Belousov struct mlx5e_tx_wqe;
44e23731dbSKonstantin Belousov struct mlx5e_ipsec_tx;
45e23731dbSKonstantin Belousov struct mlx5e_ipsec_rx;
46e23731dbSKonstantin Belousov
47e23731dbSKonstantin Belousov struct aes_gcm_keymat {
48e23731dbSKonstantin Belousov u64 seq_iv;
49e23731dbSKonstantin Belousov
50e23731dbSKonstantin Belousov u32 salt;
51e23731dbSKonstantin Belousov u32 icv_len;
52e23731dbSKonstantin Belousov
53e23731dbSKonstantin Belousov u32 key_len;
54e23731dbSKonstantin Belousov u32 aes_key[256 / 32];
55e9dcd831SSlava Shwartsman };
56e9dcd831SSlava Shwartsman
57e23731dbSKonstantin Belousov struct mlx5e_ipsec_priv_bothdir {
58e23731dbSKonstantin Belousov struct mlx5e_ipsec_sa_entry *priv_in;
59e23731dbSKonstantin Belousov struct mlx5e_ipsec_sa_entry *priv_out;
60e9dcd831SSlava Shwartsman };
61e9dcd831SSlava Shwartsman
62e23731dbSKonstantin Belousov struct mlx5e_ipsec_work {
63e23731dbSKonstantin Belousov struct work_struct work;
64e23731dbSKonstantin Belousov struct mlx5e_ipsec_sa_entry *sa_entry;
65e23731dbSKonstantin Belousov void *data;
66e9dcd831SSlava Shwartsman };
67e9dcd831SSlava Shwartsman
68e23731dbSKonstantin Belousov struct mlx5e_ipsec_dwork {
69e23731dbSKonstantin Belousov struct delayed_work dwork;
70e23731dbSKonstantin Belousov struct mlx5e_ipsec_sa_entry *sa_entry;
71e23731dbSKonstantin Belousov struct mlx5e_ipsec_priv_bothdir *pb;
72e23731dbSKonstantin Belousov };
73e9dcd831SSlava Shwartsman
74e23731dbSKonstantin Belousov struct mlx5e_ipsec_aso {
75e23731dbSKonstantin Belousov u8 __aligned(64) ctx[MLX5_ST_SZ_BYTES(ipsec_aso)];
76e23731dbSKonstantin Belousov dma_addr_t dma_addr;
77e23731dbSKonstantin Belousov struct mlx5_aso *aso;
78e23731dbSKonstantin Belousov /* Protect ASO WQ access, as it is global to whole IPsec */
79e23731dbSKonstantin Belousov spinlock_t lock;
80e23731dbSKonstantin Belousov };
81e23731dbSKonstantin Belousov
82e23731dbSKonstantin Belousov struct mlx5_replay_esn {
83e23731dbSKonstantin Belousov u32 replay_window;
84e23731dbSKonstantin Belousov u32 esn;
85e23731dbSKonstantin Belousov u32 esn_msb;
86e23731dbSKonstantin Belousov u8 overlap : 1;
87e23731dbSKonstantin Belousov u8 trigger : 1;
88e23731dbSKonstantin Belousov };
89e23731dbSKonstantin Belousov
90e23731dbSKonstantin Belousov struct mlx5_accel_esp_xfrm_attrs {
91e23731dbSKonstantin Belousov u32 spi;
92e23731dbSKonstantin Belousov struct aes_gcm_keymat aes_gcm;
93e23731dbSKonstantin Belousov
94e9dcd831SSlava Shwartsman union {
95e23731dbSKonstantin Belousov __be32 a4;
96e23731dbSKonstantin Belousov __be32 a6[4];
97e23731dbSKonstantin Belousov } saddr;
98e23731dbSKonstantin Belousov
99e23731dbSKonstantin Belousov union {
100e23731dbSKonstantin Belousov __be32 a4;
101e23731dbSKonstantin Belousov __be32 a6[4];
102e23731dbSKonstantin Belousov } daddr;
103e23731dbSKonstantin Belousov
104e23731dbSKonstantin Belousov u8 dir : 2;
105e23731dbSKonstantin Belousov u8 encap : 1;
106e23731dbSKonstantin Belousov u8 drop : 1;
107e23731dbSKonstantin Belousov u8 family;
108e23731dbSKonstantin Belousov struct mlx5_replay_esn replay_esn;
109e23731dbSKonstantin Belousov u32 authsize;
110e23731dbSKonstantin Belousov u32 reqid;
111e23731dbSKonstantin Belousov u16 sport;
112e23731dbSKonstantin Belousov u16 dport;
113e9dcd831SSlava Shwartsman };
114e9dcd831SSlava Shwartsman
115e23731dbSKonstantin Belousov enum mlx5_ipsec_cap {
116e23731dbSKonstantin Belousov MLX5_IPSEC_CAP_CRYPTO = 1 << 0,
117e23731dbSKonstantin Belousov MLX5_IPSEC_CAP_ESN = 1 << 1,
118e23731dbSKonstantin Belousov MLX5_IPSEC_CAP_PACKET_OFFLOAD = 1 << 2,
119e23731dbSKonstantin Belousov MLX5_IPSEC_CAP_ROCE = 1 << 3,
120e23731dbSKonstantin Belousov MLX5_IPSEC_CAP_PRIO = 1 << 4,
121e23731dbSKonstantin Belousov MLX5_IPSEC_CAP_TUNNEL = 1 << 5,
122e23731dbSKonstantin Belousov MLX5_IPSEC_CAP_ESPINUDP = 1 << 6,
123e23731dbSKonstantin Belousov };
124e9dcd831SSlava Shwartsman
125e23731dbSKonstantin Belousov struct mlx5e_ipsec {
126e23731dbSKonstantin Belousov struct mlx5_core_dev *mdev;
127e23731dbSKonstantin Belousov struct workqueue_struct *wq;
128e23731dbSKonstantin Belousov struct mlx5e_ipsec_tx *tx;
129e23731dbSKonstantin Belousov struct mlx5e_ipsec_rx *rx_ipv4;
130e23731dbSKonstantin Belousov struct mlx5e_ipsec_rx *rx_ipv6;
131e23731dbSKonstantin Belousov struct mlx5e_ipsec_aso *aso;
132e23731dbSKonstantin Belousov u32 pdn;
133e23731dbSKonstantin Belousov u32 mkey;
134e23731dbSKonstantin Belousov };
135e9dcd831SSlava Shwartsman
136e23731dbSKonstantin Belousov struct mlx5e_ipsec_rule {
137e23731dbSKonstantin Belousov struct mlx5_flow_handle *rule;
138e23731dbSKonstantin Belousov struct mlx5_flow_handle *kspi_rule;
139e23731dbSKonstantin Belousov struct mlx5_flow_handle *reqid_rule;
140*205263acSAriel Ehrenberg struct mlx5_flow_handle *vid_zero_rule;
141e23731dbSKonstantin Belousov struct mlx5_modify_hdr *modify_hdr;
142e23731dbSKonstantin Belousov struct mlx5_pkt_reformat *pkt_reformat;
143e23731dbSKonstantin Belousov struct mlx5_fc *fc;
144e23731dbSKonstantin Belousov };
145e9dcd831SSlava Shwartsman
146e23731dbSKonstantin Belousov struct mlx5e_ipsec_esn_state {
147e23731dbSKonstantin Belousov u32 esn;
148e23731dbSKonstantin Belousov u32 esn_msb;
149e23731dbSKonstantin Belousov u8 overlap: 1;
150e23731dbSKonstantin Belousov };
151e9dcd831SSlava Shwartsman
152e23731dbSKonstantin Belousov struct mlx5e_ipsec_sa_entry {
153e23731dbSKonstantin Belousov struct secasvar *savp;
154e23731dbSKonstantin Belousov if_t ifp;
155*205263acSAriel Ehrenberg if_t ifpo;
156e23731dbSKonstantin Belousov struct mlx5e_ipsec *ipsec;
157e23731dbSKonstantin Belousov struct mlx5_accel_esp_xfrm_attrs attrs;
158e23731dbSKonstantin Belousov struct mlx5e_ipsec_rule ipsec_rule;
159e23731dbSKonstantin Belousov struct mlx5e_ipsec_dwork *dwork;
160e23731dbSKonstantin Belousov struct mlx5e_ipsec_work *work;
161e23731dbSKonstantin Belousov u32 ipsec_obj_id;
162e23731dbSKonstantin Belousov u32 enc_key_id;
163e23731dbSKonstantin Belousov u16 kspi; /* Stack allocated unique SA identifier */
164e23731dbSKonstantin Belousov struct mlx5e_ipsec_esn_state esn_state;
165*205263acSAriel Ehrenberg u16 vid;
166e23731dbSKonstantin Belousov };
167e9dcd831SSlava Shwartsman
168e23731dbSKonstantin Belousov struct upspec {
169e23731dbSKonstantin Belousov u16 dport;
170e23731dbSKonstantin Belousov u16 sport;
171e23731dbSKonstantin Belousov u8 proto;
172e23731dbSKonstantin Belousov };
173e9dcd831SSlava Shwartsman
174e23731dbSKonstantin Belousov struct mlx5_accel_pol_xfrm_attrs {
175e23731dbSKonstantin Belousov union {
176e23731dbSKonstantin Belousov __be32 a4;
177e23731dbSKonstantin Belousov __be32 a6[4];
178e23731dbSKonstantin Belousov } saddr;
179e9dcd831SSlava Shwartsman
180e23731dbSKonstantin Belousov union {
181e23731dbSKonstantin Belousov __be32 a4;
182e23731dbSKonstantin Belousov __be32 a6[4];
183e23731dbSKonstantin Belousov } daddr;
184e23731dbSKonstantin Belousov
185e23731dbSKonstantin Belousov struct upspec upspec;
186e23731dbSKonstantin Belousov
187e23731dbSKonstantin Belousov u8 family;
188e23731dbSKonstantin Belousov u8 action;
189e23731dbSKonstantin Belousov u8 dir : 2;
190e23731dbSKonstantin Belousov u32 reqid;
191e23731dbSKonstantin Belousov u32 prio;
192*205263acSAriel Ehrenberg u16 vid;
193e23731dbSKonstantin Belousov };
194e23731dbSKonstantin Belousov
195e23731dbSKonstantin Belousov struct mlx5e_ipsec_pol_entry {
196e23731dbSKonstantin Belousov struct secpolicy *sp;
197e23731dbSKonstantin Belousov struct mlx5e_ipsec *ipsec;
198e23731dbSKonstantin Belousov struct mlx5e_ipsec_rule ipsec_rule;
199e23731dbSKonstantin Belousov struct mlx5_accel_pol_xfrm_attrs attrs;
200e23731dbSKonstantin Belousov };
201e23731dbSKonstantin Belousov
202e23731dbSKonstantin Belousov /* This function doesn't really belong here, but let's put it here for now */
203e23731dbSKonstantin Belousov void mlx5_object_change_event(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe);
204e23731dbSKonstantin Belousov
205e23731dbSKonstantin Belousov int mlx5e_ipsec_init(struct mlx5e_priv *priv);
206e23731dbSKonstantin Belousov void mlx5e_ipsec_cleanup(struct mlx5e_priv *priv);
207e23731dbSKonstantin Belousov
208e23731dbSKonstantin Belousov int mlx5e_ipsec_aso_init(struct mlx5e_ipsec *ipsec);
209e23731dbSKonstantin Belousov void mlx5e_ipsec_aso_cleanup(struct mlx5e_ipsec *ipsec);
210e23731dbSKonstantin Belousov
211e23731dbSKonstantin Belousov int mlx5_ipsec_create_sa_ctx(struct mlx5e_ipsec_sa_entry *sa_entry);
212e23731dbSKonstantin Belousov void mlx5_ipsec_free_sa_ctx(struct mlx5e_ipsec_sa_entry *sa_entry);
213e23731dbSKonstantin Belousov
214e23731dbSKonstantin Belousov u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev);
215e23731dbSKonstantin Belousov
216e23731dbSKonstantin Belousov static inline struct mlx5_core_dev *
mlx5e_ipsec_sa2dev(struct mlx5e_ipsec_sa_entry * sa_entry)217e23731dbSKonstantin Belousov mlx5e_ipsec_sa2dev(struct mlx5e_ipsec_sa_entry *sa_entry)
218e9dcd831SSlava Shwartsman {
219e23731dbSKonstantin Belousov return sa_entry->ipsec->mdev;
220e9dcd831SSlava Shwartsman }
221e9dcd831SSlava Shwartsman
222e23731dbSKonstantin Belousov static inline struct mlx5_core_dev *
mlx5e_ipsec_pol2dev(struct mlx5e_ipsec_pol_entry * pol_entry)223e23731dbSKonstantin Belousov mlx5e_ipsec_pol2dev(struct mlx5e_ipsec_pol_entry *pol_entry)
224e9dcd831SSlava Shwartsman {
225e23731dbSKonstantin Belousov return pol_entry->ipsec->mdev;
226e9dcd831SSlava Shwartsman }
227e9dcd831SSlava Shwartsman
228e23731dbSKonstantin Belousov void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
229e23731dbSKonstantin Belousov struct mlx5_accel_esp_xfrm_attrs *attrs,
230e23731dbSKonstantin Belousov u8 dir);
231e9dcd831SSlava Shwartsman
232e23731dbSKonstantin Belousov int mlx5e_accel_ipsec_fs_init(struct mlx5e_ipsec *ipsec);
233e23731dbSKonstantin Belousov void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_ipsec *ipsec);
234e23731dbSKonstantin Belousov int mlx5e_accel_ipsec_fs_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry);
235e23731dbSKonstantin Belousov void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry);
236e23731dbSKonstantin Belousov void mlx5e_accel_ipsec_fs_modify(struct mlx5e_ipsec_sa_entry *sa_entry);
237e23731dbSKonstantin Belousov struct ipsec_accel_out_tag;
238e23731dbSKonstantin Belousov void mlx5e_accel_ipsec_handle_tx_wqe(struct mbuf *mb, struct mlx5e_tx_wqe *wqe,
239e23731dbSKonstantin Belousov struct ipsec_accel_out_tag *tag);
240e23731dbSKonstantin Belousov int mlx5e_accel_ipsec_fs_add_pol(struct mlx5e_ipsec_pol_entry *pol_entry);
241e23731dbSKonstantin Belousov void mlx5e_accel_ipsec_fs_del_pol(struct mlx5e_ipsec_pol_entry *pol_entry);
mlx5e_accel_ipsec_get_metadata(unsigned int id)242e23731dbSKonstantin Belousov static inline int mlx5e_accel_ipsec_get_metadata(unsigned int id)
243e23731dbSKonstantin Belousov {
244e23731dbSKonstantin Belousov return MLX5_ETH_WQE_FT_META_IPSEC << 23 | id;
245e23731dbSKonstantin Belousov }
246e23731dbSKonstantin Belousov static inline void
mlx5e_accel_ipsec_handle_tx(struct mbuf * mb,struct mlx5e_tx_wqe * wqe)247e23731dbSKonstantin Belousov mlx5e_accel_ipsec_handle_tx(struct mbuf *mb, struct mlx5e_tx_wqe *wqe)
248e23731dbSKonstantin Belousov {
249e23731dbSKonstantin Belousov struct ipsec_accel_out_tag *tag;
250e23731dbSKonstantin Belousov
251e23731dbSKonstantin Belousov tag = (struct ipsec_accel_out_tag *)m_tag_find(mb,
252e23731dbSKonstantin Belousov PACKET_TAG_IPSEC_ACCEL_OUT, NULL);
253e23731dbSKonstantin Belousov if (tag != NULL)
254e23731dbSKonstantin Belousov mlx5e_accel_ipsec_handle_tx_wqe(mb, wqe, tag);
255e23731dbSKonstantin Belousov }
256e23731dbSKonstantin Belousov void mlx5e_accel_ipsec_fs_rx_tables_destroy(struct mlx5e_priv *priv);
257e23731dbSKonstantin Belousov int mlx5e_accel_ipsec_fs_rx_tables_create(struct mlx5e_priv *priv);
258e23731dbSKonstantin Belousov void mlx5e_accel_ipsec_fs_rx_catchall_rules_destroy(struct mlx5e_priv *priv);
259e23731dbSKonstantin Belousov int mlx5e_accel_ipsec_fs_rx_catchall_rules(struct mlx5e_priv *priv);
260d00f3505SKonstantin Belousov int mlx5_accel_ipsec_rx_tag_add(if_t ifp, struct mlx5e_rq_mbuf *mr);
261d00f3505SKonstantin Belousov void mlx5e_accel_ipsec_handle_rx_cqe(struct mbuf *mb, struct mlx5_cqe64 *cqe,
262d00f3505SKonstantin Belousov struct mlx5e_rq_mbuf *mr);
263d00f3505SKonstantin Belousov
mlx5e_accel_ipsec_flow(struct mlx5_cqe64 * cqe)264e23731dbSKonstantin Belousov static inline int mlx5e_accel_ipsec_flow(struct mlx5_cqe64 *cqe)
265e23731dbSKonstantin Belousov {
266e23731dbSKonstantin Belousov return MLX5_IPSEC_METADATA_MARKER(be32_to_cpu(cqe->ft_metadata));
267e23731dbSKonstantin Belousov }
268e23731dbSKonstantin Belousov
269d00f3505SKonstantin Belousov static inline void
mlx5e_accel_ipsec_handle_rx(struct mbuf * mb,struct mlx5_cqe64 * cqe,struct mlx5e_rq_mbuf * mr)270d00f3505SKonstantin Belousov mlx5e_accel_ipsec_handle_rx(struct mbuf *mb, struct mlx5_cqe64 *cqe,
271d00f3505SKonstantin Belousov struct mlx5e_rq_mbuf *mr)
272e23731dbSKonstantin Belousov {
273e23731dbSKonstantin Belousov u32 ipsec_meta_data = be32_to_cpu(cqe->ft_metadata);
274e23731dbSKonstantin Belousov
275d00f3505SKonstantin Belousov if (MLX5_IPSEC_METADATA_MARKER(ipsec_meta_data))
276d00f3505SKonstantin Belousov mlx5e_accel_ipsec_handle_rx_cqe(mb, cqe, mr);
277e23731dbSKonstantin Belousov }
278e9dcd831SSlava Shwartsman #endif /* __MLX5_ACCEL_IPSEC_H__ */
279