184d7b8e7SHans Petter Selasky /*-
2ebdb7006SHans Petter Selasky * Copyright (c) 2021-2022 NVIDIA corporation & affiliates.
384d7b8e7SHans Petter Selasky *
484d7b8e7SHans Petter Selasky * Redistribution and use in source and binary forms, with or without
584d7b8e7SHans Petter Selasky * modification, are permitted provided that the following conditions
684d7b8e7SHans Petter Selasky * are met:
784d7b8e7SHans Petter Selasky * 1. Redistributions of source code must retain the above copyright
884d7b8e7SHans Petter Selasky * notice, this list of conditions and the following disclaimer.
984d7b8e7SHans Petter Selasky * 2. Redistributions in binary form must reproduce the above copyright
1084d7b8e7SHans Petter Selasky * notice, this list of conditions and the following disclaimer in the
1184d7b8e7SHans Petter Selasky * documentation and/or other materials provided with the distribution.
1284d7b8e7SHans Petter Selasky *
1384d7b8e7SHans Petter Selasky * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
1484d7b8e7SHans Petter Selasky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1584d7b8e7SHans Petter Selasky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1684d7b8e7SHans Petter Selasky * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
1784d7b8e7SHans Petter Selasky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1884d7b8e7SHans Petter Selasky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1984d7b8e7SHans Petter Selasky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2084d7b8e7SHans Petter Selasky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2184d7b8e7SHans Petter Selasky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2284d7b8e7SHans Petter Selasky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2384d7b8e7SHans Petter Selasky * SUCH DAMAGE.
2484d7b8e7SHans Petter Selasky */
2584d7b8e7SHans Petter Selasky
2684d7b8e7SHans Petter Selasky #ifndef _MLX5_TLS_RX_H_
2784d7b8e7SHans Petter Selasky #define _MLX5_TLS_RX_H_
2884d7b8e7SHans Petter Selasky
2984d7b8e7SHans Petter Selasky #include <linux/completion.h>
3084d7b8e7SHans Petter Selasky
3184d7b8e7SHans Petter Selasky #define MLX5E_TLS_RX_PROGRESS_BUFFER_SIZE 128
3284d7b8e7SHans Petter Selasky
3384d7b8e7SHans Petter Selasky #define MLX5E_TLS_RX_RESYNC_MAX 32 /* units */
3484d7b8e7SHans Petter Selasky #define MLX5E_TLS_RX_NUM_MAX (1U << 11) /* packets */
3584d7b8e7SHans Petter Selasky
3684d7b8e7SHans Petter Selasky #define MLX5E_TLS_RX_TAG_LOCK(tag) mtx_lock(&(tag)->mtx)
3784d7b8e7SHans Petter Selasky #define MLX5E_TLS_RX_TAG_UNLOCK(tag) mtx_unlock(&(tag)->mtx)
3884d7b8e7SHans Petter Selasky
3984d7b8e7SHans Petter Selasky #define MLX5E_TLS_RX_STAT_INC(tag, field, num) \
4084d7b8e7SHans Petter Selasky counter_u64_add((tag)->tls_rx->stats.field, num)
4184d7b8e7SHans Petter Selasky
4284d7b8e7SHans Petter Selasky #if ((MLX5E_TLS_RX_RESYNC_MAX * MLX5E_TLS_RX_NUM_MAX) << 14) > (1U << 30)
4384d7b8e7SHans Petter Selasky #error "Please lower the limits of the TLS record length database."
4484d7b8e7SHans Petter Selasky #endif
4584d7b8e7SHans Petter Selasky
4684d7b8e7SHans Petter Selasky enum {
4784d7b8e7SHans Petter Selasky MLX5E_TLS_RX_PROGRESS_PARAMS_AUTH_STATE_NO_OFFLOAD = 0,
4884d7b8e7SHans Petter Selasky MLX5E_TLS_RX_PROGRESS_PARAMS_AUTH_STATE_OFFLOAD = 1,
4984d7b8e7SHans Petter Selasky MLX5E_TLS_RX_PROGRESS_PARAMS_AUTH_STATE_AUTHENTICATION = 2,
5084d7b8e7SHans Petter Selasky };
5184d7b8e7SHans Petter Selasky
5284d7b8e7SHans Petter Selasky enum {
5384d7b8e7SHans Petter Selasky MLX5E_TLS_RX_PROGRESS_PARAMS_RECORD_TRACKER_STATE_START = 0,
5484d7b8e7SHans Petter Selasky MLX5E_TLS_RX_PROGRESS_PARAMS_RECORD_TRACKER_STATE_TRACKING = 1,
5584d7b8e7SHans Petter Selasky MLX5E_TLS_RX_PROGRESS_PARAMS_RECORD_TRACKER_STATE_SEARCHING = 2,
5684d7b8e7SHans Petter Selasky };
5784d7b8e7SHans Petter Selasky
5884d7b8e7SHans Petter Selasky struct mlx5e_tls_rx;
5984d7b8e7SHans Petter Selasky struct mlx5e_tls_rx_tag {
6084d7b8e7SHans Petter Selasky struct m_snd_tag tag;
6184d7b8e7SHans Petter Selasky uint32_t tirn; /* HW TIR context number */
6284d7b8e7SHans Petter Selasky uint32_t dek_index; /* HW TLS context number */
6384d7b8e7SHans Petter Selasky struct mlx5e_tls_rx *tls_rx; /* parent pointer */
6484d7b8e7SHans Petter Selasky struct mlx5_flow_rule *flow_rule;
6584d7b8e7SHans Petter Selasky struct mtx mtx;
6684d7b8e7SHans Petter Selasky struct completion progress_complete;
6784d7b8e7SHans Petter Selasky uint32_t state; /* see MLX5E_TLS_RX_ST_XXX */
6884d7b8e7SHans Petter Selasky #define MLX5E_TLS_RX_ST_INIT 0
6984d7b8e7SHans Petter Selasky #define MLX5E_TLS_RX_ST_SETUP 1
7084d7b8e7SHans Petter Selasky #define MLX5E_TLS_RX_ST_READY 2
71015f22f5SHans Petter Selasky #define MLX5E_TLS_RX_ST_RELEASE 3
72015f22f5SHans Petter Selasky #define MLX5E_TLS_RX_ST_FREED 4
7384d7b8e7SHans Petter Selasky
7484d7b8e7SHans Petter Selasky /*
7584d7b8e7SHans Petter Selasky * The following fields are used to store the TCP starting
7684d7b8e7SHans Petter Selasky * point of TLS records in the past. When TLS records of same
7784d7b8e7SHans Petter Selasky * length are back to back the tcp_resync_num[] is incremented
7884d7b8e7SHans Petter Selasky * instead of creating new entries. This way up to
7984d7b8e7SHans Petter Selasky * "MLX5E_TLS_RX_RESYNC_MAX" * "MLX5E_TLS_RX_NUM_MAX" * 16
8084d7b8e7SHans Petter Selasky * KBytes, around 1GByte worth of TCP data, may be remembered
8184d7b8e7SHans Petter Selasky * in the good case. The amount of history should not exceed
8284d7b8e7SHans Petter Selasky * 2GBytes of TCP data, because then the TCP sequence numbers
8384d7b8e7SHans Petter Selasky * may wrap around.
8484d7b8e7SHans Petter Selasky *
8584d7b8e7SHans Petter Selasky * This information is used to tell if a given TCP sequence
8684d7b8e7SHans Petter Selasky * number is a valid TLS record or not.
8784d7b8e7SHans Petter Selasky */
8884d7b8e7SHans Petter Selasky uint64_t rcd_resync_start; /* starting TLS record number */
8984d7b8e7SHans Petter Selasky uint32_t tcp_resync_start; /* starting TCP sequence number */
9084d7b8e7SHans Petter Selasky uint32_t tcp_resync_next; /* next expected TCP sequence number */
9184d7b8e7SHans Petter Selasky uint32_t tcp_resync_len[MLX5E_TLS_RX_RESYNC_MAX];
9284d7b8e7SHans Petter Selasky uint32_t tcp_resync_num[MLX5E_TLS_RX_RESYNC_MAX];
9384d7b8e7SHans Petter Selasky uint16_t tcp_resync_pc; /* producer counter for arrays above */
9484d7b8e7SHans Petter Selasky uint16_t tcp_resync_cc; /* consumer counter for arrays above */
9584d7b8e7SHans Petter Selasky
9684d7b8e7SHans Petter Selasky struct work_struct work;
9784d7b8e7SHans Petter Selasky
9884d7b8e7SHans Petter Selasky uint32_t flowid;
9984d7b8e7SHans Petter Selasky uint32_t flowtype;
10084d7b8e7SHans Petter Selasky uint32_t dek_index_ok:1;
10184d7b8e7SHans Petter Selasky uint32_t tcp_resync_active:1;
10284d7b8e7SHans Petter Selasky uint32_t tcp_resync_pending:1;
10384d7b8e7SHans Petter Selasky
10484d7b8e7SHans Petter Selasky /* parameters needed */
10584d7b8e7SHans Petter Selasky uint8_t crypto_params[128] __aligned(4);
10684d7b8e7SHans Petter Selasky uint8_t rx_progress[MLX5E_TLS_RX_PROGRESS_BUFFER_SIZE * 2];
10784d7b8e7SHans Petter Selasky } __aligned(MLX5E_CACHELINE_SIZE);
10884d7b8e7SHans Petter Selasky
10984d7b8e7SHans Petter Selasky static inline void *
mlx5e_tls_rx_get_progress_buffer(struct mlx5e_tls_rx_tag * ptag)11084d7b8e7SHans Petter Selasky mlx5e_tls_rx_get_progress_buffer(struct mlx5e_tls_rx_tag *ptag)
11184d7b8e7SHans Petter Selasky {
11284d7b8e7SHans Petter Selasky /* return properly aligned RX buffer */
11384d7b8e7SHans Petter Selasky return (ptag->rx_progress +
11484d7b8e7SHans Petter Selasky ((-(uintptr_t)ptag->rx_progress) &
11584d7b8e7SHans Petter Selasky (MLX5E_TLS_RX_PROGRESS_BUFFER_SIZE - 1)));
11684d7b8e7SHans Petter Selasky }
11784d7b8e7SHans Petter Selasky
11884d7b8e7SHans Petter Selasky #define MLX5E_TLS_RX_STATS(m) \
11984d7b8e7SHans Petter Selasky m(+1, u64, rx_resync_ok, "rx_resync_ok", "Successful resync requests")\
12084d7b8e7SHans Petter Selasky m(+1, u64, rx_resync_err, "rx_resync_err", "Failed resync requests")\
12184d7b8e7SHans Petter Selasky m(+1, u64, rx_error, "rx_error", "Other errors")
12284d7b8e7SHans Petter Selasky
12384d7b8e7SHans Petter Selasky #define MLX5E_TLS_RX_STATS_NUM (0 MLX5E_TLS_RX_STATS(MLX5E_STATS_COUNT))
12484d7b8e7SHans Petter Selasky
12584d7b8e7SHans Petter Selasky struct mlx5e_tls_rx_stats {
12684d7b8e7SHans Petter Selasky struct sysctl_ctx_list ctx;
12784d7b8e7SHans Petter Selasky counter_u64_t arg[0];
12884d7b8e7SHans Petter Selasky MLX5E_TLS_RX_STATS(MLX5E_STATS_COUNTER)
12984d7b8e7SHans Petter Selasky };
13084d7b8e7SHans Petter Selasky
13184d7b8e7SHans Petter Selasky struct mlx5e_tls_rx {
13284d7b8e7SHans Petter Selasky struct sysctl_ctx_list ctx;
13384d7b8e7SHans Petter Selasky struct mlx5e_tls_rx_stats stats;
13484d7b8e7SHans Petter Selasky struct workqueue_struct *wq;
13584d7b8e7SHans Petter Selasky uma_zone_t zone;
13684d7b8e7SHans Petter Selasky uint32_t max_resources; /* max number of resources */
13784d7b8e7SHans Petter Selasky volatile uint32_t num_resources; /* current number of resources */
13884d7b8e7SHans Petter Selasky int init; /* set when ready */
13984d7b8e7SHans Petter Selasky char zname[32];
14084d7b8e7SHans Petter Selasky };
14184d7b8e7SHans Petter Selasky
14284d7b8e7SHans Petter Selasky int mlx5e_tls_rx_init(struct mlx5e_priv *);
14384d7b8e7SHans Petter Selasky void mlx5e_tls_rx_cleanup(struct mlx5e_priv *);
14484d7b8e7SHans Petter Selasky
14584d7b8e7SHans Petter Selasky if_snd_tag_alloc_t mlx5e_tls_rx_snd_tag_alloc;
14684d7b8e7SHans Petter Selasky
14784d7b8e7SHans Petter Selasky #endif /* _MLX5_TLS_RX_H_ */
148