11182f365STariq Toukan // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
21182f365STariq Toukan // Copyright (c) 2019 Mellanox Technologies.
31182f365STariq Toukan 
40419d8c9STariq Toukan #include <net/inet6_hashtables.h>
51182f365STariq Toukan #include "en_accel/en_accel.h"
6943aa7bdSLeon Romanovsky #include "en_accel/ktls.h"
71182f365STariq Toukan #include "en_accel/ktls_txrx.h"
81182f365STariq Toukan #include "en_accel/ktls_utils.h"
91182f365STariq Toukan #include "en_accel/fs_tcp.h"
101182f365STariq Toukan 
111182f365STariq Toukan struct accel_rule {
121182f365STariq Toukan 	struct work_struct work;
131182f365STariq Toukan 	struct mlx5e_priv *priv;
141182f365STariq Toukan 	struct mlx5_flow_handle *rule;
151182f365STariq Toukan };
161182f365STariq Toukan 
170419d8c9STariq Toukan #define PROGRESS_PARAMS_WRITE_UNIT	64
180419d8c9STariq Toukan #define PROGRESS_PARAMS_PADDED_SIZE	\
190419d8c9STariq Toukan 		(ALIGN(sizeof(struct mlx5_wqe_tls_progress_params_seg), \
200419d8c9STariq Toukan 		       PROGRESS_PARAMS_WRITE_UNIT))
210419d8c9STariq Toukan 
220419d8c9STariq Toukan struct mlx5e_ktls_rx_resync_buf {
230419d8c9STariq Toukan 	union {
240419d8c9STariq Toukan 		struct mlx5_wqe_tls_progress_params_seg progress;
250419d8c9STariq Toukan 		u8 pad[PROGRESS_PARAMS_PADDED_SIZE];
260419d8c9STariq Toukan 	} ____cacheline_aligned_in_smp;
270419d8c9STariq Toukan 	dma_addr_t dma_addr;
280419d8c9STariq Toukan 	struct mlx5e_ktls_offload_context_rx *priv_rx;
290419d8c9STariq Toukan };
300419d8c9STariq Toukan 
311182f365STariq Toukan enum {
321182f365STariq Toukan 	MLX5E_PRIV_RX_FLAG_DELETING,
331182f365STariq Toukan 	MLX5E_NUM_PRIV_RX_FLAGS,
341182f365STariq Toukan };
351182f365STariq Toukan 
360419d8c9STariq Toukan struct mlx5e_ktls_rx_resync_ctx {
370419d8c9STariq Toukan 	struct tls_offload_resync_async core;
380419d8c9STariq Toukan 	struct work_struct work;
390419d8c9STariq Toukan 	struct mlx5e_priv *priv;
400419d8c9STariq Toukan 	refcount_t refcnt;
410419d8c9STariq Toukan 	__be64 sw_rcd_sn_be;
420419d8c9STariq Toukan 	u32 seq;
430419d8c9STariq Toukan };
440419d8c9STariq Toukan 
451182f365STariq Toukan struct mlx5e_ktls_offload_context_rx {
464960c414SGal Pressman 	union mlx5e_crypto_info crypto_info;
471182f365STariq Toukan 	struct accel_rule rule;
481182f365STariq Toukan 	struct sock *sk;
496f4fdd53STariq Toukan 	struct mlx5e_rq_stats *rq_stats;
506f4fdd53STariq Toukan 	struct mlx5e_tls_sw_stats *sw_stats;
511182f365STariq Toukan 	struct completion add_ctx;
5209f83569SMaxim Mikityanskiy 	struct mlx5e_tir tir;
53f741db1aSJianbo Liu 	struct mlx5_crypto_dek *dek;
541182f365STariq Toukan 	u32 rxq;
551182f365STariq Toukan 	DECLARE_BITMAP(flags, MLX5E_NUM_PRIV_RX_FLAGS);
560419d8c9STariq Toukan 
570419d8c9STariq Toukan 	/* resync */
58cc4a9cc0STariq Toukan 	spinlock_t lock; /* protects resync fields */
590419d8c9STariq Toukan 	struct mlx5e_ktls_rx_resync_ctx resync;
60e9ce991bSTariq Toukan 	struct list_head list;
611182f365STariq Toukan };
621182f365STariq Toukan 
mlx5e_ktls_priv_rx_put(struct mlx5e_ktls_offload_context_rx * priv_rx)63b850bbffSMaxim Mikityanskiy static bool mlx5e_ktls_priv_rx_put(struct mlx5e_ktls_offload_context_rx *priv_rx)
64b850bbffSMaxim Mikityanskiy {
65b850bbffSMaxim Mikityanskiy 	if (!refcount_dec_and_test(&priv_rx->resync.refcnt))
66b850bbffSMaxim Mikityanskiy 		return false;
67b850bbffSMaxim Mikityanskiy 
68b850bbffSMaxim Mikityanskiy 	kfree(priv_rx);
69b850bbffSMaxim Mikityanskiy 	return true;
70b850bbffSMaxim Mikityanskiy }
71b850bbffSMaxim Mikityanskiy 
mlx5e_ktls_priv_rx_get(struct mlx5e_ktls_offload_context_rx * priv_rx)72b850bbffSMaxim Mikityanskiy static void mlx5e_ktls_priv_rx_get(struct mlx5e_ktls_offload_context_rx *priv_rx)
73b850bbffSMaxim Mikityanskiy {
74b850bbffSMaxim Mikityanskiy 	refcount_inc(&priv_rx->resync.refcnt);
75b850bbffSMaxim Mikityanskiy }
76b850bbffSMaxim Mikityanskiy 
77e9ce991bSTariq Toukan struct mlx5e_ktls_resync_resp {
78e9ce991bSTariq Toukan 	/* protects list changes */
79e9ce991bSTariq Toukan 	spinlock_t lock;
80e9ce991bSTariq Toukan 	struct list_head list;
81e9ce991bSTariq Toukan };
82e9ce991bSTariq Toukan 
mlx5e_ktls_rx_resync_destroy_resp_list(struct mlx5e_ktls_resync_resp * resp_list)83e9ce991bSTariq Toukan void mlx5e_ktls_rx_resync_destroy_resp_list(struct mlx5e_ktls_resync_resp *resp_list)
84e9ce991bSTariq Toukan {
85e9ce991bSTariq Toukan 	kvfree(resp_list);
86e9ce991bSTariq Toukan }
87e9ce991bSTariq Toukan 
88e9ce991bSTariq Toukan struct mlx5e_ktls_resync_resp *
mlx5e_ktls_rx_resync_create_resp_list(void)89e9ce991bSTariq Toukan mlx5e_ktls_rx_resync_create_resp_list(void)
90e9ce991bSTariq Toukan {
91e9ce991bSTariq Toukan 	struct mlx5e_ktls_resync_resp *resp_list;
92e9ce991bSTariq Toukan 
93e9ce991bSTariq Toukan 	resp_list = kvzalloc(sizeof(*resp_list), GFP_KERNEL);
94e9ce991bSTariq Toukan 	if (!resp_list)
95e9ce991bSTariq Toukan 		return ERR_PTR(-ENOMEM);
96e9ce991bSTariq Toukan 
97e9ce991bSTariq Toukan 	INIT_LIST_HEAD(&resp_list->list);
98e9ce991bSTariq Toukan 	spin_lock_init(&resp_list->lock);
99e9ce991bSTariq Toukan 
100e9ce991bSTariq Toukan 	return resp_list;
101e9ce991bSTariq Toukan }
102e9ce991bSTariq Toukan 
accel_rule_handle_work(struct work_struct * work)1031182f365STariq Toukan static void accel_rule_handle_work(struct work_struct *work)
1041182f365STariq Toukan {
1051182f365STariq Toukan 	struct mlx5e_ktls_offload_context_rx *priv_rx;
1061182f365STariq Toukan 	struct accel_rule *accel_rule;
1071182f365STariq Toukan 	struct mlx5_flow_handle *rule;
1081182f365STariq Toukan 
1091182f365STariq Toukan 	accel_rule = container_of(work, struct accel_rule, work);
1101182f365STariq Toukan 	priv_rx = container_of(accel_rule, struct mlx5e_ktls_offload_context_rx, rule);
1111182f365STariq Toukan 	if (unlikely(test_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags)))
1121182f365STariq Toukan 		goto out;
1131182f365STariq Toukan 
1141be44b42SLama Kayal 	rule = mlx5e_accel_fs_add_sk(accel_rule->priv->fs, priv_rx->sk,
11509f83569SMaxim Mikityanskiy 				     mlx5e_tir_get_tirn(&priv_rx->tir),
11609f83569SMaxim Mikityanskiy 				     MLX5_FS_DEFAULT_FLOW_TAG);
1171182f365STariq Toukan 	if (!IS_ERR_OR_NULL(rule))
1181182f365STariq Toukan 		accel_rule->rule = rule;
1191182f365STariq Toukan out:
1201182f365STariq Toukan 	complete(&priv_rx->add_ctx);
1211182f365STariq Toukan }
1221182f365STariq Toukan 
accel_rule_init(struct accel_rule * rule,struct mlx5e_priv * priv)1238668587aSTariq Toukan static void accel_rule_init(struct accel_rule *rule, struct mlx5e_priv *priv)
1241182f365STariq Toukan {
1251182f365STariq Toukan 	INIT_WORK(&rule->work, accel_rule_handle_work);
1261182f365STariq Toukan 	rule->priv = priv;
1271182f365STariq Toukan }
1281182f365STariq Toukan 
icosq_fill_wi(struct mlx5e_icosq * sq,u16 pi,struct mlx5e_icosq_wqe_info * wi)1291182f365STariq Toukan static void icosq_fill_wi(struct mlx5e_icosq *sq, u16 pi,
1301182f365STariq Toukan 			  struct mlx5e_icosq_wqe_info *wi)
1311182f365STariq Toukan {
1321182f365STariq Toukan 	sq->db.wqe_info[pi] = *wi;
1331182f365STariq Toukan }
1341182f365STariq Toukan 
1351182f365STariq Toukan static struct mlx5_wqe_ctrl_seg *
post_static_params(struct mlx5e_icosq * sq,struct mlx5e_ktls_offload_context_rx * priv_rx)1361182f365STariq Toukan post_static_params(struct mlx5e_icosq *sq,
1371182f365STariq Toukan 		   struct mlx5e_ktls_offload_context_rx *priv_rx)
1381182f365STariq Toukan {
1391182f365STariq Toukan 	struct mlx5e_set_tls_static_params_wqe *wqe;
1401182f365STariq Toukan 	struct mlx5e_icosq_wqe_info wi;
1413ff3874fSTariq Toukan 	u16 pi, num_wqebbs;
1421182f365STariq Toukan 
1431182f365STariq Toukan 	num_wqebbs = MLX5E_TLS_SET_STATIC_PARAMS_WQEBBS;
1443ff3874fSTariq Toukan 	if (unlikely(!mlx5e_icosq_can_post_wqe(sq, num_wqebbs)))
1451182f365STariq Toukan 		return ERR_PTR(-ENOSPC);
1461182f365STariq Toukan 
1471182f365STariq Toukan 	pi = mlx5e_icosq_get_next_pi(sq, num_wqebbs);
1481182f365STariq Toukan 	wqe = MLX5E_TLS_FETCH_SET_STATIC_PARAMS_WQE(sq, pi);
1491182f365STariq Toukan 	mlx5e_ktls_build_static_params(wqe, sq->pc, sq->sqn, &priv_rx->crypto_info,
15009f83569SMaxim Mikityanskiy 				       mlx5e_tir_get_tirn(&priv_rx->tir),
151f741db1aSJianbo Liu 				       mlx5_crypto_dek_get_id(priv_rx->dek),
152f741db1aSJianbo Liu 				       priv_rx->resync.seq, false,
1531182f365STariq Toukan 				       TLS_OFFLOAD_CTX_DIR_RX);
1541182f365STariq Toukan 	wi = (struct mlx5e_icosq_wqe_info) {
1551182f365STariq Toukan 		.wqe_type = MLX5E_ICOSQ_WQE_UMR_TLS,
1561182f365STariq Toukan 		.num_wqebbs = num_wqebbs,
1571182f365STariq Toukan 		.tls_set_params.priv_rx = priv_rx,
1581182f365STariq Toukan 	};
1591182f365STariq Toukan 	icosq_fill_wi(sq, pi, &wi);
1601182f365STariq Toukan 	sq->pc += num_wqebbs;
1611182f365STariq Toukan 
1621182f365STariq Toukan 	return &wqe->ctrl;
1631182f365STariq Toukan }
1641182f365STariq Toukan 
1651182f365STariq Toukan static struct mlx5_wqe_ctrl_seg *
post_progress_params(struct mlx5e_icosq * sq,struct mlx5e_ktls_offload_context_rx * priv_rx,u32 next_record_tcp_sn)1661182f365STariq Toukan post_progress_params(struct mlx5e_icosq *sq,
1671182f365STariq Toukan 		     struct mlx5e_ktls_offload_context_rx *priv_rx,
1681182f365STariq Toukan 		     u32 next_record_tcp_sn)
1691182f365STariq Toukan {
1701182f365STariq Toukan 	struct mlx5e_set_tls_progress_params_wqe *wqe;
1711182f365STariq Toukan 	struct mlx5e_icosq_wqe_info wi;
1723ff3874fSTariq Toukan 	u16 pi, num_wqebbs;
1731182f365STariq Toukan 
1741182f365STariq Toukan 	num_wqebbs = MLX5E_TLS_SET_PROGRESS_PARAMS_WQEBBS;
1753ff3874fSTariq Toukan 	if (unlikely(!mlx5e_icosq_can_post_wqe(sq, num_wqebbs)))
1761182f365STariq Toukan 		return ERR_PTR(-ENOSPC);
1771182f365STariq Toukan 
1781182f365STariq Toukan 	pi = mlx5e_icosq_get_next_pi(sq, num_wqebbs);
1791182f365STariq Toukan 	wqe = MLX5E_TLS_FETCH_SET_PROGRESS_PARAMS_WQE(sq, pi);
18009f83569SMaxim Mikityanskiy 	mlx5e_ktls_build_progress_params(wqe, sq->pc, sq->sqn,
18109f83569SMaxim Mikityanskiy 					 mlx5e_tir_get_tirn(&priv_rx->tir),
18209f83569SMaxim Mikityanskiy 					 false, next_record_tcp_sn,
1831182f365STariq Toukan 					 TLS_OFFLOAD_CTX_DIR_RX);
1841182f365STariq Toukan 	wi = (struct mlx5e_icosq_wqe_info) {
1851182f365STariq Toukan 		.wqe_type = MLX5E_ICOSQ_WQE_SET_PSV_TLS,
1861182f365STariq Toukan 		.num_wqebbs = num_wqebbs,
1871182f365STariq Toukan 		.tls_set_params.priv_rx = priv_rx,
1881182f365STariq Toukan 	};
1891182f365STariq Toukan 
1901182f365STariq Toukan 	icosq_fill_wi(sq, pi, &wi);
1911182f365STariq Toukan 	sq->pc += num_wqebbs;
1921182f365STariq Toukan 
1931182f365STariq Toukan 	return &wqe->ctrl;
1941182f365STariq Toukan }
1951182f365STariq Toukan 
post_rx_param_wqes(struct mlx5e_channel * c,struct mlx5e_ktls_offload_context_rx * priv_rx,u32 next_record_tcp_sn)1961182f365STariq Toukan static int post_rx_param_wqes(struct mlx5e_channel *c,
1971182f365STariq Toukan 			      struct mlx5e_ktls_offload_context_rx *priv_rx,
1981182f365STariq Toukan 			      u32 next_record_tcp_sn)
1991182f365STariq Toukan {
2001182f365STariq Toukan 	struct mlx5_wqe_ctrl_seg *cseg;
2011182f365STariq Toukan 	struct mlx5e_icosq *sq;
2021182f365STariq Toukan 	int err;
2031182f365STariq Toukan 
2041182f365STariq Toukan 	err = 0;
2051182f365STariq Toukan 	sq = &c->async_icosq;
206f42139baSMaxim Mikityanskiy 	spin_lock_bh(&c->async_icosq_lock);
2071182f365STariq Toukan 
2081182f365STariq Toukan 	cseg = post_static_params(sq, priv_rx);
2091182f365STariq Toukan 	if (IS_ERR(cseg))
2101182f365STariq Toukan 		goto err_out;
2111182f365STariq Toukan 	cseg = post_progress_params(sq, priv_rx, next_record_tcp_sn);
2121182f365STariq Toukan 	if (IS_ERR(cseg))
2131182f365STariq Toukan 		goto err_out;
2141182f365STariq Toukan 
2151182f365STariq Toukan 	mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, cseg);
2161182f365STariq Toukan unlock:
217f42139baSMaxim Mikityanskiy 	spin_unlock_bh(&c->async_icosq_lock);
2181182f365STariq Toukan 
2191182f365STariq Toukan 	return err;
2201182f365STariq Toukan 
2211182f365STariq Toukan err_out:
2226f4fdd53STariq Toukan 	priv_rx->rq_stats->tls_resync_req_skip++;
2231182f365STariq Toukan 	err = PTR_ERR(cseg);
2241182f365STariq Toukan 	complete(&priv_rx->add_ctx);
2251182f365STariq Toukan 	goto unlock;
2261182f365STariq Toukan }
2271182f365STariq Toukan 
2281182f365STariq Toukan static void
mlx5e_set_ktls_rx_priv_ctx(struct tls_context * tls_ctx,struct mlx5e_ktls_offload_context_rx * priv_rx)2291182f365STariq Toukan mlx5e_set_ktls_rx_priv_ctx(struct tls_context *tls_ctx,
2301182f365STariq Toukan 			   struct mlx5e_ktls_offload_context_rx *priv_rx)
2311182f365STariq Toukan {
2321182f365STariq Toukan 	struct mlx5e_ktls_offload_context_rx **ctx =
2331182f365STariq Toukan 		__tls_driver_ctx(tls_ctx, TLS_OFFLOAD_CTX_DIR_RX);
2341182f365STariq Toukan 
2352ec6cf9bSTariq Toukan 	BUILD_BUG_ON(sizeof(priv_rx) > TLS_DRIVER_STATE_SIZE_RX);
2361182f365STariq Toukan 
2371182f365STariq Toukan 	*ctx = priv_rx;
2381182f365STariq Toukan }
2391182f365STariq Toukan 
2401182f365STariq Toukan static struct mlx5e_ktls_offload_context_rx *
mlx5e_get_ktls_rx_priv_ctx(struct tls_context * tls_ctx)2411182f365STariq Toukan mlx5e_get_ktls_rx_priv_ctx(struct tls_context *tls_ctx)
2421182f365STariq Toukan {
2431182f365STariq Toukan 	struct mlx5e_ktls_offload_context_rx **ctx =
2441182f365STariq Toukan 		__tls_driver_ctx(tls_ctx, TLS_OFFLOAD_CTX_DIR_RX);
2451182f365STariq Toukan 
2461182f365STariq Toukan 	return *ctx;
2471182f365STariq Toukan }
2481182f365STariq Toukan 
2490419d8c9STariq Toukan /* Re-sync */
2500419d8c9STariq Toukan /* Runs in work context */
25194c4fed7SSaeed Mahameed static int
resync_post_get_progress_params(struct mlx5e_icosq * sq,struct mlx5e_ktls_offload_context_rx * priv_rx)2520419d8c9STariq Toukan resync_post_get_progress_params(struct mlx5e_icosq *sq,
2530419d8c9STariq Toukan 				struct mlx5e_ktls_offload_context_rx *priv_rx)
2540419d8c9STariq Toukan {
2550419d8c9STariq Toukan 	struct mlx5e_get_tls_progress_params_wqe *wqe;
2560419d8c9STariq Toukan 	struct mlx5e_ktls_rx_resync_buf *buf;
2570419d8c9STariq Toukan 	struct mlx5e_icosq_wqe_info wi;
2580419d8c9STariq Toukan 	struct mlx5_wqe_ctrl_seg *cseg;
2590419d8c9STariq Toukan 	struct mlx5_seg_get_psv *psv;
2600419d8c9STariq Toukan 	struct device *pdev;
2610419d8c9STariq Toukan 	int err;
2620419d8c9STariq Toukan 	u16 pi;
2630419d8c9STariq Toukan 
2640419d8c9STariq Toukan 	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
2650419d8c9STariq Toukan 	if (unlikely(!buf)) {
2660419d8c9STariq Toukan 		err = -ENOMEM;
2670419d8c9STariq Toukan 		goto err_out;
2680419d8c9STariq Toukan 	}
2690419d8c9STariq Toukan 
2707be3412aSParav Pandit 	pdev = mlx5_core_dma_dev(sq->channel->priv->mdev);
2710419d8c9STariq Toukan 	buf->dma_addr = dma_map_single(pdev, &buf->progress,
2720419d8c9STariq Toukan 				       PROGRESS_PARAMS_PADDED_SIZE, DMA_FROM_DEVICE);
2730419d8c9STariq Toukan 	if (unlikely(dma_mapping_error(pdev, buf->dma_addr))) {
2740419d8c9STariq Toukan 		err = -ENOMEM;
275581642f3SSaeed Mahameed 		goto err_free;
2760419d8c9STariq Toukan 	}
2770419d8c9STariq Toukan 
2780419d8c9STariq Toukan 	buf->priv_rx = priv_rx;
2790419d8c9STariq Toukan 
280f42139baSMaxim Mikityanskiy 	spin_lock_bh(&sq->channel->async_icosq_lock);
28194c4fed7SSaeed Mahameed 
2823ff3874fSTariq Toukan 	if (unlikely(!mlx5e_icosq_can_post_wqe(sq, MLX5E_KTLS_GET_PROGRESS_WQEBBS))) {
283f42139baSMaxim Mikityanskiy 		spin_unlock_bh(&sq->channel->async_icosq_lock);
2840419d8c9STariq Toukan 		err = -ENOSPC;
285581642f3SSaeed Mahameed 		goto err_dma_unmap;
2860419d8c9STariq Toukan 	}
2870419d8c9STariq Toukan 
2883ff3874fSTariq Toukan 	pi = mlx5e_icosq_get_next_pi(sq, MLX5E_KTLS_GET_PROGRESS_WQEBBS);
2890419d8c9STariq Toukan 	wqe = MLX5E_TLS_FETCH_GET_PROGRESS_PARAMS_WQE(sq, pi);
2900419d8c9STariq Toukan 
2910419d8c9STariq Toukan #define GET_PSV_DS_CNT (DIV_ROUND_UP(sizeof(*wqe), MLX5_SEND_WQE_DS))
2920419d8c9STariq Toukan 
2930419d8c9STariq Toukan 	cseg = &wqe->ctrl;
2940419d8c9STariq Toukan 	cseg->opmod_idx_opcode =
2950419d8c9STariq Toukan 		cpu_to_be32((sq->pc << 8) | MLX5_OPCODE_GET_PSV |
2960419d8c9STariq Toukan 			    (MLX5_OPC_MOD_TLS_TIR_PROGRESS_PARAMS << 24));
2970419d8c9STariq Toukan 	cseg->qpn_ds =
2980419d8c9STariq Toukan 		cpu_to_be32((sq->sqn << MLX5_WQE_CTRL_QPN_SHIFT) | GET_PSV_DS_CNT);
2990419d8c9STariq Toukan 
3000419d8c9STariq Toukan 	psv = &wqe->psv;
3010419d8c9STariq Toukan 	psv->num_psv      = 1 << 4;
3020419d8c9STariq Toukan 	psv->l_key        = sq->channel->mkey_be;
30309f83569SMaxim Mikityanskiy 	psv->psv_index[0] = cpu_to_be32(mlx5e_tir_get_tirn(&priv_rx->tir));
3040419d8c9STariq Toukan 	psv->va           = cpu_to_be64(buf->dma_addr);
3050419d8c9STariq Toukan 
3060419d8c9STariq Toukan 	wi = (struct mlx5e_icosq_wqe_info) {
3070419d8c9STariq Toukan 		.wqe_type = MLX5E_ICOSQ_WQE_GET_PSV_TLS,
3083ff3874fSTariq Toukan 		.num_wqebbs = MLX5E_KTLS_GET_PROGRESS_WQEBBS,
3090419d8c9STariq Toukan 		.tls_get_params.buf = buf,
3100419d8c9STariq Toukan 	};
3110419d8c9STariq Toukan 	icosq_fill_wi(sq, pi, &wi);
3120419d8c9STariq Toukan 	sq->pc++;
31394c4fed7SSaeed Mahameed 	mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, cseg);
314f42139baSMaxim Mikityanskiy 	spin_unlock_bh(&sq->channel->async_icosq_lock);
3150419d8c9STariq Toukan 
31694c4fed7SSaeed Mahameed 	return 0;
3170419d8c9STariq Toukan 
318581642f3SSaeed Mahameed err_dma_unmap:
319581642f3SSaeed Mahameed 	dma_unmap_single(pdev, buf->dma_addr, PROGRESS_PARAMS_PADDED_SIZE, DMA_FROM_DEVICE);
320581642f3SSaeed Mahameed err_free:
321581642f3SSaeed Mahameed 	kfree(buf);
3220419d8c9STariq Toukan err_out:
3236f4fdd53STariq Toukan 	priv_rx->rq_stats->tls_resync_req_skip++;
32494c4fed7SSaeed Mahameed 	return err;
3250419d8c9STariq Toukan }
3260419d8c9STariq Toukan 
3270419d8c9STariq Toukan /* Function is called with elevated refcount.
3280419d8c9STariq Toukan  * It decreases it only if no WQE is posted.
3290419d8c9STariq Toukan  */
resync_handle_work(struct work_struct * work)3300419d8c9STariq Toukan static void resync_handle_work(struct work_struct *work)
3310419d8c9STariq Toukan {
3320419d8c9STariq Toukan 	struct mlx5e_ktls_offload_context_rx *priv_rx;
3330419d8c9STariq Toukan 	struct mlx5e_ktls_rx_resync_ctx *resync;
3340419d8c9STariq Toukan 	struct mlx5e_channel *c;
3350419d8c9STariq Toukan 	struct mlx5e_icosq *sq;
3360419d8c9STariq Toukan 
3370419d8c9STariq Toukan 	resync = container_of(work, struct mlx5e_ktls_rx_resync_ctx, work);
3380419d8c9STariq Toukan 	priv_rx = container_of(resync, struct mlx5e_ktls_offload_context_rx, resync);
3390419d8c9STariq Toukan 
3400419d8c9STariq Toukan 	if (unlikely(test_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags))) {
341b850bbffSMaxim Mikityanskiy 		mlx5e_ktls_priv_rx_put(priv_rx);
3420419d8c9STariq Toukan 		return;
3430419d8c9STariq Toukan 	}
3440419d8c9STariq Toukan 
3450419d8c9STariq Toukan 	c = resync->priv->channels.c[priv_rx->rxq];
3460419d8c9STariq Toukan 	sq = &c->async_icosq;
3470419d8c9STariq Toukan 
34894c4fed7SSaeed Mahameed 	if (resync_post_get_progress_params(sq, priv_rx))
349b850bbffSMaxim Mikityanskiy 		mlx5e_ktls_priv_rx_put(priv_rx);
3500419d8c9STariq Toukan }
3510419d8c9STariq Toukan 
resync_init(struct mlx5e_ktls_rx_resync_ctx * resync,struct mlx5e_priv * priv)3520419d8c9STariq Toukan static void resync_init(struct mlx5e_ktls_rx_resync_ctx *resync,
3530419d8c9STariq Toukan 			struct mlx5e_priv *priv)
3540419d8c9STariq Toukan {
3550419d8c9STariq Toukan 	INIT_WORK(&resync->work, resync_handle_work);
3560419d8c9STariq Toukan 	resync->priv = priv;
3570419d8c9STariq Toukan 	refcount_set(&resync->refcnt, 1);
3580419d8c9STariq Toukan }
3590419d8c9STariq Toukan 
3600419d8c9STariq Toukan /* Function can be called with the refcount being either elevated or not.
3610419d8c9STariq Toukan  * It does not affect the refcount.
3620419d8c9STariq Toukan  */
resync_handle_seq_match(struct mlx5e_ktls_offload_context_rx * priv_rx,struct mlx5e_channel * c)363e9ce991bSTariq Toukan static void resync_handle_seq_match(struct mlx5e_ktls_offload_context_rx *priv_rx,
3640419d8c9STariq Toukan 				    struct mlx5e_channel *c)
3650419d8c9STariq Toukan {
366e9ce991bSTariq Toukan 	struct mlx5e_ktls_resync_resp *ktls_resync;
3670419d8c9STariq Toukan 	struct mlx5e_icosq *sq;
368e9ce991bSTariq Toukan 	bool trigger_poll;
3690419d8c9STariq Toukan 
3700419d8c9STariq Toukan 	sq = &c->async_icosq;
371e9ce991bSTariq Toukan 	ktls_resync = sq->ktls_resync;
372cc4a9cc0STariq Toukan 	trigger_poll = false;
373e9ce991bSTariq Toukan 
374e9ce991bSTariq Toukan 	spin_lock_bh(&ktls_resync->lock);
375cc4a9cc0STariq Toukan 	spin_lock_bh(&priv_rx->lock);
3764960c414SGal Pressman 	switch (priv_rx->crypto_info.crypto_info.cipher_type) {
3774960c414SGal Pressman 	case TLS_CIPHER_AES_GCM_128: {
3784960c414SGal Pressman 		struct tls12_crypto_info_aes_gcm_128 *info =
3794960c414SGal Pressman 			&priv_rx->crypto_info.crypto_info_128;
3804960c414SGal Pressman 
3814960c414SGal Pressman 		memcpy(info->rec_seq, &priv_rx->resync.sw_rcd_sn_be,
3824960c414SGal Pressman 		       sizeof(info->rec_seq));
3834960c414SGal Pressman 		break;
3844960c414SGal Pressman 	}
3854960c414SGal Pressman 	case TLS_CIPHER_AES_GCM_256: {
3864960c414SGal Pressman 		struct tls12_crypto_info_aes_gcm_256 *info =
3874960c414SGal Pressman 			&priv_rx->crypto_info.crypto_info_256;
3884960c414SGal Pressman 
3894960c414SGal Pressman 		memcpy(info->rec_seq, &priv_rx->resync.sw_rcd_sn_be,
3904960c414SGal Pressman 		       sizeof(info->rec_seq));
3914960c414SGal Pressman 		break;
3924960c414SGal Pressman 	}
3934960c414SGal Pressman 	default:
3944960c414SGal Pressman 		WARN_ONCE(1, "Unsupported cipher type %u\n",
3954960c414SGal Pressman 			  priv_rx->crypto_info.crypto_info.cipher_type);
3964960c414SGal Pressman 		spin_unlock_bh(&priv_rx->lock);
3974960c414SGal Pressman 		spin_unlock_bh(&ktls_resync->lock);
3984960c414SGal Pressman 		return;
3994960c414SGal Pressman 	}
4004960c414SGal Pressman 
401cc4a9cc0STariq Toukan 	if (list_empty(&priv_rx->list)) {
402e9ce991bSTariq Toukan 		list_add_tail(&priv_rx->list, &ktls_resync->list);
403e9ce991bSTariq Toukan 		trigger_poll = !test_and_set_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &sq->state);
404cc4a9cc0STariq Toukan 	}
405cc4a9cc0STariq Toukan 	spin_unlock_bh(&priv_rx->lock);
406e9ce991bSTariq Toukan 	spin_unlock_bh(&ktls_resync->lock);
407e9ce991bSTariq Toukan 
408e9ce991bSTariq Toukan 	if (!trigger_poll)
409e9ce991bSTariq Toukan 		return;
410e9ce991bSTariq Toukan 
411e9ce991bSTariq Toukan 	if (!napi_if_scheduled_mark_missed(&c->napi)) {
412f42139baSMaxim Mikityanskiy 		spin_lock_bh(&c->async_icosq_lock);
413e9ce991bSTariq Toukan 		mlx5e_trigger_irq(sq);
414f42139baSMaxim Mikityanskiy 		spin_unlock_bh(&c->async_icosq_lock);
415e9ce991bSTariq Toukan 	}
4160419d8c9STariq Toukan }
4170419d8c9STariq Toukan 
418b850bbffSMaxim Mikityanskiy /* Function can be called with the refcount being either elevated or not.
419b850bbffSMaxim Mikityanskiy  * It decreases the refcount and may free the kTLS priv context.
420b850bbffSMaxim Mikityanskiy  * Refcount is not elevated only if tls_dev_del has been called, but GET_PSV was
421b850bbffSMaxim Mikityanskiy  * already in flight.
422b850bbffSMaxim Mikityanskiy  */
mlx5e_ktls_handle_get_psv_completion(struct mlx5e_icosq_wqe_info * wi,struct mlx5e_icosq * sq)4230419d8c9STariq Toukan void mlx5e_ktls_handle_get_psv_completion(struct mlx5e_icosq_wqe_info *wi,
4240419d8c9STariq Toukan 					  struct mlx5e_icosq *sq)
4250419d8c9STariq Toukan {
4260419d8c9STariq Toukan 	struct mlx5e_ktls_rx_resync_buf *buf = wi->tls_get_params.buf;
4270419d8c9STariq Toukan 	struct mlx5e_ktls_offload_context_rx *priv_rx;
4280419d8c9STariq Toukan 	struct mlx5e_ktls_rx_resync_ctx *resync;
4290419d8c9STariq Toukan 	u8 tracker_state, auth_state, *ctx;
43066ce5fc0SSaeed Mahameed 	struct device *dev;
4310419d8c9STariq Toukan 	u32 hw_seq;
4320419d8c9STariq Toukan 
4330419d8c9STariq Toukan 	priv_rx = buf->priv_rx;
4340419d8c9STariq Toukan 	resync = &priv_rx->resync;
4357be3412aSParav Pandit 	dev = mlx5_core_dma_dev(resync->priv->mdev);
4360419d8c9STariq Toukan 	if (unlikely(test_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags)))
4370419d8c9STariq Toukan 		goto out;
4380419d8c9STariq Toukan 
43966ce5fc0SSaeed Mahameed 	dma_sync_single_for_cpu(dev, buf->dma_addr, PROGRESS_PARAMS_PADDED_SIZE,
44066ce5fc0SSaeed Mahameed 				DMA_FROM_DEVICE);
4410419d8c9STariq Toukan 
4420419d8c9STariq Toukan 	ctx = buf->progress.ctx;
4430419d8c9STariq Toukan 	tracker_state = MLX5_GET(tls_progress_params, ctx, record_tracker_state);
4440419d8c9STariq Toukan 	auth_state = MLX5_GET(tls_progress_params, ctx, auth_state);
4450419d8c9STariq Toukan 	if (tracker_state != MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_TRACKING ||
44676c1e1acSTariq Toukan 	    auth_state != MLX5E_TLS_PROGRESS_PARAMS_AUTH_STATE_NO_OFFLOAD) {
4476f4fdd53STariq Toukan 		priv_rx->rq_stats->tls_resync_req_skip++;
4480419d8c9STariq Toukan 		goto out;
44976c1e1acSTariq Toukan 	}
4500419d8c9STariq Toukan 
4510419d8c9STariq Toukan 	hw_seq = MLX5_GET(tls_progress_params, ctx, hw_resync_tcp_sn);
4520419d8c9STariq Toukan 	tls_offload_rx_resync_async_request_end(priv_rx->sk, cpu_to_be32(hw_seq));
4536f4fdd53STariq Toukan 	priv_rx->rq_stats->tls_resync_req_end++;
4540419d8c9STariq Toukan out:
455b850bbffSMaxim Mikityanskiy 	mlx5e_ktls_priv_rx_put(priv_rx);
45666ce5fc0SSaeed Mahameed 	dma_unmap_single(dev, buf->dma_addr, PROGRESS_PARAMS_PADDED_SIZE, DMA_FROM_DEVICE);
4570419d8c9STariq Toukan 	kfree(buf);
4580419d8c9STariq Toukan }
4590419d8c9STariq Toukan 
4600419d8c9STariq Toukan /* Runs in NAPI.
4610419d8c9STariq Toukan  * Function elevates the refcount, unless no work is queued.
4620419d8c9STariq Toukan  */
resync_queue_get_psv(struct sock * sk)4630419d8c9STariq Toukan static bool resync_queue_get_psv(struct sock *sk)
4640419d8c9STariq Toukan {
4650419d8c9STariq Toukan 	struct mlx5e_ktls_offload_context_rx *priv_rx;
4660419d8c9STariq Toukan 	struct mlx5e_ktls_rx_resync_ctx *resync;
4670419d8c9STariq Toukan 
4680419d8c9STariq Toukan 	priv_rx = mlx5e_get_ktls_rx_priv_ctx(tls_get_ctx(sk));
4690419d8c9STariq Toukan 	if (unlikely(!priv_rx))
4700419d8c9STariq Toukan 		return false;
4710419d8c9STariq Toukan 
4720419d8c9STariq Toukan 	if (unlikely(test_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags)))
4730419d8c9STariq Toukan 		return false;
4740419d8c9STariq Toukan 
4750419d8c9STariq Toukan 	resync = &priv_rx->resync;
476b850bbffSMaxim Mikityanskiy 	mlx5e_ktls_priv_rx_get(priv_rx);
4770419d8c9STariq Toukan 	if (unlikely(!queue_work(resync->priv->tls->rx_wq, &resync->work)))
478b850bbffSMaxim Mikityanskiy 		mlx5e_ktls_priv_rx_put(priv_rx);
4790419d8c9STariq Toukan 
4800419d8c9STariq Toukan 	return true;
4810419d8c9STariq Toukan }
4820419d8c9STariq Toukan 
4830419d8c9STariq Toukan /* Runs in NAPI */
resync_update_sn(struct mlx5e_rq * rq,struct sk_buff * skb)4840419d8c9STariq Toukan static void resync_update_sn(struct mlx5e_rq *rq, struct sk_buff *skb)
4850419d8c9STariq Toukan {
4860419d8c9STariq Toukan 	struct ethhdr *eth = (struct ethhdr *)(skb->data);
4870419d8c9STariq Toukan 	struct net_device *netdev = rq->netdev;
4884461568aSKuniyuki Iwashima 	struct net *net = dev_net(netdev);
4890419d8c9STariq Toukan 	struct sock *sk = NULL;
4900419d8c9STariq Toukan 	unsigned int datalen;
4910419d8c9STariq Toukan 	struct iphdr *iph;
4920419d8c9STariq Toukan 	struct tcphdr *th;
4930419d8c9STariq Toukan 	__be32 seq;
4940419d8c9STariq Toukan 	int depth = 0;
4950419d8c9STariq Toukan 
4960419d8c9STariq Toukan 	__vlan_get_protocol(skb, eth->h_proto, &depth);
4970419d8c9STariq Toukan 	iph = (struct iphdr *)(skb->data + depth);
4980419d8c9STariq Toukan 
4990419d8c9STariq Toukan 	if (iph->version == 4) {
5000419d8c9STariq Toukan 		depth += sizeof(struct iphdr);
5010419d8c9STariq Toukan 		th = (void *)iph + sizeof(struct iphdr);
5020419d8c9STariq Toukan 
5034461568aSKuniyuki Iwashima 		sk = inet_lookup_established(net, net->ipv4.tcp_death_row.hashinfo,
5040419d8c9STariq Toukan 					     iph->saddr, th->source, iph->daddr,
5050419d8c9STariq Toukan 					     th->dest, netdev->ifindex);
5060419d8c9STariq Toukan #if IS_ENABLED(CONFIG_IPV6)
5070419d8c9STariq Toukan 	} else {
5080419d8c9STariq Toukan 		struct ipv6hdr *ipv6h = (struct ipv6hdr *)iph;
5090419d8c9STariq Toukan 
5100419d8c9STariq Toukan 		depth += sizeof(struct ipv6hdr);
5110419d8c9STariq Toukan 		th = (void *)ipv6h + sizeof(struct ipv6hdr);
5120419d8c9STariq Toukan 
5134461568aSKuniyuki Iwashima 		sk = __inet6_lookup_established(net, net->ipv4.tcp_death_row.hashinfo,
5140419d8c9STariq Toukan 						&ipv6h->saddr, th->source,
5150419d8c9STariq Toukan 						&ipv6h->daddr, ntohs(th->dest),
5160419d8c9STariq Toukan 						netdev->ifindex, 0);
5170419d8c9STariq Toukan #endif
5180419d8c9STariq Toukan 	}
5190419d8c9STariq Toukan 
5200419d8c9STariq Toukan 	depth += sizeof(struct tcphdr);
5210419d8c9STariq Toukan 
522ea636098SMaxim Mikityanskiy 	if (unlikely(!sk))
5230419d8c9STariq Toukan 		return;
5240419d8c9STariq Toukan 
525ea636098SMaxim Mikityanskiy 	if (unlikely(sk->sk_state == TCP_TIME_WAIT))
526ea636098SMaxim Mikityanskiy 		goto unref;
527ea636098SMaxim Mikityanskiy 
5280419d8c9STariq Toukan 	if (unlikely(!resync_queue_get_psv(sk)))
529ea636098SMaxim Mikityanskiy 		goto unref;
5300419d8c9STariq Toukan 
5310419d8c9STariq Toukan 	seq = th->seq;
5320419d8c9STariq Toukan 	datalen = skb->len - depth;
5330419d8c9STariq Toukan 	tls_offload_rx_resync_async_request_start(sk, seq, datalen);
53476c1e1acSTariq Toukan 	rq->stats->tls_resync_req_start++;
535ea636098SMaxim Mikityanskiy 
536ea636098SMaxim Mikityanskiy unref:
537ea636098SMaxim Mikityanskiy 	sock_gen_put(sk);
5380419d8c9STariq Toukan }
5390419d8c9STariq Toukan 
mlx5e_ktls_rx_resync(struct net_device * netdev,struct sock * sk,u32 seq,u8 * rcd_sn)5400419d8c9STariq Toukan void mlx5e_ktls_rx_resync(struct net_device *netdev, struct sock *sk,
5410419d8c9STariq Toukan 			  u32 seq, u8 *rcd_sn)
5420419d8c9STariq Toukan {
5430419d8c9STariq Toukan 	struct mlx5e_ktls_offload_context_rx *priv_rx;
5440419d8c9STariq Toukan 	struct mlx5e_ktls_rx_resync_ctx *resync;
5450419d8c9STariq Toukan 	struct mlx5e_priv *priv;
5460419d8c9STariq Toukan 	struct mlx5e_channel *c;
5470419d8c9STariq Toukan 
5480419d8c9STariq Toukan 	priv_rx = mlx5e_get_ktls_rx_priv_ctx(tls_get_ctx(sk));
5490419d8c9STariq Toukan 	if (unlikely(!priv_rx))
5500419d8c9STariq Toukan 		return;
5510419d8c9STariq Toukan 
5520419d8c9STariq Toukan 	resync = &priv_rx->resync;
5530419d8c9STariq Toukan 	resync->sw_rcd_sn_be = *(__be64 *)rcd_sn;
5540419d8c9STariq Toukan 	resync->seq = seq;
5550419d8c9STariq Toukan 
5560419d8c9STariq Toukan 	priv = netdev_priv(netdev);
5570419d8c9STariq Toukan 	c = priv->channels.c[priv_rx->rxq];
5580419d8c9STariq Toukan 
5590419d8c9STariq Toukan 	resync_handle_seq_match(priv_rx, c);
5600419d8c9STariq Toukan }
5610419d8c9STariq Toukan 
5620419d8c9STariq Toukan /* End of resync section */
5630419d8c9STariq Toukan 
mlx5e_ktls_handle_rx_skb(struct mlx5e_rq * rq,struct sk_buff * skb,struct mlx5_cqe64 * cqe,u32 * cqe_bcnt)5641182f365STariq Toukan void mlx5e_ktls_handle_rx_skb(struct mlx5e_rq *rq, struct sk_buff *skb,
5651182f365STariq Toukan 			      struct mlx5_cqe64 *cqe, u32 *cqe_bcnt)
5661182f365STariq Toukan {
567a2907436STariq Toukan 	struct mlx5e_rq_stats *stats = rq->stats;
5681182f365STariq Toukan 
569a2907436STariq Toukan 	switch (get_cqe_tls_offload(cqe)) {
5701182f365STariq Toukan 	case CQE_TLS_OFFLOAD_DECRYPTED:
5711182f365STariq Toukan 		skb->decrypted = 1;
57276c1e1acSTariq Toukan 		stats->tls_decrypted_packets++;
57376c1e1acSTariq Toukan 		stats->tls_decrypted_bytes += *cqe_bcnt;
5741182f365STariq Toukan 		break;
5751182f365STariq Toukan 	case CQE_TLS_OFFLOAD_RESYNC:
57676c1e1acSTariq Toukan 		stats->tls_resync_req_pkt++;
5770419d8c9STariq Toukan 		resync_update_sn(rq, skb);
5781182f365STariq Toukan 		break;
5791182f365STariq Toukan 	default: /* CQE_TLS_OFFLOAD_ERROR: */
58076c1e1acSTariq Toukan 		stats->tls_err++;
5811182f365STariq Toukan 		break;
5821182f365STariq Toukan 	}
5831182f365STariq Toukan }
5841182f365STariq Toukan 
mlx5e_ktls_handle_ctx_completion(struct mlx5e_icosq_wqe_info * wi)5851182f365STariq Toukan void mlx5e_ktls_handle_ctx_completion(struct mlx5e_icosq_wqe_info *wi)
5861182f365STariq Toukan {
5871182f365STariq Toukan 	struct mlx5e_ktls_offload_context_rx *priv_rx = wi->tls_set_params.priv_rx;
5881182f365STariq Toukan 	struct accel_rule *rule = &priv_rx->rule;
5891182f365STariq Toukan 
5901182f365STariq Toukan 	if (unlikely(test_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags))) {
5911182f365STariq Toukan 		complete(&priv_rx->add_ctx);
5921182f365STariq Toukan 		return;
5931182f365STariq Toukan 	}
5941182f365STariq Toukan 	queue_work(rule->priv->tls->rx_wq, &rule->work);
5951182f365STariq Toukan }
5961182f365STariq Toukan 
mlx5e_ktls_sk_get_rxq(struct sock * sk)5978b5ec43dSSaeed Mahameed static int mlx5e_ktls_sk_get_rxq(struct sock *sk)
5988b5ec43dSSaeed Mahameed {
5998b5ec43dSSaeed Mahameed 	int rxq = sk_rx_queue_get(sk);
6008b5ec43dSSaeed Mahameed 
6018b5ec43dSSaeed Mahameed 	if (unlikely(rxq == -1))
6028b5ec43dSSaeed Mahameed 		rxq = 0;
6038b5ec43dSSaeed Mahameed 
6048b5ec43dSSaeed Mahameed 	return rxq;
6058b5ec43dSSaeed Mahameed }
6068b5ec43dSSaeed Mahameed 
mlx5e_ktls_add_rx(struct net_device * netdev,struct sock * sk,struct tls_crypto_info * crypto_info,u32 start_offload_tcp_sn)6071182f365STariq Toukan int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk,
6081182f365STariq Toukan 		      struct tls_crypto_info *crypto_info,
6091182f365STariq Toukan 		      u32 start_offload_tcp_sn)
6101182f365STariq Toukan {
6111182f365STariq Toukan 	struct mlx5e_ktls_offload_context_rx *priv_rx;
6120419d8c9STariq Toukan 	struct mlx5e_ktls_rx_resync_ctx *resync;
6131182f365STariq Toukan 	struct tls_context *tls_ctx;
614f741db1aSJianbo Liu 	struct mlx5_crypto_dek *dek;
6151182f365STariq Toukan 	struct mlx5e_priv *priv;
6161182f365STariq Toukan 	int rxq, err;
6171182f365STariq Toukan 
6181182f365STariq Toukan 	tls_ctx = tls_get_ctx(sk);
6191182f365STariq Toukan 	priv = netdev_priv(netdev);
6201182f365STariq Toukan 	priv_rx = kzalloc(sizeof(*priv_rx), GFP_KERNEL);
6211182f365STariq Toukan 	if (unlikely(!priv_rx))
6221182f365STariq Toukan 		return -ENOMEM;
6231182f365STariq Toukan 
6244960c414SGal Pressman 	switch (crypto_info->cipher_type) {
6254960c414SGal Pressman 	case TLS_CIPHER_AES_GCM_128:
6264960c414SGal Pressman 		priv_rx->crypto_info.crypto_info_128 =
6271182f365STariq Toukan 			*(struct tls12_crypto_info_aes_gcm_128 *)crypto_info;
6284960c414SGal Pressman 		break;
6294960c414SGal Pressman 	case TLS_CIPHER_AES_GCM_256:
6304960c414SGal Pressman 		priv_rx->crypto_info.crypto_info_256 =
6314960c414SGal Pressman 			*(struct tls12_crypto_info_aes_gcm_256 *)crypto_info;
6324960c414SGal Pressman 		break;
6334960c414SGal Pressman 	default:
6344960c414SGal Pressman 		WARN_ONCE(1, "Unsupported cipher type %u\n",
6354960c414SGal Pressman 			  crypto_info->cipher_type);
636*dd645724SGal Pressman 		err = -EOPNOTSUPP;
637*dd645724SGal Pressman 		goto err_cipher_type;
6384960c414SGal Pressman 	}
6391182f365STariq Toukan 
640*dd645724SGal Pressman 	dek = mlx5_ktls_create_key(priv->tls->dek_pool, crypto_info);
641*dd645724SGal Pressman 	if (IS_ERR(dek)) {
642*dd645724SGal Pressman 		err = PTR_ERR(dek);
643*dd645724SGal Pressman 		goto err_cipher_type;
644*dd645724SGal Pressman 	}
645*dd645724SGal Pressman 	priv_rx->dek = dek;
646*dd645724SGal Pressman 
647*dd645724SGal Pressman 	INIT_LIST_HEAD(&priv_rx->list);
648*dd645724SGal Pressman 	spin_lock_init(&priv_rx->lock);
649*dd645724SGal Pressman 
6508b5ec43dSSaeed Mahameed 	rxq = mlx5e_ktls_sk_get_rxq(sk);
65176c1e1acSTariq Toukan 	priv_rx->rxq = rxq;
65276c1e1acSTariq Toukan 	priv_rx->sk = sk;
65376c1e1acSTariq Toukan 
654be98737aSTariq Toukan 	priv_rx->rq_stats = &priv->channel_stats[rxq]->rq;
6556f4fdd53STariq Toukan 	priv_rx->sw_stats = &priv->tls->sw_stats;
6561182f365STariq Toukan 	mlx5e_set_ktls_rx_priv_ctx(tls_ctx, priv_rx);
6571182f365STariq Toukan 
6584cce2ccfSTariq Toukan 	err = mlx5e_rx_res_tls_tir_create(priv->rx_res, rxq, &priv_rx->tir);
6591182f365STariq Toukan 	if (err)
6601182f365STariq Toukan 		goto err_create_tir;
6611182f365STariq Toukan 
6621182f365STariq Toukan 	init_completion(&priv_rx->add_ctx);
6630419d8c9STariq Toukan 
6648668587aSTariq Toukan 	accel_rule_init(&priv_rx->rule, priv);
6650419d8c9STariq Toukan 	resync = &priv_rx->resync;
6660419d8c9STariq Toukan 	resync_init(resync, priv);
6670419d8c9STariq Toukan 	tls_offload_ctx_rx(tls_ctx)->resync_async = &resync->core;
6680419d8c9STariq Toukan 	tls_offload_rx_resync_set_type(sk, TLS_OFFLOAD_SYNC_TYPE_DRIVER_REQ_ASYNC);
6690419d8c9STariq Toukan 
6701182f365STariq Toukan 	err = post_rx_param_wqes(priv->channels.c[rxq], priv_rx, start_offload_tcp_sn);
6711182f365STariq Toukan 	if (err)
6721182f365STariq Toukan 		goto err_post_wqes;
6731182f365STariq Toukan 
6746f4fdd53STariq Toukan 	atomic64_inc(&priv_rx->sw_stats->rx_tls_ctx);
67576c1e1acSTariq Toukan 
6761182f365STariq Toukan 	return 0;
6771182f365STariq Toukan 
6781182f365STariq Toukan err_post_wqes:
67909f83569SMaxim Mikityanskiy 	mlx5e_tir_destroy(&priv_rx->tir);
6801182f365STariq Toukan err_create_tir:
681f741db1aSJianbo Liu 	mlx5_ktls_destroy_key(priv->tls->dek_pool, priv_rx->dek);
682*dd645724SGal Pressman err_cipher_type:
6831182f365STariq Toukan 	kfree(priv_rx);
6841182f365STariq Toukan 	return err;
6851182f365STariq Toukan }
6861182f365STariq Toukan 
mlx5e_ktls_del_rx(struct net_device * netdev,struct tls_context * tls_ctx)6871182f365STariq Toukan void mlx5e_ktls_del_rx(struct net_device *netdev, struct tls_context *tls_ctx)
6881182f365STariq Toukan {
6891182f365STariq Toukan 	struct mlx5e_ktls_offload_context_rx *priv_rx;
6900419d8c9STariq Toukan 	struct mlx5e_ktls_rx_resync_ctx *resync;
6911182f365STariq Toukan 	struct mlx5e_priv *priv;
6921182f365STariq Toukan 
6931182f365STariq Toukan 	priv = netdev_priv(netdev);
6941182f365STariq Toukan 
6951182f365STariq Toukan 	priv_rx = mlx5e_get_ktls_rx_priv_ctx(tls_ctx);
6961182f365STariq Toukan 	set_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags);
6970419d8c9STariq Toukan 	mlx5e_set_ktls_rx_priv_ctx(tls_ctx, NULL);
6984d6e6b0cSMaxim Mikityanskiy 	synchronize_net(); /* Sync with NAPI */
6991182f365STariq Toukan 	if (!cancel_work_sync(&priv_rx->rule.work))
7001182f365STariq Toukan 		/* completion is needed, as the priv_rx in the add flow
7011182f365STariq Toukan 		 * is maintained on the wqe info (wi), not on the socket.
7021182f365STariq Toukan 		 */
7031182f365STariq Toukan 		wait_for_completion(&priv_rx->add_ctx);
7040419d8c9STariq Toukan 	resync = &priv_rx->resync;
7050419d8c9STariq Toukan 	if (cancel_work_sync(&resync->work))
706b850bbffSMaxim Mikityanskiy 		mlx5e_ktls_priv_rx_put(priv_rx);
7071182f365STariq Toukan 
7086f4fdd53STariq Toukan 	atomic64_inc(&priv_rx->sw_stats->rx_tls_del);
7091182f365STariq Toukan 	if (priv_rx->rule.rule)
7101182f365STariq Toukan 		mlx5e_accel_fs_del_sk(priv_rx->rule.rule);
7111182f365STariq Toukan 
71209f83569SMaxim Mikityanskiy 	mlx5e_tir_destroy(&priv_rx->tir);
713f741db1aSJianbo Liu 	mlx5_ktls_destroy_key(priv->tls->dek_pool, priv_rx->dek);
714b850bbffSMaxim Mikityanskiy 	/* priv_rx should normally be freed here, but if there is an outstanding
715b850bbffSMaxim Mikityanskiy 	 * GET_PSV, deallocation will be delayed until the CQE for GET_PSV is
716b850bbffSMaxim Mikityanskiy 	 * processed.
717b850bbffSMaxim Mikityanskiy 	 */
718b850bbffSMaxim Mikityanskiy 	mlx5e_ktls_priv_rx_put(priv_rx);
7191182f365STariq Toukan }
720e9ce991bSTariq Toukan 
mlx5e_ktls_rx_handle_resync_list(struct mlx5e_channel * c,int budget)721e9ce991bSTariq Toukan bool mlx5e_ktls_rx_handle_resync_list(struct mlx5e_channel *c, int budget)
722e9ce991bSTariq Toukan {
723e9ce991bSTariq Toukan 	struct mlx5e_ktls_offload_context_rx *priv_rx, *tmp;
724e9ce991bSTariq Toukan 	struct mlx5e_ktls_resync_resp *ktls_resync;
725e9ce991bSTariq Toukan 	struct mlx5_wqe_ctrl_seg *db_cseg;
726e9ce991bSTariq Toukan 	struct mlx5e_icosq *sq;
727e9ce991bSTariq Toukan 	LIST_HEAD(local_list);
728e9ce991bSTariq Toukan 	int i, j;
729e9ce991bSTariq Toukan 
730e9ce991bSTariq Toukan 	sq = &c->async_icosq;
731e9ce991bSTariq Toukan 
732e9ce991bSTariq Toukan 	if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)))
733e9ce991bSTariq Toukan 		return false;
734e9ce991bSTariq Toukan 
735e9ce991bSTariq Toukan 	ktls_resync = sq->ktls_resync;
736e9ce991bSTariq Toukan 	db_cseg = NULL;
737e9ce991bSTariq Toukan 	i = 0;
738e9ce991bSTariq Toukan 
739e9ce991bSTariq Toukan 	spin_lock(&ktls_resync->lock);
740e9ce991bSTariq Toukan 	list_for_each_entry_safe(priv_rx, tmp, &ktls_resync->list, list) {
741e9ce991bSTariq Toukan 		list_move(&priv_rx->list, &local_list);
742e9ce991bSTariq Toukan 		if (++i == budget)
743e9ce991bSTariq Toukan 			break;
744e9ce991bSTariq Toukan 	}
745e9ce991bSTariq Toukan 	if (list_empty(&ktls_resync->list))
746e9ce991bSTariq Toukan 		clear_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &sq->state);
747e9ce991bSTariq Toukan 	spin_unlock(&ktls_resync->lock);
748e9ce991bSTariq Toukan 
749e9ce991bSTariq Toukan 	spin_lock(&c->async_icosq_lock);
750e9ce991bSTariq Toukan 	for (j = 0; j < i; j++) {
751e9ce991bSTariq Toukan 		struct mlx5_wqe_ctrl_seg *cseg;
752e9ce991bSTariq Toukan 
753e9ce991bSTariq Toukan 		priv_rx = list_first_entry(&local_list,
754e9ce991bSTariq Toukan 					   struct mlx5e_ktls_offload_context_rx,
755e9ce991bSTariq Toukan 					   list);
756cc4a9cc0STariq Toukan 		spin_lock(&priv_rx->lock);
757e9ce991bSTariq Toukan 		cseg = post_static_params(sq, priv_rx);
758cc4a9cc0STariq Toukan 		if (IS_ERR(cseg)) {
759cc4a9cc0STariq Toukan 			spin_unlock(&priv_rx->lock);
760e9ce991bSTariq Toukan 			break;
761cc4a9cc0STariq Toukan 		}
762cc4a9cc0STariq Toukan 		list_del_init(&priv_rx->list);
763cc4a9cc0STariq Toukan 		spin_unlock(&priv_rx->lock);
764e9ce991bSTariq Toukan 		db_cseg = cseg;
765e9ce991bSTariq Toukan 	}
766e9ce991bSTariq Toukan 	if (db_cseg)
767e9ce991bSTariq Toukan 		mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, db_cseg);
768e9ce991bSTariq Toukan 	spin_unlock(&c->async_icosq_lock);
769e9ce991bSTariq Toukan 
770e9ce991bSTariq Toukan 	priv_rx->rq_stats->tls_resync_res_ok += j;
771e9ce991bSTariq Toukan 
772e9ce991bSTariq Toukan 	if (!list_empty(&local_list)) {
773e9ce991bSTariq Toukan 		/* This happens only if ICOSQ is full.
774e9ce991bSTariq Toukan 		 * There is no need to mark busy or explicitly ask for a NAPI cycle,
775e9ce991bSTariq Toukan 		 * it will be triggered by the outstanding ICOSQ completions.
776e9ce991bSTariq Toukan 		 */
777e9ce991bSTariq Toukan 		spin_lock(&ktls_resync->lock);
778e9ce991bSTariq Toukan 		list_splice(&local_list, &ktls_resync->list);
779e9ce991bSTariq Toukan 		set_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &sq->state);
780e9ce991bSTariq Toukan 		spin_unlock(&ktls_resync->lock);
781e9ce991bSTariq Toukan 		priv_rx->rq_stats->tls_resync_res_retry++;
782e9ce991bSTariq Toukan 	}
783e9ce991bSTariq Toukan 
784e9ce991bSTariq Toukan 	return i == budget;
785e9ce991bSTariq Toukan }
786