return 0;
 }
 
+static void _update_xfrm_state(struct work_struct *work)
+{
+       struct mlx5e_ipsec_modify_state_work *modify_work =
+               container_of(work, struct mlx5e_ipsec_modify_state_work, work);
+       struct mlx5e_ipsec_sa_entry *sa_entry = container_of(
+               modify_work, struct mlx5e_ipsec_sa_entry, modify_work);
+
+       mlx5_accel_esp_modify_xfrm(sa_entry->xfrm, &modify_work->attrs);
+}
+
 static int mlx5e_xfrm_add_state(struct xfrm_state *x)
 {
        struct mlx5e_ipsec_sa_entry *sa_entry = NULL;
                                mlx5e_ipsec_set_iv_esn : mlx5e_ipsec_set_iv;
        }
 
+       INIT_WORK(&sa_entry->modify_work.work, _update_xfrm_state);
        x->xso.offload_handle = (unsigned long)sa_entry;
        goto out;
 
        struct mlx5e_priv *priv = netdev_priv(x->xso.dev);
 
        if (sa_entry->hw_context) {
-               flush_workqueue(sa_entry->ipsec->wq);
+               cancel_work_sync(&sa_entry->modify_work.work);
                mlx5e_accel_ipsec_fs_del_rule(priv, &sa_entry->xfrm->attrs,
                                              &sa_entry->ipsec_rule);
                mlx5_accel_esp_free_hw_context(sa_entry->xfrm->mdev, sa_entry->hw_context);
        hash_init(ipsec->sadb_rx);
        spin_lock_init(&ipsec->sadb_rx_lock);
        ipsec->mdev = priv->mdev;
-       ipsec->en_priv = priv;
        ipsec->wq = alloc_ordered_workqueue("mlx5e_ipsec: %s", 0,
                                            priv->netdev->name);
        if (!ipsec->wq) {
 
        mlx5e_accel_ipsec_fs_cleanup(ipsec);
        destroy_workqueue(ipsec->wq);
-
        kfree(ipsec);
        priv->ipsec = NULL;
 }
        return true;
 }
 
-struct mlx5e_ipsec_modify_state_work {
-       struct work_struct              work;
-       struct mlx5_accel_esp_xfrm_attrs attrs;
-       struct mlx5e_ipsec_sa_entry     *sa_entry;
-};
-
-static void _update_xfrm_state(struct work_struct *work)
-{
-       int ret;
-       struct mlx5e_ipsec_modify_state_work *modify_work =
-               container_of(work, struct mlx5e_ipsec_modify_state_work, work);
-       struct mlx5e_ipsec_sa_entry *sa_entry = modify_work->sa_entry;
-
-       ret = mlx5_accel_esp_modify_xfrm(sa_entry->xfrm,
-                                        &modify_work->attrs);
-       if (ret)
-               netdev_warn(sa_entry->ipsec->en_priv->netdev,
-                           "Not an IPSec offload device\n");
-
-       kfree(modify_work);
-}
-
 static void mlx5e_xfrm_advance_esn_state(struct xfrm_state *x)
 {
        struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
-       struct mlx5e_ipsec_modify_state_work *modify_work;
+       struct mlx5e_ipsec_modify_state_work *modify_work =
+               &sa_entry->modify_work;
        bool need_update;
 
        need_update = mlx5e_ipsec_update_esn_state(sa_entry);
        if (!need_update)
                return;
 
-       modify_work = kzalloc(sizeof(*modify_work), GFP_ATOMIC);
-       if (!modify_work)
-               return;
-
        mlx5e_ipsec_build_accel_xfrm_attrs(sa_entry, &modify_work->attrs);
-       modify_work->sa_entry = sa_entry;
-
-       INIT_WORK(&modify_work->work, _update_xfrm_state);
-       WARN_ON(!queue_work(sa_entry->ipsec->wq, &modify_work->work));
+       queue_work(sa_entry->ipsec->wq, &modify_work->work);
 }
 
 static const struct xfrmdev_ops mlx5e_ipsec_xfrmdev_ops = {
 
 
 struct mlx5e_ipsec {
        struct mlx5_core_dev *mdev;
-       struct mlx5e_priv *en_priv;
        DECLARE_HASHTABLE(sadb_rx, MLX5E_IPSEC_SADB_RX_BITS);
        spinlock_t sadb_rx_lock; /* Protects sadb_rx */
        struct mlx5e_ipsec_sw_stats sw_stats;
        struct mlx5_modify_hdr *set_modify_hdr;
 };
 
+struct mlx5e_ipsec_modify_state_work {
+       struct work_struct              work;
+       struct mlx5_accel_esp_xfrm_attrs attrs;
+};
+
 struct mlx5e_ipsec_sa_entry {
        struct hlist_node hlist; /* Item in SADB_RX hashtable */
        struct mlx5e_ipsec_esn_state esn_state;
                          struct xfrm_offload *xo);
        u32 ipsec_obj_id;
        struct mlx5e_ipsec_rule ipsec_rule;
+       struct mlx5e_ipsec_modify_state_work modify_work;
 };
 
 int mlx5e_ipsec_init(struct mlx5e_priv *priv);
 
 struct mlx5_ipsec_esp_xfrm {
        /* reference counter of SA ctx */
        struct mlx5_ipsec_sa_ctx *sa_ctx;
-       struct mutex lock; /* protects mlx5_ipsec_esp_xfrm */
        struct mlx5_accel_esp_xfrm accel_xfrm;
 };
 
        if (!mxfrm)
                return ERR_PTR(-ENOMEM);
 
