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

Change-Id: Ib1240333bb19366ee14d4baf9ff6fa62e2fa8239
---
 .../ethernet/mellanox/mlx5/core/en_ethtool.c  | 776 +++++++++++++++++-
 1 file changed, 747 insertions(+), 29 deletions(-)

--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -30,7 +30,9 @@
  * SOFTWARE.
  */
 
+#ifdef HAVE_ETHTOOL_NETLINK_H
 #include <linux/ethtool_netlink.h>
+#endif
 
 #include "en.h"
 #include "en/port.h"
@@ -38,6 +40,9 @@
 #include "en/ptp.h"
 #include "lib/clock.h"
 #include "en/fs_ethtool.h"
+#ifdef HAVE_BASECODE_EXTRAS
+#include "en/rx_res.h"
+#endif
 
 void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv,
 			       struct ethtool_drvinfo *drvinfo)
@@ -67,6 +72,7 @@ static void mlx5e_get_drvinfo(struct net
 	mlx5e_ethtool_get_drvinfo(priv, drvinfo);
 }
 
+#ifdef __ETHTOOL_DECLARE_LINK_MODE_MASK
 struct ptys2ethtool_config {
 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
 	__ETHTOOL_DECLARE_LINK_MODE_MASK(advertised);
@@ -222,6 +228,7 @@ void mlx5e_build_ptys2ethtool_map(void)
 				       ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT);
 }
 
+#endif
 static void mlx5e_ethtool_get_speed_arr(struct mlx5_core_dev *mdev,
 					struct ptys2ethtool_config **arr,
 					u32 *size)
@@ -233,6 +240,448 @@ static void mlx5e_ethtool_get_speed_arr(
 		      ARRAY_SIZE(ptys2legacy_ethtool_table);
 }
 
