Skip to content

Commit 3c98cbf

Browse files
Mario Limoncielloanguy11
authored andcommitted
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.limonciello@dell.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Tested-by: Yijun Shen <Yijun.shen@dell.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
1 parent 6cecf02 commit 3c98cbf

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

drivers/net/ethernet/intel/e1000e/e1000.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca);
436436
#define FLAG2_DFLT_CRC_STRIPPING BIT(12)
437437
#define FLAG2_CHECK_RX_HWTSTAMP BIT(13)
438438
#define FLAG2_CHECK_SYSTIM_OVERFLOW BIT(14)
439+
#define FLAG2_ENABLE_S0IX_FLOWS BIT(15)
439440

440441
#define E1000_RX_DESC_PS(R, i) \
441442
(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))

drivers/net/ethernet/intel/e1000e/ethtool.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ struct e1000_stats {
2323
int stat_offset;
2424
};
2525

26+
static const char e1000e_priv_flags_strings[][ETH_GSTRING_LEN] = {
27+
#define E1000E_PRIV_FLAGS_S0IX_ENABLED BIT(0)
28+
"s0ix-enabled",
29+
};
30+
31+
#define E1000E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(e1000e_priv_flags_strings)
32+
2633
#define E1000_STAT(str, m) { \
2734
.stat_string = str, \
2835
.type = E1000_STATS, \
@@ -1776,6 +1783,8 @@ static int e1000e_get_sset_count(struct net_device __always_unused *netdev,
17761783
return E1000_TEST_LEN;
17771784
case ETH_SS_STATS:
17781785
return E1000_STATS_LEN;
1786+
case ETH_SS_PRIV_FLAGS:
1787+
return E1000E_PRIV_FLAGS_STR_LEN;
17791788
default:
17801789
return -EOPNOTSUPP;
17811790
}
@@ -2097,6 +2106,10 @@ static void e1000_get_strings(struct net_device __always_unused *netdev,
20972106
p += ETH_GSTRING_LEN;
20982107
}
20992108
break;
2109+
case ETH_SS_PRIV_FLAGS:
2110+
memcpy(data, e1000e_priv_flags_strings,
2111+
E1000E_PRIV_FLAGS_STR_LEN * ETH_GSTRING_LEN);
2112+
break;
21002113
}
21012114
}
21022115

@@ -2305,6 +2318,37 @@ static int e1000e_get_ts_info(struct net_device *netdev,
23052318
return 0;
23062319
}
23072320

2321+
static u32 e1000e_get_priv_flags(struct net_device *netdev)
2322+
{
2323+
struct e1000_adapter *adapter = netdev_priv(netdev);
2324+
u32 priv_flags = 0;
2325+
2326+
if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS)
2327+
priv_flags |= E1000E_PRIV_FLAGS_S0IX_ENABLED;
2328+
2329+
return priv_flags;
2330+
}
2331+
2332+
static int e1000e_set_priv_flags(struct net_device *netdev, u32 priv_flags)
2333+
{
2334+
struct e1000_adapter *adapter = netdev_priv(netdev);
2335+
unsigned int flags2 = adapter->flags2;
2336+
2337+
flags2 &= ~FLAG2_ENABLE_S0IX_FLOWS;
2338+
if (priv_flags & E1000E_PRIV_FLAGS_S0IX_ENABLED) {
2339+
struct e1000_hw *hw = &adapter->hw;
2340+
2341+
if (hw->mac.type < e1000_pch_cnp)
2342+
return -EINVAL;
2343+
flags2 |= FLAG2_ENABLE_S0IX_FLOWS;
2344+
}
2345+
2346+
if (flags2 != adapter->flags2)
2347+
adapter->flags2 = flags2;
2348+
2349+
return 0;
2350+
}
2351+
23082352
static const struct ethtool_ops e1000_ethtool_ops = {
23092353
.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS,
23102354
.get_drvinfo = e1000_get_drvinfo,
@@ -2336,6 +2380,8 @@ static const struct ethtool_ops e1000_ethtool_ops = {
23362380
.set_eee = e1000e_set_eee,
23372381
.get_link_ksettings = e1000_get_link_ksettings,
23382382
.set_link_ksettings = e1000_set_link_ksettings,
2383+
.get_priv_flags = e1000e_get_priv_flags,
2384+
.set_priv_flags = e1000e_set_priv_flags,
23392385
};
23402386

23412387
void e1000e_set_ethtool_ops(struct net_device *netdev)

drivers/net/ethernet/intel/e1000e/netdev.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6923,7 +6923,6 @@ static __maybe_unused int e1000e_pm_suspend(struct device *dev)
69236923
struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
69246924
struct e1000_adapter *adapter = netdev_priv(netdev);
69256925
struct pci_dev *pdev = to_pci_dev(dev);
6926-
struct e1000_hw *hw = &adapter->hw;
69276926
int rc;
69286927

69296928
e1000e_flush_lpic(pdev);
@@ -6935,7 +6934,7 @@ static __maybe_unused int e1000e_pm_suspend(struct device *dev)
69356934
e1000e_pm_thaw(dev);
69366935
} else {
69376936
/* Introduce S0ix implementation */
6938-
if (hw->mac.type >= e1000_pch_cnp)
6937+
if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS)
69396938
e1000e_s0ix_entry_flow(adapter);
69406939
}
69416940

@@ -6947,11 +6946,10 @@ static __maybe_unused int e1000e_pm_resume(struct device *dev)
69476946
struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
69486947
struct e1000_adapter *adapter = netdev_priv(netdev);
69496948
struct pci_dev *pdev = to_pci_dev(dev);
6950-
struct e1000_hw *hw = &adapter->hw;
69516949
int rc;
69526950

69536951
/* Introduce S0ix implementation */
6954-
if (hw->mac.type >= e1000_pch_cnp)
6952+
if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS)
69556953
e1000e_s0ix_exit_flow(adapter);
69566954

69576955
rc = __e1000_resume(pdev);
@@ -7615,6 +7613,9 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
76157613
if (!(adapter->flags & FLAG_HAS_AMT))
76167614
e1000e_get_hw_control(adapter);
76177615

7616+
if (hw->mac.type >= e1000_pch_cnp)
7617+
adapter->flags2 |= FLAG2_ENABLE_S0IX_FLOWS;
7618+
76187619
strlcpy(netdev->name, "eth%d", sizeof(netdev->name));
76197620
err = register_netdev(netdev);
76207621
if (err)

0 commit comments

Comments
 (0)