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

Change-Id: I1d79f7746d92d2763217cc6fc748ff0a8a96b359
---
 .../net/ethernet/mellanox/mlx5/core/en_main.c | 1369 ++++++++++++++++-
 1 file changed, 1293 insertions(+), 76 deletions(-)

--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -30,17 +30,30 @@
  * SOFTWARE.
  */
 
+#ifdef CONFIG_MLX5_CLS_ACT
 #include <net/tc_act/tc_gact.h>
+#endif
 #include <net/pkt_cls.h>
 #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/if_bridge.h>
 #include <linux/irq.h>
 #include <linux/filter.h>
+#ifdef HAVE_NET_PAGE_POOL_H
 #include <net/page_pool.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"
@@ -52,7 +65,9 @@
 #include "en_accel/tls.h"
 #include "accel/ipsec.h"
 #include "accel/tls.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 +86,7 @@
 #include "qos.h"
 #include "en/trap.h"
 #include "fpga/ipsec.h"
+#include "compat.h"
 
 bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev)
 {
@@ -95,16 +111,21 @@ 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 {
@@ -270,6 +291,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),
@@ -288,8 +310,12 @@ 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
 	if (!shampo->bitmap)
 		return -ENOMEM;
 
@@ -308,6 +334,7 @@ static void mlx5e_rq_shampo_hd_info_free
 	kvfree(rq->mpwqe.shampo->bitmap);
 	kvfree(rq->mpwqe.shampo->info);
 }
+#endif
 
 static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq, int node)
 {
@@ -374,6 +401,7 @@ static int mlx5e_create_umr_mtt_mkey(str
 	return err;
 }
 
+#ifdef HAVE_SHAMPO_SUPPORT
 static int mlx5e_create_umr_klm_mkey(struct mlx5_core_dev *mdev,
 				     u64 nentries,
 				     u32 *umr_mkey)
@@ -406,6 +434,7 @@ 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)
 {
@@ -415,6 +444,7 @@ static int mlx5e_create_rq_umr_mkey(stru
 					 &rq->umr_mkey, rq->wqe_overflow.addr);
 }
 