+#ifdef HAVE_ETHTOOL_GET_SET_SETTINGS
+struct deprecated_ptys2ethtool_config {
+	u32 supported;
+	u32 advertised;
+	u32 speed;
+};
+
+static struct deprecated_ptys2ethtool_config
+deprecated_ptys2legacy_ethtool_table[MLX5E_LINK_MODES_NUMBER] = {
+	[MLX5E_1000BASE_CX_SGMII] = {
+		.supported  = SUPPORTED_1000baseKX_Full,
+		.advertised = ADVERTISED_1000baseKX_Full,
+		.speed      = SPEED_1000,
+	},
+	[MLX5E_1000BASE_KX] = {
+		.supported  = SUPPORTED_1000baseKX_Full,
+		.advertised = ADVERTISED_1000baseKX_Full,
+		.speed      = SPEED_1000,
+	},
+	[MLX5E_10GBASE_CX4] = {
+		.supported  = SUPPORTED_10000baseKX4_Full,
+		.advertised = ADVERTISED_10000baseKX4_Full,
+		.speed      = SPEED_10000,
+	},
+	[MLX5E_10GBASE_KX4] = {
+		.supported  = SUPPORTED_10000baseKX4_Full,
+		.advertised = ADVERTISED_10000baseKX4_Full,
+		.speed      = SPEED_10000,
+	},
+	[MLX5E_10GBASE_KR] = {
+		.supported  = SUPPORTED_10000baseKR_Full,
+		.advertised = ADVERTISED_10000baseKR_Full,
+		.speed      = SPEED_10000,
+	},
+	[MLX5E_20GBASE_KR2] = {
+		.supported  = SUPPORTED_20000baseKR2_Full,
+		.advertised = ADVERTISED_20000baseKR2_Full,
+		.speed      = SPEED_20000,
+	},
+	[MLX5E_40GBASE_CR4] = {
+		.supported  = SUPPORTED_40000baseCR4_Full,
+		.advertised = ADVERTISED_40000baseCR4_Full,
+		.speed      = SPEED_40000,
+	},
+	[MLX5E_40GBASE_KR4] = {
+		.supported  = SUPPORTED_40000baseKR4_Full,
+		.advertised = ADVERTISED_40000baseKR4_Full,
+		.speed      = SPEED_40000,
+	},
+	[MLX5E_56GBASE_R4] = {
+		.supported  = SUPPORTED_56000baseKR4_Full,
+		.advertised = ADVERTISED_56000baseKR4_Full,
+		.speed      = SPEED_56000,
+	},
+	[MLX5E_10GBASE_CR] = {
+		.supported  = SUPPORTED_10000baseKR_Full,
+		.advertised = ADVERTISED_10000baseKR_Full,
+		.speed      = SPEED_10000,
+	},
+	[MLX5E_10GBASE_SR] = {
+		.supported  = SUPPORTED_10000baseKR_Full,
+		.advertised = ADVERTISED_10000baseKR_Full,
+		.speed      = SPEED_10000,
+	},
+	[MLX5E_10GBASE_ER] = {
+		.supported  = SUPPORTED_10000baseKR_Full,/* TODO: verify */
+		.advertised = ADVERTISED_10000baseKR_Full,
+		.speed      = SPEED_10000,
+	},
+	[MLX5E_40GBASE_SR4] = {
+		.supported  = SUPPORTED_40000baseSR4_Full,
+		.advertised = ADVERTISED_40000baseSR4_Full,
+		.speed      = SPEED_40000,
+	},
+	[MLX5E_40GBASE_LR4] = {
+		.supported  = SUPPORTED_40000baseLR4_Full,
+		.advertised = ADVERTISED_40000baseLR4_Full,
+		.speed      = SPEED_40000,
+	},
+	[MLX5E_100GBASE_CR4] = {
+		.supported  = /*SUPPORTED_100000baseCR4_Full*/ 0,
+		.advertised = /*ADVERTISED_100000baseCR4_Full*/ 0,
+		.speed      = SPEED_100000,
+	},
+	[MLX5E_100GBASE_SR4] = {
+		.supported  = /*SUPPORTED_100000baseSR4_Full*/ 0,
+		.advertised = /*ADVERTISED_100000baseSR4_Full*/ 0,
+		.speed      = SPEED_100000,
+	},
+	[MLX5E_100GBASE_KR4] = {
+		.supported  = /*SUPPORTED_100000baseKR4_Full*/ 0,
+		.advertised = /*ADVERTISED_100000baseKR4_Full*/ 0,
+		.speed      = SPEED_100000,
+	},
+	[MLX5E_100GBASE_LR4] = {
+		.supported  = /*SUPPORTED_1000000baseLR4_Full*/ 0,
+		.advertised = /*ADVERTISED_1000000baseLR4_Full*/ 0,
+		.speed      = SPEED_100000,
+	},
+	[MLX5E_100BASE_TX]   = {
+		.supported  = SUPPORTED_100baseT_Full,
+		.advertised = ADVERTISED_100baseT_Full,
+		.speed      = SPEED_100,
+	},
+	[MLX5E_1000BASE_T]    = {
+		.supported  = SUPPORTED_1000baseT_Full,
+		.advertised = ADVERTISED_1000baseT_Full,
+		.speed      = SPEED_1000,
+	},
+	[MLX5E_10GBASE_T]    = {
+		.supported  = SUPPORTED_10000baseT_Full,
+		.advertised = ADVERTISED_10000baseT_Full,
+		.speed      = SPEED_10000,
+	},
+	[MLX5E_25GBASE_CR]   = {
+		.supported  = /*SUPPORTED_25000baseCR_Full*/ 0,
+		.advertised = /*ADVERTISED_25000baseCR_Full*/ 0,
+		.speed      = SPEED_25000,
+	},
+	[MLX5E_25GBASE_KR]   = {
+		.supported  = /*SUPPORTED_25000baseKR_Full*/ 0,
+		.advertised = /*ADVERTISED_25000baseKR_Full*/ 0,
+		.speed      = SPEED_25000,
+	},
+	[MLX5E_25GBASE_SR]   = {
+		.supported  = /*SUPPORTED_25000baseSR_Full*/ 0,
+		.advertised = /*ADVERTISED_25000baseSR_Full*/ 0,
+		.speed      = SPEED_25000,
+	},
+	[MLX5E_50GBASE_CR2]  = {
+		.supported  = /*SUPPORTED_50000baseCR2_Full*/ 0,
+		.advertised = /*ADVERTISED_50000baseCR2_Full*/ 0,
+		.speed      = SPEED_50000,
+	},
+	[MLX5E_50GBASE_KR2]  = {
+		.supported  = /*SUPPORTED_50000baseKR2_Full*/ 0,
+		.advertised = /*ADVERTISED_50000baseKR2_Full*/ 0,
+		.speed      = SPEED_50000,
+	},
+};
+
+static struct deprecated_ptys2ethtool_config
+deprecated_ptys2ext_ethtool_table[MLX5E_EXT_LINK_MODES_NUMBER] = {
+	[MLX5E_SGMII_100M] = {
+		.speed      = SPEED_100,
+	},
+	[MLX5E_1000BASE_X_SGMII] = {
+		.speed      = SPEED_1000,
+	},
+	[MLX5E_5GBASE_R] = {
+		.speed      = SPEED_5000,
+	},
+	[MLX5E_10GBASE_XFI_XAUI_1] = {
+		.speed      = SPEED_10000,
+	},
+	[MLX5E_40GBASE_XLAUI_4_XLPPI_4] = {
+		.speed      = SPEED_40000,
+	},
+	[MLX5E_25GAUI_1_25GBASE_CR_KR] = {
+		.speed      = SPEED_25000,
+	},
+	[MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2] = {
+		.speed      = SPEED_50000,
+	},
+	[MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR] = {
+		.speed      = SPEED_50000,
+	},
+	[MLX5E_CAUI_4_100GBASE_CR4_KR4] = {
+		.speed      = SPEED_100000,
+	},
+	[MLX5E_100GAUI_2_100GBASE_CR2_KR2] = {
+		.speed      = SPEED_100000,
+	},
+	[MLX5E_200GAUI_4_200GBASE_CR4_KR4] = {
+		.speed      = SPEED_200000,
+	},
+};
+
+static void
+deprecated_ethtool_get_speed_arr(bool ext, u32 *size,
+				 struct deprecated_ptys2ethtool_config **arr)
+{
+	*arr = ext ? deprecated_ptys2ext_ethtool_table :
+		     deprecated_ptys2legacy_ethtool_table;
+	*size = ext ? ARRAY_SIZE(deprecated_ptys2ext_ethtool_table) :
+		      ARRAY_SIZE(deprecated_ptys2legacy_ethtool_table);
+}
+
+static u32 deprecated_ptys2ethtool_supported_link(u32 eth_proto_cap)
+{
+	int i;
+	u32 supoprted_modes = 0;
+
+	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
+		if (eth_proto_cap & MLX5E_PROT_MASK(i))
+			supoprted_modes |= deprecated_ptys2legacy_ethtool_table[i].supported;
+	}
+	return supoprted_modes;
+}
+
+static u32 deprecated_ptys2ethtool_adver_link(u32 eth_proto_cap)
+{
+	int i;
+	u32 advertising_modes = 0;
+
+	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
+		if (eth_proto_cap & MLX5E_PROT_MASK(i))
+			advertising_modes |= deprecated_ptys2legacy_ethtool_table[i].advertised;
+	}
+	return advertising_modes;
+}
+
+static u32 deprecated_ptys2ethtool_supported_port(u32 eth_proto_cap)
+{
+	/*
+	TODO:
+	MLX5E_40GBASE_LR4	 = 16,
+	MLX5E_10GBASE_ER	 = 14,
+	MLX5E_10GBASE_CX4	 = 2,
+	*/
+
+	if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_10GBASE_CR)
+			   | MLX5E_PROT_MASK(MLX5E_10GBASE_SR)
+			   | MLX5E_PROT_MASK(MLX5E_40GBASE_CR4)
+			   | MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)
+			   | MLX5E_PROT_MASK(MLX5E_100GBASE_SR4)
+			   | MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
+		return SUPPORTED_FIBRE;
+	}
+
+	if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_100GBASE_KR4)
+			   | MLX5E_PROT_MASK(MLX5E_40GBASE_KR4)
+			   | MLX5E_PROT_MASK(MLX5E_10GBASE_KR)
+			   | MLX5E_PROT_MASK(MLX5E_10GBASE_KX4)
+			   | MLX5E_PROT_MASK(MLX5E_1000BASE_KX))) {
+		return SUPPORTED_Backplane;
+	}
+	return 0;
+}
+
+static void deprecated_get_speed_duplex(struct net_device *netdev,
+					struct mlx5_core_dev *mdev,
+					u32 eth_proto_oper,
+					struct ethtool_cmd *cmd)
+{
+	struct deprecated_ptys2ethtool_config *table;
+	u32 max_size;
+	bool ext;
+	int i;
+	u32 speed = SPEED_UNKNOWN;
+	u8 duplex = DUPLEX_UNKNOWN;
+
+	if (!netif_carrier_ok(netdev))
+		goto out;
+
+	ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
+	deprecated_ethtool_get_speed_arr(ext, &max_size, &table);
+	for (i = 0; i < max_size; ++i) {
+		if (eth_proto_oper & MLX5E_PROT_MASK(i)) {
+			speed = table[i].speed;
+			duplex = DUPLEX_FULL;
+			break;
+		}
+	}
+out:
+	ethtool_cmd_speed_set(cmd, speed);
+	cmd->duplex = duplex;
+}
+
+static void deprecated_get_supported(u32 eth_proto_cap, u32 *supported)
+{
+	*supported |= deprecated_ptys2ethtool_supported_port(eth_proto_cap);
+	*supported |= deprecated_ptys2ethtool_supported_link(eth_proto_cap);
+	*supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+}
+
+static void deprecated_get_advertising(u32 eth_proto_cap, u8 tx_pause,
+				       u8 rx_pause, u32 *advertising)
+{
+	*advertising |= deprecated_ptys2ethtool_adver_link(eth_proto_cap);
+	*advertising |= tx_pause ? ADVERTISED_Pause : 0;
+	*advertising |= (tx_pause ^ rx_pause) ? ADVERTISED_Asym_Pause : 0;
+}
+
+static void deprecated_get_lp_advertising(u32 eth_proto_lp, u32 *lp_advertising)
+{
+
+	*lp_advertising = deprecated_ptys2ethtool_adver_link(eth_proto_lp);
+}
+
+static u32 deprecated_mlx5e_ethtool2ptys_speed_link(bool ext, u32 speed)
+
+{
+	struct deprecated_ptys2ethtool_config *table;
+	u32 i, speed_links = 0;
+	u32 max_size;
+
+	deprecated_ethtool_get_speed_arr(ext, &max_size, &table);
+	for (i = 0; i < max_size; ++i) {
+		if (table[i].speed == speed)
+			speed_links |= MLX5E_PROT_MASK(i);
+	}
+
+	return speed_links;
+}
+
+static u8 get_connector_port(struct mlx5_core_dev *mdev, u32 eth_proto, u8 connector_type);
+
+int mlx5e_get_settings(struct net_device *netdev,
+		       struct ethtool_cmd *cmd)
+{
+	struct mlx5e_priv *priv    = netdev_priv(netdev);
+	struct mlx5_core_dev *mdev = priv->mdev;
+	u32 out[MLX5_ST_SZ_DW(ptys_reg)] = {0};
+	u32 eth_proto_cap;
+	u32 eth_proto_admin;
+	u32 eth_proto_lp;
+	u32 eth_proto_oper;
+	u8 an_disable_admin;
+	u8 connector_type;
+	u8 an_status;
+	bool ext;
+	int err;
+
+	err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1);
+	if (err) {
+		netdev_err(netdev, "%s: query port ptys failed: %d\n",
+			   __func__, err);
+		goto err_query_ptys;
+	}
+	ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
+	eth_proto_oper   = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
+					      eth_proto_oper);
+	eth_proto_cap    = MLX5_GET(ptys_reg, out, eth_proto_capability);
+	eth_proto_admin  = MLX5_GET(ptys_reg, out, eth_proto_admin);
+	eth_proto_lp     = MLX5_GET(ptys_reg, out, eth_proto_lp_advertise);
+	an_disable_admin = MLX5_GET(ptys_reg, out, an_disable_admin);
+	an_status        = MLX5_GET(ptys_reg, out, an_status);
+	connector_type   = MLX5_GET(ptys_reg, out, connector_type);
+
+	cmd->supported   = 0;
+	cmd->advertising = 0;
+
+	deprecated_get_supported(eth_proto_cap, &cmd->supported);
+	deprecated_get_advertising(eth_proto_admin, 0, 0, &cmd->advertising);
+	deprecated_get_speed_duplex(netdev, mdev, eth_proto_oper, cmd);
+
+	eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
+
+	connector_type = connector_type < MLX5E_CONNECTOR_TYPE_NUMBER ?
+			 connector_type : MLX5E_PORT_UNKNOWN;
+	cmd->port = get_connector_port(mdev, eth_proto_oper, connector_type);
+	deprecated_get_lp_advertising(eth_proto_lp, &cmd->lp_advertising);
+
+	cmd->lp_advertising |= an_status == MLX5_AN_COMPLETE ?
+			       ADVERTISED_Autoneg : 0;
+
+	cmd->transceiver = XCVR_INTERNAL;
+	cmd->autoneg = an_disable_admin ? AUTONEG_DISABLE : AUTONEG_ENABLE;
+	cmd->supported   |= SUPPORTED_Autoneg;
+	cmd->advertising |= !an_disable_admin ? ADVERTISED_Autoneg : 0;
+
+err_query_ptys:
+	return err;
+}
+
+static u32 deprecated_mlx5e_ethtool2ptys_adver_link(u32 link_modes)
+{
+	u32 i, ptys_modes = 0;
+
+	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
+		if (deprecated_ptys2legacy_ethtool_table[i].advertised & link_modes)
+			ptys_modes |= MLX5E_PROT_MASK(i);
+	}
+
+	return ptys_modes;
+}
+
+int mlx5e_set_settings(struct net_device *netdev,
+		       struct ethtool_cmd *cmd)
+{
+	struct mlx5e_priv *priv    = netdev_priv(netdev);
+	struct mlx5_core_dev *mdev = priv->mdev;
+	struct mlx5_port_eth_proto eproto;
+	bool an_changes = false;
+	u8 an_disable_admin;
+	u8 an_disable_cap;
+	bool an_disable;
+	u32 link_modes;
+	u8 an_status;
+	u32 speed;
+	bool ext;
+	int err;
+
+	ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
+
+	speed = ethtool_cmd_speed(cmd);
+
+	link_modes = cmd->autoneg == AUTONEG_ENABLE ?
+		deprecated_mlx5e_ethtool2ptys_adver_link(cmd->advertising) :
+		deprecated_mlx5e_ethtool2ptys_speed_link(ext, speed);
+
+	err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto);
+	if (err) {
+		netdev_err(netdev, "%s: query port eth proto failed: %d\n",
+			   __func__, err);
+		goto out;
+	}
+
+	/* Overwrite advertise bit for old kernel. When autoneg is enabled,
+	 * driver will advertise all supported speed(eth_proto_cap) and bypass
+	 * advertised speed settings from user. This is because only new
+	 * ethtool(after v4.6) supports advertising speeds like 100G, 25G, etc.
+	 */
+	if (cmd->autoneg == AUTONEG_ENABLE)
+		link_modes = eproto.cap;
+	link_modes = link_modes & eproto.cap;;
+	if (!link_modes) {
+		netdev_err(netdev, "%s: Not supported link mode(s) requested",
+			   __func__);
+		err = -EINVAL;
+		goto out;
+	}
+
+	mlx5_port_query_eth_autoneg(mdev, &an_status, &an_disable_cap,
+				    &an_disable_admin);
+
+	an_disable = cmd->autoneg == AUTONEG_DISABLE;
+	an_changes = ((!an_disable && an_disable_admin) ||
+		      (an_disable && !an_disable_admin));
+
+	if (!an_changes && link_modes == eproto.admin)
+		goto out;
+
+	mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext);
+	mlx5_toggle_port_link(mdev);
+
+out:
+	return err;
+}
+#endif /* HAVE_ETHTOOL_GET_SET_SETTINGS */
+
 typedef int (*mlx5e_pflag_handler)(struct net_device *netdev, bool enable);
 
 struct pflag_desc {
@@ -313,8 +762,12 @@ static void mlx5e_get_ethtool_stats(stru
 }
 
 void mlx5e_ethtool_get_ringparam(struct mlx5e_priv *priv,
+#if defined(HAVE_STRUCT_KERNEL_ETHTOOL_RINGPARAM) && defined(HAVE_GET_RINGPARAM_GET_4_PARAMS)
 				 struct ethtool_ringparam *param,
 				 struct kernel_ethtool_ringparam *kernel_param)
+#else
+				 struct ethtool_ringparam *param)
+#endif
 {
 	/* Limitation for regular RQ. XSK RQ may clamp the queue length in
 	 * mlx5e_mpwqe_get_log_rq_size.
@@ -334,20 +787,31 @@ void mlx5e_ethtool_get_ringparam(struct
 	param->tx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE;
 	param->tx_pending     = 1 << priv->channels.params.log_sq_size;
 
+#if defined(HAVE_STRUCT_KERNEL_ETHTOOL_RINGPARAM) && defined(HAVE_GET_RINGPARAM_GET_4_PARAMS)  && defined(HAVE_KERNEL_RINGPARAM_TCP_DATA_SPLIT)
 	kernel_param->tcp_data_split =
 		(priv->channels.params.packet_merge.type == MLX5E_PACKET_MERGE_SHAMPO) ?
 		ETHTOOL_TCP_DATA_SPLIT_ENABLED :
 		ETHTOOL_TCP_DATA_SPLIT_DISABLED;
+#endif
 }
 
 static void mlx5e_get_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);
 
+#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
 }
 
 int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv,
@@ -376,6 +840,14 @@ int mlx5e_ethtool_set_ringparam(struct m
 			    1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE);
 		return -EINVAL;
 	}
+#ifdef HAVE_BASECODE_EXTRAS
+	if (param->rx_pending > (1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE)) {
+		netdev_info(priv->netdev, "%s: rx_pending (%d) > max (%d)\n",
+			    __func__, param->rx_pending,
+			    1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE);
+		return -EINVAL;
+	}
+#endif
 
 	if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) {
 		netdev_info(priv->netdev, "%s: tx_pending (%d) < min (%d)\n",
@@ -384,6 +856,15 @@ int mlx5e_ethtool_set_ringparam(struct m
 		return -EINVAL;
 	}
 
+#ifdef HAVE_BASECODE_EXTRAS
+	if (param->tx_pending > (1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE)) {
+		netdev_info(priv->netdev, "%s: tx_pending (%d) > max (%d)\n",
+			    __func__, param->tx_pending,
+			    1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE);
+		return -EINVAL;
+	}
+#endif
+
 	log_rq_size = order_base_2(param->rx_pending);
 	log_sq_size = order_base_2(param->tx_pending);
 
@@ -410,9 +891,14 @@ unlock:
 }
 
 static int mlx5e_set_ringparam(struct net_device *dev,
-			       struct ethtool_ringparam *param,
-			       struct kernel_ethtool_ringparam *kernel_param,
-			       struct netlink_ext_ack *extack)
+#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);
 
@@ -533,7 +1019,6 @@ int mlx5e_ethtool_set_channels(struct ml
 			   __func__);
 		goto out;
 	}
-
 	new_params = *cur_params;
 	new_params.num_channels = count;
 
@@ -570,8 +1055,12 @@ static int mlx5e_set_channels(struct net
 }
 
 int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv,
+#ifdef HAVE_NDO_GET_COALESCE_GET_4_PARAMS
 			       struct ethtool_coalesce *coal,
 			       struct kernel_ethtool_coalesce *kernel_coal)
+#else
+			       struct ethtool_coalesce *coal)
+#endif
 {
 	struct dim_cq_moder *rx_moder, *tx_moder;
 
@@ -594,22 +1083,33 @@ int mlx5e_ethtool_get_coalesce(struct ml
 	coal->tx_max_coalesced_frames	= tx_moder->pkts;
 	coal->use_adaptive_tx_coalesce	= priv->channels.params.tx_dim_enabled;
 
+#ifdef HAVE_NDO_GET_COALESCE_GET_4_PARAMS
 	kernel_coal->use_cqe_mode_rx =
 		MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_BASED_MODER);
 	kernel_coal->use_cqe_mode_tx =
 		MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_TX_CQE_BASED_MODER);
+#endif
 
 	return 0;
 }
 
 static int mlx5e_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
 }
 
 #define MLX5E_MAX_COAL_TIME		MLX5_MAX_CQ_PERIOD
@@ -662,16 +1162,22 @@ static int cqe_mode_to_period_mode(bool
 }
 
 int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
+#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 dim_cq_moder *rx_moder, *tx_moder;
 	struct mlx5_core_dev *mdev = priv->mdev;
 	struct mlx5e_params new_params;
 	bool reset_rx, reset_tx;
 	bool reset = true;
+#ifdef HAVE_NDO_GET_COALESCE_GET_4_PARAMS
 	u8 cq_period_mode;
+#endif
 	int err = 0;
 
 	if (!MLX5_CAP_GEN(mdev, cq_moderation))
@@ -691,11 +1197,13 @@ int mlx5e_ethtool_set_coalesce(struct ml
 		return -ERANGE;
 	}
 
+#ifdef HAVE_NDO_GET_COALESCE_GET_4_PARAMS
 	if ((kernel_coal->use_cqe_mode_rx || kernel_coal->use_cqe_mode_tx) &&
 	    !MLX5_CAP_GEN(priv->mdev, cq_period_start_from_cqe)) {
 		NL_SET_ERR_MSG_MOD(extack, "cqe_mode_rx/tx is not supported on this device");
 		return -EOPNOTSUPP;
 	}
+#endif
 
 	mutex_lock(&priv->state_lock);
 	new_params = priv->channels.params;
@@ -722,6 +1230,7 @@ int mlx5e_ethtool_set_coalesce(struct ml
 	reset_rx = !!coal->use_adaptive_rx_coalesce != priv->channels.params.rx_dim_enabled;
 	reset_tx = !!coal->use_adaptive_tx_coalesce != priv->channels.params.tx_dim_enabled;
 
+#ifdef HAVE_NDO_GET_COALESCE_GET_4_PARAMS
 	cq_period_mode = cqe_mode_to_period_mode(kernel_coal->use_cqe_mode_rx);
 	if (cq_period_mode != rx_moder->cq_period_mode) {
 		mlx5e_set_rx_cq_mode_params(&new_params, cq_period_mode);
@@ -733,6 +1242,7 @@ int mlx5e_ethtool_set_coalesce(struct ml
 		mlx5e_set_tx_cq_mode_params(&new_params, cq_period_mode);
 		reset_tx = true;
 	}
+#endif
 
 	if (reset_rx) {
 		u8 mode = MLX5E_GET_PFLAG(&new_params,
@@ -765,13 +1275,22 @@ out:
 }
 
 static int mlx5e_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 void ptys2ethtool_supported_link(struct mlx5_core_dev *mdev,
@@ -807,7 +1326,6 @@ static void ptys2ethtool_adver_link(unsi
 			  table[proto].advertised,
 			  __ETHTOOL_LINK_MODE_MASK_NBITS);
 }
-
 static const u32 pplm_fec_2_ethtool[] = {
 	[MLX5E_FEC_NOFEC] = ETHTOOL_FEC_OFF,
 	[MLX5E_FEC_FIRECODE] = ETHTOOL_FEC_BASER,
@@ -1144,7 +1662,6 @@ int mlx5e_ethtool_get_link_ksettings(str
 			   __func__, err);
 		err = 0; /* don't fail caps query because of FEC error */
 	}
