This flag can be used for debugging and development purposes
including determining if s0ix flows work properly for a system
not currently recognized by heuristics.

Tested-by: Yijun Shen <yijun.s...@dell.com>
Signed-off-by: Mario Limonciello <mario.limoncie...@dell.com>
---
 drivers/net/ethernet/intel/e1000e/ethtool.c | 40 +++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c 
b/drivers/net/ethernet/intel/e1000e/ethtool.c
index 03215b0aee4b..eb683949ebfe 100644
--- a/drivers/net/ethernet/intel/e1000e/ethtool.c
+++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
@@ -23,6 +23,13 @@ struct e1000_stats {
        int stat_offset;
 };
 
+static const char e1000e_priv_flags_strings[][ETH_GSTRING_LEN] = {
+#define E1000E_PRIV_FLAGS_S0IX_ENABLED BIT(0)
+       "s0ix-enabled",
+};
+
+#define E1000E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(e1000e_priv_flags_strings)
+
 #define E1000_STAT(str, m) { \
                .stat_string = str, \
                .type = E1000_STATS, \
@@ -1776,6 +1783,8 @@ static int e1000e_get_sset_count(struct net_device 
__always_unused *netdev,
                return E1000_TEST_LEN;
        case ETH_SS_STATS:
                return E1000_STATS_LEN;
+       case ETH_SS_PRIV_FLAGS:
+               return E1000E_PRIV_FLAGS_STR_LEN;
        default:
                return -EOPNOTSUPP;
        }
@@ -2097,6 +2106,10 @@ static void e1000_get_strings(struct net_device 
__always_unused *netdev,
                        p += ETH_GSTRING_LEN;
                }
                break;
+       case ETH_SS_PRIV_FLAGS:
+               memcpy(data, e1000e_priv_flags_strings,
+                      E1000E_PRIV_FLAGS_STR_LEN * ETH_GSTRING_LEN);
+               break;
        }
 }
 
@@ -2305,6 +2318,31 @@ static int e1000e_get_ts_info(struct net_device *netdev,
        return 0;
 }
 
+static u32 e1000e_get_priv_flags(struct net_device *netdev)
+{
+       struct e1000_adapter *adapter = netdev_priv(netdev);
+       u32 priv_flags = 0;
+
+       if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS)
+               priv_flags |= E1000E_PRIV_FLAGS_S0IX_ENABLED;
+
+       return priv_flags;
+}
+
+static int e1000e_set_priv_flags(struct net_device *netdev, u32 priv_flags)
+{
+       struct e1000_adapter *adapter = netdev_priv(netdev);
+       unsigned int flags2 = adapter->flags2;
+
+       flags2 &= ~FLAG2_ENABLE_S0IX_FLOWS;
+       if (priv_flags & E1000E_PRIV_FLAGS_S0IX_ENABLED)
+               flags2 |= FLAG2_ENABLE_S0IX_FLOWS;
+       if (flags2 != adapter->flags2)
+               adapter->flags2 = flags2;
+
+       return 0;
+}
+
 static const struct ethtool_ops e1000_ethtool_ops = {
        .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS,
        .get_drvinfo            = e1000_get_drvinfo,
@@ -2336,6 +2374,8 @@ static const struct ethtool_ops e1000_ethtool_ops = {
        .set_eee                = e1000e_set_eee,
        .get_link_ksettings     = e1000_get_link_ksettings,
        .set_link_ksettings     = e1000_set_link_ksettings,
+       .get_priv_flags         = e1000e_get_priv_flags,
+       .set_priv_flags         = e1000e_set_priv_flags,
 };
 
 void e1000e_set_ethtool_ops(struct net_device *netdev)
-- 
2.25.1

Reply via email to