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

Change-Id: I4ed711d9c305db313d75c7a261f4de45bb0e91d7
---
 .../net/ethernet/mellanox/mlx5/core/en_rep.c  | 370 +++++++++++++++++-
 1 file changed, 354 insertions(+), 16 deletions(-)

--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -37,6 +37,9 @@
 #include <net/act_api.h>
 #include <net/devlink.h>
 #include <net/ipv6_stubs.h>
+#if defined(HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON) && defined(HAVE_DEVLINK_HAS_RELOAD_UP_DOWN)
+#include <net/udp_tunnel.h>
+#endif
 
 #include "eswitch.h"
 #include "mlx5_esw_devm.h"
@@ -58,12 +61,15 @@
 #include "lib/vxlan.h"
 #define CREATE_TRACE_POINTS
 #include "diag/en_rep_tracepoint.h"
+#ifdef HAVE_DEVLINK_HEALTH_REPORT_SUPPORT
 #include "diag/reporter_vnic.h"
+#endif
 #include "en_accel/ipsec.h"
 #include "en/tc/int_port.h"
 #include "en/ptp.h"
 #include "en/fs_ethtool.h"
 #include <generated/utsrelease.h>
+#include "compat.h"
 
 #define MLX5E_REP_PARAMS_DEF_NUM_CHANNELS 1
 
@@ -349,20 +355,35 @@ static int mlx5e_rep_get_sset_count(stru
 
 static void
 mlx5e_rep_get_ringparam(struct net_device *dev,
+#ifdef HAVE_GET_RINGPARAM_GET_4_PARAMS
 			struct ethtool_ringparam *param,
+#ifdef HAVE_STRUCT_KERNEL_ETHTOOL_RINGPARAM
 			struct kernel_ethtool_ringparam *kernel_param,
+#else
+			struct ethtool_ringparam *param,
+#endif
 			struct netlink_ext_ack *extack)
+#else
+			struct ethtool_ringparam *param)
+#endif
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
-
+#if defined(HAVE_STRUCT_KERNEL_ETHTOOL_RINGPARAM) && defined(HAVE_GET_RINGPARAM_GET_4_PARAMS)
 	mlx5e_ethtool_get_ringparam(priv, param, kernel_param);
+#else
+	mlx5e_ethtool_get_ringparam(priv, param);
+#endif
 }
 
 static int
 mlx5e_rep_set_ringparam(struct net_device *dev,
+#ifdef HAVE_GET_RINGPARAM_GET_4_PARAMS
 			struct ethtool_ringparam *param,
 			struct kernel_ethtool_ringparam *kernel_param,
 			struct netlink_ext_ack *extack)
+#else
+			struct ethtool_ringparam *param)
+#endif
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 
@@ -386,23 +407,41 @@ static int mlx5e_rep_set_channels(struct
 }
 
 static int mlx5e_rep_get_coalesce(struct net_device *netdev,
+#ifdef HAVE_NDO_GET_COALESCE_GET_4_PARAMS
 				  struct ethtool_coalesce *coal,
 				  struct kernel_ethtool_coalesce *kernel_coal,
 				  struct netlink_ext_ack *extack)
+#else
+			      struct ethtool_coalesce *coal)
+#endif
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 
-	return mlx5e_ethtool_get_coalesce(priv, coal, kernel_coal);
+	return mlx5e_ethtool_get_coalesce(priv,
+#ifdef HAVE_NDO_GET_COALESCE_GET_4_PARAMS
+					  coal, kernel_coal);
+#else
+					  coal);
+#endif
 }
 
 static int mlx5e_rep_set_coalesce(struct net_device *netdev,
+#ifdef HAVE_NDO_GET_COALESCE_GET_4_PARAMS
 				  struct ethtool_coalesce *coal,
 				  struct kernel_ethtool_coalesce *kernel_coal,
 				  struct netlink_ext_ack *extack)
+#else
+			      struct ethtool_coalesce *coal)
+#endif
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 
-	return mlx5e_ethtool_set_coalesce(priv, coal, kernel_coal, extack);
+	return mlx5e_ethtool_set_coalesce(priv,
+#ifdef HAVE_NDO_GET_COALESCE_GET_4_PARAMS
+					  coal, kernel_coal, extack);
+#else
+					  coal);
+#endif
 }
 
 static u32 mlx5e_rep_get_rxfh_key_size(struct net_device *netdev)