-
 	if (!an_disable_admin)
 		ethtool_link_ksettings_add_link_mode(link_ksettings,
 						     advertising, Autoneg);
@@ -1195,6 +1712,7 @@ static u32 mlx5e_ethtool2ptys_adver_link
 
 static u32 mlx5e_ethtool2ptys_ext_adver_link(const unsigned long *link_modes)
 {
+#ifdef HAVE_ETHTOOL_50G_PER_LANE_LINK_MODES
 	u32 i, ptys_modes = 0;
 	unsigned long modes[2];
 
@@ -1211,6 +1729,9 @@ static u32 mlx5e_ethtool2ptys_ext_adver_
 			ptys_modes |= MLX5E_PROT_MASK(i);
 	}
 	return ptys_modes;
+#else
+	return 0;
+#endif
 }
 
 static bool ext_link_mode_requested(const unsigned long *adver)
@@ -1270,6 +1791,11 @@ int mlx5e_ethtool_set_link_ksettings(str
 	link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) :
 		mlx5_port_speed2linkmodes(mdev, speed, !ext);
 
+#ifndef HAVE_ETHTOOL_50G_PER_LANE_LINK_MODES
+	if (link_ksettings->base.autoneg == AUTONEG_ENABLE && ext_supported)
+		link_modes = eproto.cap;
+#endif
+
 	err = mlx5e_speed_validate(priv->netdev, ext, link_modes, autoneg);
 	if (err)
 		goto out;
