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

Change-Id: Ic39fbdeb861fd185fd473a6d935efaea29f20841
---
 .../mellanox/mlx5/core/ipoib/ethtool.c        | 98 ++++++++++++++++++-
 1 file changed, 96 insertions(+), 2 deletions(-)

--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
@@ -67,9 +67,13 @@ static void mlx5i_get_ethtool_stats(stru
 }
 
 static int mlx5i_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 = mlx5i_epriv(dev);
 
@@ -77,9 +81,13 @@ static int mlx5i_set_ringparam(struct ne
 }
 
 static void mlx5i_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 = mlx5i_epriv(dev);
 
@@ -103,23 +111,41 @@ static void mlx5i_get_channels(struct ne
 }
 
 static int mlx5i_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 = mlx5i_epriv(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 int mlx5i_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 = mlx5i_epriv(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 mlx5i_get_ts_info(struct net_device *netdev,
@@ -190,6 +216,7 @@ static int mlx5i_get_speed_settings(u16
 	return rate * width;
 }
 
+#ifdef HAVE_GET_SET_LINK_KSETTINGS
 static int mlx5i_get_link_ksettings(struct net_device *netdev,
 				    struct ethtool_link_ksettings *link_ksettings)
 {
@@ -220,11 +247,64 @@ static int mlx5i_get_link_ksettings(stru
 
 	return 0;
 }
+#endif
+
+#ifdef HAVE_ETHTOOL_GET_SET_SETTINGS
+static int mlx5i_get_port_settings(struct net_device *netdev,
+		u16 *ib_link_width_oper, u16 *ib_proto_oper)
+{
+	struct mlx5e_priv *priv    = mlx5i_epriv(netdev);
+	struct mlx5_core_dev *mdev = priv->mdev;
+	u32 out[MLX5_ST_SZ_DW(ptys_reg)] = {0};
+	int ret;
+
+	ret = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_IB, 1);
+	if (ret)
+		return ret;
+
+	*ib_link_width_oper = MLX5_GET(ptys_reg, out, ib_link_width_oper);
+	*ib_proto_oper      = MLX5_GET(ptys_reg, out, ib_proto_oper);
+
+	return 0;
+}
+
+static int mlx5i_get_settings(struct net_device *netdev,
+			      struct ethtool_cmd *ecmd)
+{
+	u16 ib_link_width_oper;
+	u16 ib_proto_oper;
+	int speed, ret;
+
+	ret = mlx5i_get_port_settings(netdev,
+				      &ib_link_width_oper,
+				      &ib_proto_oper);
+	if (ret)
+		return ret;
+
+	speed = mlx5i_get_speed_settings(ib_link_width_oper, ib_proto_oper);
+	if (speed < 0)
+		return -EINVAL;
+
+	ecmd->duplex = DUPLEX_FULL;
+	ecmd->port = PORT_OTHER;// FIXME: till define IB port type 
+	ecmd->phy_address = 255;
+	ecmd->autoneg = AUTONEG_DISABLE;
+
+	ethtool_cmd_speed_set(ecmd, speed);
+
+	return 0;
+}
+#endif
 
 #ifdef CONFIG_MLX5_EN_RXNFC
 static u32 mlx5i_flow_type_mask(u32 flow_type)
 {
+#ifdef HAVE_FLOW_RSS
 	return flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS);
+#else
+	return flow_type & ~(FLOW_EXT | FLOW_MAC_EXT);
+#endif
+
 }
 
 static int mlx5i_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
@@ -248,9 +328,11 @@ static int mlx5i_get_rxnfc(struct net_de
 #endif
 
 const struct ethtool_ops mlx5i_ethtool_ops = {
+#ifdef HAVE_SUPPORTED_COALESCE_PARAM
 	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
 				     ETHTOOL_COALESCE_MAX_FRAMES |
 				     ETHTOOL_COALESCE_USE_ADAPTIVE,
+#endif
 	.get_drvinfo        = mlx5i_get_drvinfo,
 	.get_strings        = mlx5i_get_strings,
 	.get_sset_count     = mlx5i_get_sset_count,
@@ -267,7 +349,12 @@ const struct ethtool_ops mlx5i_ethtool_o
 	.get_rxnfc          = mlx5i_get_rxnfc,
 	.set_rxnfc          = mlx5i_set_rxnfc,
 #endif
+#ifdef HAVE_GET_SET_LINK_KSETTINGS
 	.get_link_ksettings = mlx5i_get_link_ksettings,
+#endif
+#ifdef HAVE_ETHTOOL_GET_SET_SETTINGS
+	.get_settings       = mlx5i_get_settings,
+#endif
 	.get_link           = ethtool_op_get_link,
 };
 
@@ -275,4 +362,11 @@ const struct ethtool_ops mlx5i_pkey_etht
 	.get_drvinfo        = mlx5i_get_drvinfo,
 	.get_link           = ethtool_op_get_link,
 	.get_ts_info        = mlx5i_get_ts_info,
+#ifdef HAVE_GET_SET_LINK_KSETTINGS
+	.get_link_ksettings = mlx5i_get_link_ksettings,
+#endif
+#ifdef HAVE_ETHTOOL_GET_SET_SETTINGS
+	.get_settings	    = mlx5i_get_settings,
+#endif
 };
+
