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

Change-Id: Ifd52daf16b90b68628630cf22db61d2950742a6b
---
 .../net/ethernet/mellanox/mlx5/core/en_main.c | 1385 +++++++++++++++--
 1 file changed, 1281 insertions(+), 104 deletions(-)

--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -1,4 +1,5 @@
 /*
+ *
  * Copyright (c) 2015-2016, Mellanox Technologies. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -30,17 +31,37 @@
  * SOFTWARE.
  */
 
+#include <linux/debugfs.h>
+#include <net/pkt_sched.h>
+#ifdef CONFIG_MLX5_CLS_ACT
 #include <net/tc_act/tc_gact.h>
+#endif
 #include <linux/mlx5/fs.h>
+#include <net/switchdev.h>
+#if defined(HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON)
 #include <net/vxlan.h>
+#endif
 #include <net/geneve.h>
 #include <linux/bpf.h>
-#include <linux/debugfs.h>
 #include <linux/if_bridge.h>
+#ifdef HAVE_BASECODE_EXTRAS
+#include <linux/irq.h>
+#endif
 #include <linux/filter.h>
+#ifdef HAVE_NET_PAGE_POOL_OLD_H
+#include <net/page_pool.h>
+#endif
+#ifdef HAVE_NET_PAGE_POOL_TYPES_H
 #include <net/page_pool/types.h>
-#include <net/pkt_sched.h>
+#include <net/page_pool/helpers.h>
+#endif
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+#ifdef HAVE_XDP_SOCK_DRV_H
 #include <net/xdp_sock_drv.h>
+#else
+#include <net/xdp_sock.h>
+#endif
+#endif
 #include "eswitch.h"
 #include "en.h"
 #include "en/txrx.h"
@@ -50,7 +71,9 @@
 #include "en_accel/macsec.h"
 #include "en_accel/en_accel.h"
 #include "en_accel/ktls.h"
+#if defined(HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON)
 #include "lib/vxlan.h"
+#endif
 #include "lib/clock.h"
 #include "en/port.h"
 #include "en/xdp.h"
@@ -71,6 +94,7 @@
 #include "en/trap.h"
 #include "lib/devcom.h"
 #include "lib/sd.h"
+#include "compat.h"
 
 static void mlx5e_mqprio_build_default_tc_to_txq(struct netdev_tc_txq *tc_to_txq,
 						 int ntc, int nch);