@@ -1331,6 +1857,56 @@ static u32 mlx5e_get_rxfh_indir_size(str
 	return mlx5e_ethtool_get_rxfh_indir_size(priv);
 }
 
+#ifdef HAVE_GET_RXFH_CONTEXT
+static int mlx5e_get_rxfh_context(struct net_device *dev, u32 *indir,
+				  u8 *key, u8 *hfunc, u32 rss_context)
+{
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	int err;
+
+	mutex_lock(&priv->state_lock);
+	err = mlx5e_rx_res_rss_get_rxfh(priv->rx_res, rss_context, indir, key, hfunc);
+	mutex_unlock(&priv->state_lock);
+	return err;
+}
+
+static int mlx5e_set_rxfh_context(struct net_device *dev, const u32 *indir,
+				  const u8 *key, const u8 hfunc,
+				  u32 *rss_context, bool delete)
+{
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	int err;
+
+	mutex_lock(&priv->state_lock);
+	if (delete) {
+		err = mlx5e_rx_res_rss_destroy(priv->rx_res, *rss_context);
+		goto unlock;
+	}
+
+	if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
+		unsigned int count = priv->channels.params.num_channels;
+
+		err = mlx5e_rx_res_rss_init(priv->rx_res, rss_context, count);
+		if (err)
+			goto unlock;
+	}
+
+	err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, *rss_context, indir, key,
+					hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc);
+
+unlock:
+	mutex_unlock(&priv->state_lock);
+	return err;
+}
+#endif
+
+#ifdef HAVE_GET_RXFH_CONTEXT
+int mlx5e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
+		   u8 *hfunc)
+{
+	return mlx5e_get_rxfh_context(netdev, indir, key, hfunc, 0);
+}
+#else
 int mlx5e_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh)
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -1343,37 +1919,39 @@ int mlx5e_get_rxfh(struct net_device *ne
 	mutex_unlock(&priv->state_lock);
 	return err;
 }