+#ifdef HAVE_SHAMPO_SUPPORT
 static int mlx5e_create_rq_hd_umr_mkey(struct mlx5_core_dev *mdev,
 				       struct mlx5e_rq *rq)
 {
@@ -428,6 +458,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 u64 mlx5e_get_mpwqe_offset(u16 wqe_ix)
 {
@@ -531,7 +562,9 @@ static int mlx5e_init_rxq_rq(struct mlx5
 	rq->channel      = c;
 	rq->mdev         = mdev;
 	rq->hw_mtu       = MLX5E_SW2HW_MTU(params, params->sw_mtu);
+#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 &&
@@ -543,9 +576,19 @@ static int mlx5e_init_rxq_rq(struct mlx5
 	if (err)
 		return err;
 
-	return xdp_rxq_info_reg(&rq->xdp_rxq, rq->netdev, rq->ix, 0);
+#ifdef HAVE_XDP_SUPPORT
+#ifdef HAVE_XDP_RXQ_INFO
+#ifdef HAVE_XDP_RXQ_INFO_REG_4_PARAMS
+	err = xdp_rxq_info_reg(&rq->xdp_rxq, rq->netdev, rq->ix, 0);
+#else
+	err = xdp_rxq_info_reg(&rq->xdp_rxq, rq->netdev, rq->ix);
+#endif
+#endif
+#endif /* HAVE_XDP_SUPPORT */
+	return err;
 }
 
+#ifdef HAVE_SHAMPO_SUPPORT
 static int mlx5_rq_shampo_alloc(struct mlx5_core_dev *mdev,
 				struct mlx5e_params *params,
 				struct mlx5e_rq_param *rqp,
@@ -604,6 +647,7 @@ static void mlx5e_rq_free_shampo(struct
 	mlx5_core_destroy_mkey(rq->mdev, rq->mpwqe.shampo->mkey);
 	mlx5e_rq_shampo_hd_free(rq);
 }
+#endif
 
 static void mlx5e_rx_cache_reduce_clean_pending(struct mlx5e_rq *rq)
 {
@@ -697,11 +741,20 @@ static int mlx5e_alloc_rq(struct mlx5e_p
 			  struct mlx5e_rq_param *rqp,
 			  int node, struct mlx5e_rq *rq)
 {
+#ifdef HAVE_NET_PAGE_POOL_H
 	struct page_pool_params pp_params = { 0 };
+#endif
 	struct mlx5_core_dev *mdev = rq->mdev;
 	void *rqc = rqp->rqc;
 	void *rqc_wq = MLX5_ADDR_OF(rqc, rqc, wq);
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+#ifndef HAVE_XSK_BUFF_ALLOC
+	u32 num_xsk_frames = 0;
+#endif
+#endif
+#ifdef HAVE_NET_PAGE_POOL_H
 	u32 pool_size;
+#endif
 	u32 cache_init_sz;
 	int wq_sz;
 	int err;
@@ -709,14 +762,36 @@ static int mlx5e_alloc_rq(struct mlx5e_p
 
 	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
+#ifdef HAVE_NET_PAGE_POOL_H
 	pool_size = 1 << params->log_rq_mtu_frames;
+#endif
 
 	switch (rq->wq_type) {
 	case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
@@ -733,10 +808,19 @@ static int mlx5e_alloc_rq(struct mlx5e_p
 
 		wq_sz = mlx5_wq_ll_get_size(&rq->mpwqe.wq);
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+#ifndef HAVE_XSK_BUFF_ALLOC
+		if (xsk)
+			num_xsk_frames = wq_sz <<
+				mlx5e_mpwqe_get_log_num_strides(mdev, params, xsk);
+#endif
+#endif
 		cache_init_sz = wq_sz * MLX5_MPWRQ_PAGES_PER_WQE;
 
+#ifdef HAVE_NET_PAGE_POOL_H
 		pool_size = MLX5_MPWRQ_PAGES_PER_WQE <<
 			mlx5e_mpwqe_get_log_rq_size(params, xsk);
+#endif
 
 		rq->mpwqe.log_stride_sz = mlx5e_mpwqe_get_log_stride_size(mdev, params, xsk);
 		rq->mpwqe.num_strides =
@@ -753,9 +837,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_by_rq_type;
+#endif
 
 		break;
 	default: /* MLX5_WQ_TYPE_CYCLIC */
@@ -768,6 +854,13 @@ static int mlx5e_alloc_rq(struct mlx5e_p
 
 		wq_sz = mlx5_wq_cyc_get_size(&rq->wqe.wq);
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+#ifndef HAVE_XSK_BUFF_ALLOC
+		if (xsk)
+			num_xsk_frames = wq_sz << rq->wqe.info.log_num_frags;
+#endif
+#endif
+
 		cache_init_sz = wq_sz;
 		rq->wqe.info = rqp->frags_info;
 		rq->buff.frame0_sz = rq->wqe.info.arr[0].frag_stride;
@@ -788,16 +881,38 @@ static int mlx5e_alloc_rq(struct mlx5e_p
 		rq->mkey_be = cpu_to_be32(mdev->mlx5e_res.hw_objs.mkey);
 	}
 
+	err = 0;
+#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
+#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 */
 		err = mlx5e_rx_alloc_page_cache(rq, node,
 				ilog2(cache_init_sz));
 		if (err)
 			goto err_free_by_rq_type;
 
+#ifdef HAVE_NET_PAGE_POOL_H
 		/* Create a page_pool and register it with rxq */
 		pp_params.order     = 0;
 		pp_params.flags     = 0; /* No-internal DMA mapping in page_pool */
@@ -817,10 +932,21 @@ static int mlx5e_alloc_rq(struct mlx5e_p
 			rq->page_pool = NULL;
 			goto err_free_shampo;
 		}
+#endif /* HAVE_NET_PAGE_POOL_H */
+#ifdef HAVE_XDP_SUPPORT
+#ifdef HAVE_XDP_RXQ_INFO_REG_MEM_MODEL
 		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
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	}
+#endif
+#endif /* HAVE_XDP_RXQ_INFO_REG_MEM_MODEL */
+#endif /* HAVE_XDP_SUPPORT */
 	if (err)
 		goto err_free_shampo;
 
@@ -872,7 +998,9 @@ static int mlx5e_alloc_rq(struct mlx5e_p
 	return 0;
 
 err_free_shampo:
+#ifdef HAVE_SHAMPO_SUPPORT
 	mlx5e_rq_free_shampo(rq);
+#endif
 err_free_by_rq_type:
 	switch (rq->wq_type) {
 	case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
@@ -890,22 +1018,29 @@ err_rq_frags:
 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;
 
+#ifdef HAVE_XDP_RXQ_INFO
 	if (xdp_rxq_info_is_reg(&rq->xdp_rxq)) {
+#endif
 		old_prog = rcu_dereference_protected(rq->xdp_prog,
 						     lockdep_is_held(&rq->priv->state_lock));
 		if (old_prog)
 			bpf_prog_put(old_prog);
+#ifdef HAVE_XDP_RXQ_INFO
 	}
+#endif
+#endif /* HAVE_XDP_SUPPORT */
 
 	if (rq->page_cache.page_cache)
 		mlx5e_rx_free_page_cache(rq);
@@ -915,15 +1050,23 @@ static void mlx5e_free_rq(struct mlx5e_r
 		kvfree(rq->mpwqe.info);
 		mlx5_core_destroy_mkey(rq->mdev, rq->umr_mkey);
 		mlx5e_free_mpwqe_rq_drop_page(rq);
+#ifdef HAVE_SHAMPO_SUPPORT
 		mlx5e_rq_free_shampo(rq);
+#endif
 		break;
 	default: /* MLX5_WQ_TYPE_CYCLIC */
 		kvfree(rq->wqe.frags);
 		mlx5e_free_di_list(rq);
 	}
-
+#ifdef HAVE_XDP_SUPPORT
+#ifdef HAVE_XDP_RXQ_INFO
 	xdp_rxq_info_unreg(&rq->xdp_rxq);
-	page_pool_destroy(rq->page_pool);
+#endif
+#endif
+#ifdef HAVE_NET_PAGE_POOL_H
+        if (rq->page_pool)
+		page_pool_destroy(rq->page_pool);
+#endif
 	mlx5_wq_destroy(&rq->wq_ctrl);
 }
 
@@ -983,11 +1126,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));
@@ -1129,6 +1274,7 @@ void mlx5e_free_rx_in_progress_descs(str
 		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;
 
@@ -1137,6 +1283,7 @@ void mlx5e_free_rx_in_progress_descs(str
 		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;
@@ -1164,9 +1311,11 @@ 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;
 
@@ -1179,6 +1328,59 @@ void mlx5e_free_rx_descs(struct mlx5e_rq
 
 }
 
+#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_priv *priv, struct mlx5e_params *params,
 		  struct mlx5e_rq_param *param, struct mlx5e_xsk_param *xsk,
 		  struct mlx5e_create_cq_param *ccp, struct dim_cq_moder moder,
@@ -1215,12 +1417,19 @@ int mlx5e_open_rq(struct mlx5e_priv *pri
 		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;
 
+#if defined(HAVE_UAPI_LINUX_TLS_H) && defined(CONFIG_MLX5_EN_TLS) && \
+    defined(HAVE_KTLS_RX_SUPPORT)
 	if (mlx5e_is_tls_on(rq->priv) && !mlx5e_accel_is_ktls_device(mdev))
 		__set_bit(MLX5E_RQ_STATE_FPGA_TLS, &rq->state); /* must be FPGA */
+#endif
 
 	if (MLX5_CAP_ETH(mdev, cqe_checksum_full))
 		__set_bit(MLX5E_RQ_STATE_CSUM_FULL, &rq->state);
@@ -1232,7 +1441,11 @@ int mlx5e_open_rq(struct mlx5e_priv *pri
 	 * 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
@@ -1242,6 +1455,9 @@ int mlx5e_open_rq(struct mlx5e_priv *pri
 	    MLX5_CAP_GEN(mdev, mini_cqe_resp_stride_index))
 		__set_bit(MLX5E_RQ_STATE_MINI_CQE_HW_STRIDX, &rq->state);
 
+	if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_SKB_XMIT_MORE))
+		__set_bit(MLX5E_RQ_STATE_SKB_XMIT_MORE, &rq->state);
+
 	return 0;
 
 err_destroy_rq:
@@ -1277,6 +1493,7 @@ void mlx5e_close_rq(struct mlx5e_priv *p
 	memset(rq, 0, sizeof(*rq));
 }
 
+#ifdef HAVE_XDP_SUPPORT
 static void mlx5e_free_xdpsq_db(struct mlx5e_xdpsq *sq)
 {
 	kvfree(sq->db.xdpi_fifo.xi);
@@ -1324,7 +1541,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)
@@ -1340,11 +1563,19 @@ 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);
+#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) :
@@ -1374,6 +1605,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)
 {
@@ -1701,6 +1933,9 @@ int mlx5e_open_txqsq(struct mlx5e_channe
 	if (params->tx_dim_enabled)
 		sq->state |= BIT(MLX5E_SQ_STATE_AM);
 
+	if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_SKB_XMIT_MORE))
+		set_bit(MLX5E_SQ_STATE_SKB_XMIT_MORE, &sq->state);
+
 	return 0;
 
 err_free_txqsq:
@@ -1798,6 +2033,7 @@ static int mlx5e_open_icosq(struct mlx5e
 	if (err)
 		goto err_free_icosq;
 
+#if defined(CONFIG_MLX5_EN_TLS) && defined(HAVE_KTLS_RX_SUPPORT)
 	if (param->is_tls) {
 		sq->ktls_resync = mlx5e_ktls_rx_resync_create_resp_list();
 		if (IS_ERR(sq->ktls_resync)) {
@@ -1805,10 +2041,13 @@ static int mlx5e_open_icosq(struct mlx5e
 			goto err_destroy_icosq;
 		}
 	}
+#endif
 	return 0;
 
+#if defined(CONFIG_MLX5_EN_TLS) && defined(HAVE_KTLS_RX_SUPPORT)
 err_destroy_icosq:
 	mlx5e_destroy_sq(c->mdev, sq->sqn);
+#endif
 err_free_icosq:
 	mlx5e_free_icosq(sq);
 
@@ -1836,14 +2075,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;
 
@@ -1860,6 +2111,9 @@ int mlx5e_open_xdpsq(struct mlx5e_channe
 	if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_TX_XDP_CSUM))
 		set_bit(MLX5E_SQ_STATE_TX_XDP_CSUM, &sq->state);
 
+	if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_SKB_XMIT_MORE))
+		set_bit(MLX5E_SQ_STATE_SKB_XMIT_MORE, &sq->state);
+
 	if (!param->is_mpw) {
 		unsigned int ds_cnt = MLX5E_XDP_TX_DS_COUNT;
 		unsigned int inline_hdr_sz = 0;
@@ -1916,6 +2170,7 @@ void mlx5e_close_xdpsq(struct mlx5e_xdps
 	mlx5e_free_xdpsq_descs(sq);
 	mlx5e_free_xdpsq(sq);
 }
+#endif
 
 int mlx5e_alloc_cq_common(struct mlx5e_priv *priv,
 			  struct mlx5e_cq_param *param,
@@ -1968,6 +2223,9 @@ static int mlx5e_alloc_cq(struct mlx5e_p
 
 	cq->napi     = ccp->napi;
 	cq->ch_stats = ccp->ch_stats;
+#ifndef HAVE_NAPI_STATE_MISSED
+	cq->ch_flags = ccp->ch_flags;
+#endif
 
 	return err;
 }
@@ -2094,6 +2352,7 @@ static void mlx5e_close_tx_cqs(struct ml
 		mlx5e_close_cq(&c->sq[tc].cq);
 }
 
+#ifdef HAVE_TC_MQPRIO_QOPT_OFFLOAD
 static int mlx5e_mqprio_txq_to_tc(struct netdev_tc_txq *tc_to_txq, unsigned int txq)
 {
 	int tc;
@@ -2129,7 +2388,7 @@ static int mlx5e_txq_get_qos_node_hw_id(
 	*hw_id = params->mqprio.channel.hw_id[tc];
 	return 0;
 }
-
+#endif
 static int mlx5e_open_sqs(struct mlx5e_channel *c,
 			  struct mlx5e_params *params,
 			  struct mlx5e_channel_param *cparam)
@@ -2138,15 +2397,21 @@ static int mlx5e_open_sqs(struct mlx5e_c
 
 	for (tc = 0; tc < mlx5e_get_dcb_num_tc(params); tc++) {
 		int txq_ix = c->ix + tc * params->num_channels;
+#ifdef HAVE_TC_MQPRIO_QOPT_OFFLOAD
 		u32 qos_queue_group_id;
 
 		err = mlx5e_txq_get_qos_node_hw_id(params, txq_ix, &qos_queue_group_id);
 		if (err)
 			goto err_close_sqs;
+#endif
 
 		err = mlx5e_open_txqsq(c, c->priv->tisn[c->lag_port][tc], txq_ix,
 				       params, &cparam->txq_sq, &c->sq[tc], tc,
+#ifdef HAVE_TC_MQPRIO_QOPT_OFFLOAD
 				       qos_queue_group_id,
+#else
+					0,
+#endif
 				       &c->priv->channel_stats[c->ix]->sq[tc]);
 		if (err)
 			goto err_close_sqs;
@@ -2219,6 +2484,7 @@ static int mlx5e_set_sq_maxrate(struct n
 	return 0;
 }
 
+#if defined(HAVE_NDO_SET_TX_MAXRATE) || defined(HAVE_NDO_SET_TX_MAXRATE_EXTENDED)
 static int mlx5e_set_tx_maxrate(struct net_device *dev, int index, u32 rate)
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
@@ -2249,6 +2515,7 @@ static int mlx5e_set_tx_maxrate(struct n
 
 	return err;
 }
+#endif
 
 static int mlx5e_open_rxq_rq(struct mlx5e_channel *c, struct mlx5e_params *params,
 			     struct mlx5e_create_cq_param *ccp, struct mlx5e_rq_param *rq_params)
@@ -2271,12 +2538,10 @@ static int mlx5e_open_queues(struct mlx5
 	int err;
 
 	mlx5e_build_create_cq_param(&ccp, c);
-
 	err = mlx5e_open_cq(c->priv, icocq_moder, &cparam->async_icosq.cqp, &ccp,
 			    &c->async_icosq.cq);
 	if (err)
 		return err;
-
 	err = mlx5e_open_cq(c->priv, icocq_moder, &cparam->icosq.cqp, &ccp,
 			    &c->icosq.cq);
 	if (err)
@@ -2286,6 +2551,7 @@ static int mlx5e_open_queues(struct mlx5
 	if (err)
 		goto err_close_icosq_cq;
 
+#ifdef HAVE_XDP_SUPPORT
 	err = mlx5e_open_cq(c->priv, params->tx_cq_moderation, &cparam->xdp_sq.cqp, &ccp,
 			    &c->xdpsq.cq);
 	if (err)
@@ -2295,6 +2561,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);
 
@@ -2318,25 +2585,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);
@@ -2348,6 +2626,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);
 
@@ -2355,6 +2634,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:
@@ -2368,9 +2648,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);
@@ -2378,9 +2660,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);
@@ -2434,12 +2718,20 @@ void mlx5e_trigger_napi_sched(struct nap
 static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
 			      struct mlx5e_params *params,
 			      struct mlx5e_channel_param *cparam,
+#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)
 {
 	int cpu = cpumask_first(mlx5_comp_irq_get_affinity_mask(priv->mdev, ix));
 	struct net_device *netdev = priv->netdev;
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	struct mlx5e_xsk_param xsk;
+#endif
 	const struct cpumask *aff;
 	struct mlx5e_channel *c;
 	unsigned int irq;
@@ -2449,7 +2741,17 @@ 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);
+#elif defined(HAVE_IRQ_GET_AFFINITY_MASK)
+	aff = irq_get_affinity_mask(irq);
+#else
+#ifndef HAVE_IRQ_DATA_AFFINITY
+	aff = irq_data_get_affinity_mask(irq_desc_get_irq_data(irq_to_desc(irq)));
+#else
+	aff = irq_desc_get_irq_data(irq_to_desc(irq))->affinity;
+#endif
+#endif
 
 	err = mlx5e_channel_stats_alloc(priv, ix, cpu);
 	if (err)
@@ -2468,30 +2770,40 @@ static int mlx5e_open_channel(struct mlx
 	c->netdev   = priv->netdev;
 	c->mkey_be  = cpu_to_be32(priv->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 = aff;
 	c->lag_port = mlx5e_enumerate_lag_port(priv->mdev, ix);
 
+#ifdef HAVE_NETIF_NAPI_ADD_GET_3_PARAMS //forwardport
+	netif_napi_add(netdev, &c->napi, mlx5e_napi_poll);
+#else
 	netif_napi_add(netdev, &c->napi, mlx5e_napi_poll, 64);
+#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;
 
 	return 0;
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 err_close_queues:
 	mlx5e_close_queues(c);
+#endif
 
 err_napi_del:
 	netif_napi_del(&c->napi);
@@ -2506,13 +2818,19 @@ static void mlx5e_rq_channel_activate(st
 	if (c->priv->shared_rq)
 		return;
 
+#ifdef HAVE_XDP_SUPPORT
 	if (c->xdp)
 		mlx5e_activate_xdpsq(&c->rq_xdpsq);
+#endif
 	mlx5e_activate_rq(&c->rq);
+#ifdef HAVE_XDP_SUPPORT
 	mlx5e_activate_xdpsq(&c->xdpsq);
+#endif
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state))
 		mlx5e_activate_xsk(c);
+#endif
 
 	mlx5e_trigger_napi_icosq(c);
 }
@@ -2544,13 +2862,19 @@ static void mlx5e_rq_channel_deactivate(
 	if (c->priv->shared_rq)
 		return;
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state))
 		mlx5e_deactivate_xsk(c);
+#endif
 
+#ifdef HAVE_XDP_SUPPORT
 	mlx5e_deactivate_xdpsq(&c->xdpsq);
+#endif
 	mlx5e_deactivate_rq(&c->rq);
+#ifdef HAVE_XDP_SUPPORT
 	if (c->xdp)
 		mlx5e_deactivate_xdpsq(&c->rq_xdpsq);
+#endif
 }
 
 static void mlx5e_disable_channel(struct mlx5e_channel *c)
@@ -2578,8 +2902,10 @@ static void mlx5e_stop_channel(struct ml
 
 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);
@@ -2606,12 +2932,20 @@ int mlx5e_open_channels(struct mlx5e_pri
 		goto err_free;
 
 	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, cparam, xsk_pool, &chs->c[i]);
+#endif
+		err = mlx5e_open_channel(priv, i, &chs->params, cparam,
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+					xsk_pool,
+#endif
+					&chs->c[i]);
 		if (err)
 			goto err_close_channels;
 	}
@@ -2722,7 +3056,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)
@@ -2777,10 +3111,14 @@ MLX5E_DEFINE_PREACTIVATE_WRAPPER_CTX(mlx
 
 void mlx5e_set_netdev_mtu_boundaries(struct mlx5e_priv *priv)
 {
+#if defined(HAVE_NET_DEVICE_MIN_MAX_MTU) || defined(HAVE_NET_DEVICE_MIN_MAX_MTU_EXTENDED)
 	struct mlx5e_params *params = &priv->channels.params;
 	struct net_device *netdev   = priv->netdev;
 	struct mlx5_core_dev *mdev  = priv->mdev;
 	u16 max_mtu;
+#endif
+
+#ifdef HAVE_NET_DEVICE_MIN_MAX_MTU
 
 	/* MTU range: 68 - hw-specific max */
 	netdev->min_mtu = ETH_MIN_MTU;
@@ -2788,6 +3126,12 @@ void mlx5e_set_netdev_mtu_boundaries(str
 	mlx5_query_port_max_mtu(mdev, &max_mtu, 1);
 	netdev->max_mtu = min_t(unsigned int, MLX5E_HW2SW_MTU(params, max_mtu),
 				ETH_MAX_MTU);
+#elif defined(HAVE_NET_DEVICE_MIN_MAX_MTU_EXTENDED)
+	netdev->extended->min_mtu = ETH_MIN_MTU;
+	mlx5_query_port_max_mtu(mdev, &max_mtu, 1);
+	netdev->extended->max_mtu = min_t(unsigned int, MLX5E_HW2SW_MTU(params, max_mtu),
+			ETH_MAX_MTU);
+#endif
 }
 
 static int mlx5e_netdev_set_tcs(struct net_device *netdev, u16 nch, u8 ntc,
@@ -2820,6 +3164,10 @@ static int mlx5e_netdev_set_tcs(struct n
 int mlx5e_update_tx_netdev_queues(struct mlx5e_priv *priv)
 {
 	int qos_queues, nch, ntc, num_txqs, err;
+#ifndef HAVE_NET_SYNCHRONIZE_IN_SET_REAL_NUM_TX_QUEUES
+        struct net_device *netdev = priv->netdev;
+        bool disabling;
+#endif
 
 	qos_queues = mlx5e_qos_cur_leaf_nodes(priv);
 
@@ -2828,6 +3176,9 @@ 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;
+#ifndef HAVE_NET_SYNCHRONIZE_IN_SET_REAL_NUM_TX_QUEUES
+        disabling = num_txqs < netdev->real_num_tx_queues;
+#endif
 
 	mlx5e_dbg(DRV, priv, "Setting num_txqs %d\n", num_txqs);
 	err = netif_set_real_num_tx_queues(priv->netdev, num_txqs);
@@ -2835,6 +3186,11 @@ int mlx5e_update_tx_netdev_queues(struct
 		netdev_warn(priv->netdev, "netif_set_real_num_tx_queues failed (%d > %d), %d\n",
 			    num_txqs, priv->netdev->num_tx_queues, err);
 
+#ifndef HAVE_NET_SYNCHRONIZE_IN_SET_REAL_NUM_TX_QUEUES
+	if (disabling)
+		synchronize_net();
+#endif
+
 	return err;
 }
 
@@ -2886,8 +3242,11 @@ err_out:
 	return err;
 }
 
+#if defined(HAVE_NDO_SETUP_TC_TAKES_TC_SETUP_TYPE) || defined(HAVE_NDO_SETUP_TC_RH_EXTENDED)
+#ifdef HAVE_TC_MQPRIO_QOPT_OFFLOAD
 static MLX5E_DEFINE_PREACTIVATE_WRAPPER_CTX(mlx5e_update_netdev_queues);
-
+#endif
+#endif
 static void mlx5e_set_default_xps_cpumasks(struct mlx5e_priv *priv,
 					   struct mlx5e_params *params)
 {
@@ -2921,7 +3280,11 @@ static int mlx5e_num_channels_changed(st
 	mlx5e_set_default_xps_cpumasks(priv, &priv->channels.params);
 
 	/* This function may be called on attach, before priv->rx_res is created. */
+#ifdef HAVE_NETIF_IS_RXFH_CONFIGURED
 	if (!netif_is_rxfh_configured(priv->netdev) && priv->rx_res)
+#else
+	if (priv->rx_res)
+#endif
 		mlx5e_rx_res_rss_set_indir_uniform(priv->rx_res, count);
 
 	return 0;
@@ -3002,8 +3365,9 @@ void mlx5e_activate_priv_channels(struct
 	mlx5e_build_txq_maps(priv);
 	mlx5e_activate_channels(&priv->channels);
 	mlx5e_qos_activate_queues(priv);
+#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.
 	 * Make it happy to avoid TX timeout false alarms.
@@ -3039,7 +3403,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);
 }
 
@@ -3284,8 +3650,11 @@ static int mlx5e_alloc_drop_rq(struct ml
 		return err;
 
 	/* Mark as unused given "Drop-RQ" packets never reach XDP */
+#ifdef HAVE_XDP_SUPPORT
+#ifdef HAVE_XDP_RXQ_INFO
 	xdp_rxq_info_unused(&rq->xdp_rxq);
-
+#endif
+#endif
 	rq->mdev = mdev;
 
 	return 0;
@@ -3449,7 +3818,10 @@ static int mlx5e_modify_channels_scatter
 	return 0;
 }
 
-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;
@@ -3483,6 +3855,23 @@ static void mlx5e_mqprio_build_default_t
 	}
 }
 
+static void mlx5e_params_mqprio_dcb_set(struct mlx5e_params *params, u8 num_tc)
+{
+#ifdef HAVE_TC_MQPRIO_QOPT_OFFLOAD
+	params->mqprio.mode = TC_MQPRIO_MODE_DCB;
+#endif
+	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);
+}
+
+#if defined(HAVE_NDO_SETUP_TC_TAKES_TC_SETUP_TYPE) || defined(HAVE_NDO_SETUP_TC_RH_EXTENDED)
+#ifdef HAVE_TC_MQPRIO_QOPT_OFFLOAD
 static void mlx5e_mqprio_build_tc_to_txq(struct netdev_tc_txq *tc_to_txq,
 					 struct tc_mqprio_qopt *qopt)
 {
@@ -3496,14 +3885,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)
 {
@@ -3533,11 +3914,7 @@ static void mlx5e_params_mqprio_channel_
 	mlx5e_mqprio_rl_update_params(params, rl);
 	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);
-}
+#endif
 
 static int mlx5e_setup_tc_mqprio_dcb(struct mlx5e_priv *priv,
 				     struct tc_mqprio_qopt *mqprio)
@@ -3576,6 +3953,7 @@ static int mlx5e_setup_tc_mqprio_dcb(str
 	return err;
 }
 
+#ifdef HAVE_TC_MQPRIO_QOPT_OFFLOAD
 static int mlx5e_mqprio_channel_validate(struct mlx5e_priv *priv,
 					 struct tc_mqprio_qopt_offload *mqprio)
 {
@@ -3706,16 +4084,24 @@ static int mlx5e_setup_tc_mqprio_channel
 
 	return 0;
 }
+#endif
+#endif
 
+#if defined(HAVE_NDO_SETUP_TC_TAKES_TC_SETUP_TYPE) || defined(HAVE_NDO_SETUP_TC_RH_EXTENDED)
 int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv,
-				 struct tc_mqprio_qopt_offload *mqprio)
+#ifdef HAVE_TC_MQPRIO_QOPT_OFFLOAD
+				struct tc_mqprio_qopt_offload *mqprio
+#else
+				struct tc_mqprio_qopt *mqprio
+#endif
+)
 {
 	/* MQPRIO is another toplevel qdisc that can't be attached
 	 * simultaneously with the offloaded HTB.
 	 */
 	if (WARN_ON(priv->htb.maj_id))
 		return -EINVAL;
-
+#ifdef HAVE_TC_MQPRIO_QOPT_OFFLOAD
 	switch (mqprio->mode) {
 	case TC_MQPRIO_MODE_DCB:
 		return mlx5e_setup_tc_mqprio_dcb(priv, &mqprio->qopt);
@@ -3724,8 +4110,55 @@ int mlx5e_setup_tc_mqprio(struct mlx5e_p
 	default:
 		return -EOPNOTSUPP;
 	}
+#else
+	return mlx5e_setup_tc_mqprio_dcb(priv, mqprio);
+#endif
+
+}
+#else
+int mlx5e_setup_tc(struct net_device *netdev, u8 tc)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5e_params new_params;
+	int err = 0;
+
+	if (tc && tc != MLX5E_MAX_NUM_TC
+#ifdef CONFIG_MLX5_CORE_EN_DCB
+			&& priv->dcbx_dp.trust_state != MLX5_QPTS_TRUST_PCP
+#endif
+			)
+                return -EINVAL;
+
+        mutex_lock(&priv->state_lock);
+
+        /* MQPRIO is another toplevel qdisc that can't be attached
+ *          * simultaneously with the offloaded HTB.
+ *                   */
+        if (WARN_ON(priv->htb.maj_id)) {
+                err = -EINVAL;
+                goto out;
+        }
+
+        new_params = priv->channels.params;
+        mlx5e_params_mqprio_dcb_set(&new_params, tc ? tc : 1);
+
+#ifdef CONFIG_MLX5_CORE_EN_DCB
+	if (priv->dcbx_dp.trust_state == MLX5_QPTS_TRUST_PCP)
+		priv->pcp_tc_num = tc;
+#endif
+
+        err = mlx5e_safe_switch_params(priv, &new_params,
+                                       mlx5e_num_channels_changed_ctx, NULL, true);
+
+out:
+	priv->max_opened_tc = max_t(u8, priv->max_opened_tc,
+				    mlx5e_get_dcb_num_tc(&priv->channels.params));
+        mutex_unlock(&priv->state_lock);
+        return err;
 }
+#endif
 
+#ifdef HAVE_ENUM_TC_HTB_COMMAND
 static int mlx5e_setup_tc_htb(struct mlx5e_priv *priv, struct tc_htb_qopt_offload *htb)
 {
 	int res;
@@ -3747,7 +4180,12 @@ static int mlx5e_setup_tc_htb(struct mlx
 		return mlx5e_htb_leaf_to_inner(priv, htb->parent_classid, htb->classid,
 					       htb->rate, htb->ceil, htb->extack);
 	case TC_HTB_LEAF_DEL:
+#ifndef HAVE_TC_HTB_COMMAND_HAS_MOVED_QID /* will be base code next rebase */
 		return mlx5e_htb_leaf_del(priv, &htb->classid, htb->extack);
+#else
+		return mlx5e_htb_leaf_del(priv, htb->classid, &htb->moved_qid, &htb->qid,
+				          htb->extack);
+#endif
 	case TC_HTB_LEAF_DEL_LAST:
 	case TC_HTB_LEAF_DEL_LAST_FORCE:
 		return mlx5e_htb_leaf_del_last(priv, htb->classid,
@@ -3766,47 +4204,138 @@ static int mlx5e_setup_tc_htb(struct mlx
 		return -EOPNOTSUPP;
 	}
 }
+#endif
 
+#if defined(HAVE_NDO_SETUP_TC_TAKES_TC_SETUP_TYPE) || defined(HAVE_NDO_SETUP_TC_RH_EXTENDED)
+#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_setup_tc_htb(priv, type_data);
 		mutex_unlock(&priv->state_lock);
 		return err;
+#endif
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+#else /* HAVE_NDO_SETUP_TC_TAKES_TC_SETUP_TYPE || HAVE_NDO_SETUP_TC_RH_EXTENDED */
+#if defined(HAVE_NDO_SETUP_TC_4_PARAMS) || defined(HAVE_NDO_SETUP_TC_TAKES_CHAIN_INDEX)
+static int mlx5e_ndo_setup_tc(struct net_device *dev, u32 handle,
+#ifdef HAVE_NDO_SETUP_TC_TAKES_CHAIN_INDEX
+			      u32 chain_index, __be16 proto,
+#else
+			      __be16 proto,
+#endif
+			      struct tc_to_netdev *tc)
+{
+#ifdef HAVE_TC_FLOWER_OFFLOAD
+#ifdef CONFIG_MLX5_CLS_ACT
+	struct mlx5e_priv *priv = netdev_priv(dev);
+#endif /*CONFIG_MLX5_CLS_ACT*/
+
+	if (!netif_device_present(dev))
+		return -EOPNOTSUPP;
+
+	if (TC_H_MAJ(handle) != TC_H_MAJ(TC_H_INGRESS))
+		goto mqprio;
+
+#ifdef HAVE_NDO_SETUP_TC_TAKES_CHAIN_INDEX
+	if (chain_index)
+		return -EOPNOTSUPP;
+#endif
+
+	switch (tc->type) {
+#ifdef CONFIG_MLX5_CLS_ACT
+	case TC_SETUP_CLSFLOWER:
+		switch (tc->cls_flower->command) {
+		case TC_CLSFLOWER_REPLACE:
+			return mlx5e_configure_flower(priv->netdev, priv, tc->cls_flower,
+						      MLX5_TC_FLAG(INGRESS));
+		case TC_CLSFLOWER_DESTROY:
+			return mlx5e_delete_flower(priv->netdev, priv, tc->cls_flower,
+						   MLX5_TC_FLAG(INGRESS));
+#ifdef HAVE_TC_CLSFLOWER_STATS
+		case TC_CLSFLOWER_STATS:
+			return mlx5e_stats_flower(priv->netdev, priv, tc->cls_flower,
+						  MLX5_TC_FLAG(INGRESS));
+#endif
+		}
+#endif /*CONFIG_MLX5_CLS_ACT*/
 	default:
 		return -EOPNOTSUPP;
 	}
+
+mqprio:
+#endif /* HAVE_TC_FLOWER_OFFLOAD */
+	if (tc->type != TC_SETUP_MQPRIO)
+		return -EINVAL;
+
+#ifdef HAVE_TC_TO_NETDEV_TC
+	return mlx5e_setup_tc(dev, tc->tc);
+#else
+	tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+
+	return mlx5e_setup_tc(dev, tc->mqprio->num_tc);
+#endif /* HAVE_TC_TO_NETDEV_TC */
 }
+#endif /* HAVE_NDO_SETUP_TC_4_PARAMS || HAVE_NDO_SETUP_TC_TAKES_CHAIN_INDEX */
+#endif /* HAVE_NDO_SETUP_TC_TAKES_TC_SETUP_TYPE || HAVE_NDO_SETUP_TC_RH_EXTENDED */
 
 void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s)
 {
@@ -3814,13 +4343,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];
@@ -3848,14 +4391,26 @@ void mlx5e_fold_sw_stats64(struct mlx5e_
 	}
 }
 
-void
-mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
+#ifdef HAVE_NDO_GET_STATS64_RET_VOID
+void mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
+#elif defined(HAVE_NDO_GET_STATS64)
+struct rtnl_link_stats64 * mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
+#else
+struct net_device_stats * mlx5e_get_stats(struct net_device *dev)
+#endif
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 	struct mlx5e_pport_stats *pstats = &priv->stats.pport;
+#if !defined(HAVE_NDO_GET_STATS64) && !defined(HAVE_NDO_GET_STATS64_RET_VOID)
+	struct net_device_stats *stats = &priv->netdev_stats;
+#endif
 
 	if (!netif_device_present(dev))
+#ifdef HAVE_NDO_GET_STATS64_RET_VOID
 		return;
+#else
+		return stats;
+#endif
 
 	/* In switchdev mode, monitor counters doesn't monitor
 	 * rx/tx stats of 802_3. The update stats mechanism
@@ -3896,6 +4451,10 @@ mlx5e_get_stats(struct net_device *dev,
 	stats->rx_errors = stats->rx_length_errors + stats->rx_crc_errors +
 			   stats->rx_frame_errors;
 	stats->tx_errors = stats->tx_aborted_errors + stats->tx_carrier_errors;
+
+#ifndef HAVE_NDO_GET_STATS64_RET_VOID
+	return stats;
+#endif
 }
 
 static void mlx5e_nic_set_rx_mode(struct mlx5e_priv *priv)
@@ -3922,7 +4481,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);
@@ -3951,29 +4514,44 @@ static int set_feature_lro(struct net_de
 
 	mutex_lock(&priv->state_lock);
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	if (enable && priv->xsk.refcnt) {
 		netdev_warn(netdev, "LRO is incompatible with AF_XDP (%u XSKs are active)\n",
 			    priv->xsk.refcnt);
 		err = -EINVAL;
 		goto out;
 	}
+#endif
 
 	cur_params = &priv->channels.params;
-	if (enable && !MLX5E_GET_PFLAG(cur_params, MLX5E_PFLAG_RX_STRIDING_RQ)) {
-		netdev_warn(netdev, "can't set LRO with legacy RQ\n");
-		err = -EINVAL;
-		goto out;
-	}
 
 	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 out;
+	}
+#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)) {
 		if (cur_params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
@@ -3983,6 +4561,13 @@ static int set_feature_lro(struct net_de
 		}
 	}
 
+	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;
+	}
+
 	err = mlx5e_safe_switch_params(priv, &new_params,
 				       mlx5e_modify_tirs_packet_merge_ctx, NULL, reset);
 out:
@@ -3990,6 +4575,7 @@ out:
 	return err;
 }
 
+#ifdef HAVE_NETIF_F_GRO_HW
 static int set_feature_hw_gro(struct net_device *netdev, bool enable)
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -4018,6 +4604,7 @@ out:
 	mutex_unlock(&priv->state_lock);
 	return err;
 }
+#endif
 
 static int set_feature_cvlan_filter(struct net_device *netdev, bool enable)
 {
@@ -4147,6 +4734,7 @@ unlock:
 }
 
 #ifdef CONFIG_MLX5_EN_ARFS
+#ifndef HAVE_NET_FLOW_KEYS_H
 static int set_feature_arfs(struct net_device *netdev, bool enable)
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -4160,6 +4748,7 @@ static int set_feature_arfs(struct net_d
 	return err;
 }
 #endif
+#endif
 
 static int mlx5e_handle_feature(struct net_device *netdev,
 				netdev_features_t *features,
@@ -4193,7 +4782,9 @@ int mlx5e_set_features(struct net_device
 	mlx5e_handle_feature(netdev, &oper_features, feature, handler)
 
 	err |= MLX5E_HANDLE_FEATURE(NETIF_F_LRO, set_feature_lro);
+#ifdef HAVE_NETIF_F_GRO_HW
 	err |= MLX5E_HANDLE_FEATURE(NETIF_F_GRO_HW, set_feature_hw_gro);
+#endif
 	err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_FILTER,
 				    set_feature_cvlan_filter);
 	err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_TC, set_feature_hw_tc);
@@ -4201,9 +4792,13 @@ int mlx5e_set_features(struct net_device
 	err |= MLX5E_HANDLE_FEATURE(NETIF_F_RXFCS, set_feature_rx_fcs);
 	err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_RX, set_feature_rx_vlan);
 #ifdef CONFIG_MLX5_EN_ARFS
+#ifndef HAVE_NET_FLOW_KEYS_H
 	err |= MLX5E_HANDLE_FEATURE(NETIF_F_NTUPLE, set_feature_arfs);
 #endif
+#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;
@@ -4216,6 +4811,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");
@@ -4224,13 +4820,20 @@ static netdev_features_t mlx5e_fix_uplin
 	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
+#ifndef HAVE_NET_FLOW_KEYS_H
 	features &= ~NETIF_F_NTUPLE;
 	if (netdev->features & NETIF_F_NTUPLE)
 		netdev_warn(netdev, "Disabling ntuple, not supported in switchdev mode\n");
+#endif
+#endif
 
+#ifdef HAVE_NETIF_F_GRO_HW
 	features &= ~NETIF_F_GRO_HW;
 	if (netdev->features & NETIF_F_GRO_HW)
 		netdev_warn(netdev, "Disabling HW_GRO, not supported in switchdev mode\n");
+#endif
 
 	return features;
 }
@@ -4253,28 +4856,39 @@ 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;
 		}
+#ifdef HAVE_NETIF_F_GRO_HW
 		if (features & NETIF_F_GRO_HW) {
 			netdev_warn(netdev, "Disabling HW-GRO, not supported in legacy RQ\n");
 			features &= ~NETIF_F_GRO_HW;
 		}
+#endif
 	}
 
+#ifdef HAVE_XDP_SUPPORT
 	if (params->xdp_prog) {
 		if (features & NETIF_F_LRO) {
 			netdev_warn(netdev, "LRO is incompatible with XDP\n");
 			features &= ~NETIF_F_LRO;
 		}
+#ifdef HAVE_NETIF_F_GRO_HW
 		if (features & NETIF_F_GRO_HW) {
 			netdev_warn(netdev, "HW GRO is incompatible with XDP\n");
 			features &= ~NETIF_F_GRO_HW;
 		}
+#endif
 	}
+#endif
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	if (priv->xsk.refcnt) {
 		if (features & NETIF_F_GRO_HW) {
 			netdev_warn(netdev, "HW GRO is incompatible with AF_XDP (%u XSKs are active)\n",
@@ -4282,16 +4896,19 @@ 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;
 		if (netdev->features & NETIF_F_RXHASH)
 			netdev_warn(netdev, "Disabling rxhash, not supported when CQE compress is active\n");
 
+#ifdef HAVE_NETIF_F_GRO_HW
 		if (features & NETIF_F_GRO_HW) {
 			netdev_warn(netdev, "Disabling HW-GRO, not supported when CQE compress is active\n");
 			features &= ~NETIF_F_GRO_HW;
 		}
+#endif
 	}
 
 	/* LRO/HW-GRO features cannot be combined with RX-FCS */
@@ -4300,16 +4917,20 @@ static netdev_features_t mlx5e_fix_featu
 			netdev_warn(netdev, "Dropping LRO feature since RX-FCS is requested\n");
 			features &= ~NETIF_F_LRO;
 		}
+#ifdef HAVE_NETIF_F_GRO_HW
 		if (features & NETIF_F_GRO_HW) {
 			netdev_warn(netdev, "Dropping HW-GRO feature since RX-FCS is requested\n");
 			features &= ~NETIF_F_GRO_HW;
 		}
+#endif
 	}
 
+#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);
@@ -4319,6 +4940,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,
@@ -4327,8 +4949,13 @@ 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;
 
 		if (!xsk_pool)
@@ -4356,6 +4983,7 @@ static bool mlx5e_xsk_validate_mtu(struc
 
 	return true;
 }
+#endif /* HAVE_XSK_ZERO_COPY_SUPPORT */
 
 int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
 		     mlx5e_fp_preactivate preactivate)
@@ -4363,19 +4991,38 @@ int mlx5e_change_mtu(struct net_device *
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 	struct mlx5e_params new_params;
 	struct mlx5e_params *params;
+#if !defined(HAVE_NET_DEVICE_MIN_MAX_MTU) && !defined(HAVE_NET_DEVICE_MIN_MAX_MTU_EXTENDED)
+	struct mlx5_core_dev *mdev = priv->mdev;
+	u16 max_mtu;
+	u16 min_mtu;
+#endif
 	bool reset = true;
 	int err = 0;
 
 	mutex_lock(&priv->state_lock);
 
 	params = &priv->channels.params;
+#if !defined(HAVE_NET_DEVICE_MIN_MAX_MTU) && !defined(HAVE_NET_DEVICE_MIN_MAX_MTU_EXTENDED)
+	mlx5_query_port_max_mtu(mdev, &max_mtu, 1);
+	max_mtu = min_t(unsigned int, MLX5E_HW2SW_MTU(params, max_mtu),
+			ETH_MAX_MTU);
+	min_mtu = ETH_MIN_MTU;
+
+	if (new_mtu > max_mtu || new_mtu < min_mtu) {
+		netdev_err(netdev,
+			   "%s: Bad MTU (%d), valid range is: [%d..%d]\n",
+			   __func__, new_mtu, min_mtu, max_mtu);
+		mutex_unlock(&priv->state_lock);
+		return -EINVAL;
+	}
+#endif
 
 	new_params = *params;
 	new_params.sw_mtu = new_mtu;
 	err = mlx5e_validate_params(priv->mdev, &new_params);
 	if (err)
 		goto out;
-
+#ifdef HAVE_XDP_SUPPORT
 	if (params->xdp_prog &&
 	    !mlx5e_rx_is_linear_skb(&new_params, NULL)) {
 		netdev_err(netdev, "MTU(%d) > %d is not allowed while XDP enabled\n",
@@ -4384,6 +5031,7 @@ int mlx5e_change_mtu(struct net_device *
 		goto out;
 	}
 
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	if (priv->xsk.refcnt &&
 	    !mlx5e_xsk_validate_mtu(netdev, &priv->channels,
 				    &new_params, priv->mdev)) {
@@ -4391,7 +5039,13 @@ int mlx5e_change_mtu(struct net_device *
 		goto out;
 	}
 
+#endif /* HAVE_XSK_ZERO_COPY_SUPPORT */
+#endif /* HAVE_XDP_SUPPORT */
+#ifdef CONFIG_COMPAT_LRO_ENABLED_IPOIB
+	if (IS_HW_LRO(&priv->channels.params))
+#else
 	if (params->packet_merge.type == MLX5E_PACKET_MERGE_LRO)
+#endif
 		reset = false;
 
 	if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
@@ -4405,7 +5059,10 @@ int mlx5e_change_mtu(struct net_device *
 		 * Check that the mode was non-linear and didn't change.
 		 * If XSK is active, XSK RQs are 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
 		    ppw_old == ppw_new)
 			reset = false;
 	}
@@ -4532,7 +5189,6 @@ int mlx5e_hwstamp_set(struct mlx5e_priv
 	memcpy(&priv->tstamp, &config, sizeof(config));
 	mutex_unlock(&priv->state_lock);
 
-	/* might need to fix some features */
 	netdev_update_features(priv->netdev);
 
 	return copy_to_user(ifr->ifr_data, &config,
@@ -4575,15 +5231,24 @@ int mlx5e_set_vf_mac(struct net_device *
 	return mlx5_eswitch_set_vport_mac(mdev->priv.eswitch, vf + 1, mac);
 }
 
+#if defined(HAVE_NDO_SET_VF_VLAN) || defined(HAVE_NDO_SET_VF_VLAN_EXTENDED)
+#ifdef HAVE_VF_VLAN_PROTO
 static int mlx5e_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos,
 			     __be16 vlan_proto)
+#else
+static int mlx5e_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos)
+#endif
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 	struct mlx5_core_dev *mdev = priv->mdev;
+#ifndef HAVE_VF_VLAN_PROTO
+	__be16 vlan_proto = htons(ETH_P_8021Q);
+#endif
 
 	return mlx5_eswitch_set_vport_vlan(mdev->priv.eswitch, vf + 1,
 					   vlan, qos, vlan_proto);
 }
+#endif /* HAVE_NDO_SET_VF_VLAN */
 
 #ifdef HAVE_NETDEV_OPS_NDO_SET_VF_TRUNK_RANGE
 static int mlx5e_add_vf_vlan_trunk_range(struct net_device *dev, int vf,
@@ -4623,6 +5288,7 @@ static int mlx5e_set_vf_spoofchk(struct
 	return mlx5_eswitch_set_vport_spoofchk(mdev->priv.eswitch, vf + 1, setting);
 }
 
+#if defined(HAVE_NETDEV_OPS_NDO_SET_VF_TRUST) || defined(HAVE_NETDEV_OPS_NDO_SET_VF_TRUST_EXTENDED)
 static int mlx5e_set_vf_trust(struct net_device *dev, int vf, bool setting)
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
@@ -4630,14 +5296,28 @@ static int mlx5e_set_vf_trust(struct net
 
 	return mlx5_eswitch_set_vport_trust(mdev->priv.eswitch, vf + 1, setting);
 }
+#endif
 
 int mlx5e_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
 		      int max_tx_rate)
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 	struct mlx5_core_dev *mdev = priv->mdev;
+	int vport = (vf == 0xffff) ? 0 : vf + 1;
 
-	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;
+	}
+
+	return mlx5_eswitch_set_vport_rate(mdev->priv.eswitch, vport,
 					   max_tx_rate, min_tx_rate);
 }
 
@@ -4693,6 +5373,7 @@ int mlx5e_get_vf_config(struct net_devic
 	return 0;
 }
 
+#ifdef HAVE_NDO_GET_VF_STATS
 int mlx5e_get_vf_stats(struct net_device *dev,
 		       int vf, struct ifla_vf_stats *vf_stats)
 {
@@ -4702,13 +5383,19 @@ int mlx5e_get_vf_stats(struct net_device
 	return mlx5_eswitch_get_vport_stats(mdev->priv.eswitch, vf + 1,
 					    vf_stats);
 }
+#endif
 
+#if defined(HAVE_NDO_HAS_OFFLOAD_STATS_GETS_NET_DEVICE) || defined(HAVE_NDO_HAS_OFFLOAD_STATS_EXTENDED)
 static bool
 mlx5e_has_offload_stats(const struct net_device *dev, int attr_id)
 {
 	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))
@@ -4716,7 +5403,9 @@ mlx5e_has_offload_stats(const struct net
 
 	return mlx5e_rep_has_offload_stats(dev, attr_id);
 }
+#endif
 
+#if defined(HAVE_NDO_GET_OFFLOAD_STATS) || defined(HAVE_NDO_GET_OFFLOAD_STATS_EXTENDED)
 static int
 mlx5e_get_offload_stats(int attr_id, const struct net_device *dev,
 			void *sp)
@@ -4729,6 +5418,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)
 {
@@ -4744,6 +5434,112 @@ 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;
+};
+
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_NDO_UDP_TUNNEL_ADD_EXTENDED) || defined(HAVE_NDO_ADD_VXLAN_PORT)
+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
+
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_NDO_UDP_TUNNEL_ADD_EXTENDED)
+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);
+}
+#elif defined(HAVE_NDO_ADD_VXLAN_PORT)
+void mlx5e_add_vxlan_port(struct net_device *netdev,
+		sa_family_t sa_family, __be16 port)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+
+	if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
+		return;
+
+	mlx5e_vxlan_queue_work(priv, be16_to_cpu(port), 1);
+}
+
+void mlx5e_del_vxlan_port(struct net_device *netdev,
+		sa_family_t sa_family, __be16 port)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+
+	if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
+		return;
+
+	mlx5e_vxlan_queue_work(priv, be16_to_cpu(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)
 {
@@ -4764,9 +5560,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;
+#ifdef HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON
 	u16 port;
+#endif
 
 	switch (vlan_get_protocol(skb)) {
 	case htons(ETH_P_IP):
@@ -4789,6 +5589,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);
@@ -4796,6 +5597,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 features;
+#endif
 
 #if IS_ENABLED(CONFIG_GENEVE)
 		/* Support Geneve offload for default UDP port */
@@ -4821,7 +5623,9 @@ netdev_features_t mlx5e_features_check(s
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 
 	features = vlan_features_check(skb, features);
+#ifdef HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON
 	features = vxlan_features_check(skb, features);
+#endif /* HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON */
 
 	/* Validate if the tunneled packet is being offloaded by HW */
 	if (skb->encapsulation &&
@@ -4865,7 +5669,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);
 
@@ -4873,12 +5681,17 @@ 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 mlx5e_priv *priv, struct bpf_prog *prog)
 {
 	struct net_device *netdev = priv->netdev;
 	struct mlx5e_params new_params;
 
+#ifdef CONFIG_COMPAT_LRO_ENABLED_IPOIB
+	if (IS_HW_LRO(&priv->channels.params)) {
+#else
 	if (priv->channels.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;
 	}
@@ -4966,15 +5779,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:
@@ -4987,23 +5818,81 @@ 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
+
+#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
+#if defined(HAVE_NDO_BRIDGE_GETLINK) || defined(HAVE_NDO_BRIDGE_GETLINK_NLFLAGS)
 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
+#if defined(HAVE_NDO_BRIDGE_GETLINK_NLFLAGS)
+				, int nlflags)
+#elif defined(HAVE_NDO_BRIDGE_GETLINK)
+				)
+#endif
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 	struct mlx5_core_dev *mdev = priv->mdev;
@@ -5014,13 +5903,35 @@ 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
+#if defined(HAVE_NDO_DFLT_BRIDGE_GETLINK_FLAG_MASK)
+				       , 0, 0);
+#endif
+#if defined(HAVE_NDO_DFLT_BRIDGE_GETLINK_FLAG_MASK_NFLAGS) && defined(HAVE_NDO_BRIDGE_GETLINK)
+				       , 0, 0, 0);
+#endif
+#if defined(HAVE_NDO_DFLT_BRIDGE_GETLINK_FLAG_MASK_NFLAGS) && defined(HAVE_NDO_BRIDGE_GETLINK_NLFLAGS)
+				       , 0, 0, nlflags);
+#endif
+#if defined(HAVE_NDO_DFLT_BRIDGE_GETLINK_FLAG_MASK_NFLAGS_FILTER) && defined(HAVE_NDO_BRIDGE_GETLINK)
+				       , 0, 0, 0, filter_mask, NULL);
+#endif
+#if defined(HAVE_NDO_DFLT_BRIDGE_GETLINK_FLAG_MASK_NFLAGS_FILTER) && defined(HAVE_NDO_BRIDGE_GETLINK_NLFLAGS)
+				       , 0, 0, nlflags, filter_mask, NULL);
+#endif
 }