@@ -101,16 +125,22 @@ void mlx5e_update_carrier(struct mlx5e_p
 {
 	struct mlx5_core_dev *mdev = priv->mdev;
 	u8 port_state;
+#ifdef HAVE_NETIF_CARRIER_EVENT
 	bool up;
+#endif
 
 	port_state = mlx5_query_vport_state(mdev,
 					    MLX5_VPORT_STATE_OP_MOD_VNIC_VPORT,
 					    0);
 
+#ifdef HAVE_NETIF_CARRIER_EVENT
 	up = port_state == VPORT_STATE_UP;
 	if (up == netif_carrier_ok(priv->netdev))
 		netif_carrier_event(priv->netdev);
 	if (up) {
+#else
+	if (port_state == VPORT_STATE_UP) {
+#endif
 		netdev_info(priv->netdev, "Link up\n");
 		netif_carrier_on(priv->netdev);
 	} else {
@@ -357,6 +387,7 @@ static inline void mlx5e_build_umr_wqe(s
 	ucseg->mkey_mask     = cpu_to_be64(MLX5_MKEY_MASK_FREE);
 }
 
+#ifdef HAVE_SHAMPO_SUPPORT
 static int mlx5e_rq_shampo_hd_alloc(struct mlx5e_rq *rq, int node)
 {
 	rq->mpwqe.shampo = kvzalloc_node(sizeof(*rq->mpwqe.shampo),
@@ -375,11 +406,21 @@ static int mlx5e_rq_shampo_hd_info_alloc
 {
 	struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo;
 
+#ifdef HAVE_BITMAP_ZALLOC_NODE
 	shampo->bitmap = bitmap_zalloc_node(shampo->hd_per_wq, GFP_KERNEL,
 					    node);
+#else
+	shampo->bitmap = bitmap_zalloc(shampo->hd_per_wq, GFP_KERNEL);
+#endif
+#ifndef HAVE_PAGE_POOL_DEFRAG_PAGE
+	if (!shampo->bitmap)
+		return -ENOMEM;
+#endif
+
 	shampo->info = kvzalloc_node(array_size(shampo->hd_per_wq,
 						sizeof(*shampo->info)),
 				     GFP_KERNEL, node);
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 	shampo->pages = kvzalloc_node(array_size(shampo->hd_per_wq,
 						 sizeof(*shampo->pages)),
 				     GFP_KERNEL, node);
@@ -394,22 +435,32 @@ err_nomem:
 	kvfree(shampo->pages);
 
 	return -ENOMEM;
+#else
+	return 0;
+#endif
 }
 
 static void mlx5e_rq_shampo_hd_info_free(struct mlx5e_rq *rq)
 {
 	kvfree(rq->mpwqe.shampo->bitmap);
 	kvfree(rq->mpwqe.shampo->info);
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 	kvfree(rq->mpwqe.shampo->pages);
+#endif
 }
+#endif
 
 static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq, int node)
 {
 	int wq_sz = mlx5_wq_ll_get_size(&rq->mpwqe.wq);
 	size_t alloc_size;
-
+	int i;
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 	alloc_size = array_size(wq_sz, struct_size(rq->mpwqe.info,
 						   alloc_units.frag_pages,
+#else
+	alloc_size = array_size(wq_sz, struct_size(rq->mpwqe.info, alloc_units,
+#endif /*HAVE_PAGE_POOL_DEFRAG_PAGE*/
 						   rq->mpwqe.pages_per_wqe));
 
 	rq->mpwqe.info = kvzalloc_node(alloc_size, GFP_KERNEL, node);
@@ -419,7 +470,7 @@ static int mlx5e_rq_alloc_mpwqe_info(str
 	/* For deferred page release (release right before alloc), make sure
 	 * that on first round release is not called.
 	 */
-	for (int i = 0; i < wq_sz; i++) {
+	for (i = 0; i < wq_sz; i++) {
 		struct mlx5e_mpw_info *wi = mlx5e_get_mpw_info(rq, i);
 
 		bitmap_fill(wi->skip_release_bitmap, rq->mpwqe.pages_per_wqe);
@@ -450,8 +501,11 @@ static u8 mlx5e_mpwrq_access_mode(enum m
 static int mlx5e_create_umr_mkey(struct mlx5_core_dev *mdev,
 				 u32 npages, u8 page_shift, u32 *umr_mkey,
 				 dma_addr_t filler_addr,
-				 enum mlx5e_mpwrq_umr_mode umr_mode,
-				 u32 xsk_chunk_size)
+				 enum mlx5e_mpwrq_umr_mode umr_mode
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+				 , u32 xsk_chunk_size
+#endif
+				)
 {
 	struct mlx5_mtt *mtt;
 	struct mlx5_ksm *ksm;
@@ -511,12 +565,16 @@ static int mlx5e_create_umr_mkey(struct
 		for (i = 0; i < npages; i++) {
 			klm[i << 1] = (struct mlx5_klm) {
 				.va = cpu_to_be64(filler_addr),
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 				.bcount = cpu_to_be32(xsk_chunk_size),
+#endif
 				.key = cpu_to_be32(mdev->mlx5e_res.hw_objs.mkey),
 			};
 			klm[(i << 1) + 1] = (struct mlx5_klm) {
 				.va = cpu_to_be64(filler_addr),
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 				.bcount = cpu_to_be32((1 << page_shift) - xsk_chunk_size),
+#endif
 				.key = cpu_to_be32(mdev->mlx5e_res.hw_objs.mkey),
 			};
 		}
@@ -553,6 +611,7 @@ static int mlx5e_create_umr_mkey(struct
 	return err;
 }
 
+#ifdef HAVE_SHAMPO_SUPPORT
 static int mlx5e_create_umr_klm_mkey(struct mlx5_core_dev *mdev,
 				     u64 nentries,
 				     u32 *umr_mkey)
@@ -585,10 +644,21 @@ static int mlx5e_create_umr_klm_mkey(str
 	kvfree(in);
 	return err;
 }
+#endif
 
 static int mlx5e_create_rq_umr_mkey(struct mlx5_core_dev *mdev, struct mlx5e_rq *rq)
 {
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+#ifdef HAVE_NETDEV_BPF_XSK_BUFF_POOL
 	u32 xsk_chunk_size = rq->xsk_pool ? rq->xsk_pool->chunk_size : 0;
+#else
+#ifdef HAVE_XDP_UMEM_CHUNK_SIZE
+	u32 xsk_chunk_size = rq->umem ? rq->umem->chunk_size : 0;
+#else
+	u32 xsk_chunk_size = rq->umem ? rq->umem->chunk_size_nohr + rq->umem->headroom : 0;
+#endif /*HAVE_XDP_UMEM_CHUNK_SIZE */
+#endif /* HAVE_NETDEV_BF_XSK_BUFF_POOL*/
+#endif /* HAVE_XSK_COPY_SUPPORT*/
 	u32 wq_size = mlx5_wq_ll_get_size(&rq->mpwqe.wq);
 	u32 num_entries, max_num_entries;
 	u32 umr_mkey;
@@ -604,13 +674,20 @@ static int mlx5e_create_rq_umr_mkey(stru
 			      __func__, wq_size, rq->mpwqe.mtts_per_wqe,
 			      max_num_entries);
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	err = mlx5e_create_umr_mkey(mdev, num_entries, rq->mpwqe.page_shift,
 				    &umr_mkey, rq->wqe_overflow.addr,
 				    rq->mpwqe.umr_mode, xsk_chunk_size);
+#else
+	err = mlx5e_create_umr_mkey(mdev, num_entries, rq->mpwqe.page_shift,
+				    &umr_mkey, rq->wqe_overflow.addr,
+				    rq->mpwqe.umr_mode);
+#endif
 	rq->mpwqe.umr_mkey_be = cpu_to_be32(umr_mkey);
 	return err;
 }
 
+#ifdef HAVE_SHAMPO_SUPPORT
 static int mlx5e_create_rq_hd_umr_mkey(struct mlx5_core_dev *mdev,
 				       struct mlx5e_rq *rq)
 {
@@ -624,6 +701,7 @@ static int mlx5e_create_rq_hd_umr_mkey(s
 	return mlx5e_create_umr_klm_mkey(mdev, rq->mpwqe.shampo->hd_per_wq,
 					 &rq->mpwqe.shampo->mkey);
 }
+#endif
 
 static void mlx5e_init_frags_partition(struct mlx5e_rq *rq)
 {
@@ -631,12 +709,28 @@ static void mlx5e_init_frags_partition(s
 	struct mlx5e_wqe_frag_info *prev = NULL;
 	int i;
 
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
+#if defined(HAVE_XDP_SUPPORT) && defined(HAVE_NETDEV_BPF_XSK_BUFF_POOL)
 	WARN_ON(rq->xsk_pool);
+#endif
 
 	next_frag.frag_page = &rq->wqe.alloc_units->frag_pages[0];
 
 	/* Skip first release due to deferred release. */
 	next_frag.flags = BIT(MLX5E_WQE_FRAG_SKIP_RELEASE);
+#else /* HAVE_PAGE_POOL_DEFRAG_PAGE */
+
+#if defined(HAVE_XDP_SUPPORT) && defined(HAVE_NETDEV_BPF_XSK_BUFF_POOL)
+	if (rq->xsk_pool) {
+		/* Assumptions used by XSK batched allocator. */
+		WARN_ON(rq->wqe.info.num_frags != 1);
+		WARN_ON(rq->wqe.info.log_num_frags != 0);
+		WARN_ON(rq->wqe.info.arr[0].frag_stride != PAGE_SIZE);
+	}
+#endif
+
+	next_frag.au = &rq->wqe.alloc_units[0];
+#endif /* HAVE_PAGE_POOL_DEFRAG_PAGE */
 
 	for (i = 0; i < mlx5_wq_cyc_get_size(&rq->wqe.wq); i++) {
 		struct mlx5e_rq_frag_info *frag_info = &rq->wqe.info.arr[0];
@@ -646,11 +740,19 @@ static void mlx5e_init_frags_partition(s
 
 		for (f = 0; f < rq->wqe.info.num_frags; f++, frag++) {
 			if (next_frag.offset + frag_info[f].frag_stride > PAGE_SIZE) {
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 				/* Pages are assigned at runtime. */
 				next_frag.frag_page++;
+#else
+				next_frag.au++;
+#endif
 				next_frag.offset = 0;
 				if (prev)
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 					prev->flags |= BIT(MLX5E_WQE_FRAG_LAST_IN_PAGE);
+#else
+					prev->last_in_page = true;
+#endif
 			}
 			*frag = next_frag;
 
@@ -661,9 +763,15 @@ static void mlx5e_init_frags_partition(s
 	}
 
 	if (prev)
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 		prev->flags |= BIT(MLX5E_WQE_FRAG_LAST_IN_PAGE);
+#else
+					prev->last_in_page = true;
+#endif
 }
 
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
+#if defined(HAVE_XSK_ZERO_COPY_SUPPORT) && defined(HAVE_NETDEV_BPF_XSK_BUFF_POOL)
 static void mlx5e_init_xsk_buffs(struct mlx5e_rq *rq)
 {
 	int i;
@@ -685,6 +793,7 @@ static void mlx5e_init_xsk_buffs(struct
 		rq->wqe.frags[i].flags |= BIT(MLX5E_WQE_FRAG_SKIP_RELEASE);
 	}
 }
+#endif
 
 static int mlx5e_init_wqe_alloc_info(struct mlx5e_rq *rq, int node)
 {
@@ -694,9 +803,11 @@ static int mlx5e_init_wqe_alloc_info(str
 	union mlx5e_alloc_units *aus;
 	int aus_sz;
 
+#ifdef HAVE_XDP_SUPPORT
 	if (rq->xsk_pool)
 		aus_sz = sizeof(*aus->xsk_buffs);
 	else
+#endif
 		aus_sz = sizeof(*aus->frag_pages);
 
 	aus = kvzalloc_node(array_size(len, aus_sz), GFP_KERNEL, node);
@@ -712,9 +823,11 @@ static int mlx5e_init_wqe_alloc_info(str
 	rq->wqe.alloc_units = aus;
 	rq->wqe.frags = frags;
 
+#ifdef HAVE_XDP_SUPPORT
 	if (rq->xsk_pool)
 		mlx5e_init_xsk_buffs(rq);
 	else
+#endif
 		mlx5e_init_frags_partition(rq);
 
 	return 0;
@@ -725,6 +838,26 @@ static void mlx5e_free_wqe_alloc_info(st
 	kvfree(rq->wqe.frags);
 	kvfree(rq->wqe.alloc_units);
 }
+#else /* HAVE_PAGE_POOL_DEFRAG_PAGE */
+static int mlx5e_init_au_list(struct mlx5e_rq *rq, int wq_sz, int node)
+{
+	int len = wq_sz << rq->wqe.info.log_num_frags;
+
+	rq->wqe.alloc_units = kvzalloc_node(array_size(len, sizeof(*rq->wqe.alloc_units)),
+					    GFP_KERNEL, node);
+	if (!rq->wqe.alloc_units)
+		return -ENOMEM;
+
+	mlx5e_init_frags_partition(rq);
+
+	return 0;
+}
+
+static void mlx5e_free_au_list(struct mlx5e_rq *rq)
+{
+	kvfree(rq->wqe.alloc_units);
+}
+#endif /* HAVE_PAGE_POOL_DEFRAG_PAGE */
 
 static void mlx5e_rq_err_cqe_work(struct work_struct *recover_work)
 {
@@ -773,7 +906,9 @@ static int mlx5e_init_rxq_rq(struct mlx5
 	rq->mdev         = mdev;
 	rq->hw_mtu =
 		MLX5E_SW2HW_MTU(params, params->sw_mtu) - ETH_FCS_LEN * !params->scatter_fcs_en;
+#ifdef HAVE_XDP_SUPPORT
 	rq->xdpsq        = &c->rq_xdpsq;
+#endif
 	rq->stats        = &c->priv->channel_stats[c->ix]->rq;
 	rq->ptp_cyc2time = mlx5_rq_ts_translator(mdev);
 	if (mlx5_eswitch_mode(mdev) == MLX5_ESWITCH_OFFLOADS &&
@@ -785,10 +920,21 @@ static int mlx5e_init_rxq_rq(struct mlx5
 	if (err)
 		return err;
 
+#if defined(HAVE_XDP_SUPPORT)
+#ifdef HAVE_UNDERSCORE_XDP_RXQ_INFO_REG
 	return __xdp_rxq_info_reg(&rq->xdp_rxq, rq->netdev, rq->ix, c->napi.napi_id,
 				  xdp_frag_size);
+#elif defined(HAVE_XDP_RXQ_INFO_REG_4_PARAMS)
+	return xdp_rxq_info_reg(&rq->xdp_rxq, rq->netdev, rq->ix, c->napi.napi_id);
+#else
+	return xdp_rxq_info_reg(&rq->xdp_rxq, rq->netdev, rq->ix);
+#endif
+#else /* HAVE_XDP_SUPPORT */
+	return err;
+#endif /* HAVE_XDP_SUPPORT */
 }
 
+#ifdef HAVE_SHAMPO_SUPPORT
 static int mlx5_rq_shampo_alloc(struct mlx5_core_dev *mdev,
 				struct mlx5e_params *params,
 				struct mlx5e_rq_param *rqp,
@@ -847,30 +993,153 @@ static void mlx5e_rq_free_shampo(struct
 	mlx5_core_destroy_mkey(rq->mdev, rq->mpwqe.shampo->mkey);
 	mlx5e_rq_shampo_hd_free(rq);
 }
+#endif /* HAVE_SHAMPO_SUPPORT */
+#ifndef HAVE_PAGE_POOL_DEFRAG_PAGE
+static void mlx5e_rx_cache_reduce_clean_pending(struct mlx5e_rq *rq)
+{
+	struct mlx5e_page_cache_reduce *reduce = &rq->page_cache.reduce;
+	int i;
+
+	if (!test_bit(MLX5E_RQ_STATE_CACHE_REDUCE_PENDING, &rq->state))
+		return;
+
+	for (i = 0; i < reduce->npages; i++)
+		mlx5e_page_release_dynamic(rq, &reduce->pending[i], false);
+
+	clear_bit(MLX5E_RQ_STATE_CACHE_REDUCE_PENDING, &rq->state);
+}
+
+static void mlx5e_rx_cache_reduce_work(struct work_struct *work)
+{
+	struct delayed_work *dwork = to_delayed_work(work);
+	struct mlx5e_page_cache_reduce *reduce =
+		container_of(dwork, struct mlx5e_page_cache_reduce, reduce_work);
+	struct mlx5e_page_cache *cache =
+		container_of(reduce, struct mlx5e_page_cache, reduce);
+	struct mlx5e_rq *rq = container_of(cache, struct mlx5e_rq, page_cache);
+
+	local_bh_disable();
+	napi_schedule(rq->cq.napi);
+	local_bh_enable();
+	mlx5e_rx_cache_reduce_clean_pending(rq);
+
+	if (ilog2(cache->sz) > cache->log_min_sz)
+		schedule_delayed_work_on(smp_processor_id(),
+					 dwork, reduce->delay);
+}
+
+static int mlx5e_rx_alloc_page_cache(struct mlx5e_rq *rq,
+				     int node, u8 log_init_sz)
+{
+	struct mlx5e_page_cache *cache = &rq->page_cache;
+	struct mlx5e_page_cache_reduce *reduce = &cache->reduce;
+	u32 max_sz;
+
+	cache->log_max_sz = log_init_sz + MLX5E_PAGE_CACHE_LOG_MAX_RQ_MULT;
+	cache->log_min_sz = log_init_sz;
+	max_sz = 1 << cache->log_max_sz;
+
+	cache->page_cache = kvzalloc_node(max_sz * sizeof(*cache->page_cache),
+					  GFP_KERNEL, node);
+	if (!cache->page_cache)
+		return -ENOMEM;
+
+	reduce->pending = kvzalloc_node(max_sz * sizeof(*reduce->pending),
+					GFP_KERNEL, node);
+	if (!reduce->pending)
+		goto err_free_cache;
+
+	cache->sz = 1 << cache->log_min_sz;
+	cache->head = -1;
+	INIT_DELAYED_WORK(&reduce->reduce_work, mlx5e_rx_cache_reduce_work);
+	reduce->delay = msecs_to_jiffies(MLX5E_PAGE_CACHE_REDUCE_WORK_INTERVAL);
+	reduce->graceful_period = msecs_to_jiffies(MLX5E_PAGE_CACHE_REDUCE_GRACE_PERIOD);
+	reduce->next_ts = MAX_JIFFY_OFFSET; /* in init, no reduce is needed */
+
+	return 0;
+
+err_free_cache:
+	kvfree(cache->page_cache);
+
+	return -ENOMEM;
+}
+
+static void mlx5e_rx_free_page_cache(struct mlx5e_rq *rq)
+{
+	struct mlx5e_page_cache *cache = &rq->page_cache;
+	struct mlx5e_page_cache_reduce *reduce = &cache->reduce;
+	int i;
+
+	cancel_delayed_work_sync(&reduce->reduce_work);
+	mlx5e_rx_cache_reduce_clean_pending(rq);
+	kvfree(reduce->pending);
+
+	for (i = 0; i <= cache->head; i++) {
+		struct mlx5e_alloc_unit *au = &cache->page_cache[i];
+
+		mlx5e_page_release_dynamic(rq, au, false);
+	}
+	kvfree(cache->page_cache);
+}
+#endif
 
 static int mlx5e_alloc_rq(struct mlx5e_params *params,
 			  struct mlx5e_xsk_param *xsk,
 			  struct mlx5e_rq_param *rqp,
 			  int node, struct mlx5e_rq *rq)
 {
+#ifndef HAVE_PAGE_POOL_DEFRAG_PAGE
+	u32 cache_init_sz;
+#ifdef HAVE_NET_PAGE_POOL_H
+	struct page_pool_params pp_params = { 0 };
+#endif
+#endif
 	struct mlx5_core_dev *mdev = rq->mdev;
 	void *rqc = rqp->rqc;
 	void *rqc_wq = MLX5_ADDR_OF(rqc, rqc, wq);
+#if defined(HAVE_XSK_ZERO_COPY_SUPPORT) && !defined(HAVE_XSK_BUFF_ALLOC)
+	u32 num_xsk_frames = 0;
+#endif
+#ifdef HAVE_NET_PAGE_POOL_H
 	u32 pool_size;
+#endif
 	int wq_sz;
-	int err;
+	int err = 0;
 	int i;
 
 	rqp->wq.db_numa_node = node;
 	INIT_WORK(&rq->recover_work, mlx5e_rq_err_cqe_work);
 
+#ifdef HAVE_XDP_SUPPORT
 	if (params->xdp_prog)
+#ifndef HAVE_BPF_PROG_ADD_RET_STRUCT
 		bpf_prog_inc(params->xdp_prog);
+#else
+	{
+		struct bpf_prog *prog = bpf_prog_inc(params->xdp_prog);
+		if (IS_ERR(prog)) {
+			err = PTR_ERR(prog);
+			goto err_rq_xdp_prog;
+		}
+	}
+#endif /* HAVE_BPF_PROG_ADD_RET_STRUCT */
 	RCU_INIT_POINTER(rq->xdp_prog, params->xdp_prog);
 
 	rq->buff.map_dir = params->xdp_prog ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE;
+#else
+	rq->buff.map_dir = DMA_FROM_DEVICE;
+#endif
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	rq->buff.headroom = mlx5e_get_rq_headroom(mdev, params, xsk);
+#ifndef HAVE_XSK_BUFF_ALLOC
+	rq->buff.umem_headroom = xsk ? xsk->headroom : 0;
+#endif
+#else
+	rq->buff.headroom = mlx5e_get_rq_headroom(mdev, params, NULL);
+#endif /* HAVE_XSK_ZERO_COPY_SUPPORT */
+#ifdef HAVE_NET_PAGE_POOL_H
 	pool_size = 1 << params->log_rq_mtu_frames;
+#endif
 
 	rq->mkey_be = cpu_to_be32(mdev->mlx5e_res.hw_objs.mkey);
 
@@ -888,6 +1157,11 @@ static int mlx5e_alloc_rq(struct mlx5e_p
 		rq->mpwqe.wq.db = &rq->mpwqe.wq.db[MLX5_RCV_DBR];
 
 		wq_sz = mlx5_wq_ll_get_size(&rq->mpwqe.wq);
+#if defined(HAVE_XSK_ZERO_COPY_SUPPORT) && !defined(HAVE_XSK_BUFF_ALLOC)
+		if (xsk)
+			num_xsk_frames = wq_sz <<
+				mlx5e_mpwqe_get_log_num_strides(mdev, params, xsk);
+#endif
 
 		rq->mpwqe.page_shift = mlx5e_mpwrq_page_shift(mdev, xsk);
 		rq->mpwqe.umr_mode = mlx5e_mpwrq_umr_mode(mdev, xsk);
@@ -901,12 +1175,20 @@ static int mlx5e_alloc_rq(struct mlx5e_p
 			mlx5e_mpwrq_mtts_per_wqe(mdev, rq->mpwqe.page_shift,
 						 rq->mpwqe.umr_mode);
 
+#ifdef HAVE_NET_PAGE_POOL_H
 		pool_size = rq->mpwqe.pages_per_wqe <<
 			mlx5e_mpwqe_get_log_rq_size(mdev, params, xsk);
 
-		if (!mlx5e_rx_mpwqe_is_linear_skb(mdev, params, xsk) && params->xdp_prog)
+#ifdef HAVE_XDP_SUPPORT
+		if (!mlx5e_rx_mpwqe_is_linear_skb(mdev, params, xsk)&& params->xdp_prog)
 			pool_size *= 2; /* additional page per packet for the linear part */
+#endif
+#endif
 
+#ifndef HAVE_PAGE_POOL_DEFRAG_PAGE
+		cache_init_sz = rq->mpwqe.pages_per_wqe <<
+			mlx5e_mpwqe_get_log_rq_size(mdev, params, xsk);
+#endif
 		rq->mpwqe.log_stride_sz = mlx5e_mpwqe_get_log_stride_size(mdev, params, xsk);
 		rq->mpwqe.num_strides =
 			BIT(mlx5e_mpwqe_get_log_num_strides(mdev, params, xsk));
@@ -922,9 +1204,11 @@ static int mlx5e_alloc_rq(struct mlx5e_p
 		if (err)
 			goto err_rq_mkey;
 
+#ifdef HAVE_SHAMPO_SUPPORT
 		err = mlx5_rq_shampo_alloc(mdev, params, rqp, rq, &pool_size, node);
 		if (err)
 			goto err_free_mpwqe_info;
+#endif
 
 		break;
 	default: /* MLX5_WQ_TYPE_CYCLIC */
@@ -937,31 +1221,97 @@ static int mlx5e_alloc_rq(struct mlx5e_p
 
 		wq_sz = mlx5_wq_cyc_get_size(&rq->wqe.wq);
 
+#if defined(HAVE_XSK_ZERO_COPY_SUPPORT) && !defined(HAVE_XSK_BUFF_ALLOC)
+		if (xsk)
+		    num_xsk_frames = wq_sz << rq->wqe.info.log_num_frags;
+#endif
+
+#ifndef HAVE_PAGE_POOL_DEFRAG_PAGE
+		cache_init_sz = wq_sz;
+#endif
 		rq->wqe.info = rqp->frags_info;
 		rq->buff.frame0_sz = rq->wqe.info.arr[0].frag_stride;
 
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 		err = mlx5e_init_wqe_alloc_info(rq, node);
 		if (err)
 			goto err_rq_wq_destroy;
+#else
+		rq->wqe.frags =
+			kvzalloc_node(array_size(sizeof(*rq->wqe.frags),
+					(wq_sz << rq->wqe.info.log_num_frags)),
+				      GFP_KERNEL, node);
+		if (!rq->wqe.frags) {
+			err = -ENOMEM;
+			goto err_rq_wq_destroy;
+		}
+
+		err = mlx5e_init_au_list(rq, wq_sz, node);
+		if (err)
+			goto err_rq_frags;
+#endif
 	}
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	if (xsk) {
+#ifdef HAVE_XSK_BUFF_ALLOC
 		err = xdp_rxq_info_reg_mem_model(&rq->xdp_rxq,
 						 MEM_TYPE_XSK_BUFF_POOL, NULL);
+#ifdef HAVE_NETDEV_BPF_XSK_BUFF_POOL
 		xsk_pool_set_rxq_info(rq->xsk_pool, &rq->xdp_rxq);
+#else
+		xsk_buff_set_rxq_info(rq->umem, &rq->xdp_rxq);
+#endif /* HAVE_NETDEV_BPF_XSK_BUFF_POOL*/
+#else
+		err = mlx5e_xsk_resize_reuseq(rq->umem, num_xsk_frames);
+		if (unlikely(err)) {
+			mlx5_core_err(mdev, "Unable to allocate the Reuse Ring for %u frames\n",
+					num_xsk_frames);
+			goto err_free_by_rq_type;
+		}
+		rq->zca.free = mlx5e_xsk_zca_free;
+		err = xdp_rxq_info_reg_mem_model(&rq->xdp_rxq,
+						 MEM_TYPE_ZERO_COPY,
+						 &rq->zca);
+
+#endif /* HAVE_XSK_BUFF_ALLOC */
 	} else {
+#endif /* HAVE_XSK_ZERO_COPY_SUPPORT */
 		/* Create a page_pool and register it with rxq */
+#ifndef HAVE_PAGE_POOL_DEFRAG_PAGE
+		err = mlx5e_rx_alloc_page_cache(rq, node,
+				ilog2(cache_init_sz));
+		if (err)
+			goto err_free_by_rq_type;
+#endif
+#ifdef HAVE_NET_PAGE_POOL_H
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 		struct page_pool_params pp_params = { 0 };
+#endif
 
 		pp_params.order     = 0;
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
+#ifdef PP_FLAG_PAGE_FRAG
+		pp_params.flags     = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV | PP_FLAG_PAGE_FRAG;
+#else
 		pp_params.flags     = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV;
+#endif /*PP_FLAG_PAGE_FRAG*/ 
+#else
+		pp_params.flags     = 0; /* No-internal DMA mapping in page_pool */
+#endif
 		pp_params.pool_size = pool_size;
 		pp_params.nid       = node;
 		pp_params.dev       = rq->pdev;
+#ifdef HAVE_PAGE_POOL_PARAM_HAS_NAPI
 		pp_params.napi      = rq->cq.napi;
+#endif
+#ifdef HAVE_PAGE_POOL_PARAMS_HAS_NETDEV
 		pp_params.netdev    = rq->netdev;
+#endif
 		pp_params.dma_dir   = rq->buff.map_dir;
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 		pp_params.max_len   = PAGE_SIZE;
+#endif
 
 		/* page_pool can be used even when there is no rq->xdp_prog,
 		 * given page_pool does not handle DMA mapping there is no
@@ -972,15 +1322,32 @@ static int mlx5e_alloc_rq(struct mlx5e_p
 		if (IS_ERR(rq->page_pool)) {
 			err = PTR_ERR(rq->page_pool);
 			rq->page_pool = NULL;
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 			goto err_free_by_rq_type;
+#else
+			goto err_free_page_cache;
+#endif
 		}
+#endif /* HAVE_NET_PAGE_POOL_H */
+#if defined(HAVE_XDP_SUPPORT)
 		if (xdp_rxq_info_is_reg(&rq->xdp_rxq))
 			err = xdp_rxq_info_reg_mem_model(&rq->xdp_rxq,
+#ifdef HAVE_NET_PAGE_POOL_H
 							 MEM_TYPE_PAGE_POOL, rq->page_pool);
+#else
+							 MEM_TYPE_PAGE_ORDER0, NULL);
+#endif /* HAVE_NET_PAGE_POOL_H*/
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	}
+#endif
 	if (err)
+#ifdef HAVE_NET_PAGE_POOL_H
 		goto err_destroy_page_pool;
+#else
+		goto err_free_by_rq_type;
+#endif
 
+#endif /* HAVE_XDP_SUPPORT */
 	for (i = 0; i < wq_sz; i++) {
 		if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
 			struct mlx5e_rx_wqe_ll *wqe =
@@ -1029,13 +1396,21 @@ static int mlx5e_alloc_rq(struct mlx5e_p
 
 	return 0;
 
+#if defined(HAVE_XDP_SUPPORT) && defined(HAVE_NET_PAGE_POOL_H)
 err_destroy_page_pool:
 	page_pool_destroy(rq->page_pool);
+#endif
+#ifndef HAVE_PAGE_POOL_DEFRAG_PAGE
+err_free_page_cache:
+	mlx5e_rx_free_page_cache(rq);
+#endif
 err_free_by_rq_type:
 	switch (rq->wq_type) {
 	case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+#ifdef HAVE_SHAMPO_SUPPORT
 		mlx5e_rq_free_shampo(rq);
 err_free_mpwqe_info:
+#endif
 		kvfree(rq->mpwqe.info);
 err_rq_mkey:
 		mlx5_core_destroy_mkey(mdev, be32_to_cpu(rq->mpwqe.umr_mkey_be));
@@ -1043,19 +1418,28 @@ err_rq_drop_page:
 		mlx5e_free_mpwqe_rq_drop_page(rq);
 		break;
 	default: /* MLX5_WQ_TYPE_CYCLIC */
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 		mlx5e_free_wqe_alloc_info(rq);
+#else
+		mlx5e_free_au_list(rq);
+err_rq_frags:
+		kvfree(rq->wqe.frags);
+#endif
 	}
 err_rq_wq_destroy:
 	mlx5_wq_destroy(&rq->wq_ctrl);
 err_rq_xdp_prog:
+#ifdef HAVE_XDP_SUPPORT
 	if (params->xdp_prog)
 		bpf_prog_put(params->xdp_prog);
+#endif
 
 	return err;
 }
 
 static void mlx5e_free_rq(struct mlx5e_rq *rq)
 {
+#ifdef HAVE_XDP_SUPPORT
 	struct bpf_prog *old_prog;
 
 	if (xdp_rxq_info_is_reg(&rq->xdp_rxq)) {
@@ -1064,20 +1448,40 @@ static void mlx5e_free_rq(struct mlx5e_r
 		if (old_prog)
 			bpf_prog_put(old_prog);
 	}
+#endif /* HAVE_XDP_SUPPORT */
 
+#ifndef HAVE_PAGE_POOL_DEFRAG_PAGE
+	if (rq->page_cache.page_cache)
+		mlx5e_rx_free_page_cache(rq);
+#endif
 	switch (rq->wq_type) {
 	case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
 		kvfree(rq->mpwqe.info);
 		mlx5_core_destroy_mkey(rq->mdev, be32_to_cpu(rq->mpwqe.umr_mkey_be));
 		mlx5e_free_mpwqe_rq_drop_page(rq);
+#ifdef HAVE_SHAMPO_SUPPORT
 		mlx5e_rq_free_shampo(rq);
+#endif
 		break;
 	default: /* MLX5_WQ_TYPE_CYCLIC */
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 		mlx5e_free_wqe_alloc_info(rq);
+#else
+		kvfree(rq->wqe.frags);
+		mlx5e_free_au_list(rq);
+#endif
 	}
 
+#if defined(HAVE_XDP_SUPPORT)
 	xdp_rxq_info_unreg(&rq->xdp_rxq);
-	page_pool_destroy(rq->page_pool);
+#endif
+
+#ifdef HAVE_NET_PAGE_POOL_H
+#ifdef HAVE_BASECODE_EXTRAS
+        if (rq->page_pool)
+#endif /* HAVE_BASECODE_EXTRAS */
+		page_pool_destroy(rq->page_pool);
+#endif
 	mlx5_wq_destroy(&rq->wq_ctrl);
 }
 
@@ -1138,11 +1542,13 @@ int mlx5e_create_rq(struct mlx5e_rq *rq,
 						MLX5_ADAPTER_PAGE_SHIFT);
 	MLX5_SET64(wq, wq,  dbr_addr,		rq->wq_ctrl.db.dma);
 
+#ifdef HAVE_SHAMPO_SUPPORT
 	if (test_bit(MLX5E_RQ_STATE_SHAMPO, &rq->state)) {
 		MLX5_SET(wq, wq, log_headers_buffer_entry_num,
 			 order_base_2(rq->mpwqe.shampo->hd_per_wq));
 		MLX5_SET(wq, wq, headers_mkey, rq->mpwqe.shampo->mkey);
 	}
+#endif
 
 	mlx5_fill_page_frag_array(&rq->wq_ctrl.buf,
 				  (__be64 *)MLX5_ADDR_OF(wq, wq, pas));
@@ -1275,7 +1681,11 @@ int mlx5e_wait_for_min_rx_wqes(struct ml
 	return -ETIMEDOUT;
 }
 
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 void mlx5e_free_rx_missing_descs(struct mlx5e_rq *rq)
+#else
+void mlx5e_free_rx_in_progress_descs(struct mlx5e_rq *rq)
+#endif
 {
 	struct mlx5_wq_ll *wq;
 	u16 head;
@@ -1287,16 +1697,22 @@ void mlx5e_free_rx_missing_descs(struct
 	wq = &rq->mpwqe.wq;
 	head = wq->head;
 
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 	/* Release WQEs that are in missing state: they have been
 	 * popped from the list after completion but were not freed
 	 * due to deferred release.
 	 * Also free the linked-list reserved entry, hence the "+ 1".
 	 */
 	for (i = 0; i < mlx5_wq_ll_missing(wq) + 1; i++) {
+#else
+	/* Outstanding UMR WQEs (in progress) start at wq->head */
+	for (i = 0; i < rq->mpwqe.umr_in_progress; i++) {
+#endif
 		rq->dealloc_wqe(rq, head);
 		head = mlx5_wq_ll_get_wqe_next_ix(wq, head);
 	}
 
+#ifdef HAVE_SHAMPO_SUPPORT
 	if (test_bit(MLX5E_RQ_STATE_SHAMPO, &rq->state)) {
 		u16 len;
 
@@ -1305,6 +1721,7 @@ void mlx5e_free_rx_missing_descs(struct
 		mlx5e_shampo_dealloc_hd(rq, len, rq->mpwqe.shampo->ci, false);
 		rq->mpwqe.shampo->pi = rq->mpwqe.shampo->ci;
 	}
+#endif
 
 	rq->mpwqe.actual_wq_head = wq->head;
 	rq->mpwqe.umr_in_progress = 0;
@@ -1319,7 +1736,11 @@ void mlx5e_free_rx_descs(struct mlx5e_rq
 	if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
 		struct mlx5_wq_ll *wq = &rq->mpwqe.wq;
 
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 		mlx5e_free_rx_missing_descs(rq);
+#else
+		mlx5e_free_rx_in_progress_descs(rq);
+#endif
 
 		while (!mlx5_wq_ll_is_empty(wq)) {
 			struct mlx5e_rx_wqe_ll *wqe;
@@ -1332,19 +1753,24 @@ void mlx5e_free_rx_descs(struct mlx5e_rq
 				       &wqe->next.next_wqe_index);
 		}
 
+#ifdef HAVE_SHAMPO_SUPPORT
 		if (test_bit(MLX5E_RQ_STATE_SHAMPO, &rq->state))
 			mlx5e_shampo_dealloc_hd(rq, rq->mpwqe.shampo->hd_per_wq,
 						0, true);
+#endif
 	} else {
 		struct mlx5_wq_cyc *wq = &rq->wqe.wq;
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 		u16 missing = mlx5_wq_cyc_missing(wq);
 		u16 head = mlx5_wq_cyc_get_head(wq);
+#endif
 
 		while (!mlx5_wq_cyc_is_empty(wq)) {
 			wqe_ix = mlx5_wq_cyc_get_tail(wq);
 			rq->dealloc_wqe(rq, wqe_ix);
 			mlx5_wq_cyc_pop(wq);
 		}
+#ifdef HAVE_PAGE_POOL_DEFRAG_PAGE
 		/* Missing slots might also contain unreleased pages due to
 		 * deferred release.
 		 */
@@ -1352,10 +1778,64 @@ void mlx5e_free_rx_descs(struct mlx5e_rq
 			wqe_ix = mlx5_wq_cyc_ctr2ix(wq, head++);
 			rq->dealloc_wqe(rq, wqe_ix);
 		}
+#endif
 	}
 
 }
 
+#ifdef CONFIG_COMPAT_LRO_ENABLED_IPOIB
+static int get_skb_hdr(struct sk_buff *skb, void **iphdr,
+			void **tcph, u64 *hdr_flags, void *priv)
+{
+	unsigned int ip_len;
+	struct iphdr *iph;
+
+	if (unlikely(skb->protocol != htons(ETH_P_IP)))
+		return -1;
+
+	/*
+	* In the future we may add an else clause that verifies the
+	* checksum and allows devices which do not calculate checksum
+	* to use LRO.
+	*/
+	if (unlikely(skb->ip_summed != CHECKSUM_UNNECESSARY))
+		return -1;
+
+	/* Check for non-TCP packet */
+	skb_reset_network_header(skb);
+	iph = ip_hdr(skb);
+	if (iph->protocol != IPPROTO_TCP)
+		return -1;
+
+	ip_len = ip_hdrlen(skb);
+	skb_set_transport_header(skb, ip_len);
+	*tcph = tcp_hdr(skb);
+
+	/* check if IP header and TCP header are complete */
+	if (ntohs(iph->tot_len) < ip_len + tcp_hdrlen(skb))
+		return -1;
+
+	*hdr_flags = LRO_IPV4 | LRO_TCP;
+	*iphdr = iph;
+
+	return 0;
+}
+
+static void mlx5e_rq_sw_lro_init(struct mlx5e_rq *rq)
+{
+	rq->sw_lro = &rq->priv->sw_lro[rq->ix];
+	rq->sw_lro->lro_mgr.max_aggr 		= 64;
+	rq->sw_lro->lro_mgr.max_desc		= MLX5E_LRO_MAX_DESC;
+	rq->sw_lro->lro_mgr.lro_arr		= rq->sw_lro->lro_desc;
+	rq->sw_lro->lro_mgr.get_skb_header	= get_skb_hdr;
+	rq->sw_lro->lro_mgr.features		= LRO_F_NAPI;
+	rq->sw_lro->lro_mgr.frag_align_pad	= NET_IP_ALIGN;
+	rq->sw_lro->lro_mgr.dev			= rq->netdev;
+	rq->sw_lro->lro_mgr.ip_summed		= CHECKSUM_UNNECESSARY;
+	rq->sw_lro->lro_mgr.ip_summed_aggr	= CHECKSUM_UNNECESSARY;
+}
+#endif
+
 int mlx5e_open_rq(struct mlx5e_params *params, struct mlx5e_rq_param *param,
 		  struct mlx5e_xsk_param *xsk, int node, u16 q_counter,
 		  struct mlx5e_rq *rq, struct mlx5e_create_cq_param *ccp)
@@ -1391,6 +1871,10 @@ int mlx5e_open_rq(struct mlx5e_params *p
 		mlx5_core_warn(mdev, "Failed to enable delay drop err=%d\n",
 			       err);
 
+#ifdef CONFIG_COMPAT_LRO_ENABLED_IPOIB
+	mlx5e_rq_sw_lro_init(rq);
+#endif
+
 	err = mlx5e_modify_rq_state(rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY);
 	if (err)
 		goto err_destroy_rq;
@@ -1405,7 +1889,11 @@ int mlx5e_open_rq(struct mlx5e_params *p
 	 * XDP programs might manipulate packets which will render
 	 * skb->checksum incorrect.
 	 */
+#ifdef HAVE_XDP_SUPPORT
 	if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_NO_CSUM_COMPLETE) || params->xdp_prog)
+#else
+	if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_NO_CSUM_COMPLETE))
+#endif
 		__set_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &rq->state);
 
 	/* For CQE compression on striding RQ, use stride index provided by
@@ -1469,6 +1957,7 @@ u32 mlx5e_profile_get_tisn(struct mlx5_c
 	return mdev->mlx5e_res.hw_objs.tisn[lag_port][tc];
 }
 
+#ifdef HAVE_XDP_SUPPORT
 static void mlx5e_free_xdpsq_db(struct mlx5e_xdpsq *sq)
 {
 	kvfree(sq->db.xdpi_fifo.xi);
@@ -1520,7 +2009,13 @@ static int mlx5e_alloc_xdpsq_db(struct m
 
 static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c,
 			     struct mlx5e_params *params,
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+#ifdef HAVE_NETDEV_BPF_XSK_BUFF_POOL
 			     struct xsk_buff_pool *xsk_pool,
+#else
+			     struct xdp_umem *xsk_pool,
+#endif
+#endif
 			     struct mlx5e_sq_param *param,
 			     struct mlx5e_xdpsq *sq,
 			     bool is_redirect)
@@ -1536,11 +2031,20 @@ static int mlx5e_alloc_xdpsq(struct mlx5
 	sq->uar_map   = mdev->mlx5e_res.hw_objs.bfreg.map;
 	sq->min_inline_mode = params->tx_min_inline_mode;
 	sq->hw_mtu    = MLX5E_SW2HW_MTU(params, params->sw_mtu) - ETH_FCS_LEN;
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+#ifdef HAVE_NETDEV_BPF_XSK_BUFF_POOL
 	sq->xsk_pool  = xsk_pool;
 
 	sq->stats = sq->xsk_pool ?
+#else
+	sq->umem  = xsk_pool;
+	sq->stats = sq->umem ?
+#endif
 		&c->priv->channel_stats[c->ix]->xsksq :
 		is_redirect ?
+#else
+	sq->stats = is_redirect ?
+#endif
 			&c->priv->channel_stats[c->ix]->xdpsq :
 			&c->priv->channel_stats[c->ix]->rq_xdpsq;
 	sq->stop_room = param->is_mpw ? mlx5e_stop_room_for_mpwqe(mdev) :
@@ -1570,6 +2074,7 @@ static void mlx5e_free_xdpsq(struct mlx5
 	mlx5e_free_xdpsq_db(sq);
 	mlx5_wq_destroy(&sq->wq_ctrl);
 }
+#endif /* HAVE_XDP_SUPPORT */
 
 static void mlx5e_free_icosq_db(struct mlx5e_icosq *sq)
 {
@@ -1912,7 +2417,9 @@ void mlx5e_activate_txqsq(struct mlx5e_t
 	set_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
 	netdev_tx_reset_queue(sq->txq);
 	netif_tx_start_queue(sq->txq);
+#ifdef HAVE_QUEUE_AND_NAPI_ASSOCIATION
 	netif_queue_set_napi(sq->netdev, sq->txq_ix, NETDEV_QUEUE_TYPE_TX, sq->cq.napi);
+#endif
 }
 
 void mlx5e_tx_disable_queue(struct netdev_queue *txq)
@@ -1926,7 +2433,9 @@ void mlx5e_deactivate_txqsq(struct mlx5e
 {
 	struct mlx5_wq_cyc *wq = &sq->wq;
 
+#ifdef HAVE_QUEUE_AND_NAPI_ASSOCIATION
 	netif_queue_set_napi(sq->netdev, sq->txq_ix, NETDEV_QUEUE_TYPE_TX, NULL);
+#endif
 	clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
 	synchronize_net(); /* Sync with NAPI to prevent netif_tx_wake_queue. */
 
@@ -1988,6 +2497,7 @@ static int mlx5e_open_icosq(struct mlx5e
 	if (err)
 		goto err_free_icosq;
 
+#ifdef HAVE_KTLS_RX_SUPPORT
 	if (param->is_tls) {
 		sq->ktls_resync = mlx5e_ktls_rx_resync_create_resp_list();
 		if (IS_ERR(sq->ktls_resync)) {
@@ -1995,10 +2505,13 @@ static int mlx5e_open_icosq(struct mlx5e
 			goto err_destroy_icosq;
 		}
 	}
+#endif
 	return 0;
 
+#ifdef HAVE_KTLS_RX_SUPPORT
 err_destroy_icosq:
 	mlx5e_destroy_sq(c->mdev, sq->sqn);
+#endif
 err_free_icosq:
 	mlx5e_free_icosq(sq);
 
@@ -2027,14 +2540,26 @@ static void mlx5e_close_icosq(struct mlx
 	mlx5e_free_icosq(sq);
 }
 
+#ifdef HAVE_XDP_SUPPORT
 int mlx5e_open_xdpsq(struct mlx5e_channel *c, struct mlx5e_params *params,
-		     struct mlx5e_sq_param *param, struct xsk_buff_pool *xsk_pool,
+		     struct mlx5e_sq_param *param,
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+#ifdef HAVE_NETDEV_BPF_XSK_BUFF_POOL
+		     struct xsk_buff_pool *xsk_pool,
+#else
+		     struct xdp_umem *xsk_pool,
+#endif
+#endif
 		     struct mlx5e_xdpsq *sq, bool is_redirect)
 {
 	struct mlx5e_create_sq_param csp = {};
 	int err;
 
-	err = mlx5e_alloc_xdpsq(c, params, xsk_pool, param, sq, is_redirect);
+	err = mlx5e_alloc_xdpsq(c, params,
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+				xsk_pool,
+#endif
+				param, sq, is_redirect);
 	if (err)
 		return err;
 
@@ -2103,6 +2628,7 @@ void mlx5e_close_xdpsq(struct mlx5e_xdps
 	mlx5e_free_xdpsq_descs(sq);
 	mlx5e_free_xdpsq(sq);
 }
+#endif
 
 static int mlx5e_alloc_cq_common(struct mlx5_core_dev *mdev,
 				 struct net_device *netdev,
@@ -2477,6 +3003,7 @@ static int mlx5e_open_queues(struct mlx5
 	if (err)
 		goto err_close_icosq_cq;
 
+#ifdef HAVE_XDP_SUPPORT
 	err = mlx5e_open_cq(c->mdev, params->tx_cq_moderation, &cparam->xdp_sq.cqp, &ccp,
 			    &c->xdpsq.cq);
 	if (err)
@@ -2486,6 +3013,7 @@ static int mlx5e_open_queues(struct mlx5
 				     &ccp, &c->rq_xdpsq.cq) : 0;
 	if (err)
 		goto err_close_xdp_tx_cqs;
+#endif
 
 	spin_lock_init(&c->async_icosq_lock);
 
@@ -2509,25 +3037,36 @@ static int mlx5e_open_queues(struct mlx5
 	if (err)
 		goto err_close_sqs;
 
+#ifdef HAVE_XDP_SUPPORT
 	if (c->xdp) {
-		err = mlx5e_open_xdpsq(c, params, &cparam->xdp_sq, NULL,
+		err = mlx5e_open_xdpsq(c, params, &cparam->xdp_sq,
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+				       NULL,
+#endif
 				       &c->rq_xdpsq, false);
 		if (err)
 			goto err_close_rq;
 	}
 
-	err = mlx5e_open_xdpsq(c, params, &cparam->xdp_sq, NULL, &c->xdpsq, true);
+	err = mlx5e_open_xdpsq(c, params, &cparam->xdp_sq,
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+			      NULL,
+#endif
+			      &c->xdpsq, true);
 	if (err)
 		goto err_close_xdp_sq;
+#endif
 
 	return 0;
 
+#ifdef HAVE_XDP_SUPPORT
 err_close_xdp_sq:
 	if (c->xdp)
 		mlx5e_close_xdpsq(&c->rq_xdpsq);
 
 err_close_rq:
 	mlx5e_close_rq(c->priv, &c->rq);
+#endif
 
 err_close_sqs:
 	mlx5e_close_sqs(c);
@@ -2539,6 +3078,7 @@ err_close_async_icosq:
 	mlx5e_close_icosq(&c->async_icosq);
 
 err_close_xdpsq_cq:
+#ifdef HAVE_XDP_SUPPORT
 	if (c->xdp)
 		mlx5e_close_cq(&c->rq_xdpsq.cq);
 
@@ -2546,6 +3086,7 @@ err_close_xdp_tx_cqs:
 	mlx5e_close_cq(&c->xdpsq.cq);
 
 err_close_tx_cqs:
+#endif
 	mlx5e_close_tx_cqs(c);
 
 err_close_icosq_cq:
@@ -2559,9 +3100,11 @@ err_close_async_icosq_cq:
 
 static void mlx5e_close_queues(struct mlx5e_channel *c)
 {
+#ifdef HAVE_XDP_SUPPORT
 	mlx5e_close_xdpsq(&c->xdpsq);
 	if (c->xdp)
 		mlx5e_close_xdpsq(&c->rq_xdpsq);
+#endif
 	/* The same ICOSQ is used for UMRs for both RQ and XSKRQ. */
 	cancel_work_sync(&c->icosq.recover_work);
 	mlx5e_close_rq(c->priv, &c->rq);
@@ -2569,9 +3112,11 @@ static void mlx5e_close_queues(struct ml
 	mlx5e_close_icosq(&c->icosq);
 	mutex_destroy(&c->icosq_recovery_lock);
 	mlx5e_close_icosq(&c->async_icosq);
+#ifdef HAVE_XDP_SUPPORT
 	if (c->xdp)
 		mlx5e_close_cq(&c->rq_xdpsq.cq);
 	mlx5e_close_cq(&c->xdpsq.cq);
+#endif
 	mlx5e_close_tx_cqs(c);
 	mlx5e_close_cq(&c->icosq.cq);
 	mlx5e_close_cq(&c->async_icosq.cq);
@@ -2624,13 +3169,23 @@ void mlx5e_trigger_napi_sched(struct nap
 
 static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
 			      struct mlx5e_params *params,
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+#ifdef HAVE_NETDEV_BPF_XSK_BUFF_POOL
 			      struct xsk_buff_pool *xsk_pool,
+#else
+
+			      struct xdp_umem *xsk_pool,
+#endif
+#endif
 			      struct mlx5e_channel **cp)
 {
 	struct net_device *netdev = priv->netdev;
 	struct mlx5e_channel_param *cparam;
 	struct mlx5_core_dev *mdev;
+	const struct cpumask *aff;
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	struct mlx5e_xsk_param xsk;
+#endif
 	struct mlx5e_channel *c;
 	unsigned int irq;
 	int vec_ix;
@@ -2649,6 +3204,11 @@ static int mlx5e_open_channel(struct mlx
 	if (err)
 		return err;
 
+#ifdef HAVE_IRQ_GET_EFFECTIVE_AFFINITY_MASK
+	aff = irq_get_effective_affinity_mask(irq);
+#else 
+	aff = irq_get_affinity_mask(irq);
+#endif
 	c = kvzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu));
 	cparam = kvzalloc(sizeof(*cparam), GFP_KERNEL);
 	if (!c || !cparam) {
@@ -2671,32 +3231,44 @@ static int mlx5e_open_channel(struct mlx
 	c->netdev   = priv->netdev;
 	c->mkey_be  = cpu_to_be32(mdev->mlx5e_res.hw_objs.mkey);
 	c->num_tc   = mlx5e_get_dcb_num_tc(params);
+#ifdef HAVE_XDP_SUPPORT
 	c->xdp      = !!params->xdp_prog;
+#endif
 	c->stats    = &priv->channel_stats[ix]->ch;
-	c->aff_mask = irq_get_effective_affinity_mask(irq);
+	c->aff_mask = aff;
 	c->lag_port = mlx5e_enumerate_lag_port(mdev, ix);
 
+#ifdef HAVE_NETIF_NAPI_ADD_GET_3_PARAMS
 	netif_napi_add(netdev, &c->napi, mlx5e_napi_poll);
+#else
+	netif_napi_add(netdev, &c->napi, mlx5e_napi_poll, 64);
+#endif
+#ifdef HAVE_QUEUE_AND_NAPI_ASSOCIATION
 	netif_napi_set_irq(&c->napi, irq);
+#endif
 
 	err = mlx5e_open_queues(c, params, cparam);
 	if (unlikely(err))
 		goto err_napi_del;
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	if (xsk_pool) {
 		mlx5e_build_xsk_param(xsk_pool, &xsk);
 		err = mlx5e_open_xsk(priv, params, &xsk, xsk_pool, c);
 		if (unlikely(err))
 			goto err_close_queues;
 	}
+#endif
 
 	*cp = c;
 
 	kvfree(cparam);
 	return 0;
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 err_close_queues:
 	mlx5e_close_queues(c);
+#endif
 
 err_napi_del:
 	netif_napi_del(&c->napi);
@@ -2713,9 +3285,11 @@ static void mlx5e_rq_channel_activate(st
 	if (c->priv->shared_rq)
 		return;
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state))
 		mlx5e_activate_xsk(c);
 	else
+#endif
 		mlx5e_activate_rq(&c->rq);
 }
 
@@ -2733,7 +3307,9 @@ static void mlx5e_activate_channel(struc
 	mlx5e_rq_channel_activate(c);
 
 	mlx5e_trigger_napi_icosq(c);
+#ifdef HAVE_QUEUE_AND_NAPI_ASSOCIATION
 	netif_queue_set_napi(c->netdev, c->ix, NETDEV_QUEUE_TYPE_RX, &c->napi);
+#endif
 }
 
 static void mlx5e_rq_channel_deactivate(struct mlx5e_channel *c)
@@ -2741,11 +3317,15 @@ static void mlx5e_rq_channel_deactivate(
 	if (c->priv->shared_rq)
 		return;
 
+#ifdef HAVE_QUEUE_AND_NAPI_ASSOCIATION
 	netif_queue_set_napi(c->netdev, c->ix, NETDEV_QUEUE_TYPE_RX, NULL);
+#endif
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state))
 		mlx5e_deactivate_xsk(c);
 	else
+#endif
 		mlx5e_deactivate_rq(&c->rq);
 }
 
@@ -2766,8 +3346,10 @@ static void mlx5e_deactivate_channel(str
 
 static void mlx5e_close_channel(struct mlx5e_channel *c)
 {
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state))
 		mlx5e_close_xsk(c);
+#endif
 	mlx5e_close_queues(c);
 	mlx5e_qos_close_queues(c);
 	netif_napi_del(&c->napi);
@@ -2788,12 +3370,22 @@ int mlx5e_open_channels(struct mlx5e_pri
 		goto err_out;
 
 	for (i = 0; i < chs->num; i++) {
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+#ifdef HAVE_NETDEV_BPF_XSK_BUFF_POOL
 		struct xsk_buff_pool *xsk_pool = NULL;
+#else
+		struct xdp_umem *xsk_pool = NULL;
+#endif
 
 		if (chs->params.xdp_prog)
 			xsk_pool = mlx5e_xsk_get_pool(&chs->params, chs->params.xsk, i);
 
-		err = mlx5e_open_channel(priv, i, &chs->params, xsk_pool, &chs->c[i]);
+#endif
+		err = mlx5e_open_channel(priv, i, &chs->params,
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+					xsk_pool,
+#endif
+					&chs->c[i]);
 		if (err)
 			goto err_close_channels;
 	}
@@ -2899,7 +3491,7 @@ int mlx5e_modify_tirs_packet_merge(struc
 	return mlx5e_rx_res_packet_merge_set_param(res, &priv->channels.params.packet_merge);
 }
 
-static MLX5E_DEFINE_PREACTIVATE_WRAPPER_CTX(mlx5e_modify_tirs_packet_merge);
+MLX5E_DEFINE_PREACTIVATE_WRAPPER_CTX(mlx5e_modify_tirs_packet_merge);
 
 static int mlx5e_set_mtu(struct mlx5_core_dev *mdev,
 			 struct mlx5e_params *params, u16 mtu)
@@ -2998,7 +3590,6 @@ int mlx5e_update_tx_netdev_queues(struct
 {
 	int nch, ntc, num_txqs, err;
 	int qos_queues = 0;
-
 	if (priv->htb)
 		qos_queues = mlx5e_htb_cur_leaf_nodes(priv->htb);
 
@@ -3007,13 +3598,11 @@ int mlx5e_update_tx_netdev_queues(struct
 	num_txqs = nch * ntc + qos_queues;
 	if (MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_TX_PORT_TS))
 		num_txqs += ntc;
-
 	netdev_dbg(priv->netdev, "Setting num_txqs %d\n", num_txqs);
 	err = netif_set_real_num_tx_queues(priv->netdev, num_txqs);
 	if (err)
 		netdev_warn(priv->netdev, "netif_set_real_num_tx_queues failed (%d > %d), %d\n",
 			    num_txqs, priv->netdev->num_tx_queues, err);
-
 	return err;
 }
 
@@ -3178,7 +3767,9 @@ void mlx5e_activate_priv_channels(struct
 {
 	mlx5e_build_txq_maps(priv);
 	mlx5e_activate_channels(priv, &priv->channels);
+#ifdef HAVE_XDP_SUPPORT
 	mlx5e_xdp_tx_enable(priv);
+#endif
 
 	/* dev_watchdog() wants all TX queues to be started when the carrier is
 	 * OK, including the ones in range real_num_tx_queues..num_tx_queues-1.
@@ -3227,7 +3818,9 @@ void mlx5e_deactivate_priv_channels(stru
 	 */
 	netif_tx_disable(priv->netdev);
 
+#ifdef HAVE_XDP_SUPPORT
 	mlx5e_xdp_tx_disable(priv);
+#endif
 	mlx5e_deactivate_channels(&priv->channels);
 }
 
@@ -3476,7 +4069,9 @@ static int mlx5e_alloc_drop_rq(struct ml
 		return err;
 
 	/* Mark as unused given "Drop-RQ" packets never reach XDP */
+#ifdef HAVE_XDP_SUPPORT
 	xdp_rxq_info_unused(&rq->xdp_rxq);
+#endif
 
 	rq->mdev = mdev;
 
@@ -3558,7 +4153,10 @@ static void mlx5e_cleanup_nic_tx(struct
 	mlx5e_accel_cleanup_tx(priv);
 }
 
-static int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd)
+#ifndef LEGACY_ETHTOOL_OPS
+static
+#endif
+int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd)
 {
 	int err;
 	int i;
@@ -3592,6 +4190,19 @@ static void mlx5e_mqprio_build_default_t
 	}
 }
 
+static void mlx5e_params_mqprio_dcb_set(struct mlx5e_params *params, u8 num_tc)
+{
+	params->mqprio.mode = TC_MQPRIO_MODE_DCB;
+	params->mqprio.num_tc = num_tc;
+	mlx5e_mqprio_build_default_tc_to_txq(params->mqprio.tc_to_txq, num_tc,
+					     params->num_channels);
+}
+
+static void mlx5e_params_mqprio_reset(struct mlx5e_params *params)
+{
+	mlx5e_params_mqprio_dcb_set(params, 1);
+}
+
 static void mlx5e_mqprio_build_tc_to_txq(struct netdev_tc_txq *tc_to_txq,
 					 struct tc_mqprio_qopt *qopt)
 {
@@ -3605,14 +4216,6 @@ static void mlx5e_mqprio_build_tc_to_txq
 	}
 }
 
-static void mlx5e_params_mqprio_dcb_set(struct mlx5e_params *params, u8 num_tc)
-{
-	params->mqprio.mode = TC_MQPRIO_MODE_DCB;
-	params->mqprio.num_tc = num_tc;
-	mlx5e_mqprio_build_default_tc_to_txq(params->mqprio.tc_to_txq, num_tc,
-					     params->num_channels);
-}
-
 static void mlx5e_mqprio_rl_update_params(struct mlx5e_params *params,
 					  struct mlx5e_mqprio_rl *rl)
 {
@@ -3643,11 +4246,6 @@ static void mlx5e_params_mqprio_channel_
 	mlx5e_mqprio_build_tc_to_txq(params->mqprio.tc_to_txq, &mqprio->qopt);
 }
 
-static void mlx5e_params_mqprio_reset(struct mlx5e_params *params)
-{
-	mlx5e_params_mqprio_dcb_set(params, 1);
-}
-
 static int mlx5e_setup_tc_mqprio_dcb(struct mlx5e_priv *priv,
 				     struct tc_mqprio_qopt *mqprio)
 {
@@ -3818,7 +4416,8 @@ static int mlx5e_setup_tc_mqprio_channel
 }
 
 int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv,
-				 struct tc_mqprio_qopt_offload *mqprio)
+				struct tc_mqprio_qopt_offload *mqprio
+)
 {
 	/* MQPRIO is another toplevel qdisc that can't be attached
 	 * simultaneously with the offloaded HTB.
@@ -3834,44 +4433,72 @@ int mlx5e_setup_tc_mqprio(struct mlx5e_p
 	default:
 		return -EOPNOTSUPP;
 	}
+
 }
 
+#ifdef HAVE_FLOW_CLS_OFFLOAD
 static LIST_HEAD(mlx5e_block_cb_list);
+#endif
 
+#ifdef HAVE_TC_SETUP_CB_EGDEV_REGISTER
+int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type,
+		   void *type_data)
+#else
 static int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type,
 			  void *type_data)
+#endif
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 	bool tc_unbind = false;
 	int err;
 
+#if defined(HAVE_TC_BLOCK_OFFLOAD) || defined(HAVE_FLOW_BLOCK_OFFLOAD)
 	if (type == TC_SETUP_BLOCK &&
 	    ((struct flow_block_offload *)type_data)->command == FLOW_BLOCK_UNBIND)
 		tc_unbind = true;
+#endif
 
 	if (!netif_device_present(dev) && !tc_unbind)
 		return -ENODEV;
 
 	switch (type) {
+#ifdef CONFIG_MLX5_ESWITCH
+#if defined(HAVE_TC_BLOCK_OFFLOAD) || defined(HAVE_FLOW_BLOCK_OFFLOAD)
+#ifdef HAVE_FLOW_BLOCK_CB_SETUP_SIMPLE
 	case TC_SETUP_BLOCK: {
+#ifdef HAVE_UNLOCKED_DRIVER_CB
 		struct flow_block_offload *f = type_data;
 
 		f->unlocked_driver_cb = true;
+#endif
 		return flow_block_cb_setup_simple(type_data,
 						  &mlx5e_block_cb_list,
 						  mlx5e_setup_tc_block_cb,
 						  priv, priv, true);
 	}
+#else /* HAVE_FLOW_BLOCK_CB_SETUP_SIMPLE */
+	case TC_SETUP_BLOCK:
+		return mlx5e_setup_tc_block(dev, type_data);
+#endif /* HAVE_FLOW_BLOCK_CB_SETUP_SIMPLE */
+#else
+	case TC_SETUP_CLSFLOWER:
+#ifdef CONFIG_MLX5_CLS_ACT
+		return mlx5e_setup_tc_cls_flower(dev, type_data, MLX5_TC_FLAG(INGRESS));
+#endif
+#endif /* HAVE_TC_BLOCK_OFFLOAD || HAVE_FLOW_BLOCK_OFFLOAD */
+#endif /* CONFIG_MLX5_ESWITCH */
 	case TC_SETUP_QDISC_MQPRIO:
 		mutex_lock(&priv->state_lock);
 		err = mlx5e_setup_tc_mqprio(priv, type_data);
 		mutex_unlock(&priv->state_lock);
 		return err;
+#ifdef HAVE_ENUM_TC_HTB_COMMAND
 	case TC_SETUP_QDISC_HTB:
 		mutex_lock(&priv->state_lock);
 		err = mlx5e_htb_setup_tc(priv, type_data);
 		mutex_unlock(&priv->state_lock);
 		return err;
+#endif
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -3883,13 +4510,27 @@ void mlx5e_fold_sw_stats64(struct mlx5e_
 
 	for (i = 0; i < priv->stats_nch; i++) {
 		struct mlx5e_channel_stats *channel_stats = priv->channel_stats[i];
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 		struct mlx5e_rq_stats *xskrq_stats = &channel_stats->xskrq;
+#endif
 		struct mlx5e_rq_stats *rq_stats = &channel_stats->rq;
 		int j;
 
-		s->rx_packets   += rq_stats->packets + xskrq_stats->packets;
-		s->rx_bytes     += rq_stats->bytes + xskrq_stats->bytes;
-		s->multicast    += rq_stats->mcast_packets + xskrq_stats->mcast_packets;
+		s->rx_packets   += rq_stats->packets
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+				+ xskrq_stats->packets
+#endif
+				;
+		s->rx_bytes     += rq_stats->bytes
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+				+ xskrq_stats->bytes
+#endif
+				;
+		s->multicast    += rq_stats->mcast_packets
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+				+ xskrq_stats->mcast_packets
+#endif
+				;
 
 		for (j = 0; j < priv->max_opened_tc; j++) {
 			struct mlx5e_sq_stats *sq_stats = &channel_stats->sq[j];
@@ -3917,8 +4558,7 @@ void mlx5e_fold_sw_stats64(struct mlx5e_
 	}
 }
 
-void
-mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
+void mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 	struct mlx5e_pport_stats *pstats = &priv->stats.pport;
@@ -3992,7 +4632,11 @@ static int mlx5e_set_mac(struct net_devi
 		return -EADDRNOTAVAIL;
 
 	netif_addr_lock_bh(netdev);
+#ifdef HAVE_DEV_ADDR_MOD
 	eth_hw_addr_set(netdev, saddr->sa_data);
+#else
+	ether_addr_copy(netdev->dev_addr, saddr->sa_data);
+#endif
 	netif_addr_unlock_bh(netdev);
 
 	mlx5e_nic_set_rx_mode(priv);
@@ -4025,11 +4669,27 @@ static int set_feature_lro(struct net_de
 	new_params = *cur_params;
 
 	if (enable)
+#if defined(CONFIG_COMPAT_LRO_ENABLED_IPOIB)
+	{
+		new_params.lro_en = true;
+		if (IS_HW_LRO(&new_params))
+			new_params.packet_merge.type = MLX5E_PACKET_MERGE_LRO;
+	}
+	else if (new_params.packet_merge.type == MLX5E_PACKET_MERGE_LRO) {
+		new_params.lro_en = false;
+		new_params.packet_merge.type = MLX5E_PACKET_MERGE_NONE;
+
+	} else {
+		new_params.lro_en = false;
+		goto update_params;
+	}
+#else
 		new_params.packet_merge.type = MLX5E_PACKET_MERGE_LRO;
 	else if (new_params.packet_merge.type == MLX5E_PACKET_MERGE_LRO)
 		new_params.packet_merge.type = MLX5E_PACKET_MERGE_NONE;
 	else
 		goto out;
+#endif
 
 	if (!(cur_params->packet_merge.type == MLX5E_PACKET_MERGE_SHAMPO &&
 	      new_params.packet_merge.type == MLX5E_PACKET_MERGE_LRO)) {
@@ -4040,6 +4700,18 @@ static int set_feature_lro(struct net_de
 		}
 	}
 
+#ifdef HAVE_BASECODE_EXTRAS
+	if ((new_params.packet_merge.type != MLX5E_PACKET_MERGE_NONE) &&
+	    !MLX5E_GET_PFLAG(cur_params, MLX5E_PFLAG_RX_STRIDING_RQ)) {
+		netdev_warn(netdev, "can't set HW LRO with legacy RQ\n");
+		err = -EINVAL;
+		goto out;
+	}
+#endif
+
+#if defined(CONFIG_COMPAT_LRO_ENABLED_IPOIB)
+update_params:
+#endif
 	err = mlx5e_safe_switch_params(priv, &new_params,
 				       mlx5e_modify_tirs_packet_merge_ctx, NULL, reset);
 out:
@@ -4257,6 +4929,7 @@ static int mlx5e_handle_feature(struct n
 	return 0;
 }
 
+#ifdef HAVE_XDP_SET_FEATURES_FLAG
 void mlx5e_set_xdp_feature(struct net_device *netdev)
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -4275,6 +4948,7 @@ void mlx5e_set_xdp_feature(struct net_de
 	      NETDEV_XDP_ACT_NDO_XMIT_SG;
 	xdp_set_features_flag(netdev, val);
 }
+#endif
 
 int mlx5e_set_features(struct net_device *netdev, netdev_features_t features)
 {
@@ -4295,15 +4969,19 @@ int mlx5e_set_features(struct net_device
 #ifdef CONFIG_MLX5_EN_ARFS
 	err |= MLX5E_HANDLE_FEATURE(NETIF_F_NTUPLE, set_feature_arfs);
 #endif
+#ifdef HAVE_NETIF_F_HW_TLS_RX
 	err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_TLS_RX, mlx5e_ktls_set_feature_rx);
+#endif
 
 	if (err) {
 		netdev->features = oper_features;
 		return -EINVAL;
 	}
 
+#ifdef HAVE_XDP_SET_FEATURES_FLAG
 	/* update XDP supported features */
 	mlx5e_set_xdp_feature(netdev);
+#endif
 
 	return 0;
 }
@@ -4311,6 +4989,7 @@ int mlx5e_set_features(struct net_device
 static netdev_features_t mlx5e_fix_uplink_rep_features(struct net_device *netdev,
 						       netdev_features_t features)
 {
+#ifdef HAVE_NETIF_F_HW_TLS_RX
 	features &= ~NETIF_F_HW_TLS_RX;
 	if (netdev->features & NETIF_F_HW_TLS_RX)
 		netdev_warn(netdev, "Disabling hw_tls_rx, not supported in switchdev mode\n");
@@ -4318,10 +4997,12 @@ static netdev_features_t mlx5e_fix_uplin
 	features &= ~NETIF_F_HW_TLS_TX;
 	if (netdev->features & NETIF_F_HW_TLS_TX)
 		netdev_warn(netdev, "Disabling hw_tls_tx, not supported in switchdev mode\n");
-
+#endif
+#ifdef CONFIG_MLX5_EN_ARFS
 	features &= ~NETIF_F_NTUPLE;
 	if (netdev->features & NETIF_F_NTUPLE)
 		netdev_warn(netdev, "Disabling ntuple, not supported in switchdev mode\n");
+#endif
 
 	features &= ~NETIF_F_GRO_HW;
 	if (netdev->features & NETIF_F_GRO_HW)
@@ -4330,7 +5011,6 @@ static netdev_features_t mlx5e_fix_uplin
 	features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
 	if (netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
 		netdev_warn(netdev, "Disabling HW_VLAN CTAG FILTERING, not supported in switchdev mode\n");
-
 	return features;
 }
 
@@ -4357,7 +5037,11 @@ static netdev_features_t mlx5e_fix_featu
 			netdev_warn(netdev, "Dropping C-tag vlan stripping offload due to S-tag vlan\n");
 	}
 
-	if (!MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_STRIDING_RQ)) {
+	if (!MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_STRIDING_RQ)
+#ifdef CONFIG_COMPAT_LRO_ENABLED_IPOIB
+			&& IS_HW_LRO(&priv->channels.params)
+#endif
+	) {
 		if (features & NETIF_F_LRO) {
 			netdev_warn(netdev, "Disabling LRO, not supported in legacy RQ\n");
 			features &= ~NETIF_F_LRO;
@@ -4368,6 +5052,7 @@ static netdev_features_t mlx5e_fix_featu
 		}
 	}
 
+#ifdef HAVE_XDP_SUPPORT
 	if (params->xdp_prog) {
 		if (features & NETIF_F_LRO) {
 			netdev_warn(netdev, "LRO is incompatible with XDP\n");
@@ -4378,7 +5063,9 @@ static netdev_features_t mlx5e_fix_featu
 			features &= ~NETIF_F_GRO_HW;
 		}
 	}
+#endif
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	if (priv->xsk.refcnt) {
 		if (features & NETIF_F_LRO) {
 			netdev_warn(netdev, "LRO is incompatible with AF_XDP (%u XSKs are active)\n",
@@ -4391,6 +5078,7 @@ static netdev_features_t mlx5e_fix_featu
 			features &= ~NETIF_F_GRO_HW;
 		}
 	}
+#endif
 
 	if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS)) {
 		features &= ~NETIF_F_RXHASH;
@@ -4415,16 +5103,26 @@ static netdev_features_t mlx5e_fix_featu
 		}
 	}
 
+#ifdef HAVE_NETIF_F_HW_TLS_RX
 	if ((features & NETIF_F_HW_TLS_RX) && !(features & NETIF_F_RXCSUM)) {
 		netdev_warn(netdev, "Dropping TLS RX HW offload feature since no RXCSUM feature.\n");
 		features &= ~NETIF_F_HW_TLS_RX;
 	}
+#endif
 
 	if (mlx5e_is_uplink_rep(priv)) {
 		features = mlx5e_fix_uplink_rep_features(netdev, features);
+#ifdef HAVE_NETDEV_NETNS_LOCAL
+		netdev->netns_local = true;
+#else
 		features |= NETIF_F_NETNS_LOCAL;
+#endif
 	} else {
+#ifdef HAVE_NETDEV_NETNS_LOCAL
+		netdev->netns_local = false;
+#else
 		features &= ~NETIF_F_NETNS_LOCAL;
+#endif
 	}
 
 	mutex_unlock(&priv->state_lock);
@@ -4432,6 +5130,7 @@ static netdev_features_t mlx5e_fix_featu
 	return features;
 }
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 static bool mlx5e_xsk_validate_mtu(struct net_device *netdev,
 				   struct mlx5e_channels *chs,
 				   struct mlx5e_params *new_params,
@@ -4440,7 +5139,11 @@ static bool mlx5e_xsk_validate_mtu(struc
 	u16 ix;
 
 	for (ix = 0; ix < chs->params.num_channels; ix++) {
+#ifdef HAVE_NETDEV_BPF_XSK_BUFF_POOL
 		struct xsk_buff_pool *xsk_pool =
+#else
+		struct xdp_umem *xsk_pool =
+#endif
 			mlx5e_xsk_get_pool(&chs->params, chs->params.xsk, ix);
 		struct mlx5e_xsk_param xsk;
 		int max_xdp_mtu;
@@ -4473,7 +5176,9 @@ static bool mlx5e_xsk_validate_mtu(struc
 
 	return true;
 }
+#endif /* HAVE_XSK_ZERO_COPY_SUPPORT */
 
+#ifdef HAVE_XDP_SUPPORT
 static bool mlx5e_params_validate_xdp(struct net_device *netdev,
 				      struct mlx5_core_dev *mdev,
 				      struct mlx5e_params *params)
@@ -4488,6 +5193,7 @@ static bool mlx5e_params_validate_xdp(st
 		mlx5e_rx_mpwqe_is_linear_skb(mdev, params, NULL);
 
 	if (!is_linear) {
+#ifdef HAVE_XDP_HAS_FRAGS
 		if (!params->xdp_prog->aux->xdp_has_frags) {
 			netdev_warn(netdev, "MTU(%d) > %d, too big for an XDP program not aware of multi buffer\n",
 				    params->sw_mtu,
@@ -4497,6 +5203,10 @@ static bool mlx5e_params_validate_xdp(st
 		if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ &&
 		    !mlx5e_verify_params_rx_mpwqe_strides(mdev, params, NULL)) {
 			netdev_warn(netdev, "XDP is not allowed with striding RQ and MTU(%d) > %d\n",
+#else
+		{
+			netdev_warn(netdev, "XDP is not allowed with MTU(%d) > %d\n",
+#endif
 				    params->sw_mtu,
 				    mlx5e_xdp_max_mtu(params, NULL));
 			return false;
@@ -4505,6 +5215,7 @@ static bool mlx5e_params_validate_xdp(st
 
 	return true;
 }
+#endif /* HAVE_XDP_SUPPORT */
 
 int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
 		     mlx5e_fp_preactivate preactivate)
@@ -4525,18 +5236,22 @@ int mlx5e_change_mtu(struct net_device *
 	if (err)
 		goto out;
 
+#ifdef HAVE_XDP_SUPPORT
 	if (new_params.xdp_prog && !mlx5e_params_validate_xdp(netdev, priv->mdev,
 							      &new_params)) {
 		err = -EINVAL;
 		goto out;
 	}
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	if (priv->xsk.refcnt &&
 	    !mlx5e_xsk_validate_mtu(netdev, &priv->channels,
 				    &new_params, priv->mdev)) {
 		err = -EINVAL;
 		goto out;
 	}
+#endif /* HAVE_XSK_ZERO_COPY_SUPPORT */
+#endif /* HAVE_XDP_SUPPORT */
 
 	if (params->packet_merge.type == MLX5E_PACKET_MERGE_LRO)
 		reset = false;
@@ -4554,7 +5269,10 @@ int mlx5e_change_mtu(struct net_device *
 		 * If XSK is active, XSK RQs are linear.
 		 * Reset if the RQ size changed, even if it's non-linear.
 		 */
-		if (!is_linear_old && !is_linear_new && !priv->xsk.refcnt &&
+		if (!is_linear_old && !is_linear_new &&
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+		    !priv->xsk.refcnt &&
+#endif
 		    sz_old == sz_new)
 			reset = false;
 	}
@@ -4734,36 +5452,6 @@ static int mlx5e_set_vf_vlan(struct net_
 					   vlan, qos, vlan_proto);
 }
 
-#ifdef HAVE_NETDEV_OPS_NDO_SET_VF_TRUNK_RANGE
-static int mlx5e_add_vf_vlan_trunk_range(struct net_device *dev, int vf,
-					 u16 start_vid, u16 end_vid,
-					 __be16 vlan_proto)
-{
-	struct mlx5e_priv *priv = netdev_priv(dev);
-	struct mlx5_core_dev *mdev = priv->mdev;
-
-	if (vlan_proto != htons(ETH_P_8021Q))
-		return -EPROTONOSUPPORT;
-
-	return mlx5_eswitch_add_vport_trunk_range(mdev->priv.eswitch, vf + 1,
-						  start_vid, end_vid);
-}
-
-static int mlx5e_del_vf_vlan_trunk_range(struct net_device *dev, int vf,
-					 u16 start_vid, u16 end_vid,
-					 __be16 vlan_proto)
-{
-	struct mlx5e_priv *priv = netdev_priv(dev);
-	struct mlx5_core_dev *mdev = priv->mdev;
-
-	if (vlan_proto != htons(ETH_P_8021Q))
-		return -EPROTONOSUPPORT;
-
-	return mlx5_eswitch_del_vport_trunk_range(mdev->priv.eswitch, vf + 1,
-						  start_vid, end_vid);
-}
-#endif
-
 static int mlx5e_set_vf_spoofchk(struct net_device *dev, int vf, bool setting)
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
@@ -4785,8 +5473,24 @@ int mlx5e_set_vf_rate(struct net_device
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 	struct mlx5_core_dev *mdev = priv->mdev;
+	int vport = (vf == 0xffff) ? 0 : vf + 1;
+
+#ifdef HAVE_BASECODE_EXTRAS
 
-	return mlx5_eswitch_set_vport_rate(mdev->priv.eswitch, vf + 1,
+	/* MLNX OFED only -??
+	 * Allow to set eswitch min rate for the PF.
+	 * In order to avoid bottlenecks on the slow-path arising from
+	 * VF->PF packet transitions consuming a high amount of HW BW,
+	 * resulting in drops of packets destined from PF->WIRE.
+	 * This essentially assigns PF->WIRE a higher priority than VF->PF
+	 * packet processing. */
+	if (vport == 0) {
+		min_tx_rate = max_tx_rate;
+		max_tx_rate = 0;
+	}
+#endif
+
+	return mlx5_eswitch_set_vport_rate(mdev->priv.eswitch, vport,
 					   max_tx_rate, min_tx_rate);
 }
 
@@ -4857,7 +5561,11 @@ mlx5e_has_offload_stats(const struct net
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 
+#ifdef HAVE_NETIF_DEVICE_PRESENT_GET_CONST
 	if (!netif_device_present(dev))
+#else
+	if (!netif_device_present_const(dev))
+#endif
 		return false;
 
 	if (!mlx5e_is_uplink_rep(priv))
@@ -4877,7 +5585,7 @@ mlx5e_get_offload_stats(int attr_id, con
 
 	return mlx5e_rep_get_offload_stats(attr_id, dev, sp);
 }
-#endif
+#endif /*CONFIG_MLX5_ESWITCH*/
 
 static bool mlx5e_tunnel_proto_supported_tx(struct mlx5_core_dev *mdev, u8 proto_type)
 {
@@ -4893,6 +5601,90 @@ static bool mlx5e_tunnel_proto_supported
 	}
 }
 
+
+#ifdef HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON
+struct mlx5e_vxlan_work {
+	struct work_struct      work;
+	struct mlx5e_priv       *priv;
+	u16                     port;
+};
+
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+static void mlx5e_vxlan_add_work(struct work_struct *work)
+{
+	struct mlx5e_vxlan_work *vxlan_work =
+		container_of(work, struct mlx5e_vxlan_work, work);
+	struct mlx5e_priv *priv = vxlan_work->priv;
+	u16 port = vxlan_work->port;
+
+	mutex_lock(&priv->state_lock);
+	mlx5_vxlan_add_port(priv->mdev->vxlan, port);
+	mutex_unlock(&priv->state_lock);
+
+	kfree(vxlan_work);
+}
+
+static void mlx5e_vxlan_del_work(struct work_struct *work)
+{
+	struct mlx5e_vxlan_work *vxlan_work =
+		container_of(work, struct mlx5e_vxlan_work, work);
+	struct mlx5e_priv *priv         = vxlan_work->priv;
+	u16 port = vxlan_work->port;
+
+	mutex_lock(&priv->state_lock);
+	mlx5_vxlan_del_port(priv->mdev->vxlan, port);
+	mutex_unlock(&priv->state_lock);
+	kfree(vxlan_work);
+}
+
+static void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, u16 port, int add)
+{
+	struct mlx5e_vxlan_work *vxlan_work;
+
+	vxlan_work = kmalloc(sizeof(*vxlan_work), GFP_ATOMIC);
+	if (!vxlan_work)
+		return;
+
+	if (add)
+		INIT_WORK(&vxlan_work->work, mlx5e_vxlan_add_work);
+	else
+		INIT_WORK(&vxlan_work->work, mlx5e_vxlan_del_work);
+
+	vxlan_work->priv = priv;
+	vxlan_work->port = port;
+	queue_work(priv->wq, &vxlan_work->work);
+}
+#endif
+
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+void mlx5e_add_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+
+	if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
+		return;
+
+	if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
+		return;
+
+	mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 1);
+}
+
+void mlx5e_del_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+
+	if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
+		return;
+
+	if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
+		return;
+
+	mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 0);
+}
+#endif
+#endif /* HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON */
+
 static bool mlx5e_gre_tunnel_inner_proto_offload_supported(struct mlx5_core_dev *mdev,
 							   struct sk_buff *skb)
 {
@@ -4913,9 +5705,13 @@ static netdev_features_t mlx5e_tunnel_fe
 						     netdev_features_t features)
 {
 	unsigned int offset = 0;
+#ifdef HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON
 	struct udphdr *udph;
+#endif
 	u8 proto;
+#if defined(HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON) || IS_ENABLED(CONFIG_GENEVE)
 	u16 port;
+#endif
 
 	switch (vlan_get_protocol(skb)) {
 	case htons(ETH_P_IP):
@@ -4938,6 +5734,7 @@ static netdev_features_t mlx5e_tunnel_fe
 		if (mlx5e_tunnel_proto_supported_tx(priv->mdev, IPPROTO_IPIP))
 			return features;
 		break;
+#ifdef HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON
 	case IPPROTO_UDP:
 		udph = udp_hdr(skb);
 		port = be16_to_cpu(udph->dest);
@@ -4945,6 +5742,7 @@ static netdev_features_t mlx5e_tunnel_fe
 		/* Verify if UDP port is being offloaded by HW */
 		if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, port))
 			return vxlan_features_check(skb, features);
+#endif
 
 #if IS_ENABLED(CONFIG_GENEVE)
 		/* Support Geneve offload for default UDP port */
@@ -5018,7 +5816,11 @@ unlock:
 	rtnl_unlock();
 }
 
+#ifdef HAVE_NDO_TX_TIMEOUT_GET_2_PARAMS
 static void mlx5e_tx_timeout(struct net_device *dev, unsigned int txqueue)
+#else
+static void mlx5e_tx_timeout(struct net_device *dev)
+#endif
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 
@@ -5026,10 +5828,15 @@ static void mlx5e_tx_timeout(struct net_
 	queue_work(priv->wq, &priv->tx_timeout_work);
 }
 
+#ifdef HAVE_XDP_SUPPORT
 static int mlx5e_xdp_allowed(struct net_device *netdev, struct mlx5_core_dev *mdev,
 			     struct mlx5e_params *params)
 {
+#ifdef CONFIG_COMPAT_LRO_ENABLED_IPOIB
+	if (IS_HW_LRO(&priv->channels.params)) {
+#else
 	if (params->packet_merge.type != MLX5E_PACKET_MERGE_NONE) {
+#endif
 		netdev_warn(netdev, "can't set XDP while HW-GRO/LRO is on, disable them first\n");
 		return -EINVAL;
 	}
@@ -5088,15 +5895,33 @@ static int mlx5e_xdp_set(struct net_devi
 	/* exchanging programs w/o reset, we update ref counts on behalf
 	 * of the channels RQs here.
 	 */
+#ifndef HAVE_BPF_PROG_ADD_RET_STRUCT
 	bpf_prog_add(prog, priv->channels.num);
+#else
+		prog = bpf_prog_add(prog, priv->channels.num);
+		if (IS_ERR(prog)) {
+			err = PTR_ERR(prog);
+			goto unlock;
+		}
+#endif
 	for (i = 0; i < priv->channels.num; i++) {
 		struct mlx5e_channel *c = priv->channels.c[i];
 
 		mlx5e_rq_replace_xdp_prog(&c->rq, prog);
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 		if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state)) {
+#ifndef HAVE_BPF_PROG_ADD_RET_STRUCT
 			bpf_prog_inc(prog);
+#else
+			prog = bpf_prog_inc(prog);
+			if (IS_ERR(prog)) {
+				err = PTR_ERR(prog);
+				goto unlock;
+			}
+#endif
 			mlx5e_rq_replace_xdp_prog(&c->xskrq, prog);
 		}
+#endif
 	}
 
 unlock:
@@ -5109,23 +5934,76 @@ unlock:
 	return err;
 }
 
+#ifndef HAVE_DEV_XDP_PROG_ID
+static u32 mlx5e_xdp_query(struct net_device *dev)
+{
+       struct mlx5e_priv *priv = netdev_priv(dev);
+       const struct bpf_prog *xdp_prog;
+       u32 prog_id = 0;
+
+       if (!netif_device_present(dev))
+	       goto out;
+
+       mutex_lock(&priv->state_lock);
+       xdp_prog = priv->channels.params.xdp_prog;
+       if (xdp_prog)
+              prog_id = xdp_prog->aux->id;
+       mutex_unlock(&priv->state_lock);
+
+out:
+       return prog_id;
+}
+#endif
+
 static int mlx5e_xdp(struct net_device *dev, struct netdev_bpf *xdp)
 {
 	switch (xdp->command) {
 	case XDP_SETUP_PROG:
 		return mlx5e_xdp_set(dev, xdp->prog);
+#ifndef HAVE_DEV_XDP_PROG_ID
+	case XDP_QUERY_PROG:
+		xdp->prog_id = mlx5e_xdp_query(dev);
+		return 0;
+#endif
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+#ifdef HAVE_NETDEV_BPF_XSK_BUFF_POOL
 	case XDP_SETUP_XSK_POOL:
 		return mlx5e_xsk_setup_pool(dev, xdp->xsk.pool,
 					    xdp->xsk.queue_id);
+#else
+	case XDP_SETUP_XSK_UMEM:
+		return mlx5e_xsk_setup_pool(dev, xdp->xsk.umem,
+					    xdp->xsk.queue_id);
+#endif
+#endif
 	default:
 		return -EINVAL;
 	}
 }
+#endif /* HAVE_XDP_SUPPORT */
+
+#ifndef HAVE_NETPOLL_POLL_DEV_EXPORTED
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/* Fake "interrupt" called by netpoll (eg netconsole) to send skbs without
+ * reenabling interrupts.
+ */
+static void mlx5e_netpoll(struct net_device *dev)
+{
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	struct mlx5e_channels *chs = &priv->channels;
+
+	int i;
+
+	for (i = 0; i < chs->num; i++)
+		napi_schedule(&chs->c[i]->napi);
+}
+#endif
+#endif/*HAVE_NETPOLL_POLL_DEV__EXPORTED*/
 
 #ifdef CONFIG_MLX5_ESWITCH
 static int mlx5e_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
-				struct net_device *dev, u32 filter_mask,
-				int nlflags)
+				struct net_device *dev, u32 filter_mask
+				, int nlflags)
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 	struct mlx5_core_dev *mdev = priv->mdev;
@@ -5136,13 +6014,17 @@ static int mlx5e_bridge_getlink(struct s
 	if (err)
 		return err;
 	mode = setting ? BRIDGE_MODE_VEPA : BRIDGE_MODE_VEB;
-	return ndo_dflt_bridge_getlink(skb, pid, seq, dev,
-				       mode,
-				       0, 0, nlflags, filter_mask, NULL);
+	return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode
+				       , 0, 0, nlflags, filter_mask, NULL);
 }
 
-static int mlx5e_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
-				u16 flags, struct netlink_ext_ack *extack)
+#ifdef HAVE_NDO_BRIDGE_SETLINK_EXTACK
+	static int mlx5e_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
+			                                u16 flags, struct netlink_ext_ack *extack)
+#elif defined(HAVE_NDO_BRIDGE_SETLINK)
+	static int mlx5e_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
+			                                u16 flags)
+#endif
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 	struct mlx5_core_dev *mdev = priv->mdev;
@@ -5172,8 +6054,71 @@ static int mlx5e_bridge_setlink(struct n
 	setting = (mode == BRIDGE_MODE_VEPA) ?  1 : 0;
 	return mlx5_eswitch_set_vepa(mdev->priv.eswitch, setting);
 }
+
+#ifndef HAVE_DEVLINK_PORT_ATTRS_PCI_PF_SET
+int mlx5e_get_phys_port_name(struct net_device *dev,
+			     char *buf, size_t len)
+{
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	unsigned int fn;
+	int ret;
+
+	if (!netif_device_present(dev))
+		return -EOPNOTSUPP;
+
+	if (mlx5e_is_uplink_rep(priv))
+		return mlx5e_rep_get_phys_port_name(dev, buf, len);
+
+	/* Only rename ecpf, don't rename non-smartnic PF/VF/SF */
+	if (!mlx5_core_is_pf(priv->mdev) &&
+	    !mlx5_core_is_ecpf(priv->mdev))
+		return -EOPNOTSUPP;
+
+	fn = mlx5_get_dev_index(priv->mdev);
+	ret = snprintf(buf, len, "p%d", fn);
+	if (ret >= len)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
 #endif
 
+#if defined(HAVE_NDO_GET_PORT_PARENT_ID)
+#ifdef HAVE_BASECODE_EXTRAS
+#ifdef HAVE_DEVLINK_PORT_ATTRS_PCI_PF_SET
+void
+#else
+int
+#endif
+mlx5e_get_port_parent_id(struct net_device *dev,
+			 struct netdev_phys_item_id *ppid)
+{
+	struct mlx5e_priv *priv = netdev_priv(dev);
+
+	if (!netif_device_present(dev))
+#ifndef HAVE_DEVLINK_PORT_ATTRS_PCI_PF_SET
+		return -EOPNOTSUPP;
+#else
+	return;
+#endif
+
+	if (!mlx5e_is_uplink_rep(priv))
+#ifndef HAVE_DEVLINK_PORT_ATTRS_PCI_PF_SET
+		return -EOPNOTSUPP;
+#else
+		return;
+#endif
+
+#ifndef HAVE_DEVLINK_PORT_ATTRS_PCI_PF_SET
+	return mlx5e_rep_get_port_parent_id(dev, ppid);
+#else
+	mlx5e_rep_get_port_parent_id(dev, ppid);
+#endif
+}
+#endif
+#endif
+#endif /* CONFIG_MLX5_ESWITCH */
+
 const struct net_device_ops mlx5e_netdev_ops = {
 	.ndo_open                = mlx5e_open,
 	.ndo_stop                = mlx5e_close,
@@ -5188,39 +6133,74 @@ const struct net_device_ops mlx5e_netdev
 	.ndo_set_features        = mlx5e_set_features,
 	.ndo_fix_features        = mlx5e_fix_features,
 	.ndo_change_mtu          = mlx5e_change_nic_mtu,
+
+#ifdef HAVE_NDO_ETH_IOCTL
 	.ndo_eth_ioctl            = mlx5e_ioctl,
+#else
+	.ndo_do_ioctl		  = mlx5e_ioctl,
+#endif
+
 	.ndo_set_tx_maxrate      = mlx5e_set_tx_maxrate,
+
+#ifdef HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON
+#if defined(HAVE_UDP_TUNNEL_NIC_INFO) && defined(HAVE_NDO_UDP_TUNNEL_ADD)
+	.ndo_udp_tunnel_add      = udp_tunnel_nic_add_port,
+	.ndo_udp_tunnel_del      = udp_tunnel_nic_del_port,
+#elif defined(HAVE_NDO_UDP_TUNNEL_ADD)
+	.ndo_udp_tunnel_add      = mlx5e_add_vxlan_port,
+	.ndo_udp_tunnel_del      = mlx5e_del_vxlan_port,
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+#endif
 	.ndo_features_check      = mlx5e_features_check,
 	.ndo_tx_timeout          = mlx5e_tx_timeout,
-	.ndo_bpf		 = mlx5e_xdp,
+#ifdef HAVE_XDP_SUPPORT
+	.ndo_bpf                 = mlx5e_xdp,
 	.ndo_xdp_xmit            = mlx5e_xdp_xmit,
+#endif /* HAVE_XDP_SUPPORT */
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+#ifdef HAVE_NDO_XSK_WAKEUP
 	.ndo_xsk_wakeup          = mlx5e_xsk_wakeup,
+#else
+	.ndo_xsk_async_xmit	 = mlx5e_xsk_wakeup,
+#endif
+#endif
 #ifdef CONFIG_MLX5_EN_ARFS
 	.ndo_rx_flow_steer	 = mlx5e_rx_flow_steer,
 #endif
+#ifndef HAVE_NETPOLL_POLL_DEV_EXPORTED
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	 = mlx5e_netpoll,
+#endif
+#endif
 #ifdef CONFIG_MLX5_ESWITCH
+#if defined(HAVE_NDO_BRIDGE_SETLINK) || defined(HAVE_NDO_BRIDGE_SETLINK_EXTACK)
 	.ndo_bridge_setlink      = mlx5e_bridge_setlink,
+#endif
 	.ndo_bridge_getlink      = mlx5e_bridge_getlink,
 
 	/* SRIOV E-Switch NDOs */
 	.ndo_set_vf_mac          = mlx5e_set_vf_mac,
 	.ndo_set_vf_vlan         = mlx5e_set_vf_vlan,
 
-	/* these ndo's are not upstream yet */
-#ifdef HAVE_NETDEV_OPS_NDO_SET_VF_TRUNK_RANGE
-	.ndo_add_vf_vlan_trunk_range = mlx5e_add_vf_vlan_trunk_range,
-	.ndo_del_vf_vlan_trunk_range = mlx5e_del_vf_vlan_trunk_range,
-#endif
-
 	.ndo_set_vf_spoofchk     = mlx5e_set_vf_spoofchk,
 	.ndo_set_vf_trust        = mlx5e_set_vf_trust,
 	.ndo_set_vf_rate         = mlx5e_set_vf_rate,
-	.ndo_get_vf_config       = mlx5e_get_vf_config,
 	.ndo_set_vf_link_state   = mlx5e_set_vf_link_state,
-	.ndo_get_vf_stats        = mlx5e_get_vf_stats,
+	.ndo_get_vf_config       = mlx5e_get_vf_config,
+	.ndo_get_vf_stats	 = mlx5e_get_vf_stats,
+#ifndef HAVE_NET_DEVICE_HAS_DEVLINK_PORT
+#ifdef HAVE_NDO_GET_DEVLINK_PORT
+	.ndo_get_devlink_port    = mlx5e_get_devlink_port,
+#else
+	.ndo_get_phys_port_name  = mlx5e_get_phys_port_name,
+#ifdef HAVE_NDO_GET_PORT_PARENT_ID
+	.ndo_get_port_parent_id  = mlx5e_get_port_parent_id,
+#endif
+#endif
+#endif /* HAVE_NET_DEVICE_HAS_DEVLINK_PORT */
 	.ndo_has_offload_stats   = mlx5e_has_offload_stats,
 	.ndo_get_offload_stats   = mlx5e_get_offload_stats,
-#endif
+#endif /* CONFIG_MLX5_ESWITCH */
 };
 
 static void mlx5e_init_delay_drop(struct mlx5e_priv *priv,
@@ -5235,7 +6215,11 @@ static void mlx5e_init_delay_drop(struct
 	INIT_WORK(&priv->delay_drop.work, mlx5e_delay_drop_handler);
 }
 
-void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16 mtu)
+void mlx5e_build_nic_params(struct mlx5e_priv *priv,
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+			   struct mlx5e_xsk *xsk,
+#endif
+			   u16 mtu)
 {
 	struct mlx5e_params *params = &priv->channels.params;
 	struct mlx5_core_dev *mdev = priv->mdev;
@@ -5245,6 +6229,9 @@ void mlx5e_build_nic_params(struct mlx5e
 	params->hard_mtu = MLX5E_ETH_HARD_MTU;
 	params->num_channels = min_t(unsigned int, MLX5E_MAX_NUM_CHANNELS / 2,
 				     priv->max_nch);
+#ifndef HAVE_PAGE_POOL_DEFRAG_PAGE
+	params->log_rx_page_cache_mult = MLX5E_PAGE_CACHE_LOG_MAX_RQ_MULT;
+#endif
 	mlx5e_params_mqprio_reset(params);
 
 	/* SQ */
@@ -5254,7 +6241,9 @@ void mlx5e_build_nic_params(struct mlx5e
 	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_SKB_TX_MPWQE, mlx5e_tx_mpwqe_supported(mdev));
 
 	/* XDP SQ */
+#ifdef HAVE_XDP_SUPPORT
 	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_XDP_TX_MPWQE, mlx5e_tx_mpwqe_supported(mdev));
+#endif
 
 	/* set CQE compression */
 	params->rx_cqe_compress_def = false;
@@ -5263,6 +6252,9 @@ void mlx5e_build_nic_params(struct mlx5e
 		params->rx_cqe_compress_def = slow_pci_heuristic(mdev);
 
 	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS, params->rx_cqe_compress_def);
+#ifdef HAVE_BASECODE_EXTRAS
+	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_TX_CQE_COMPRESS, false);
+#endif
 	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_NO_CSUM_COMPLETE, false);
 
 	/* RQ */
@@ -5276,6 +6268,12 @@ void mlx5e_build_nic_params(struct mlx5e
 	rx_cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
 			MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
 			MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
+
+#ifdef CONFIG_COMPAT_LRO_ENABLED_IPOIB
+	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_HWLRO, MLX5_CAP_ETH(mdev, lro_cap) &&
+			MLX5_CAP_GEN(mdev, striding_rq));
+#endif
+
 	params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
 	params->tx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
 	mlx5e_set_rx_cq_mode_params(params, rx_cq_period_mode);
@@ -5285,11 +6283,14 @@ void mlx5e_build_nic_params(struct mlx5e
 	mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
 
 	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_PER_CH_STATS, true);
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	/* AF_XDP */
 	params->xsk = xsk;
+#endif
 
 	/* TX HW checksum offload for XDP is off by default */
 	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_TX_XDP_CSUM, 0);
+
 	/* Do not update netdev->features directly in here
 	 * on mlx5e_attach_netdev() we will call mlx5e_update_features()
 	 * To update netdev->features please modify mlx5e_fix_features()
@@ -5299,19 +6300,28 @@ void mlx5e_build_nic_params(struct mlx5e
 static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
-	u8 addr[ETH_ALEN];
+#ifdef HAVE_DEV_ADDR_MOD
+       u8 addr[ETH_ALEN];
 
-	mlx5_query_mac_address(priv->mdev, addr);
-	if (is_zero_ether_addr(addr) &&
+       mlx5_query_mac_address(priv->mdev, addr);
+       if (is_zero_ether_addr(addr) &&
+#else
+	mlx5_query_mac_address(priv->mdev, netdev->dev_addr);
+	if (is_zero_ether_addr(netdev->dev_addr) &&
+#endif
 	    !MLX5_CAP_GEN(priv->mdev, vport_group_manager)) {
 		eth_hw_addr_random(netdev);
 		mlx5_core_info(priv->mdev, "Assigned random MAC address %pM\n", netdev->dev_addr);
+#ifdef HAVE_DEV_ADDR_MOD
 		return;
+#endif
 	}
-
+#ifdef HAVE_DEV_ADDR_MOD
 	eth_hw_addr_set(netdev, addr);
+#endif
 }
 
+#if defined(HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON) && defined(HAVE_UDP_TUNNEL_NIC_INFO_FULL)
 static int mlx5e_vxlan_set_port(struct net_device *netdev, unsigned int table,
 				unsigned int entry, struct udp_tunnel_info *ti)
 {
@@ -5344,6 +6354,13 @@ void mlx5e_vxlan_set_netdev_info(struct
 
 	priv->netdev->udp_tunnel_nic_info = &priv->nic_info;
 }
+#endif
+
+#if defined(CONFIG_MLX5_ESWITCH) && defined(HAVE_SWITCHDEV_OPS)
+static const struct switchdev_ops mlx5e_switchdev_ops = {
+		.switchdev_port_attr_get	= mlx5e_attr_get,
+};
+#endif
 
 static bool mlx5e_tunnel_any_tx_proto_supported(struct mlx5_core_dev *mdev)
 {
@@ -5353,7 +6370,11 @@ static bool mlx5e_tunnel_any_tx_proto_su
 		if (mlx5e_tunnel_proto_supported_tx(mdev, mlx5_get_proto_by_tunnel_type(tt)))
 			return true;
 	}
+#ifdef HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON
 	return (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev));
+#else
+	return false;
+#endif
 }
 
 static void mlx5e_build_nic_netdev(struct net_device *netdev)
@@ -5366,18 +6387,27 @@ static void mlx5e_build_nic_netdev(struc
 	SET_NETDEV_DEV(netdev, mdev->device);
 
 	netdev->netdev_ops = &mlx5e_netdev_ops;
+#if defined(HAVE_XDP_METADATA_OPS) && defined(HAVE_XDP_SUPPORT)
 	netdev->xdp_metadata_ops = &mlx5e_xdp_metadata_ops;
+#endif
+#if defined(HAVE_XSK_TX_METADATA_OPS) && defined(HAVE_XDP_SUPPORT)
 	netdev->xsk_tx_metadata_ops = &mlx5e_xsk_tx_metadata_ops;
+#endif
 
 	mlx5e_dcbnl_build_netdev(netdev);
 
+#if defined(CONFIG_MLX5_ESWITCH) && defined(HAVE_SWITCHDEV_OPS)
+        netdev->switchdev_ops = &mlx5e_switchdev_ops;
+#endif
 	netdev->watchdog_timeo    = 15 * HZ;
 
 	netdev->ethtool_ops	  = &mlx5e_ethtool_ops;
 
 	netdev->vlan_features    |= NETIF_F_SG;
 	netdev->vlan_features    |= NETIF_F_HW_CSUM;
+#ifdef CONFIG_MLX5_MACSEC
 	netdev->vlan_features    |= NETIF_F_HW_MACSEC;
+#endif
 	netdev->vlan_features    |= NETIF_F_GRO;
 	netdev->vlan_features    |= NETIF_F_TSO;
 	netdev->vlan_features    |= NETIF_F_TSO6;
@@ -5398,12 +6428,17 @@ static void mlx5e_build_nic_netdev(struc
 	 * for inner TIRs while having it enabled for outer TIRs. Due to this,
 	 * block LRO altogether if the firmware declares tunneled LRO support.
 	 */
+	/* If SW LRO is supported turn on LRO Primary flags*/
+#ifdef CONFIG_COMPAT_LRO_ENABLED_IPOIB
+	netdev->vlan_features    |= NETIF_F_LRO;
+#else
 	if (!!MLX5_CAP_ETH(mdev, lro_cap) &&
 	    !MLX5_CAP_ETH(mdev, tunnel_lro_vxlan) &&
 	    !MLX5_CAP_ETH(mdev, tunnel_lro_gre) &&
 	    mlx5e_check_fragmented_striding_rq_cap(mdev, PAGE_SHIFT,
 						   MLX5E_MPWRQ_UMR_MODE_ALIGNED))
 		netdev->vlan_features    |= NETIF_F_LRO;
+#endif
 
 	netdev->hw_features       = netdev->vlan_features;
 	netdev->hw_features      |= NETIF_F_HW_VLAN_CTAG_TX;
@@ -5418,6 +6453,7 @@ static void mlx5e_build_nic_netdev(struc
 		netdev->hw_enc_features |= NETIF_F_GSO_PARTIAL;
 	}
 
+#ifdef HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON
 	if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev)) {
 		netdev->hw_features     |= NETIF_F_GSO_UDP_TUNNEL |
 					   NETIF_F_GSO_UDP_TUNNEL_CSUM;
@@ -5427,6 +6463,7 @@ static void mlx5e_build_nic_netdev(struc
 		netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL |
 					 NETIF_F_GSO_UDP_TUNNEL_CSUM;
 	}
+#endif
 
 	if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_GRE)) {
 		netdev->hw_features     |= NETIF_F_GSO_GRE |
@@ -5457,9 +6494,6 @@ static void mlx5e_build_nic_netdev(struc
 	if (MLX5_CAP_ETH(mdev, scatter_fcs))
 		netdev->hw_features |= NETIF_F_RXFCS;
 
-	if (mlx5_qos_is_supported(mdev))
-		netdev->hw_features |= NETIF_F_HW_TC;
-
 	netdev->features          = netdev->hw_features;
 
 	/* Defaults */
@@ -5487,8 +6521,12 @@ static void mlx5e_build_nic_netdev(struc
 
 	netdev->priv_flags       |= IFF_UNICAST_FLT;
 
+#ifdef HAVE_STRUCT_HOP_JUMBO_HDR
 	netif_set_tso_max_size(netdev, GSO_MAX_SIZE);
+#endif
+#ifdef HAVE_XDP_SET_FEATURES_FLAG
 	mlx5e_set_xdp_feature(netdev);
+#endif
 	mlx5e_set_netdev_dev_addr(netdev);
 	mlx5e_macsec_build_netdev(priv);
 	mlx5e_ipsec_build_netdev(priv);
@@ -5549,8 +6587,14 @@ static int mlx5e_nic_init(struct mlx5_co
 	struct mlx5e_flow_steering *fs;
 	int err;
 
-	mlx5e_build_nic_params(priv, &priv->xsk, netdev->mtu);
+	mlx5e_build_nic_params(priv,
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+			      &priv->xsk,
+#endif
+			      netdev->mtu);
+#if defined(HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON) && defined(HAVE_UDP_TUNNEL_NIC_INFO_FULL)
 	mlx5e_vxlan_set_netdev_info(priv);
+#endif
 
 	mlx5e_init_delay_drop(priv, &priv->channels.params);
 
@@ -5582,8 +6626,10 @@ static int mlx5e_nic_init(struct mlx5_co
 	if (take_rtnl)
 		rtnl_lock();
 
+#ifdef HAVE_XDP_SET_FEATURES_FLAG
 	/* update XDP supported features */
 	mlx5e_set_xdp_feature(netdev);
+#endif
 
 	if (take_rtnl)
 		rtnl_unlock();
@@ -5730,6 +6776,11 @@ static void mlx5e_nic_enable(struct mlx5
 
 	mlx5_lag_add_netdev(mdev, netdev);
 
+#ifdef HAVE_BASECODE_EXTRAS
+	if (!is_valid_ether_addr(netdev->perm_addr))
+		memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
+#endif
+
 	mlx5e_enable_async_events(priv);
 	mlx5e_enable_blocking_events(priv);
 	if (mlx5e_monitor_counter_supported(priv))
@@ -5745,7 +6796,12 @@ static void mlx5e_nic_enable(struct mlx5
 	rtnl_lock();
 	if (netif_running(netdev))
 		mlx5e_open(netdev);
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
 	udp_tunnel_nic_reset_ntf(priv->netdev);
+#elif defined(HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON) && defined(HAVE_DEVLINK_HAS_RELOAD_UP_DOWN)
+	if (mlx5_vxlan_allowed(priv->mdev->vxlan))
+		udp_tunnel_get_rx_info(priv->netdev);
+#endif
 	netif_device_attach(netdev);
 	rtnl_unlock();
 }
@@ -5760,6 +6816,13 @@ static void mlx5e_nic_disable(struct mlx
 	rtnl_lock();
 	if (netif_running(priv->netdev))
 		mlx5e_close(priv->netdev);
+#ifndef HAVE_UDP_TUNNEL_NIC_INFO
+#if defined(HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON) && defined(HAVE_DEVLINK_HAS_RELOAD_UP_DOWN)
+	if (mlx5_vxlan_allowed(priv->mdev->vxlan))
+		udp_tunnel_drop_rx_info(priv->netdev);
+
+#endif
+#endif
 	netif_device_detach(priv->netdev);
 	rtnl_unlock();
 
@@ -5777,7 +6840,9 @@ static void mlx5e_nic_disable(struct mlx
 	}
 	mlx5e_disable_async_events(priv);
 	mlx5_lag_remove_netdev(mdev, priv->netdev);
+#if defined(HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON) && defined(HAVE_DEVLINK_HAS_RELOAD_UP_DOWN)
 	mlx5_vxlan_reset_to_default(mdev->vxlan);
+#endif
 	mlx5e_macsec_cleanup(priv);
 	mlx5e_ipsec_cleanup(priv);
 }
@@ -6235,8 +7300,12 @@ void mlx5e_destroy_netdev(struct mlx5e_p
 static int _mlx5e_resume(struct auxiliary_device *adev)
 {
 	struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev);
+#ifdef HAVE_DEVLINK_PER_AUXDEV
 	struct mlx5e_dev *mlx5e_dev = auxiliary_get_drvdata(adev);
 	struct mlx5e_priv *priv = mlx5e_dev->priv;
+#else
+	struct mlx5e_priv *priv = auxiliary_get_drvdata(adev);
+#endif
 	struct net_device *netdev = priv->netdev;
 	struct mlx5_core_dev *mdev = edev->mdev;
 	struct mlx5_core_dev *pos, *to;
@@ -6283,8 +7352,12 @@ static int mlx5e_resume(struct auxiliary
 
 static int _mlx5e_suspend(struct auxiliary_device *adev, bool pre_netdev_reg)
 {
+#ifdef HAVE_DEVLINK_PER_AUXDEV
 	struct mlx5e_dev *mlx5e_dev = auxiliary_get_drvdata(adev);
 	struct mlx5e_priv *priv = mlx5e_dev->priv;
+#else
+	struct mlx5e_priv *priv = auxiliary_get_drvdata(adev);
+#endif
 	struct net_device *netdev = priv->netdev;
 	struct mlx5_core_dev *mdev = priv->mdev;
 	struct mlx5_core_dev *pos;
@@ -6320,6 +7393,10 @@ static int mlx5e_suspend(struct auxiliar
 	return err;
 }
 
+#ifdef HAVE_DEVLINK_PER_AUXDEV
+/* Since KORG 6.1 probe flow completely changes .In order to keep it clean
+ * for debugging we keep both version .On developer to consider to put fixes/changes
+ * in both in order to maintain both versions*/
 static int _mlx5e_probe(struct auxiliary_device *adev)
 {
 	struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev);
@@ -6398,6 +7475,93 @@ err_devlink_unregister:
 	mlx5e_destroy_devlink(mlx5e_dev);
 	return err;
 }
+#else
+/* Since KORG 6.1 probe flow completely changes .In order to keep it clean
+ * for debugging we keep both version .On developer to consider to put fixes/changes
+ * in both in order to maintain both versions*/
+static int _mlx5e_probe(struct auxiliary_device *adev)
+{
+	struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev);
+	const struct mlx5e_profile *profile = &mlx5e_nic_profile;
+	struct mlx5_core_dev *mdev = edev->mdev;
+	struct net_device *netdev;
+	pm_message_t state = {};
+	struct mlx5e_priv *priv;
+	int err;
+
+	netdev = mlx5e_create_netdev(mdev, profile);
+	if (!netdev) {
+		mlx5_core_err(mdev, "mlx5e_create_netdev failed\n");
+		return -ENOMEM;
+	}
+
+	mlx5e_build_nic_netdev(netdev);
+
+	priv = netdev_priv(netdev);
+	auxiliary_set_drvdata(adev, priv);
+
+	priv->profile = profile;
+	priv->ppriv = NULL;
+
+#ifdef HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT
+	err = mlx5e_devlink_port_register(priv);
+	if (err) {
+		mlx5_core_err(mdev, "mlx5e_devlink_port_register failed, %d\n", err);
+		goto err_destroy_netdev;
+	}
+#endif
+
+	err = profile->init(mdev, netdev);
+	if (err) {
+		mlx5_core_err(mdev, "mlx5e_nic_profile init failed, %d\n", err);
+		goto err_devlink_cleanup;
+	}
+
+	err = _mlx5e_resume(adev);
+	if (err) {
+		mlx5_core_err(mdev, "_mlx5e_resume failed, %d\n", err);
+		goto err_profile_cleanup;
+	}
+
+#ifdef HAVE_BASECODE_EXTRAS
+	mlx5e_rep_set_sysfs_attr(netdev);
+#endif
+#ifdef HAVE_NETDEV_DEVLINK_PORT
+	 SET_NETDEV_DEVLINK_PORT(netdev, mlx5e_devlink_get_dl_port(priv));
+#endif
+	err = register_netdev(netdev);
+	if (err) {
+		mlx5_core_err(mdev, "register_netdev failed, %d\n", err);
+		goto err_resume;
+	}
+
+#if defined(HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT) && !defined(HAVE_NETDEV_DEVLINK_PORT)
+	mlx5e_devlink_port_type_eth_set(priv);
+#endif
+
+	err = mlx5e_sysfs_create(netdev);
+	if (err)
+		goto err_unregister_netdev;
+
+	mlx5e_dcbnl_init_app(priv);
+	mlx5_core_uplink_netdev_set(mdev, netdev);
+	return 0;
+
+err_unregister_netdev:
+	unregister_netdev(netdev);
+err_resume:
+	mlx5e_suspend(adev, state);
+err_profile_cleanup:
+	profile->cleanup(priv);
+err_devlink_cleanup:
+#ifdef HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT
+	mlx5e_devlink_port_unregister(priv);
+err_destroy_netdev:
+#endif
+	mlx5e_destroy_netdev(priv);
+	return err;
+}
+#endif /* HAVE_DEVLINK_PER_AUXDEV */
 
 static int mlx5e_probe(struct auxiliary_device *adev,
 		       const struct auxiliary_device_id *id)
@@ -6420,8 +7584,12 @@ static int mlx5e_probe(struct auxiliary_
 static void _mlx5e_remove(struct auxiliary_device *adev)
 {
 	struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev);
+#ifdef HAVE_DEVLINK_PER_AUXDEV
 	struct mlx5e_dev *mlx5e_dev = auxiliary_get_drvdata(adev);
 	struct mlx5e_priv *priv = mlx5e_dev->priv;
+#else
+	struct mlx5e_priv *priv = auxiliary_get_drvdata(adev);
+#endif
 	struct mlx5_core_dev *mdev = edev->mdev;
 
 	mlx5_core_uplink_netdev_set(mdev, NULL);
@@ -6432,9 +7600,16 @@ static void _mlx5e_remove(struct auxilia
 	/* Avoid cleanup if profile rollback failed. */
 	if (priv->profile)
 		priv->profile->cleanup(priv);
+#ifdef HAVE_DEVLINK_PER_AUXDEV
 	mlx5e_destroy_netdev(priv);
 	mlx5e_devlink_port_unregister(mlx5e_dev);
 	mlx5e_destroy_devlink(mlx5e_dev);
+#else
+#ifdef HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT
+	mlx5e_devlink_port_unregister(priv);
+#endif
+	mlx5e_destroy_netdev(priv);
+#endif /* HAVE_DEVLINK_PER_AUXDEV */
 }
 
 static void mlx5e_remove(struct auxiliary_device *adev)
@@ -6470,7 +7645,9 @@ int mlx5e_init(void)
 {
 	int ret;
 
-	mlx5e_build_ptys2ethtool_map();
+#ifdef __ETHTOOL_DECLARE_LINK_MODE_MASK
+       mlx5e_build_ptys2ethtool_map();
+#endif
 	ret = auxiliary_driver_register(&mlx5e_driver);
 	if (ret)
 		return ret;