+#endif
 
+#ifdef HAVE_GET_RXFH_CONTEXT
+int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
+		   const u8 *key, const u8 hfunc)
+{
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	int err;
+
+	mutex_lock(&priv->state_lock);
+	err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, 0, indir, key,
+					hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc);
+	mutex_unlock(&priv->state_lock);
+	return err;
+}
+#else
 int mlx5e_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
 		   struct netlink_ext_ack *extack)
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 	u32 *rss_context = &rxfh->rss_context;
 	u8 hfunc = rxfh->hfunc;
-	unsigned int count;
 	int err;
 
 	mutex_lock(&priv->state_lock);
-
-	count = priv->channels.params.num_channels;
-
-	if (hfunc == ETH_RSS_HASH_XOR) {
-		unsigned int xor8_max_channels = mlx5e_rqt_max_num_channels_allowed_for_xor8();
-
-		if (count > xor8_max_channels) {
-			err = -EINVAL;
-			netdev_err(priv->netdev, "%s: Cannot set RSS hash function to XOR, current number of channels (%d) exceeds the maximum allowed for XOR8 RSS hfunc (%d)\n",
-				   __func__, count, xor8_max_channels);
-			goto unlock;
-		}
-	}
-
 	if (*rss_context && rxfh->rss_delete) {
 		err = mlx5e_rx_res_rss_destroy(priv->rx_res, *rss_context);
 		goto unlock;
 	}
 
 	if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