+#endif
 
+#if defined(HAVE_NDO_BRIDGE_SETLINK) || defined(HAVE_NDO_BRIDGE_SETLINK_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)
+#endif
+#ifdef 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;
@@ -5055,37 +5966,184 @@ static int mlx5e_bridge_setlink(struct n
 }
 #endif
 
+#ifndef HAVE_DEVLINK_PORT_ATTRS_PCI_PF_SET
+#if defined(HAVE_NDO_GET_PHYS_PORT_NAME) || defined(HAVE_NDO_GET_PHYS_PORT_NAME_EXTENDED)
+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
+#endif
+
+#if defined(HAVE_NDO_GET_PORT_PARENT_ID)
+#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 /* CONFIG_MLX5_ESWITCH */
+
 const struct net_device_ops mlx5e_netdev_ops = {
 	.ndo_open                = mlx5e_open,
 	.ndo_stop                = mlx5e_close,
 	.ndo_start_xmit          = mlx5e_xmit,
+#ifdef HAVE_NDO_SETUP_TC_RH_EXTENDED
+	.extended.ndo_setup_tc_rh = mlx5e_setup_tc,
+#else
+#ifdef HAVE_NDO_SETUP_TC
+#ifdef HAVE_NDO_SETUP_TC_TAKES_TC_SETUP_TYPE
 	.ndo_setup_tc            = mlx5e_setup_tc,
+#else
+#if defined(HAVE_NDO_SETUP_TC_4_PARAMS) || defined(HAVE_NDO_SETUP_TC_TAKES_CHAIN_INDEX)
+	.ndo_setup_tc		 = mlx5e_ndo_setup_tc,
+#else
+	.ndo_setup_tc		 = mlx5e_setup_tc,
+#endif
+#endif
+#endif
+#endif
 	.ndo_select_queue        = mlx5e_select_queue,
+#if defined(HAVE_NDO_GET_STATS64) || defined(HAVE_NDO_GET_STATS64_RET_VOID)
 	.ndo_get_stats64         = mlx5e_get_stats,
+#else
+	.ndo_get_stats		 = mlx5e_get_stats,
+#endif
 	.ndo_set_rx_mode         = mlx5e_set_rx_mode,
 	.ndo_set_mac_address     = mlx5e_set_mac,
 	.ndo_vlan_rx_add_vid     = mlx5e_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid    = mlx5e_vlan_rx_kill_vid,
 	.ndo_set_features        = mlx5e_set_features,
 	.ndo_fix_features        = mlx5e_fix_features,
-	.ndo_change_mtu          = mlx5e_change_nic_mtu,
+#ifdef HAVE_NDO_CHANGE_MTU_EXTENDED
+	.extended.ndo_change_mtu = mlx5e_change_nic_mtu,
+#else
+       .ndo_change_mtu          = mlx5e_change_nic_mtu,
+#endif
+
+#ifdef HAVE_NDO_ETH_IOCTL
 	.ndo_eth_ioctl            = mlx5e_ioctl,
+#else
+	.ndo_do_ioctl		  = mlx5e_ioctl,
+#endif
+
+#ifdef HAVE_NDO_SET_TX_MAXRATE
 	.ndo_set_tx_maxrate      = mlx5e_set_tx_maxrate,
+#elif defined(HAVE_NDO_SET_TX_MAXRATE_EXTENDED)
+	.extended.ndo_set_tx_maxrate      = mlx5e_set_tx_maxrate,
+#endif
+
+#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,
+#elif defined(HAVE_NDO_UDP_TUNNEL_ADD_EXTENDED)
+	.extended.ndo_udp_tunnel_add	  = mlx5e_add_vxlan_port,
+	.extended.ndo_udp_tunnel_del	  = mlx5e_del_vxlan_port,
+#elif defined(HAVE_NDO_ADD_VXLAN_PORT)
+	.ndo_add_vxlan_port	 = mlx5e_add_vxlan_port,
+	.ndo_del_vxlan_port	 = 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
+#ifdef HAVE_NDO_XDP_EXTENDED
+	.extended.ndo_xdp        = mlx5e_xdp,
+#else
+	.ndo_bpf                 = mlx5e_xdp,
+#endif
+#ifdef HAVE_NDO_XDP_XMIT
 	.ndo_xdp_xmit            = mlx5e_xdp_xmit,
+#endif
+#ifdef HAVE_NDO_XDP_FLUSH
+        .ndo_xdp_flush           = mlx5e_xdp_flush,
+#endif
+#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
+#ifndef HAVE_NET_FLOW_KEYS_H
 	.ndo_rx_flow_steer	 = mlx5e_rx_flow_steer,
 #endif
+#endif
+#ifndef HAVE_NETPOLL_POLL_DEV_EXPORTED
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	 = mlx5e_netpoll,
+#endif
+#endif
+#ifdef HAVE_NET_DEVICE_OPS_EXTENDED
+	.ndo_size = sizeof(struct net_device_ops),
+#endif
 #ifdef CONFIG_MLX5_ESWITCH
+#if defined(HAVE_NDO_BRIDGE_SETLINK) || defined(HAVE_NDO_BRIDGE_SETLINK_EXTACK)
 	.ndo_bridge_setlink      = mlx5e_bridge_setlink,
+#endif
+#if defined(HAVE_NDO_BRIDGE_GETLINK) || defined(HAVE_NDO_BRIDGE_GETLINK_NLFLAGS)
 	.ndo_bridge_getlink      = mlx5e_bridge_getlink,
+#endif
 
 	/* SRIOV E-Switch NDOs */
 	.ndo_set_vf_mac          = mlx5e_set_vf_mac,
+#if defined(HAVE_NDO_SET_VF_VLAN)
 	.ndo_set_vf_vlan         = mlx5e_set_vf_vlan,
+#elif defined(HAVE_NDO_SET_VF_VLAN_EXTENDED)
+	.extended.ndo_set_vf_vlan  = mlx5e_set_vf_vlan,
+#endif
 
 	/* these ndo's are not upstream yet */
 #ifdef HAVE_NETDEV_OPS_NDO_SET_VF_TRUNK_RANGE
@@ -5094,15 +6152,42 @@ const struct net_device_ops mlx5e_netdev
 #endif
 
 	.ndo_set_vf_spoofchk     = mlx5e_set_vf_spoofchk,
+#ifdef HAVE_NETDEV_OPS_NDO_SET_VF_TRUST
 	.ndo_set_vf_trust        = mlx5e_set_vf_trust,
+#elif defined(HAVE_NETDEV_OPS_NDO_SET_VF_TRUST_EXTENDED)
+	.extended.ndo_set_vf_trust        = mlx5e_set_vf_trust,
+#endif
 	.ndo_set_vf_rate         = mlx5e_set_vf_rate,
+	.ndo_set_vf_link_state	 = mlx5e_set_vf_link_state,
 	.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,
+#ifdef HAVE_NDO_GET_VF_STATS
+	.ndo_get_vf_stats	 = mlx5e_get_vf_stats,
+#endif
+#ifndef HAVE_NET_DEVICE_HAS_DEVLINK_PORT
+#ifdef HAVE_NDO_GET_DEVLINK_PORT
+	.ndo_get_devlink_port    = mlx5e_get_devlink_port,
+#else
+#ifdef HAVE_NDO_GET_PHYS_PORT_NAME
+	.ndo_get_phys_port_name  = mlx5e_get_phys_port_name,
+#elif defined(HAVE_NDO_GET_PHYS_PORT_NAME_EXTENDED)
+	.extended.ndo_get_phys_port_name = mlx5e_get_phys_port_name,
+#endif
+#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 */
+#ifdef HAVE_NDO_HAS_OFFLOAD_STATS_GETS_NET_DEVICE
 	.ndo_has_offload_stats   = mlx5e_has_offload_stats,
+#elif defined(HAVE_NDO_HAS_OFFLOAD_STATS_EXTENDED)
+	.extended.ndo_has_offload_stats   = mlx5e_has_offload_stats,
+#endif
+#ifdef HAVE_NDO_GET_OFFLOAD_STATS
 	.ndo_get_offload_stats   = mlx5e_get_offload_stats,
+#elif defined(HAVE_NDO_GET_OFFLOAD_STATS_EXTENDED)
+	.extended.ndo_get_offload_stats   = mlx5e_get_offload_stats,
 #endif
-	.ndo_get_devlink_port    = mlx5e_get_devlink_port,
+#endif /* CONFIG_MLX5_ESWITCH */
 };
 
 u32 mlx5e_choose_lro_timeout(struct mlx5_core_dev *mdev, u32 wanted_timeout)
