From: Valentine Fatiev <valentinef@nvidia.com>
Subject: [PATCH] BACKPORT:
 drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c

Change-Id: I0b3d2b27c18b214baa2c63650b331cd82395dacd
---
 .../mellanox/mlx5/core/en_accel/ipsec.c       | 70 ++++++++++++++++++-
 1 file changed, 69 insertions(+), 1 deletion(-)

--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
@@ -48,9 +48,11 @@
 #include "en/ipsec_aso.h"
 #include "../esw/ipsec.h"
 
+#ifdef HAVE_XFRM_STATE_OFFLOAD
 #ifndef XFRM_OFFLOAD_FULL
 #define XFRM_OFFLOAD_FULL 4
 #endif
+#endif /* HAVE_XFRM_STATE_OFFLOAD */
 
 struct mlx5e_ipsec_async_work {
 	struct delayed_work dwork;
@@ -316,10 +318,20 @@ initialize_lifetime_limit(struct mlx5e_i
 	if (MLX5_CAP_GEN(priv->mdev, fpga))
 		return;
 
+#ifndef HAVE_XFRM_STATE_EXPIRE
+	attrs->soft_packet_limit = IPSEC_NO_LIMIT;
+	attrs->hard_packet_limit = IPSEC_NO_LIMIT;
+	return;
+#endif
+
 	hard_limit = x->lft.hard_packet_limit;
 	soft_limit = (x->lft.soft_packet_limit == IPSEC_NO_LIMIT)
 			? 0 : x->lft.soft_packet_limit;
+#ifdef HAVE_XFRM_STATE_OFFLOAD
 	if (!(x->xso.flags & XFRM_OFFLOAD_FULL) ||
+#else
+	if (
+#endif
 	    (hard_limit <= soft_limit) ||
 	    (hard_limit == IPSEC_NO_LIMIT)) {
 		attrs->soft_packet_limit = IPSEC_NO_LIMIT;
@@ -419,7 +431,11 @@ mlx5e_ipsec_build_accel_xfrm_attrs(struc
 	attrs->keymat_type = MLX5_ACCEL_ESP_KEYMAT_AES_GCM;
 
 	/* action */
+#ifndef HAVE_XFRM_STATE_OFFLOAD
+	attrs->action = (!(x->xso.dir == XFRM_DEV_OFFLOAD_IN)) ?
+#else
 	attrs->action = (!(x->xso.flags & XFRM_OFFLOAD_INBOUND)) ?
+#endif
 			MLX5_ACCEL_ESP_ACTION_ENCRYPT :
 			MLX5_ACCEL_ESP_ACTION_DECRYPT;
 	/* flags */
@@ -428,9 +444,11 @@ mlx5e_ipsec_build_accel_xfrm_attrs(struc
 			MLX5_ACCEL_ESP_FLAGS_TUNNEL;
 
 /* Valid till stack changes accepted */
+#ifdef HAVE_XFRM_STATE_OFFLOAD
 #define XFRM_OFFLOAD_FULL 4
 	if (x->xso.flags & XFRM_OFFLOAD_FULL)
 		attrs->flags |= MLX5_ACCEL_ESP_FLAGS_FULL_OFFLOAD;
+#endif
 
 	/* spi */
 	attrs->spi = x->id.spi;
@@ -452,9 +470,15 @@ mlx5e_ipsec_build_accel_xfrm_attrs(struc
 
 static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
 {
+#ifdef HAVE_NET_DEVICE_REAL_DEV
 	struct net_device *netdev = x->xso.real_dev;
+#else
+	struct net_device *netdev = x->xso.dev;
+#endif
 	struct mlx5_core_dev *mdev;
+#ifdef CONFIG_MLX5_ESWITCH
 	struct mlx5_eswitch *esw;
+#endif
 	struct mlx5e_priv *priv;
 
 	priv = netdev_priv(netdev);
@@ -527,11 +551,23 @@ static inline int mlx5e_xfrm_validate_st
 		netdev_info(netdev, "IPv6 xfrm state offload is not supported by this device\n");
 		return -EINVAL;
 	}
+
+#ifdef HAVE_XFRM_STATE_OFFLOAD
 	if (x->xso.flags & XFRM_OFFLOAD_FULL) {
+#else
+/* For XFRM_OFFLOAD_INBOUND it can be replaced using “xso->dir ==  XFRM_DEV_OFFLOAD_IN“,
+ * And for XFRM_OFFLOAD_FULL, these can be replaced with if (0) (as if not supported) as this flag exists anyway only in BlueField
+ * kernel.
+ */
+	if ( 0 ) {
+#endif
 		if (!(mlx5_accel_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_CAP_FULL_OFFLOAD)) {
 			netdev_info(netdev, "IPsec full offload is not supported by this device.\n");
 			return -EINVAL;
 		}
+#ifndef CONFIG_MLX5_ESWITCH
+			return -EINVAL;
+#else
 		esw = mdev->priv.eswitch;
 		if (!esw || esw->mode != MLX5_ESWITCH_OFFLOADS) {
 			netdev_info(netdev, "IPsec full offload allowed only in switchdev mode.\n");
@@ -549,8 +585,10 @@ static inline int mlx5e_xfrm_validate_st
 				    "IPsec crypto only offload is not allowed when devlink ipsec mode is full.\n");
 			return -EINVAL;
 		}
+#endif
 	}
 
+#ifdef HAVE_XFRM_STATE_OFFLOAD
 	if ((x->xso.flags & XFRM_OFFLOAD_FULL) &&
 	    ((x->lft.hard_byte_limit != XFRM_INF) ||
 	     (x->lft.soft_byte_limit != XFRM_INF))) {
@@ -561,6 +599,7 @@ static inline int mlx5e_xfrm_validate_st
 				x->lft.soft_byte_limit);
 		return -EINVAL;
 	}
+#endif
 
 	return 0;
 }
@@ -586,10 +625,19 @@ static void mlx5e_xfrm_fs_del_rule(struc
 				      &sa_entry->ipsec_rule);
 }
 
+#ifdef HAVE_XDO_XFRM_ADD_STATE_GET_EXTACK
+static int mlx5e_xfrm_add_state(struct xfrm_state *x,
+		struct netlink_ext_ack *extack)
+#else
 static int mlx5e_xfrm_add_state(struct xfrm_state *x)
+#endif
 {
 	struct mlx5e_ipsec_sa_entry *sa_entry = NULL;
+#ifdef HAVE_NET_DEVICE_REAL_DEV
 	struct net_device *netdev = x->xso.real_dev;
+#else
+	struct net_device *netdev = x->xso.dev;
+#endif
 	struct mlx5_accel_esp_xfrm_attrs attrs;
 	struct mlx5e_priv *priv;
 	unsigned int sa_handle;
@@ -641,7 +689,11 @@ static int mlx5e_xfrm_add_state(struct x
 	if (err)
 		goto err_hw_ctx;
 
+#ifndef HAVE_XFRM_STATE_OFFLOAD
+	if (x->xso.dir == XFRM_DEV_OFFLOAD_IN) {
+#else
 	if (x->xso.flags & XFRM_OFFLOAD_INBOUND) {
+#endif
 		err = mlx5e_ipsec_sadb_rx_add(sa_entry, sa_handle);
 		if (err)
 			goto err_add_rule;
@@ -676,7 +728,11 @@ static void mlx5e_xfrm_del_state(struct
 	if (!sa_entry || sa_entry->is_removed)
 		return;
 
+#ifndef HAVE_XFRM_STATE_OFFLOAD
+	if (x->xso.dir == XFRM_DEV_OFFLOAD_IN)
+#else
 	if (x->xso.flags & XFRM_OFFLOAD_INBOUND)
+#endif
 		mlx5e_ipsec_sadb_rx_del(sa_entry);
 	else
 		mlx5e_ipsec_sadb_tx_del(sa_entry);
@@ -812,6 +868,7 @@ struct mlx5e_ipsec_modify_state_work {
 	struct mlx5e_ipsec_sa_entry	*sa_entry;
 };
 
+#ifdef HAVE_XDO_DEV_STATE_ADVANCE_ESN
 static void _update_xfrm_state(struct work_struct *work)
 {
 	int ret;
@@ -851,13 +908,16 @@ static void mlx5e_xfrm_advance_esn_state
 	INIT_WORK(&modify_work->work, _update_xfrm_state);
 	WARN_ON(!queue_work(sa_entry->ipsec->wq, &modify_work->work));
 }
+#endif
 
 static const struct xfrmdev_ops mlx5e_ipsec_xfrmdev_ops = {
 	.xdo_dev_state_add	= mlx5e_xfrm_add_state,
 	.xdo_dev_state_delete	= mlx5e_xfrm_del_state,
 	.xdo_dev_state_free	= mlx5e_xfrm_free_state,
 	.xdo_dev_offload_ok	= mlx5e_ipsec_offload_ok,
+#ifdef HAVE_XDO_DEV_STATE_ADVANCE_ESN
 	.xdo_dev_state_advance_esn = mlx5e_xfrm_advance_esn_state,
+#endif
 };
 
 void mlx5e_ipsec_build_netdev(struct mlx5e_priv *priv)
@@ -964,14 +1024,22 @@ static void _mlx5e_ipsec_async_event(str
 		goto out_xs_state;
 
 	/* Life time event */
-	if (!hard_cnt) /* Notify hard lifetime to xfrm stack */
+	if (!hard_cnt) { /* Notify hard lifetime to xfrm stack */
+#ifdef HAVE_XFRM_STATE_EXPIRE
+		xfrm_state_expire(xs, 1);
+#endif
 		goto out_xs_state;
+	}
 
 	/* 0: no more soft
 	 * 1: notify soft
 	 */
 	if (lft->round_soft) {
 		lft->round_soft--;
+#ifdef HAVE_XFRM_STATE_EXPIRE
+		if (!lft->round_soft)
+			xfrm_state_expire(xs, 0);
+#endif
 	}
 
 	if (!lft->is_simulated) /* hard_limit < IPSEC_HW_LIMIT */