+		unsigned int count = priv->channels.params.num_channels;
+
 		err = mlx5e_rx_res_rss_init(priv->rx_res, rss_context, count);
 		if (err)
 			goto unlock;
@@ -1387,6 +1965,7 @@ unlock:
 	mutex_unlock(&priv->state_lock);
 	return err;
 }
+#endif
 
 #define MLX5E_PFC_PREVEN_AUTO_TOUT_MSEC		100
 #define MLX5E_PFC_PREVEN_TOUT_MAX_MSEC		8000
@@ -1478,7 +2057,7 @@ static int mlx5e_set_tunable(struct net_
 	mutex_unlock(&priv->state_lock);
 	return err;
 }
-
+#ifdef HAVE_GET_PAUSE_STATS
 static void mlx5e_get_pause_stats(struct net_device *netdev,
 				  struct ethtool_pause_stats *pause_stats)
 {
@@ -1486,7 +2065,7 @@ static void mlx5e_get_pause_stats(struct
 
 	mlx5e_stats_pause_get(priv, pause_stats);
 }
-
+#endif
 void mlx5e_ethtool_get_pauseparam(struct mlx5e_priv *priv,
 				  struct ethtool_pauseparam *pauseparam)
 {
@@ -1571,7 +2150,6 @@ static int mlx5e_get_ts_info(struct net_
 
 	return mlx5e_ethtool_get_ts_info(priv, info);
 }
-
 static __u32 mlx5e_get_wol_supported(struct mlx5_core_dev *mdev)
 {
 	__u32 ret = 0;
@@ -1694,7 +2272,7 @@ static int mlx5e_set_wol(struct net_devi
 
 	return mlx5_set_port_wol(mdev, mlx5_wol_mode);
 }
-
+#ifdef HAVE_NDO_GET_FEC_STATS
 static void mlx5e_get_fec_stats(struct net_device *netdev,
 				struct ethtool_fec_stats *fec_stats)
 {
@@ -1702,7 +2280,7 @@ static void mlx5e_get_fec_stats(struct n
 
 	mlx5e_stats_fec_get(priv, fec_stats);
 }
-
+#endif
 static int mlx5e_get_fecparam(struct net_device *netdev,
 			      struct ethtool_fecparam *fecparam)
 {
@@ -1862,6 +2440,7 @@ static int mlx5e_get_module_eeprom(struc
 	return 0;
 }
 
+#ifdef HAVE_GET_MODULE_EEPROM_BY_PAGE
 static int mlx5e_get_module_eeprom_by_page(struct net_device *netdev,
 					   const struct ethtool_module_eeprom *page_data,
 					   struct netlink_ext_ack *extack)
@@ -1904,6 +2483,7 @@ static int mlx5e_get_module_eeprom_by_pa
 
 	return i;
 }
+#endif
 
 int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
 			       struct ethtool_flash *flash)
@@ -2020,6 +2600,39 @@ int mlx5e_modify_rx_cqe_compression_lock
 	return 0;
 }
 
+#ifdef HAVE_BASECODE_EXTRAS
+int mlx5e_modify_tx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val)
+{
+	bool curr_val = MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_TX_CQE_COMPRESS);
+	struct mlx5e_params new_params;
+	int err = 0;
+
+	if (!MLX5_CAP_GEN(priv->mdev, cqe_compression))
+		return new_val ? -EOPNOTSUPP : 0;
+
+	if (curr_val == new_val)
+		return 0;
+
+	new_params = priv->channels.params;
+	MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_TX_CQE_COMPRESS, new_val);
+
+	if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
+		priv->channels.params = new_params;
+		return 0;
+	}
+
+	err = mlx5e_safe_switch_params(priv, &new_params, NULL ,NULL, true);
+	if (err)
+		return err;
+
+	netdev_dbg(priv->netdev, "MLX5E: TxCqeCmprss was turned %s\n",
+		  MLX5E_GET_PFLAG(&priv->channels.params,
+				  MLX5E_PFLAG_TX_CQE_COMPRESS) ? "ON" : "OFF");
+
+	return 0;
+}
+#endif
+
 static int set_pflag_rx_cqe_compress(struct net_device *netdev,
 				     bool enable)
 {
@@ -2041,6 +2654,21 @@ static int set_pflag_rx_cqe_compress(str
 	return 0;
 }
 
+#ifdef HAVE_BASECODE_EXTRAS
+static int set_pflag_tx_cqe_compress(struct net_device *netdev, bool enable)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5_core_dev *mdev = priv->mdev;
+
+	if (!MLX5_CAP_GEN(mdev, cqe_compression))
+		return -EOPNOTSUPP;
+
+	mlx5e_modify_tx_cqe_compression_locked(priv, enable);
+
+	return 0;
+}
+#endif
+
 static int set_pflag_rx_striding_rq(struct net_device *netdev, bool enable)
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -2057,7 +2685,11 @@ static int set_pflag_rx_striding_rq(stru
 
 		if (err)
 			return err;
+#ifndef CONFIG_COMPAT_LRO_ENABLED_IPOIB
 	} else if (priv->channels.params.packet_merge.type != MLX5E_PACKET_MERGE_NONE) {
+#else
+	} else if (IS_HW_LRO(&priv->channels.params)) {
+#endif
 		netdev_warn(netdev, "Can't set legacy RQ with HW-GRO/LRO, disable them first\n");
 		return -EINVAL;
 	}