@@ -5129,7 +6214,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;
@@ -5149,7 +6238,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;
@@ -5158,6 +6249,7 @@ 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);
+	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_TX_CQE_COMPRESS, false);
 	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_NO_CSUM_COMPLETE, false);
 
 	/* RQ */
@@ -5169,6 +6261,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);
@@ -5180,11 +6278,17 @@ void mlx5e_build_nic_params(struct mlx5e
 	params->tunneled_offload_en = mlx5_tunnel_inner_ft_supported(mdev);
 
 	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);
+
+	/* skb xmit_more in driver is off by default */
+	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_SKB_XMIT_MORE, 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()
@@ -5194,19 +6298,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)
 static int mlx5e_vxlan_set_port(struct net_device *netdev, unsigned int table,
 				unsigned int entry, struct udp_tunnel_info *ti)
 {
@@ -5239,6 +6352,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)
 {
@@ -5248,7 +6368,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)
@@ -5264,6 +6388,9 @@ static void mlx5e_build_nic_netdev(struc
 
 	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;
@@ -5289,12 +6416,16 @@ 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))
 		netdev->vlan_features    |= NETIF_F_LRO;
-
+#endif
 	netdev->hw_features       = netdev->vlan_features;
 	netdev->hw_features      |= NETIF_F_HW_VLAN_CTAG_TX;
 	netdev->hw_features      |= NETIF_F_HW_VLAN_CTAG_RX;