-       mutex_init(&mxfrm->lock);
        memcpy(&mxfrm->accel_xfrm.attrs, attrs,
               sizeof(mxfrm->accel_xfrm.attrs));
 
        struct mlx5_ipsec_esp_xfrm *mxfrm = container_of(xfrm, struct mlx5_ipsec_esp_xfrm,
                                                         accel_xfrm);
 
-       /* assuming no sa_ctx are connected to this xfrm_ctx */
-       WARN_ON(mxfrm->sa_ctx);
        kfree(mxfrm);
 }
 
        sa_ctx->dev = mdev;
 
        mxfrm = container_of(accel_xfrm, struct mlx5_ipsec_esp_xfrm, accel_xfrm);
-       mutex_lock(&mxfrm->lock);
        sa_ctx->mxfrm = mxfrm;
 
        /* key */
 
        *hw_handle = sa_ctx->ipsec_obj_id;
        mxfrm->sa_ctx = sa_ctx;
-       mutex_unlock(&mxfrm->lock);
 
        return sa_ctx;
 
 err_enc_key:
        mlx5_destroy_encryption_key(mdev, sa_ctx->enc_key_id);
 err_sa_ctx:
-       mutex_unlock(&mxfrm->lock);
        kfree(sa_ctx);
        return ERR_PTR(err);
 }
 static void mlx5_ipsec_offload_delete_sa_ctx(void *context)
 {
        struct mlx5_ipsec_sa_ctx *sa_ctx = (struct mlx5_ipsec_sa_ctx *)context;
-       struct mlx5_ipsec_esp_xfrm *mxfrm = sa_ctx->mxfrm;
 
-       mutex_lock(&mxfrm->lock);
        mlx5_destroy_ipsec_obj(sa_ctx->dev, sa_ctx->ipsec_obj_id);
        mlx5_destroy_encryption_key(sa_ctx->dev, sa_ctx->enc_key_id);
        kfree(sa_ctx);
-       mxfrm->sa_ctx = NULL;
-       mutex_unlock(&mxfrm->lock);
 }
 
 static int mlx5_modify_ipsec_obj(struct mlx5_core_dev *mdev,
        return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
 }
 
-static int mlx5_ipsec_offload_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
-                                             const struct mlx5_accel_esp_xfrm_attrs *attrs)
+static void mlx5_ipsec_offload_esp_modify_xfrm(
+       struct mlx5_accel_esp_xfrm *xfrm,
+       const struct mlx5_accel_esp_xfrm_attrs *attrs)
 {
        struct mlx5_ipsec_obj_attrs ipsec_attrs = {};
        struct mlx5_core_dev *mdev = xfrm->mdev;
        struct mlx5_ipsec_esp_xfrm *mxfrm;
-
        int err = 0;
 
-       if (!memcmp(&xfrm->attrs, attrs, sizeof(xfrm->attrs)))
-               return 0;
-
-       if (mlx5_ipsec_offload_esp_validate_xfrm_attrs(mdev, attrs))
-               return -EOPNOTSUPP;
-
        mxfrm = container_of(xfrm, struct mlx5_ipsec_esp_xfrm, accel_xfrm);
 
-       mutex_lock(&mxfrm->lock);
-
-       if (!mxfrm->sa_ctx)
-               /* Not bound xfrm, change only sw attrs */
-               goto change_sw_xfrm_attrs;
-
        /* need to add find and replace in ipsec_rhash_sa the sa_ctx */
        /* modify device with new hw_sa */
        ipsec_attrs.accel_flags = attrs->flags;
                                    &ipsec_attrs,
                                    mxfrm->sa_ctx->ipsec_obj_id);
 
-change_sw_xfrm_attrs:
        if (!err)
                memcpy(&xfrm->attrs, attrs, sizeof(xfrm->attrs));
-
-       mutex_unlock(&mxfrm->lock);
-       return err;
 }
 
 void *mlx5_accel_esp_create_hw_context(struct mlx5_core_dev *mdev,
        mlx5_ipsec_offload_esp_destroy_xfrm(xfrm);
 }
 
-int mlx5_accel_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
-                              const struct mlx5_accel_esp_xfrm_attrs *attrs)
+void mlx5_accel_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
+                               const struct mlx5_accel_esp_xfrm_attrs *attrs)
 {
-       return mlx5_ipsec_offload_esp_modify_xfrm(xfrm, attrs);
+       mlx5_ipsec_offload_esp_modify_xfrm(xfrm, attrs);
 }
 
 mlx5_accel_esp_create_xfrm(struct mlx5_core_dev *mdev,
                           const struct mlx5_accel_esp_xfrm_attrs *attrs);
 void mlx5_accel_esp_destroy_xfrm(struct mlx5_accel_esp_xfrm *xfrm);
-int mlx5_accel_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
-                              const struct mlx5_accel_esp_xfrm_attrs *attrs);
+void mlx5_accel_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
+                               const struct mlx5_accel_esp_xfrm_attrs *attrs);
 
 #else
 
 }
 static inline void
 mlx5_accel_esp_destroy_xfrm(struct mlx5_accel_esp_xfrm *xfrm) {}
-static inline int
+static inline void
 mlx5_accel_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
-                          const struct mlx5_accel_esp_xfrm_attrs *attrs) { return -EOPNOTSUPP; }
+                          const struct mlx5_accel_esp_xfrm_attrs *attrs)
+{
+}
 
 #endif /* CONFIG_MLX5_EN_IPSEC */
 #endif /* __MLX5_ACCEL_H__ */