@@ -2071,12 +2703,52 @@ static int set_pflag_rx_striding_rq(stru
 	if (err)
 		return err;
 
+#ifdef HAVE_XDP_SET_FEATURES_FLAG
 	/* update XDP supported features */
 	mlx5e_set_xdp_feature(netdev);
+#endif
 
 	return 0;
 }
 
+#ifdef CONFIG_COMPAT_LRO_ENABLED_IPOIB
+static int set_pflag_hwlro(struct net_device *netdev, bool enable)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5e_params new_params;
+	int err = 0;
+	bool reset;
+
+
+	if (!mlx5e_check_fragmented_striding_rq_cap(priv->mdev, PAGE_SHIFT, false)) {
+		netdev_warn(netdev, "HW LRO is off[fixed], can't toggle without errors\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (priv->channels.params.rq_wq_type !=
+			MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
+		netdev_warn(netdev, "Can't toggle HW LRO with legacy RQ\n");
+		return -EINVAL;
+	}
+
+	new_params = priv->channels.params;
+	MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_HWLRO, enable);
+	reset = test_bit(MLX5E_STATE_OPENED, &priv->state) &&
+		(new_params.packet_merge.type != MLX5E_PACKET_MERGE_NONE);
+
+	if (!reset) {
+		priv->channels.params = new_params;
+		err = mlx5e_modify_tirs_packet_merge(priv);
+		goto out;
+	}
+
+	err = mlx5e_safe_switch_params(priv, &new_params,
+			mlx5e_modify_tirs_packet_merge_ctx, NULL, true);
+out:
+	return err;
+}
+#endif
+
 static int set_pflag_rx_no_csum_complete(struct net_device *netdev, bool enable)
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -2085,7 +2757,11 @@ static int set_pflag_rx_no_csum_complete
 	int i;
 
 	if (!test_bit(MLX5E_STATE_OPENED, &priv->state) ||
+#ifdef HAVE_XDP_SUPPORT
 	    priv->channels.params.xdp_prog)