@@ -5305,41 +6436,55 @@ static void mlx5e_build_nic_netdev(struc
 		netdev->hw_enc_features |= NETIF_F_HW_CSUM;
 		netdev->hw_enc_features |= NETIF_F_TSO;
 		netdev->hw_enc_features |= NETIF_F_TSO6;
+#ifdef HAVE_NETIF_F_GSO_PARTIAL
 		netdev->hw_enc_features |= NETIF_F_GSO_PARTIAL;
+#endif
 	}
 
+#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;
 		netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL |
 					   NETIF_F_GSO_UDP_TUNNEL_CSUM;
+#ifdef HAVE_NETIF_F_GSO_PARTIAL
 		netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
+#endif
 		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 |
 					   NETIF_F_GSO_GRE_CSUM;
 		netdev->hw_enc_features |= NETIF_F_GSO_GRE |
 					   NETIF_F_GSO_GRE_CSUM;
+#ifdef HAVE_NETIF_F_GSO_PARTIAL
 		netdev->gso_partial_features |= NETIF_F_GSO_GRE |
 						NETIF_F_GSO_GRE_CSUM;
+#endif
 	}
 
 	if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_IPIP)) {
+#ifdef HAVE_NETIF_F_GSO_IPXIP6
 		netdev->hw_features |= NETIF_F_GSO_IPXIP4 |
 				       NETIF_F_GSO_IPXIP6;
 		netdev->hw_enc_features |= NETIF_F_GSO_IPXIP4 |
 					   NETIF_F_GSO_IPXIP6;
 		netdev->gso_partial_features |= NETIF_F_GSO_IPXIP4 |
 						NETIF_F_GSO_IPXIP6;
+#endif
 	}
 