@@ -420,9 +459,11 @@ static u32 mlx5e_rep_get_rxfh_indir_size
 }
 
 static const struct ethtool_ops mlx5e_rep_ethtool_ops = {
+#ifdef HAVE_SUPPORTED_COALESCE_PARAM
 	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
 				     ETHTOOL_COALESCE_MAX_FRAMES |
 				     ETHTOOL_COALESCE_USE_ADAPTIVE,
+#endif
 	.get_drvinfo	   = mlx5e_rep_get_drvinfo,
 	.get_link	   = ethtool_op_get_link,
 	.get_strings       = mlx5e_rep_get_strings,
@@ -575,7 +616,9 @@ mlx5e_add_sqs_fwd_rules(struct mlx5e_pri
 {
 	int sqs_per_channel = mlx5e_get_dcb_num_tc(&priv->channels.params);
 	struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
+#ifdef HAVE_XDP_SUPPORT
 	bool is_uplink_rep = mlx5e_is_uplink_rep(priv);
+#endif
 	struct mlx5e_rep_priv *rpriv = priv->ppriv;
 	struct mlx5_eswitch_rep *rep = rpriv->rep;
 	int n, tc, nch, num_sqs = 0;
@@ -590,10 +633,12 @@ mlx5e_add_sqs_fwd_rules(struct mlx5e_pri
 	/* +2 for xdpsqs, they don't exist on the ptp channel but will not be
 	 * counted for by num_sqs.
 	 */
+#ifdef HAVE_XDP_SUPPORT
 	if (is_uplink_rep)
 		sqs_per_channel += 2;
 
-	sqs = kvcalloc(nch * sqs_per_channel, sizeof(*sqs), GFP_KERNEL);
+#endif
+	sqs = kcalloc(nch * sqs_per_channel, sizeof(*sqs), GFP_KERNEL);
 	if (!sqs)
 		goto out;
 
@@ -602,12 +647,14 @@ mlx5e_add_sqs_fwd_rules(struct mlx5e_pri
 		for (tc = 0; tc < c->num_tc; tc++)
 			sqs[num_sqs++] = c->sq[tc].sqn;
 
+#ifdef HAVE_XDP_SUPPORT
 		if (is_uplink_rep) {
 			if (c->xdp)
 				sqs[num_sqs++] = c->rq_xdpsq.sqn;
 
 			sqs[num_sqs++] = c->xdpsq.sqn;
 		}
+#endif
 	}
 	if (ptp_sq) {
 		struct mlx5e_ptp *ptp_ch = priv->channels.ptp;
@@ -718,6 +765,49 @@ static int mlx5e_rep_close(struct net_de
 	return ret;
 }
 
+#ifndef HAVE_DEVLINK_PORT_ATTRS_PCI_PF_SET
+int mlx5e_rep_get_phys_port_name(struct net_device *dev,
+				 char *buf, size_t len)
+{
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	struct mlx5e_rep_priv *rpriv;
+	struct mlx5_eswitch_rep *rep;
+	struct mlx5_eswitch *esw;
+	int ret = -EOPNOTSUPP;
+	unsigned int fn;
+
+	if (!netif_device_present(dev))
+		return -EOPNOTSUPP;
+
+	esw = priv->mdev->priv.eswitch;
+	if (!esw || (!mlx5_sriov_is_enabled(esw->dev) && !is_mdev_switchdev_mode(esw->dev)))
+		return -EOPNOTSUPP;
+
+	fn = mlx5_get_dev_index(priv->mdev);
+	if (fn >= MLX5_MAX_PORTS)
+		return -EOPNOTSUPP;
+
+	rpriv = priv->ppriv;
+	if (!rpriv)
+		return -EOPNOTSUPP;
+	rep = rpriv->rep;
+
+	if (rep->vport == MLX5_VPORT_UPLINK)
+		ret = snprintf(buf, len, "p%d", fn);
+	else if (rep->vport == MLX5_VPORT_PF)
+		ret = snprintf(buf, len, "pf%d", fn);
+	else if (mlx5_eswitch_is_vf_vport(priv->mdev->priv.eswitch, rep->vport))
+		ret = snprintf(buf, len, "pf%dvf%d", fn, rep->vport - 1);
+	else 
+		return -EOPNOTSUPP;
+
+	if (ret >= len)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+#endif
+
 bool mlx5e_is_uplink_rep(const struct mlx5e_priv *priv)
 {
 	struct mlx5e_rep_priv *rpriv = priv->ppriv;
@@ -733,6 +823,80 @@ bool mlx5e_is_uplink_rep(const struct ml
 	return (rep->vport == MLX5_VPORT_UPLINK);
 }
 
+#if defined(HAVE_NDO_GET_PORT_PARENT_ID) || defined(HAVE_SWITCHDEV_OPS)
+#ifdef HAVE_DEVLINK_PORT_ATTRS_PCI_PF_SET
+void
+#else
+int
+#endif
+mlx5e_rep_get_port_parent_id(struct net_device *dev,
+			     struct netdev_phys_item_id *ppid)
+{
+#ifndef HAVE_DEVLINK_PORT_ATTRS_PCI_PF_SET
+	struct mlx5_eswitch *esw;
+#endif
+	struct mlx5e_priv *priv;
+	u64 parent_id;
+
+	priv = netdev_priv(dev);
+#ifndef HAVE_DEVLINK_PORT_ATTRS_PCI_PF_SET
+	esw = priv->mdev->priv.eswitch;
+
+	if (!esw || (!mlx5_sriov_is_enabled(esw->dev) && !is_mdev_switchdev_mode(esw->dev)))
+		return -EOPNOTSUPP;
+#endif
+
+	parent_id = mlx5_query_nic_system_image_guid(priv->mdev);
+	ppid->id_len = sizeof(parent_id);
+	memcpy(ppid->id, &parent_id, sizeof(parent_id));
+#ifndef HAVE_DEVLINK_PORT_ATTRS_PCI_PF_SET
+	return 0;
+#endif
+}
+#endif
+
+#if  !defined(HAVE_DEVLINK_PORT_ATTRS_PCI_SF_SET_GET_4_PARAMS) && \
+     !defined(HAVE_DEVLINK_PORT_ATTRS_PCI_SF_SET_GET_5_PARAMS) && \
+     defined(HAVE_NDO_GET_PORT_PARENT_ID)
+static int mlx5e_rep_sf_port_parent_id(struct net_device *dev,
+				       struct netdev_phys_item_id *ppid)
+{
+	mlx5e_rep_get_port_parent_id(dev, ppid);
+	return 0;
+}
+#endif
+
+#if  !defined(HAVE_DEVLINK_PORT_ATTRS_PCI_SF_SET_GET_4_PARAMS) && \
+     !defined(HAVE_DEVLINK_PORT_ATTRS_PCI_SF_SET_GET_5_PARAMS)
+static int mlx5e_rep_sf_get_phys_port_name(struct net_device *dev,
+					   char *buf, size_t len)
+{
+#ifdef CONFIG_MLXDEVM
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	struct mlx5e_rep_priv *rpriv = priv->ppriv;
+	struct mlx5_eswitch_rep *rep = rpriv->rep;
+	struct mlx5_eswitch *esw;
+	unsigned int fn;
+	u32 controller;
+	int ret;
+
+	fn = mlx5_get_dev_index(priv->mdev);
+	esw = priv->mdev->priv.eswitch;
+
+	controller = mlx5_devm_sf_vport_to_controller(priv->mdev, rep->vport);
+	if (controller)
+		ret = snprintf(buf, len, "c%dpf%dsf%d",
+			       controller, fn,
+			       mlx5_devm_sf_vport_to_sfnum(priv->mdev, rep->vport));
+	else
+		ret = snprintf(buf, len, "pf%dsf%d", fn,
+			       mlx5_devm_sf_vport_to_sfnum(priv->mdev, rep->vport));
+	if (ret >= len)
+		return -EOPNOTSUPP;
+#endif
+	return 0;
+}
+#endif
 bool mlx5e_rep_has_offload_stats(const struct net_device *dev, int attr_id)
 {
 	switch (attr_id) {
@@ -764,8 +928,8 @@ int mlx5e_rep_get_offload_stats(int attr
 	return -EINVAL;
 }
 
-static void
-mlx5e_rep_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
+static
+void mlx5e_rep_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 
@@ -779,6 +943,17 @@ static int mlx5e_rep_change_mtu(struct n
 	return mlx5e_change_mtu(netdev, new_mtu, NULL);
 }
 
+#ifdef HAVE_NDO_GET_DEVLINK_PORT
+static struct devlink_port *mlx5e_rep_get_devlink_port(struct net_device *netdev)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5e_rep_priv *rpriv = priv->ppriv;
+	struct mlx5_core_dev *dev = priv->mdev;
+
+	return mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
+}
+#endif
+
 static int mlx5e_rep_change_carrier(struct net_device *dev, bool new_carrier)
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
@@ -806,11 +981,25 @@ static const struct net_device_ops mlx5e
 	.ndo_open                = mlx5e_rep_open,
 	.ndo_stop                = mlx5e_rep_close,
 	.ndo_start_xmit          = mlx5e_xmit,
-	.ndo_setup_tc            = mlx5e_rep_setup_tc,
+#ifdef CONFIG_MLX5_CLS_ACT
+#if defined(HAVE_TC_FLOWER_OFFLOAD) || defined(HAVE_FLOW_CLS_OFFLOAD)
+        .ndo_setup_tc            = mlx5e_rep_setup_tc,
+#endif
+#endif	/* CONFIG_MLX5_CLS_ACT */
+#ifndef HAVE_NET_DEVICE_HAS_DEVLINK_PORT
+#ifdef HAVE_NDO_GET_DEVLINK_PORT
+	.ndo_get_devlink_port    = mlx5e_rep_get_devlink_port,
+#else
+        .ndo_get_phys_port_name  = mlx5e_rep_get_phys_port_name,
+#ifdef HAVE_NDO_GET_PORT_PARENT_ID
+	.ndo_get_port_parent_id  = mlx5e_rep_get_port_parent_id,
+#endif
+#endif
+#endif /* HAVE_NET_DEVICE_HAS_DEVLINK_PORT */
 	.ndo_get_stats64         = mlx5e_rep_get_stats,
 	.ndo_has_offload_stats	 = mlx5e_rep_has_offload_stats,
 	.ndo_get_offload_stats	 = mlx5e_rep_get_offload_stats,
-	.ndo_change_mtu          = mlx5e_rep_change_mtu,
+        .ndo_change_mtu          = mlx5e_rep_change_mtu,
 	.ndo_change_carrier      = mlx5e_rep_change_carrier,
 };
 
@@ -818,10 +1007,26 @@ static const struct net_device_ops mlx5e
 	.ndo_open                = mlx5e_rep_open,
 	.ndo_stop                = mlx5e_rep_close,
 	.ndo_start_xmit          = mlx5e_xmit,
+#ifdef CONFIG_MLX5_CLS_ACT
+#if defined(HAVE_TC_FLOWER_OFFLOAD) || defined(HAVE_FLOW_CLS_OFFLOAD)
 	.ndo_setup_tc            = mlx5e_rep_setup_tc,
+#endif
+#endif
+#ifdef HAVE_NDO_GET_DEVLINK_PORT
+	.ndo_get_devlink_port    = mlx5e_rep_get_devlink_port,
+#endif
+#if  !defined(HAVE_DEVLINK_PORT_ATTRS_PCI_SF_SET_GET_4_PARAMS) && \
+     !defined(HAVE_DEVLINK_PORT_ATTRS_PCI_SF_SET_GET_5_PARAMS)
+	.ndo_get_phys_port_name  = mlx5e_rep_sf_get_phys_port_name,
+#endif /* !defined(HAVE_DEVLINK_PORT_ATTRS_PCI_SF_SET_GET_4_PARAMS) && !defined(HAVE_DEVLINK_PORT_ATTRS_PCI_SF_SET_GET_5_PARAMS) */
+#if  !defined(HAVE_DEVLINK_PORT_ATTRS_PCI_SF_SET_GET_4_PARAMS) && \
+     !defined(HAVE_DEVLINK_PORT_ATTRS_PCI_SF_SET_GET_5_PARAMS) && \
+     defined(HAVE_NDO_GET_PORT_PARENT_ID)
+	.ndo_get_port_parent_id  = mlx5e_rep_sf_port_parent_id,
+#endif
 	.ndo_get_stats64         = mlx5e_rep_get_stats,
-	.ndo_has_offload_stats	 = mlx5e_rep_has_offload_stats,
-	.ndo_get_offload_stats	 = mlx5e_rep_get_offload_stats,
+	.ndo_has_offload_stats   = mlx5e_rep_has_offload_stats,
+	.ndo_get_offload_stats   = mlx5e_rep_get_offload_stats,
 	.ndo_change_mtu          = mlx5e_rep_change_mtu,
 };
 
@@ -851,7 +1056,9 @@ static int mlx5e_rep_max_nch_limit(struc
 
 static void mlx5e_build_rep_params(struct net_device *netdev)
 {
+#ifdef HAVE_XDP_SET_FEATURES_FLAG
 	const bool take_rtnl = netdev->reg_state == NETREG_REGISTERED;
+#endif
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 	struct mlx5e_rep_priv *rpriv = priv->ppriv;
 	struct mlx5_eswitch_rep *rep = rpriv->rep;
@@ -877,12 +1084,14 @@ static void mlx5e_build_rep_params(struc
 	/* If netdev is already registered (e.g. move from nic profile to uplink,
 	 * RTNL lock must be held before triggering netdev notifiers.
 	 */
+#ifdef HAVE_XDP_SET_FEATURES_FLAG
 	if (take_rtnl)
 		rtnl_lock();
 	/* update XDP supported features */
 	mlx5e_set_xdp_feature(netdev);
 	if (take_rtnl)
 		rtnl_unlock();
+#endif
 
 	/* CQ moderation params */
 	params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
@@ -897,6 +1106,12 @@ static void mlx5e_build_rep_params(struc
 	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_PER_CH_STATS, true);
 }
 
+#ifdef HAVE_SWITCHDEV_OPS
+static const struct switchdev_ops mlx5e_rep_switchdev_ops = {
+	.switchdev_port_attr_get    = mlx5e_attr_get,
+};
+#endif
+
 static void mlx5e_build_rep_netdev(struct net_device *netdev,
 				   struct mlx5_core_dev *mdev,
 				   struct mlx5_eswitch_rep *rep)
@@ -911,6 +1126,10 @@ static void mlx5e_build_rep_netdev(struc
 	eth_hw_addr_random(netdev);
 	netdev->ethtool_ops = &mlx5e_rep_ethtool_ops;
 
+#ifdef HAVE_SWITCHDEV_OPS
+	netdev->switchdev_ops = &mlx5e_rep_switchdev_ops;
+#endif
+
 	netdev->watchdog_timeo    = 15 * HZ;
 
 #if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
@@ -925,7 +1144,11 @@ static void mlx5e_build_rep_netdev(struc
 	netdev->hw_features    |= NETIF_F_RXCSUM;
 
 	netdev->features |= netdev->hw_features;
+#ifdef HAVE_NETDEV_NETNS_LOCAL
+	netdev->netns_local = true;
+#else
 	netdev->features |= NETIF_F_NETNS_LOCAL;
+#endif
 }
 
 static int mlx5e_init_rep(struct mlx5_core_dev *mdev,
@@ -965,7 +1188,9 @@ static int mlx5e_init_ul_rep(struct mlx5
 		return -ENOMEM;
 	}
 
+#if defined(HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON) && defined(HAVE_UDP_TUNNEL_NIC_INFO_FULL)
 	mlx5e_vxlan_set_netdev_info(priv);
+#endif
 	mlx5e_build_rep_params(netdev);
 	mlx5e_timestamp_init(priv);
 	return 0;
@@ -1312,6 +1537,7 @@ static int mlx5e_init_uplink_rep_tx(stru
 	mlx5_init_port_tun_entropy(&uplink_priv->tun_entropy, priv->mdev);
 
 	mlx5e_rep_bond_init(rpriv);
+#if defined( HAVE_TC_BLOCK_OFFLOAD) || defined(HAVE_FLOW_BLOCK_OFFLOAD)
 	err = mlx5e_rep_tc_netdevice_event_register(rpriv);
 	if (err) {
 		mlx5_core_err(priv->mdev, "Failed to register netdev notifier, err: %d\n",
@@ -1324,12 +1550,20 @@ static int mlx5e_init_uplink_rep_tx(stru
 err_event_reg:
 	mlx5e_rep_bond_cleanup(rpriv);
 	mlx5e_rep_tc_cleanup(rpriv);
+#endif
 	return err;
 }
 
 static void mlx5e_cleanup_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
 {
+#if defined( HAVE_TC_BLOCK_OFFLOAD) || defined(HAVE_FLOW_BLOCK_OFFLOAD)
 	mlx5e_rep_tc_netdevice_event_unregister(rpriv);
+#ifndef HAVE_FLOW_INDR_DEV_REGISTER
+#if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
+	mlx5e_rep_indr_clean_block_privs(rpriv);
+#endif
+#endif /* HAVE_FLOW_INDR_DEV_REGISTER */
+#endif
 	mlx5e_rep_bond_cleanup(rpriv);
 	mlx5e_rep_tc_cleanup(rpriv);
 }
@@ -1465,7 +1699,12 @@ static void mlx5e_uplink_rep_enable(stru
 	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();
 
@@ -1479,6 +1718,12 @@ static void mlx5e_uplink_rep_disable(str
 	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();
 
@@ -1487,7 +1732,9 @@ static void mlx5e_uplink_rep_disable(str
 	mlx5_notifier_unregister(mdev, &priv->events_nb);
 	mlx5e_rep_tc_disable(priv);
 	mlx5_lag_remove_netdev(mdev, priv->netdev);
+#if defined(HAVE_UDP_TUNNEL_NIC_INFO) && defined(HAVE_KERNEL_WITH_VXLAN_SUPPORT_ON) && defined(HAVE_DEVLINK_HAS_RELOAD_UP_DOWN)
 	mlx5_vxlan_reset_to_default(mdev->vxlan);
+#endif
 
 	mlx5e_ipsec_cleanup(priv);
 }
@@ -1534,17 +1781,26 @@ static unsigned int mlx5e_ul_rep_stats_g
 	return ARRAY_SIZE(mlx5e_ul_rep_stats_grps);
 }
 
+#ifdef HAVE_NETDEV_DEVLINK_PORT
 static int
 mlx5e_rep_vnic_reporter_diagnose(struct devlink_health_reporter *reporter,
-				 struct devlink_fmsg *fmsg,
-				 struct netlink_ext_ack *extack)
+				 struct devlink_fmsg *fmsg
+#ifdef HAVE_HEALTH_REPORTER_RECOVER_HAS_EXTACK
+				 , struct netlink_ext_ack *extack
+#endif
+				)
 {
 	struct mlx5e_rep_priv *rpriv = devlink_health_reporter_priv(reporter);
 	struct mlx5_eswitch_rep *rep = rpriv->rep;
 
+#ifndef HAVE_INT_DEVLINK_FMSG_U8_PAIR
 	mlx5_reporter_vnic_diagnose_counters(rep->esw->dev, fmsg, rep->vport,
-					     true);
+		   			     true);
 	return 0;
+#else
+	return mlx5_reporter_vnic_diagnose_counters(rep->esw->dev, fmsg,
+					 	    rep->vport, true);
+#endif
 }
 
 static const struct devlink_health_reporter_ops mlx5_rep_vnic_reporter_ops = {
@@ -1558,9 +1814,14 @@ static void mlx5e_rep_vnic_reporter_crea
 	struct mlx5e_rep_priv *rpriv = priv->ppriv;
 	struct devlink_health_reporter *reporter;
 
-	reporter = devl_port_health_reporter_create(dl_port,
+	reporter =
+#ifdef HAVE_DEVL_PORT_HEALTH_REPORTER_CREATE
+		devl_port_health_reporter_create(dl_port,
+#else
+		devlink_port_health_reporter_create(dl_port,
+#endif
 						    &mlx5_rep_vnic_reporter_ops,
-						    0, rpriv);
+						    0,rpriv);
 	if (IS_ERR(reporter)) {
 		mlx5_core_err(priv->mdev,
 			      "Failed to create representor vnic reporter, err = %ld\n",
@@ -1570,14 +1831,18 @@ static void mlx5e_rep_vnic_reporter_crea
 
 	rpriv->rep_vnic_reporter = reporter;
 }
-
 static void mlx5e_rep_vnic_reporter_destroy(struct mlx5e_priv *priv)
 {
 	struct mlx5e_rep_priv *rpriv = priv->ppriv;
 
 	if (!IS_ERR_OR_NULL(rpriv->rep_vnic_reporter))
+#ifdef HAVE_DEVL_PORT_HEALTH_REPORTER_CREATE
 		devl_health_reporter_destroy(rpriv->rep_vnic_reporter);
+#else
+		devlink_health_reporter_destroy(rpriv->rep_vnic_reporter);
+#endif
 }
+#endif /* HAVE_NETDEV_DEVLINK_PORT */
 
 static const struct mlx5e_profile mlx5e_rep_profile = {
 	.init			= mlx5e_init_rep,
@@ -1621,6 +1886,9 @@ mlx5e_vport_uplink_rep_load(struct mlx5_
 {
 	struct mlx5e_priv *priv = netdev_priv(mlx5_uplink_netdev_get(dev));
 	struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
+#if defined(HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT) && !defined(HAVE_NETDEV_DEVLINK_PORT)
+	struct devlink_port *dl_port;
+#endif
 	int err;
 
 	rpriv->netdev = priv->netdev;
@@ -1634,6 +1902,19 @@ mlx5e_vport_uplink_rep_load(struct mlx5_
  	if (err)
 		goto err_metadata_insert;
 
+#ifndef HAVE_NETDEV_DEVLINK_PORT
+#ifdef HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT
+	dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
+	if (dl_port)
+#ifdef HAVE_DEVLINK_PORT_TYPE_ETH_SET_GET_1_PARAM
+		devlink_port_type_eth_set(dl_port);
+#else
+		devlink_port_type_eth_set(dl_port, rpriv->netdev);
+
+#endif
+#endif /* HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT */
+#endif /* HAVE_NETDEV_DEVLINK_PORT */
+
 	mlx5_smartnic_sysfs_init(rpriv->netdev);
 	mlx5_rep_sysfs_init(rpriv);
 	mlx5e_ipsec_build_netdev(priv);
@@ -1650,6 +1931,9 @@ static void
 mlx5e_vport_uplink_rep_unload(struct mlx5e_rep_priv *rpriv)
 {
 	struct net_device *netdev = rpriv->netdev;
+#if defined(HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT) && !defined(HAVE_NETDEV_DEVLINK_PORT)
+	struct devlink_port *dl_port;
+#endif
 	struct mlx5_core_dev *dev;
 	struct mlx5e_priv *priv;
 
@@ -1659,11 +1943,22 @@ mlx5e_vport_uplink_rep_unload(struct mlx
 	mlx5e_rep_metadata_remove(priv, rpriv->rep, false);
 	xa_destroy(&rpriv->vport_rep_map);
 
+#if defined(HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT) && !defined(HAVE_NETDEV_DEVLINK_PORT)
+	dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
+	if (dl_port)
+		devlink_port_type_clear(dl_port);
+#endif
+
 	mlx5_smartnic_sysfs_cleanup(netdev);
 	if (test_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state)) {
 		mlx5e_detach_netdev(priv);
 		priv->profile->cleanup(priv);
 		mlx5e_destroy_mdev_resources(priv->mdev);
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+		rtnl_lock();
+		udp_tunnel_nic_reset_ntf(priv->netdev);
+		rtnl_unlock();
+#endif
 	} else {
 		mlx5e_netdev_attach_nic_profile(priv);
 	}
@@ -1674,7 +1969,9 @@ mlx5e_vport_vf_rep_load(struct mlx5_core
 {
 	struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
 	const struct mlx5e_profile *profile;
+#if defined(HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT) || defined(HAVE_NETDEV_DEVLINK_PORT)
 	struct devlink_port *dl_port;
+#endif
 	struct net_device *netdev;
 	struct mlx5e_priv *priv;
 	int err;
@@ -1713,12 +2010,18 @@ mlx5e_vport_vf_rep_load(struct mlx5_core
 		goto err_cleanup_profile;
 	}
 
+	err = mlx5e_vport_rep_load_compat(priv);
+	if (err)
+		goto err_compat_cleanup;
+
+#ifdef HAVE_NETDEV_DEVLINK_PORT
 	dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch,
 						 rpriv->rep->vport);
 	if (!IS_ERR(dl_port)) {
 		SET_NETDEV_DEVLINK_PORT(netdev, dl_port);
 		mlx5e_rep_vnic_reporter_create(priv, dl_port);
 	}
+#endif
 
 	err = register_netdev(netdev);
 	if (err) {
@@ -1730,11 +2033,30 @@ mlx5e_vport_vf_rep_load(struct mlx5_core
 
 	mlx5_rep_sysfs_init(rpriv);
 
+#if defined(HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT) && !defined(HAVE_NETDEV_DEVLINK_PORT)
+	dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
+#if  !defined(HAVE_DEVLINK_PORT_ATTRS_PCI_SF_SET_GET_4_PARAMS) && \
+     !defined(HAVE_DEVLINK_PORT_ATTRS_PCI_SF_SET_GET_5_PARAMS)
+	if ((dl_port) && !mlx5_esw_is_sf_vport(dev->priv.eswitch, rpriv->rep->vport))
+#else
+	if (dl_port)
+#endif
+#ifdef HAVE_DEVLINK_PORT_TYPE_ETH_SET_GET_1_PARAM
+		devlink_port_type_eth_set(dl_port);
+#else
+		devlink_port_type_eth_set(dl_port, netdev);
+#endif
+#endif /* HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT */
 	mlx5_devm_sf_port_type_eth_set(dev, rpriv->rep->vport, netdev);
 	return 0;
 
+err_compat_cleanup:
+	mlx5e_vport_rep_unload_compat(priv);
+
 err_detach_netdev:
+#ifdef HAVE_NETDEV_DEVLINK_PORT
 	mlx5e_rep_vnic_reporter_destroy(priv);
+#endif
 	mlx5e_detach_netdev(netdev_priv(netdev));
 err_cleanup_profile:
 	priv->profile->cleanup(priv);
@@ -1777,6 +2099,9 @@ mlx5e_vport_rep_unload(struct mlx5_eswit
 	struct net_device *netdev = rpriv->netdev;
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 	struct mlx5_core_dev *dev = priv->mdev;
+#if defined(HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT) && !defined(HAVE_NETDEV_DEVLINK_PORT)
+	struct devlink_port *dl_port;
+#endif
 	void *ppriv = priv->ppriv;
 
 	mlx5_rep_destroy_miss_meter(dev, rpriv);
@@ -1794,8 +2119,21 @@ mlx5e_vport_rep_unload(struct mlx5_eswit
 	}
 
 	mlx5e_rep_metadata_remove(priv, rep, false);
+#if defined(HAVE_DEVLINK_PORT_ATRRS_SET_GET_SUPPORT) && !defined(HAVE_NETDEV_DEVLINK_PORT)
+	dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
+#if  !defined(HAVE_DEVLINK_PORT_ATTRS_PCI_SF_SET_GET_4_PARAMS) && \
+     !defined(HAVE_DEVLINK_PORT_ATTRS_PCI_SF_SET_GET_5_PARAMS)
+	if ((dl_port) && !mlx5_esw_is_sf_vport(dev->priv.eswitch, rpriv->rep->vport))
+#else
+	if (dl_port)
+#endif
+		devlink_port_type_clear(dl_port);
+#endif
 	unregister_netdev(netdev);
+#ifdef HAVE_NETDEV_DEVLINK_PORT
 	mlx5e_rep_vnic_reporter_destroy(priv);
+#endif
+	mlx5e_vport_rep_unload_compat(priv);
 	mlx5e_detach_netdev(priv);
 	priv->profile->cleanup(priv);
 	mlx5e_destroy_netdev(priv);