+#else
+	    false)
+#endif
 		return 0;
 
 	for (i = 0; i < channels->num; i++) {
@@ -2122,10 +2798,12 @@ static int set_pflag_per_channel_stats(s
 	return 0;
 }
 
+#ifdef HAVE_XDP_SUPPORT
 static int set_pflag_xdp_tx_mpwqe(struct net_device *netdev, bool enable)
 {
 	return set_pflag_tx_mpwqe_common(netdev, MLX5E_PFLAG_XDP_TX_MPWQE, enable);
 }
+#endif
 
 static int set_pflag_skb_tx_mpwqe(struct net_device *netdev, bool enable)
 {
@@ -2154,6 +2832,7 @@ static int set_pflag_tx_port_ts(struct n
 	}
 
 	new_params = priv->channels.params;
+
 	/* Don't allow enabling TX-port-TS if MQPRIO mode channel  offload is
 	 * active, since it defines explicitly which TC accepts the packet.
 	 * This conflicts with TX-port-TS hijacking the PTP traffic to a specific
@@ -2244,13 +2923,21 @@ static const struct pflag_desc mlx5e_pri
 	{ "rx_cqe_moder",        set_pflag_rx_cqe_based_moder },
 	{ "tx_cqe_moder",        set_pflag_tx_cqe_based_moder },
 	{ "rx_cqe_compress",     set_pflag_rx_cqe_compress },
+#ifdef HAVE_BASECODE_EXTRAS
+	{ "tx_cqe_compress",     set_pflag_tx_cqe_compress },
+#endif
 	{ "rx_striding_rq",      set_pflag_rx_striding_rq },
 	{ "rx_no_csum_complete", set_pflag_rx_no_csum_complete },
+#ifdef HAVE_XDP_SUPPORT
 	{ "xdp_tx_mpwqe",        set_pflag_xdp_tx_mpwqe },
+#endif
 	{ "skb_tx_mpwqe",        set_pflag_skb_tx_mpwqe },
 	{ "tx_port_ts",          set_pflag_tx_port_ts },
 	{ "dropless_rq",	 set_pflag_dropless_rq},
 	{ "per_channel_stats",	 set_pflag_per_channel_stats},
+#ifdef CONFIG_COMPAT_LRO_ENABLED_IPOIB
+	{ "hw_lro",              set_pflag_hwlro },
+#endif
 	{ "tx_xdp_hw_checksum",  set_pflag_tx_xdp_hw_checksum},
 };
 
@@ -2331,6 +3018,7 @@ static int mlx5e_set_rxnfc(struct net_de
 	return mlx5e_ethtool_set_rxnfc(priv, cmd);
 }
 
+#ifdef HAVE_GET_LINK_EXT_STATE
 static int query_port_status_opcode(struct mlx5_core_dev *mdev, u32 *status_opcode)
 {
 	struct mlx5_ifc_pddr_troubleshooting_page_bits *pddr_troubleshooting_page;
@@ -2500,7 +3188,8 @@ mlx5e_get_link_ext_state(struct net_devi
 
 	return -ENODATA;
 }
-
+#endif //HAVE_GET_LINK_EXT_STATE
+#ifdef HAVE_NDO_ETH_PHY_STATS
 static void mlx5e_get_eth_phy_stats(struct net_device *netdev,
 				    struct ethtool_eth_phy_stats *phy_stats)
 {
@@ -2533,16 +3222,27 @@ static void mlx5e_get_rmon_stats(struct
 
 	mlx5e_stats_rmon_get(priv, rmon_stats, ranges);
 }
+#endif
 
 const struct ethtool_ops mlx5e_ethtool_ops = {
+#ifndef HAVE_GET_RXFH_CONTEXT
 	.cap_rss_ctx_supported	= true,
+#endif
+#ifdef HAVE_SUPPORTED_COALESCE_PARAM
 	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
 				     ETHTOOL_COALESCE_MAX_FRAMES |
+#ifdef HAVE_NDO_GET_COALESCE_GET_4_PARAMS
 				     ETHTOOL_COALESCE_USE_ADAPTIVE |
 				     ETHTOOL_COALESCE_USE_CQE,
+#else
+				     ETHTOOL_COALESCE_USE_ADAPTIVE,
+#endif
+#endif
 	.get_drvinfo       = mlx5e_get_drvinfo,
 	.get_link          = ethtool_op_get_link,
+#ifdef HAVE_GET_LINK_EXT_STATE
 	.get_link_ext_state  = mlx5e_get_link_ext_state,
+#endif
 	.get_strings       = mlx5e_get_strings,
 	.get_sset_count    = mlx5e_get_sset_count,
 	.get_ethtool_stats = mlx5e_get_ethtool_stats,
@@ -2554,15 +3254,25 @@ const struct ethtool_ops mlx5e_ethtool_o
 	.set_coalesce      = mlx5e_set_coalesce,
 	.get_link_ksettings  = mlx5e_get_link_ksettings,
 	.set_link_ksettings  = mlx5e_set_link_ksettings,
+#ifdef HAVE_ETHTOOL_GET_SET_SETTINGS
+	.get_settings  = mlx5e_get_settings,
+	.set_settings  = mlx5e_set_settings,
+#endif
 	.get_rxfh_key_size   = mlx5e_get_rxfh_key_size,
 	.get_rxfh_indir_size = mlx5e_get_rxfh_indir_size,
+#ifdef HAVE_GET_RXFH_CONTEXT
+ 	.get_rxfh_context  = mlx5e_get_rxfh_context,
+ 	.set_rxfh_context  = mlx5e_set_rxfh_context,
+#endif
 	.get_rxfh          = mlx5e_get_rxfh,
 	.set_rxfh          = mlx5e_set_rxfh,
 	.get_rxnfc         = mlx5e_get_rxnfc,
 	.set_rxnfc         = mlx5e_set_rxnfc,
 	.get_tunable       = mlx5e_get_tunable,
 	.set_tunable       = mlx5e_set_tunable,
+#ifdef HAVE_GET_PAUSE_STATS
 	.get_pause_stats   = mlx5e_get_pause_stats,
+#endif
 	.get_pauseparam    = mlx5e_get_pauseparam,
 	.set_pauseparam    = mlx5e_set_pauseparam,
 	.get_ts_info       = mlx5e_get_ts_info,
@@ -2571,21 +3281,29 @@ const struct ethtool_ops mlx5e_ethtool_o
 	.set_wol	   = mlx5e_set_wol,
 	.get_module_info   = mlx5e_get_module_info,
 	.get_module_eeprom = mlx5e_get_module_eeprom,
+#ifdef HAVE_GET_MODULE_EEPROM_BY_PAGE
 	.get_module_eeprom_by_page = mlx5e_get_module_eeprom_by_page,
+#endif
 	.flash_device      = mlx5e_flash_device,
 	.get_priv_flags    = mlx5e_get_priv_flags,
 	.set_priv_flags    = mlx5e_set_priv_flags,
 	.self_test         = mlx5e_self_test,
+#ifdef HAVE_NDO_GET_FEC_STATS
 	.get_fec_stats     = mlx5e_get_fec_stats,
+#endif
 	.set_priv_flags    = mlx5e_set_priv_flags,
 	.get_dump_flag     = mlx5e_get_dump_flag,
 	.get_dump_data     = mlx5e_get_dump_data,
 	.set_dump          = mlx5e_set_dump,
 	.get_fecparam      = mlx5e_get_fecparam,
 	.set_fecparam      = mlx5e_set_fecparam,
+#ifdef HAVE_NDO_ETH_PHY_STATS
 	.get_eth_phy_stats = mlx5e_get_eth_phy_stats,
 	.get_eth_mac_stats = mlx5e_get_eth_mac_stats,
 	.get_eth_ctrl_stats = mlx5e_get_eth_ctrl_stats,
 	.get_rmon_stats    = mlx5e_get_rmon_stats,
+#endif
+#ifdef HAVE_NDO_LINK_EXT_STATS
 	.get_link_ext_stats = mlx5e_get_link_ext_stats
+#endif
 };