+#ifdef HAVE_NETIF_F_GSO_PARTIAL
 	netdev->hw_features	                 |= NETIF_F_GSO_PARTIAL;
+#endif
+#ifdef HAVE_NETIF_F_GSO_UDP_L4
 	netdev->gso_partial_features             |= NETIF_F_GSO_UDP_L4;
 	netdev->hw_features                      |= NETIF_F_GSO_UDP_L4;
 	netdev->features                         |= NETIF_F_GSO_UDP_L4;
+#endif
 
 	mlx5_query_port_fcs(mdev, &fcs_supported, &fcs_enabled);
 
@@ -5349,8 +6494,12 @@ static void mlx5e_build_nic_netdev(struc
 	if (MLX5_CAP_ETH(mdev, scatter_fcs))
 		netdev->hw_features |= NETIF_F_RXFCS;
 
+#ifdef CONFIG_COMPAT_CLS_FLOWER_MOD
+#if !defined(CONFIG_NET_SCHED_NEW) && !defined(CONFIG_COMPAT_KERNEL_4_14)
 	if (mlx5_qos_is_supported(mdev))
 		netdev->hw_features |= NETIF_F_HW_TC;
+#endif
+#endif
 
 	netdev->features          = netdev->hw_features;
 
@@ -5358,7 +6507,9 @@ static void mlx5e_build_nic_netdev(struc
 	if (fcs_enabled)
 		netdev->features  &= ~NETIF_F_RXALL;
 	netdev->features  &= ~NETIF_F_LRO;
+#ifdef HAVE_NETIF_F_GRO_HW
 	netdev->features  &= ~NETIF_F_GRO_HW;
+#endif
 	netdev->features  &= ~NETIF_F_RXFCS;
 
 #define FT_CAP(f) MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_receive.f)
@@ -5370,8 +6521,10 @@ static void mlx5e_build_nic_netdev(struc
 		netdev->hw_features      |= NETIF_F_HW_TC;
 #endif
 #ifdef CONFIG_MLX5_EN_ARFS
+#ifndef HAVE_NET_FLOW_KEYS_H
 		netdev->hw_features	 |= NETIF_F_NTUPLE;
 #endif
+#endif
 	}
 
 	netdev->features         |= NETIF_F_HIGHDMA;
@@ -5429,8 +6582,14 @@ static int mlx5e_nic_init(struct mlx5_co
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 	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)
 	mlx5e_vxlan_set_netdev_info(priv);
+#endif
 	mutex_init(&priv->aso_lock);
 
 	mlx5e_init_delay_drop(priv, &priv->channels.params);
@@ -5484,7 +6643,11 @@ static int mlx5e_init_nic_rx(struct mlx5
 		goto err_destroy_q_counters;
 	}
 
-	features = MLX5E_RX_RES_FEATURE_XSK | MLX5E_RX_RES_FEATURE_PTP;
+	features = MLX5E_RX_RES_FEATURE_PTP
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
+        | MLX5E_RX_RES_FEATURE_XSK
+#endif
+        ;
 	if (priv->channels.params.tunneled_offload_en)
 		features |= MLX5E_RX_RES_FEATURE_INNER_FT;
 	err = mlx5e_rx_res_init(priv->rx_res, priv->mdev, features,
@@ -5541,6 +6704,7 @@ static void mlx5e_cleanup_nic_rx(struct
 	priv->rx_res = NULL;
 }
 
+#ifdef HAVE_TC_MQPRIO_QOPT_OFFLOAD
 static void mlx5e_set_mqprio_rl(struct mlx5e_priv *priv)
 {
 	struct mlx5e_params *params;
@@ -5557,6 +6721,7 @@ static void mlx5e_set_mqprio_rl(struct m
 	priv->mqprio_rl = rl;
 	mlx5e_mqprio_rl_update_params(params, rl);
 }
+#endif
 
 static int mlx5e_init_nic_tx(struct mlx5e_priv *priv)
 {
@@ -5567,8 +6732,9 @@ static int mlx5e_init_nic_tx(struct mlx5
 		mlx5_core_warn(priv->mdev, "create tises failed, %d\n", err);
 		return err;
 	}
-
+#ifdef HAVE_TC_MQPRIO_QOPT_OFFLOAD
 	mlx5e_set_mqprio_rl(priv);
+#endif
 	mlx5e_dcbnl_initialize(priv);
 	return 0;
 }
@@ -5578,6 +6744,9 @@ static void mlx5e_nic_enable(struct mlx5
 	struct net_device *netdev = priv->netdev;
 	struct mlx5_core_dev *mdev = priv->mdev;
 	int err;
+#if defined(HAVE_NET_DEVICE_MIN_MAX_MTU_EXTENDED)
+	u16 max_mtu;
+#endif
 
 	mlx5e_init_l2_addr(priv);
 
@@ -5589,11 +6758,20 @@ static void mlx5e_nic_enable(struct mlx5
 	if (!netif_running(netdev))
 		mlx5e_modify_admin_state(mdev, MLX5_PORT_DOWN);
 
+#ifdef HAVE_NET_DEVICE_MIN_MAX_MTU
 	mlx5e_set_netdev_mtu_boundaries(priv);
+#elif defined(HAVE_NET_DEVICE_MIN_MAX_MTU_EXTENDED)
+	netdev->extended->min_mtu = ETH_MIN_MTU;
+	mlx5_query_port_max_mtu(priv->mdev, &max_mtu, 1);
+	netdev->extended->max_mtu = MLX5E_HW2SW_MTU(&priv->channels.params, max_mtu);
+#endif
 	mlx5e_set_dev_port_mtu(priv);
 
 	mlx5_lag_add_netdev(mdev, netdev);
 
+	if (!is_valid_ether_addr(netdev->perm_addr))
+		memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
+
 	mlx5e_enable_async_events(priv);
 	mlx5e_enable_blocking_events(priv);
 	if (mlx5e_monitor_counter_supported(priv))
@@ -5609,7 +6787,13 @@ 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_UDP_TUNNEL_RX_INFO) && 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();
 }
@@ -5624,6 +6808,14 @@ 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_UDP_TUNNEL_RX_INFO) && 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();
 
@@ -5641,7 +6833,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);
 }
 
@@ -5664,7 +6858,11 @@ static const struct mlx5e_profile mlx5e_
 	.update_carrier	   = mlx5e_update_carrier,
 	.rx_handlers       = &mlx5e_rx_handlers_nic,
 	.max_tc		   = MLX5E_MAX_NUM_TC,
+#ifdef HAVE_XSK_ZERO_COPY_SUPPORT
 	.rq_groups	   = MLX5E_NUM_RQ_GROUPS(XSK),
+#else
+	.rq_groups         = MLX5E_NUM_RQ_GROUPS(REGULAR),
+#endif
 	.stats_grps	   = mlx5e_nic_stats_grps,
 	.stats_grps_num	   = mlx5e_nic_stats_grps_num,
 	.features          = BIT(MLX5E_PROFILE_FEATURE_PTP_RX) |
@@ -5913,12 +7111,16 @@ int mlx5e_attach_netdev(struct mlx5e_pri
 		/* Reducing the number of channels - RXFH has to be reset, and
 		 * mlx5e_num_channels_changed below will build the RQT.
 		 */
+#ifdef HAVE_NETDEV_IFF_RXFH_CONFIGURED
 		priv->netdev->priv_flags &= ~IFF_RXFH_CONFIGURED;
+#endif
 		priv->channels.params.num_channels = max_nch;
+#ifdef HAVE_TC_MQPRIO_QOPT_OFFLOAD
 		if (priv->channels.params.mqprio.mode == TC_MQPRIO_MODE_CHANNEL) {
 			mlx5_core_warn(priv->mdev, "MLX5E: Disabling MQPRIO channel mode\n");
 			mlx5e_params_mqprio_reset(&priv->channels.params);
 		}
+#endif
 	}
 	if (max_nch != priv->max_nch) {
 		mlx5_core_warn(priv->mdev,
@@ -6151,11 +7353,13 @@ static int mlx5e_probe(struct auxiliary_
 	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) {
@@ -6169,13 +7373,20 @@ static int mlx5e_probe(struct auxiliary_
 		goto err_profile_cleanup;
 	}
 
+	mlx5e_rep_set_sysfs_attr(netdev);
+
+#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)
@@ -6192,8 +7403,10 @@ err_resume:
 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;
 }
@@ -6208,7 +7421,9 @@ static void mlx5e_remove(struct auxiliar
 	unregister_netdev(priv->netdev);
 	mlx5e_suspend(adev, state);
 	priv->profile->cleanup(priv);
+#ifdef HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT
 	mlx5e_devlink_port_unregister(priv);
+#endif
 	mlx5e_destroy_netdev(priv);
 }
 
@@ -6233,7 +7448,9 @@ int mlx5e_init(void)
 	int ret;
 
 	mlx5e_ipsec_build_inverse_table();
+#ifdef __ETHTOOL_DECLARE_LINK_MODE_MASK
 	mlx5e_build_ptys2ethtool_map();
+#endif
 	ret = auxiliary_driver_register(&mlx5e_driver);
 	if (ret)
 		return ret;
