struct tx_sync_info {
        u64 rcd_sn;
-       s32 sync_len;
+       u32 sync_len;
        int nr_frags;
        skb_frag_t frags[MAX_SKB_FRAGS];
 };
 
 static enum mlx5e_ktls_sync_retval
 tx_sync_info_get(struct mlx5e_ktls_offload_context_tx *priv_tx,
-                u32 tcp_seq, struct tx_sync_info *info)
+                u32 tcp_seq, int datalen, struct tx_sync_info *info)
 {
        struct tls_offload_context_tx *tx_ctx = priv_tx->tx_ctx;
        enum mlx5e_ktls_sync_retval ret = MLX5E_KTLS_SYNC_DONE;
        struct tls_record_info *record;
        int remaining, i = 0;
        unsigned long flags;
+       bool ends_before;
 
        spin_lock_irqsave(&tx_ctx->lock, flags);
        record = tls_get_record(tx_ctx, tcp_seq, &info->rcd_sn);
                goto out;
        }
 
-       if (unlikely(tcp_seq < tls_record_start_seq(record))) {
-               ret = tls_record_is_start_marker(record) ?
-                       MLX5E_KTLS_SYNC_SKIP_NO_DATA : MLX5E_KTLS_SYNC_FAIL;
+       /* There are the following cases:
+        * 1. packet ends before start marker: bypass offload.
+        * 2. packet starts before start marker and ends after it: drop,
+        *    not supported, breaks contract with kernel.
+        * 3. packet ends before tls record info starts: drop,
+        *    this packet was already acknowledged and its record info
+        *    was released.
+        */
+       ends_before = before(tcp_seq + datalen, tls_record_start_seq(record));
+
+       if (unlikely(tls_record_is_start_marker(record))) {
+               ret = ends_before ? MLX5E_KTLS_SYNC_SKIP_NO_DATA : MLX5E_KTLS_SYNC_FAIL;
+               goto out;
+       } else if (ends_before) {
+               ret = MLX5E_KTLS_SYNC_FAIL;
                goto out;
        }
 
        u8 num_wqebbs;
        int i = 0;
 
-       ret = tx_sync_info_get(priv_tx, seq, &info);
+       ret = tx_sync_info_get(priv_tx, seq, datalen, &info);
        if (unlikely(ret != MLX5E_KTLS_SYNC_DONE)) {
                if (ret == MLX5E_KTLS_SYNC_SKIP_NO_DATA) {
                        stats->tls_skip_no_sync_data++;
                goto err_out;
        }
 
-       if (unlikely(info.sync_len < 0)) {
-               if (likely(datalen <= -info.sync_len))
-                       return MLX5E_KTLS_SYNC_DONE;
-
-               stats->tls_drop_bypass_req++;
-               goto err_out;
-       }
-
        stats->tls_ooo++;
 
        tx_post_resync_params(sq, priv_tx, info.rcd_sn);