> -----Original Message----- > From: Limonciello, Mario <mario_limoncie...@dell.com> > Sent: Tuesday, December 15, 2020 3:30 AM > To: Jeff Kirsher; Tony Nguyen; intel-wired-...@lists.osuosl.org > Cc: linux-kernel@vger.kernel.org; Netdev; Alexander Duyck; Jakub Kicinski; > Sasha Netfin; Aaron Brown; Stefan Assmann; David Miller; > darc...@redhat.com; Shen, Yijun; Yuan, Perry; > anthony.w...@canonical.com; Hans de Goede; Limonciello, Mario > Subject: [PATCH v5 4/4] e1000e: Export S0ix flags to ethtool > > This flag can be used by an end user to disable S0ix flows on a buggy system > or by an OEM for development purposes. > > If you need this flag to be persisted across reboots, it's suggested to use a > udev rule to call adjust it until the kernel could have your configuration in > a > disallow list. > > Signed-off-by: Mario Limonciello <mario.limoncie...@dell.com>
Verified this series patches with Dell Systems. Tested-By: Yijun Shen <yijun.s...@dell.com> > --- > drivers/net/ethernet/intel/e1000e/e1000.h | 1 + > drivers/net/ethernet/intel/e1000e/ethtool.c | 46 +++++++++++++++++++++ > drivers/net/ethernet/intel/e1000e/netdev.c | 9 ++-- > 3 files changed, 52 insertions(+), 4 deletions(-) > > diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h > b/drivers/net/ethernet/intel/e1000e/e1000.h > index ba7a0f8f6937..5b2143f4b1f8 100644 > --- a/drivers/net/ethernet/intel/e1000e/e1000.h > +++ b/drivers/net/ethernet/intel/e1000e/e1000.h > @@ -436,6 +436,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter > *adapter, u32 *timinca); > #define FLAG2_DFLT_CRC_STRIPPING BIT(12) > #define FLAG2_CHECK_RX_HWTSTAMP BIT(13) > #define FLAG2_CHECK_SYSTIM_OVERFLOW BIT(14) > +#define FLAG2_ENABLE_S0IX_FLOWS BIT(15) > > #define E1000_RX_DESC_PS(R, i) \ > (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) diff --git > a/drivers/net/ethernet/intel/e1000e/ethtool.c > b/drivers/net/ethernet/intel/e1000e/ethtool.c > index 03215b0aee4b..06442e6bef73 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,37 @@ 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) { > + struct e1000_hw *hw = &adapter->hw; > + > + if (hw->mac.type < e1000_pch_cnp) > + return -EINVAL; > + 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 +2380,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) diff --git > a/drivers/net/ethernet/intel/e1000e/netdev.c > b/drivers/net/ethernet/intel/e1000e/netdev.c > index b9800ba2006c..e9b82c209c2d 100644 > --- a/drivers/net/ethernet/intel/e1000e/netdev.c > +++ b/drivers/net/ethernet/intel/e1000e/netdev.c > @@ -6923,7 +6923,6 @@ static __maybe_unused int > e1000e_pm_suspend(struct device *dev) > struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); > struct e1000_adapter *adapter = netdev_priv(netdev); > struct pci_dev *pdev = to_pci_dev(dev); > - struct e1000_hw *hw = &adapter->hw; > int rc; > > e1000e_flush_lpic(pdev); > @@ -6935,7 +6934,7 @@ static __maybe_unused int > e1000e_pm_suspend(struct device *dev) > e1000e_pm_thaw(dev); > } else { > /* Introduce S0ix implementation */ > - if (hw->mac.type >= e1000_pch_cnp) > + if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS) > e1000e_s0ix_entry_flow(adapter); > } > > @@ -6947,11 +6946,10 @@ static __maybe_unused int > e1000e_pm_resume(struct device *dev) > struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); > struct e1000_adapter *adapter = netdev_priv(netdev); > struct pci_dev *pdev = to_pci_dev(dev); > - struct e1000_hw *hw = &adapter->hw; > int rc; > > /* Introduce S0ix implementation */ > - if (hw->mac.type >= e1000_pch_cnp) > + if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS) > e1000e_s0ix_exit_flow(adapter); > > rc = __e1000_resume(pdev); > @@ -7615,6 +7613,9 @@ static int e1000_probe(struct pci_dev *pdev, const > struct pci_device_id *ent) > if (!(adapter->flags & FLAG_HAS_AMT)) > e1000e_get_hw_control(adapter); > > + if (hw->mac.type >= e1000_pch_cnp) > + adapter->flags2 |= FLAG2_ENABLE_S0IX_FLOWS; > + > strlcpy(netdev->name, "eth%d", sizeof(netdev->name)); > err = register_netdev(netdev); > if (err) > -- > 2.25.1