netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/6][pull request] Intel Wired LAN Driver Updates 2024-08-30 (igc, e1000e, i40e)
@ 2024-08-30 21:04 Tony Nguyen
  2024-08-30 21:04 ` [PATCH net-next 1/6] igc: Add MQPRIO offload support Tony Nguyen
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Tony Nguyen @ 2024-08-30 21:04 UTC (permalink / raw)
  To: davem, kuba, pabeni, edumazet, netdev; +Cc: Tony Nguyen

This series contains updates to igc, e1000e, and i40 drivers.

Kurt Kanzenbach adds support for MQPRIO offloads and stops unintended,
excess interrupts on igc.

Sasha adds reporting of EEE (Energy Efficient Ethernet) ability and
moves a register define to a better suited file for igc.

Vitaly stops reporting errors on shutdown and suspend as they are not
fatal for e1000e.

Alex adds reporting of EEE to i40e.

The following are changes since commit fbdaffe41adca26cb9566e92060b97cd6dd87b60:
  Merge branch 'am-qt2025-phy-rust'
and are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue 1GbE

Aleksandr Loktionov (1):
  i40e: Add Energy Efficient Ethernet ability for X710 Base-T/KR/KX
    cards

Kurt Kanzenbach (2):
  igc: Add MQPRIO offload support
  igc: Get rid of spurious interrupts

Sasha Neftin (2):
  igc: Add Energy Efficient Ethernet ability
  igc: Move the MULTI GBT AN Control Register to _regs file

Vitaly Lifshits (1):
  e1000e: avoid failing the system during pm_suspend

 drivers/net/ethernet/intel/e1000e/netdev.c    | 19 ++--
 drivers/net/ethernet/intel/i40e/i40e.h        |  1 +
 .../net/ethernet/intel/i40e/i40e_ethtool.c    | 36 ++++++-
 drivers/net/ethernet/intel/i40e/i40e_main.c   | 24 ++++-
 drivers/net/ethernet/intel/igc/igc.h          | 11 ++-
 drivers/net/ethernet/intel/igc/igc_defines.h  | 22 ++++-
 drivers/net/ethernet/intel/igc/igc_ethtool.c  | 77 ++++++++++++++-
 drivers/net/ethernet/intel/igc/igc_main.c     | 99 ++++++++++++++++++-
 drivers/net/ethernet/intel/igc/igc_phy.c      |  4 +-
 drivers/net/ethernet/intel/igc/igc_regs.h     | 12 +++
 drivers/net/ethernet/intel/igc/igc_tsn.c      | 67 +++++++++++++
 11 files changed, 347 insertions(+), 25 deletions(-)

-- 
2.42.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH net-next 1/6] igc: Add MQPRIO offload support
  2024-08-30 21:04 [PATCH net-next 0/6][pull request] Intel Wired LAN Driver Updates 2024-08-30 (igc, e1000e, i40e) Tony Nguyen
@ 2024-08-30 21:04 ` Tony Nguyen
  2024-08-30 21:04 ` [PATCH net-next 2/6] igc: Get rid of spurious interrupts Tony Nguyen
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Tony Nguyen @ 2024-08-30 21:04 UTC (permalink / raw)
  To: davem, kuba, pabeni, edumazet, netdev
  Cc: Kurt Kanzenbach, anthony.l.nguyen, bigeasy, sasha.neftin,
	vitaly.lifshits, dima.ruinskiy, horms, shenjian15,
	Wojciech Drewek, Vinicius Costa Gomes, Mor Bar-Gabay

From: Kurt Kanzenbach <kurt@linutronix.de>

Add support for offloading MQPRIO. The hardware has four priorities as well
as four queues. Each queue must be a assigned with a unique priority.

However, the priorities are only considered in TSN Tx mode. There are two
TSN Tx modes. In case of MQPRIO the Qbv capability is not required.
Therefore, use the legacy TSN Tx mode, which performs strict priority
arbitration.

Example for mqprio with hardware offload:

|tc qdisc replace dev ${INTERFACE} handle 100 parent root mqprio num_tc 4 \
|   map 0 0 0 0 0 1 2 3 0 0 0 0 0 0 0 0 \
|   queues 1@0 1@1 1@2 1@3 \
|   hw 1

The mqprio Qdisc also allows to configure the `preemptible_tcs'. However,
frame preemption is not supported yet.

Tested on Intel i225 and implemented by following data sheet section 7.5.2,
Transmit Scheduling.

Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Mor Bar-Gabay <morx.bar.gabay@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
 drivers/net/ethernet/intel/igc/igc.h         | 10 ++-
 drivers/net/ethernet/intel/igc/igc_defines.h | 11 ++++
 drivers/net/ethernet/intel/igc/igc_ethtool.c |  4 ++
 drivers/net/ethernet/intel/igc/igc_main.c    | 69 ++++++++++++++++++++
 drivers/net/ethernet/intel/igc/igc_regs.h    |  2 +
 drivers/net/ethernet/intel/igc/igc_tsn.c     | 67 +++++++++++++++++++
 6 files changed, 161 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index c38b4d0f00ce..8642d67af6cc 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -259,6 +259,10 @@ struct igc_adapter {
 	 */
 	spinlock_t qbv_tx_lock;
 
+	bool strict_priority_enable;
+	u8 num_tc;
+	u16 queue_per_tc[IGC_MAX_TX_QUEUES];
+
 	/* OS defined structs */
 	struct pci_dev *pdev;
 	/* lock for statistics */
@@ -382,9 +386,11 @@ extern char igc_driver_name[];
 #define IGC_FLAG_RX_LEGACY		BIT(16)
 #define IGC_FLAG_TSN_QBV_ENABLED	BIT(17)
 #define IGC_FLAG_TSN_QAV_ENABLED	BIT(18)
+#define IGC_FLAG_TSN_LEGACY_ENABLED	BIT(19)
 
-#define IGC_FLAG_TSN_ANY_ENABLED \
-	(IGC_FLAG_TSN_QBV_ENABLED | IGC_FLAG_TSN_QAV_ENABLED)
+#define IGC_FLAG_TSN_ANY_ENABLED				\
+	(IGC_FLAG_TSN_QBV_ENABLED | IGC_FLAG_TSN_QAV_ENABLED |	\
+	 IGC_FLAG_TSN_LEGACY_ENABLED)
 
 #define IGC_FLAG_RSS_FIELD_IPV4_UDP	BIT(6)
 #define IGC_FLAG_RSS_FIELD_IPV6_UDP	BIT(7)
diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
index 511384f3ec5c..52fe10b44b35 100644
--- a/drivers/net/ethernet/intel/igc/igc_defines.h
+++ b/drivers/net/ethernet/intel/igc/igc_defines.h
@@ -4,6 +4,8 @@
 #ifndef _IGC_DEFINES_H_
 #define _IGC_DEFINES_H_
 
+#include <linux/bitfield.h>
+
 /* Number of Transmit and Receive Descriptors must be a multiple of 8 */
 #define REQ_TX_DESCRIPTOR_MULTIPLE	8
 #define REQ_RX_DESCRIPTOR_MULTIPLE	8
@@ -553,6 +555,15 @@
 
 #define IGC_MAX_SR_QUEUES		2
 
+#define IGC_TXARB_TXQ_PRIO_0_MASK	GENMASK(1, 0)
+#define IGC_TXARB_TXQ_PRIO_1_MASK	GENMASK(3, 2)
+#define IGC_TXARB_TXQ_PRIO_2_MASK	GENMASK(5, 4)
+#define IGC_TXARB_TXQ_PRIO_3_MASK	GENMASK(7, 6)
+#define IGC_TXARB_TXQ_PRIO_0(x)		FIELD_PREP(IGC_TXARB_TXQ_PRIO_0_MASK, (x))
+#define IGC_TXARB_TXQ_PRIO_1(x)		FIELD_PREP(IGC_TXARB_TXQ_PRIO_1_MASK, (x))
+#define IGC_TXARB_TXQ_PRIO_2(x)		FIELD_PREP(IGC_TXARB_TXQ_PRIO_2_MASK, (x))
+#define IGC_TXARB_TXQ_PRIO_3(x)		FIELD_PREP(IGC_TXARB_TXQ_PRIO_3_MASK, (x))
+
 /* Receive Checksum Control */
 #define IGC_RXCSUM_CRCOFL	0x00000800   /* CRC32 offload enable */
 #define IGC_RXCSUM_PCSD		0x00002000   /* packet checksum disabled */
diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c
index 3d3ef4e1547c..9ecb2cbbe8e5 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -1540,6 +1540,10 @@ static int igc_ethtool_set_channels(struct net_device *netdev,
 	if (ch->other_count != NON_Q_VECTORS)
 		return -EINVAL;
 
+	/* Do not allow channel reconfiguration when mqprio is enabled */
+	if (adapter->strict_priority_enable)
+		return -EINVAL;
+
 	/* Verify the number of channels doesn't exceed hw limits */
 	max_combined = igc_get_max_rss_queues(adapter);
 	if (count > max_combined)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index dfd6c00b4205..96b2f2a37bc3 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -6515,6 +6515,13 @@ static int igc_tc_query_caps(struct igc_adapter *adapter,
 	struct igc_hw *hw = &adapter->hw;
 
 	switch (base->type) {
+	case TC_SETUP_QDISC_MQPRIO: {
+		struct tc_mqprio_caps *caps = base->caps;
+
+		caps->validate_queue_counts = true;
+
+		return 0;
+	}
 	case TC_SETUP_QDISC_TAPRIO: {
 		struct tc_taprio_caps *caps = base->caps;
 
@@ -6532,6 +6539,65 @@ static int igc_tc_query_caps(struct igc_adapter *adapter,
 	}
 }
 
+static void igc_save_mqprio_params(struct igc_adapter *adapter, u8 num_tc,
+				   u16 *offset)
+{
+	int i;
+
+	adapter->strict_priority_enable = true;
+	adapter->num_tc = num_tc;
+
+	for (i = 0; i < num_tc; i++)
+		adapter->queue_per_tc[i] = offset[i];
+}
+
+static int igc_tsn_enable_mqprio(struct igc_adapter *adapter,
+				 struct tc_mqprio_qopt_offload *mqprio)
+{
+	struct igc_hw *hw = &adapter->hw;
+	int i;
+
+	if (hw->mac.type != igc_i225)
+		return -EOPNOTSUPP;
+
+	if (!mqprio->qopt.num_tc) {
+		adapter->strict_priority_enable = false;
+		goto apply;
+	}
+
+	/* There are as many TCs as Tx queues. */
+	if (mqprio->qopt.num_tc != adapter->num_tx_queues) {
+		NL_SET_ERR_MSG_FMT_MOD(mqprio->extack,
+				       "Only %d traffic classes supported",
+				       adapter->num_tx_queues);
+		return -EOPNOTSUPP;
+	}
+
+	/* Only one queue per TC is supported. */
+	for (i = 0; i < mqprio->qopt.num_tc; i++) {
+		if (mqprio->qopt.count[i] != 1) {
+			NL_SET_ERR_MSG_MOD(mqprio->extack,
+					   "Only one queue per TC supported");
+			return -EOPNOTSUPP;
+		}
+	}
+
+	/* Preemption is not supported yet. */
+	if (mqprio->preemptible_tcs) {
+		NL_SET_ERR_MSG_MOD(mqprio->extack,
+				   "Preemption is not supported yet");
+		return -EOPNOTSUPP;
+	}
+
+	igc_save_mqprio_params(adapter, mqprio->qopt.num_tc,
+			       mqprio->qopt.offset);
+
+	mqprio->qopt.hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+
+apply:
+	return igc_tsn_offload_apply(adapter);
+}
+
 static int igc_setup_tc(struct net_device *dev, enum tc_setup_type type,
 			void *type_data)
 {
@@ -6551,6 +6617,9 @@ static int igc_setup_tc(struct net_device *dev, enum tc_setup_type type,
 	case TC_SETUP_QDISC_CBS:
 		return igc_tsn_enable_cbs(adapter, type_data);
 
+	case TC_SETUP_QDISC_MQPRIO:
+		return igc_tsn_enable_mqprio(adapter, type_data);
+
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h
index e5b893fc5b66..c83c723f7c7e 100644
--- a/drivers/net/ethernet/intel/igc/igc_regs.h
+++ b/drivers/net/ethernet/intel/igc/igc_regs.h
@@ -238,6 +238,8 @@
 #define IGC_TQAVCC(_n)		(0x3004 + ((_n) * 0x40))
 #define IGC_TQAVHC(_n)		(0x300C + ((_n) * 0x40))
 
+#define IGC_TXARB		0x3354 /* Tx Arbitration Control TxARB - RW */
+
 /* System Time Registers */
 #define IGC_SYSTIML	0x0B600  /* System time register Low - RO */
 #define IGC_SYSTIMH	0x0B604  /* System time register High - RO */
diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c
index d68fa7f3d5f0..1e44374ca1ff 100644
--- a/drivers/net/ethernet/intel/igc/igc_tsn.c
+++ b/drivers/net/ethernet/intel/igc/igc_tsn.c
@@ -46,6 +46,9 @@ static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter)
 	if (is_cbs_enabled(adapter))
 		new_flags |= IGC_FLAG_TSN_QAV_ENABLED;
 
+	if (adapter->strict_priority_enable)
+		new_flags |= IGC_FLAG_TSN_LEGACY_ENABLED;
+
 	return new_flags;
 }
 
@@ -102,11 +105,32 @@ bool igc_tsn_is_taprio_activated_by_user(struct igc_adapter *adapter)
 		adapter->taprio_offload_enable;
 }
 
+static void igc_tsn_tx_arb(struct igc_adapter *adapter, u16 *queue_per_tc)
+{
+	struct igc_hw *hw = &adapter->hw;
+	u32 txarb;
+
+	txarb = rd32(IGC_TXARB);
+
+	txarb &= ~(IGC_TXARB_TXQ_PRIO_0_MASK |
+		   IGC_TXARB_TXQ_PRIO_1_MASK |
+		   IGC_TXARB_TXQ_PRIO_2_MASK |
+		   IGC_TXARB_TXQ_PRIO_3_MASK);
+
+	txarb |= IGC_TXARB_TXQ_PRIO_0(queue_per_tc[3]);
+	txarb |= IGC_TXARB_TXQ_PRIO_1(queue_per_tc[2]);
+	txarb |= IGC_TXARB_TXQ_PRIO_2(queue_per_tc[1]);
+	txarb |= IGC_TXARB_TXQ_PRIO_3(queue_per_tc[0]);
+
+	wr32(IGC_TXARB, txarb);
+}
+
 /* Returns the TSN specific registers to their default values after
  * the adapter is reset.
  */
 static int igc_tsn_disable_offload(struct igc_adapter *adapter)
 {
+	u16 queue_per_tc[4] = { 3, 2, 1, 0 };
 	struct igc_hw *hw = &adapter->hw;
 	u32 tqavctrl;
 	int i;
@@ -133,7 +157,16 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter)
 	wr32(IGC_QBVCYCLET_S, 0);
 	wr32(IGC_QBVCYCLET, NSEC_PER_SEC);
 
+	/* Reset mqprio TC configuration. */
+	netdev_reset_tc(adapter->netdev);
+
+	/* Restore the default Tx arbitration: Priority 0 has the highest
+	 * priority and is assigned to queue 0 and so on and so forth.
+	 */
+	igc_tsn_tx_arb(adapter, queue_per_tc);
+
 	adapter->flags &= ~IGC_FLAG_TSN_QBV_ENABLED;
+	adapter->flags &= ~IGC_FLAG_TSN_LEGACY_ENABLED;
 
 	return 0;
 }
@@ -172,6 +205,40 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)
 	if (igc_is_device_id_i226(hw))
 		igc_tsn_set_retx_qbvfullthreshold(adapter);
 
+	if (adapter->strict_priority_enable) {
+		int err;
+
+		err = netdev_set_num_tc(adapter->netdev, adapter->num_tc);
+		if (err)
+			return err;
+
+		for (i = 0; i < adapter->num_tc; i++) {
+			err = netdev_set_tc_queue(adapter->netdev, i, 1,
+						  adapter->queue_per_tc[i]);
+			if (err)
+				return err;
+		}
+
+		/* In case the card is configured with less than four queues. */
+		for (; i < IGC_MAX_TX_QUEUES; i++)
+			adapter->queue_per_tc[i] = i;
+
+		/* Configure queue priorities according to the user provided
+		 * mapping.
+		 */
+		igc_tsn_tx_arb(adapter, adapter->queue_per_tc);
+
+		/* Enable legacy TSN mode which will do strict priority without
+		 * any other TSN features.
+		 */
+		tqavctrl = rd32(IGC_TQAVCTRL);
+		tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN;
+		tqavctrl &= ~IGC_TQAVCTRL_ENHANCED_QAV;
+		wr32(IGC_TQAVCTRL, tqavctrl);
+
+		return 0;
+	}
+
 	for (i = 0; i < adapter->num_tx_queues; i++) {
 		struct igc_ring *ring = adapter->tx_ring[i];
 		u32 txqctl = 0;
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 2/6] igc: Get rid of spurious interrupts
  2024-08-30 21:04 [PATCH net-next 0/6][pull request] Intel Wired LAN Driver Updates 2024-08-30 (igc, e1000e, i40e) Tony Nguyen
  2024-08-30 21:04 ` [PATCH net-next 1/6] igc: Add MQPRIO offload support Tony Nguyen
@ 2024-08-30 21:04 ` Tony Nguyen
  2024-09-05  6:16   ` Ruinskiy, Dima
  2024-08-30 21:04 ` [PATCH net-next 3/6] igc: Add Energy Efficient Ethernet ability Tony Nguyen
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Tony Nguyen @ 2024-08-30 21:04 UTC (permalink / raw)
  To: davem, kuba, pabeni, edumazet, netdev
  Cc: Kurt Kanzenbach, anthony.l.nguyen, sasha.neftin, vitaly.lifshits,
	dima.ruinskiy, maciej.fijalkowski, magnus.karlsson, ast, daniel,
	hawk, john.fastabend, bpf, bigeasy, Vinicius Costa Gomes,
	Simon Horman, Mor Bar-Gabay

From: Kurt Kanzenbach <kurt@linutronix.de>

When running the igc with XDP/ZC in busy polling mode with deferral of hard
interrupts, interrupts still happen from time to time. That is caused by
the igc task watchdog which triggers Rx interrupts periodically.

That mechanism has been introduced to overcome skb/memory allocation
failures [1]. So the Rx clean functions stop processing the Rx ring in case
of such failure. The task watchdog triggers Rx interrupts periodically in
the hope that memory became available in the mean time.

The current behavior is undesirable for real time applications, because the
driver induced Rx interrupts trigger also the softirq processing. However,
all real time packets should be processed by the application which uses the
busy polling method.

Therefore, only trigger the Rx interrupts in case of real allocation
failures. Introduce a new flag for signaling that condition.

[1] - https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/?id=3be507547e6177e5c808544bd6a2efa2c7f1d436

Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Acked-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Mor Bar-Gabay <morx.bar.gabay@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
 drivers/net/ethernet/intel/igc/igc.h      |  1 +
 drivers/net/ethernet/intel/igc/igc_main.c | 30 ++++++++++++++++++++---
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index 8642d67af6cc..eac0f966e0e4 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -687,6 +687,7 @@ enum igc_ring_flags_t {
 	IGC_RING_FLAG_TX_DETECT_HANG,
 	IGC_RING_FLAG_AF_XDP_ZC,
 	IGC_RING_FLAG_TX_HWTSTAMP,
+	IGC_RING_FLAG_RX_ALLOC_FAILED,
 };
 
 #define ring_uses_large_buffer(ring) \
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 96b2f2a37bc3..da322899e834 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -2191,6 +2191,7 @@ static bool igc_alloc_mapped_page(struct igc_ring *rx_ring,
 	page = dev_alloc_pages(igc_rx_pg_order(rx_ring));
 	if (unlikely(!page)) {
 		rx_ring->rx_stats.alloc_failed++;
+		set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
 		return false;
 	}
 
@@ -2207,6 +2208,7 @@ static bool igc_alloc_mapped_page(struct igc_ring *rx_ring,
 		__free_page(page);
 
 		rx_ring->rx_stats.alloc_failed++;
+		set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
 		return false;
 	}
 
@@ -2658,6 +2660,7 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
 		if (!skb) {
 			rx_ring->rx_stats.alloc_failed++;
 			rx_buffer->pagecnt_bias++;
+			set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
 			break;
 		}
 
@@ -2738,6 +2741,7 @@ static void igc_dispatch_skb_zc(struct igc_q_vector *q_vector,
 	skb = igc_construct_skb_zc(ring, xdp);
 	if (!skb) {
 		ring->rx_stats.alloc_failed++;
+		set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &ring->flags);
 		return;
 	}
 
@@ -5807,11 +5811,29 @@ static void igc_watchdog_task(struct work_struct *work)
 	if (adapter->flags & IGC_FLAG_HAS_MSIX) {
 		u32 eics = 0;
 
-		for (i = 0; i < adapter->num_q_vectors; i++)
-			eics |= adapter->q_vector[i]->eims_value;
-		wr32(IGC_EICS, eics);
+		for (i = 0; i < adapter->num_q_vectors; i++) {
+			struct igc_q_vector *q_vector = adapter->q_vector[i];
+			struct igc_ring *rx_ring;
+
+			if (!q_vector->rx.ring)
+				continue;
+
+			rx_ring = adapter->rx_ring[q_vector->rx.ring->queue_index];
+
+			if (test_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags)) {
+				eics |= q_vector->eims_value;
+				clear_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
+			}
+		}
+		if (eics)
+			wr32(IGC_EICS, eics);
 	} else {
-		wr32(IGC_ICS, IGC_ICS_RXDMT0);
+		struct igc_ring *rx_ring = adapter->rx_ring[0];
+
+		if (test_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags)) {
+			clear_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
+			wr32(IGC_ICS, IGC_ICS_RXDMT0);
+		}
 	}
 
 	igc_ptp_tx_hang(adapter);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 3/6] igc: Add Energy Efficient Ethernet ability
  2024-08-30 21:04 [PATCH net-next 0/6][pull request] Intel Wired LAN Driver Updates 2024-08-30 (igc, e1000e, i40e) Tony Nguyen
  2024-08-30 21:04 ` [PATCH net-next 1/6] igc: Add MQPRIO offload support Tony Nguyen
  2024-08-30 21:04 ` [PATCH net-next 2/6] igc: Get rid of spurious interrupts Tony Nguyen
@ 2024-08-30 21:04 ` Tony Nguyen
  2024-09-03 19:49   ` Jakub Kicinski
  2024-08-30 21:04 ` [PATCH net-next 4/6] igc: Move the MULTI GBT AN Control Register to _regs file Tony Nguyen
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Tony Nguyen @ 2024-08-30 21:04 UTC (permalink / raw)
  To: davem, kuba, pabeni, edumazet, netdev
  Cc: Sasha Neftin, anthony.l.nguyen, vitaly.lifshits, dima.ruinskiy,
	Avigail Dahan

From: Sasha Neftin <sasha.neftin@intel.com>

According to the IEEE standard report the EEE ability (registers 7.60 and
7.62) and the EEE Link Partner ability (registers 7.61 and 7.63). Use the
kernel's 'ethtool_keee' structure and report EEE link modes.

Example:
ethtool --show-eee <device>

Before:
Advertised EEE link modes:  Not reported
Link partner advertised EEE link modes:  Not reported

After:
	Advertised EEE link modes:  100baseT/Full
	                            1000baseT/Full
	                            2500baseT/Full
	Link partner advertised EEE link modes:  100baseT/Full
	                                         1000baseT/Full
	                                         2500baseT/Full

Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
Tested-by: Avigail Dahan <avigailx.dahan@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
 drivers/net/ethernet/intel/igc/igc_defines.h | 10 +++
 drivers/net/ethernet/intel/igc/igc_ethtool.c | 73 +++++++++++++++++++-
 drivers/net/ethernet/intel/igc/igc_regs.h    |  7 ++
 3 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
index 52fe10b44b35..6d6717ba4ffd 100644
--- a/drivers/net/ethernet/intel/igc/igc_defines.h
+++ b/drivers/net/ethernet/intel/igc/igc_defines.h
@@ -652,6 +652,16 @@
 #define IGC_MDIC_READY		0x10000000
 #define IGC_MDIC_ERROR		0x40000000
 
+/* EEE Link Ability */
+#define IGC_EEE_2500BT_MASK	BIT(0)
+#define IGC_EEE_1000BT_MASK	BIT(2)
+#define IGC_EEE_100BT_MASK	BIT(1)
+
+/* EEE Link-Partner Ability */
+#define IGC_LP_EEE_2500BT_MASK	BIT(0)
+#define IGC_LP_EEE_1000BT_MASK	BIT(2)
+#define IGC_LP_EEE_100BT_MASK	BIT(1)
+
 #define IGC_N0_QUEUE		-1
 
 #define IGC_MAX_MAC_HDR_LEN	127
diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c
index 9ecb2cbbe8e5..457b5d7f1610 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -1631,8 +1631,11 @@ static int igc_ethtool_get_eee(struct net_device *netdev,
 {
 	struct igc_adapter *adapter = netdev_priv(netdev);
 	struct igc_hw *hw = &adapter->hw;
-	u32 eeer;
+	struct igc_phy_info *phy = &hw->phy;
+	u16 eee_advert, eee_lp_advert;
+	u32 eeer, ret_val;
 
+	/* EEE supported */
 	linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
 			 edata->supported);
 	linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
@@ -1640,6 +1643,74 @@ static int igc_ethtool_get_eee(struct net_device *netdev,
 	linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
 			 edata->supported);
 
+	/* EEE Advertisement 1 - reg 7.60 */
+	ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
+				    MMD_DEVADDR_SHIFT) |
+				    IGC_ANEG_EEE_AB1,
+				    &eee_advert);
+	if (ret_val) {
+		netdev_err(adapter->netdev,
+			   "Failed to read IEEE 7.60 register\n");
+		return -EINVAL;
+	}
+
+	if (eee_advert & IGC_EEE_1000BT_MASK)
+		linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+				 edata->advertised);
+
+	if (eee_advert & IGC_EEE_100BT_MASK)
+		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+				 edata->advertised);
+
+	/* EEE Advertisement 2 - reg 7.62 */
+	ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
+				    MMD_DEVADDR_SHIFT) |
+				    IGC_ANEG_EEE_AB2,
+				    &eee_advert);
+	if (ret_val) {
+		netdev_err(adapter->netdev,
+			   "Failed to read IEEE 7.62 register\n");
+		return -EINVAL;
+	}
+
+	if (eee_advert & IGC_EEE_2500BT_MASK)
+		linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+				 edata->advertised);
+
+	/* EEE Link-Partner Ability 1 - reg 7.61 */
+	ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
+				    MMD_DEVADDR_SHIFT) |
+				    IGC_ANEG_EEE_LP_AB1,
+				    &eee_lp_advert);
+	if (ret_val) {
+		netdev_err(adapter->netdev,
+			   "Failed to read IEEE 7.61 register\n");
+		return -EINVAL;
+	}
+
+	if (eee_lp_advert & IGC_LP_EEE_1000BT_MASK)
+		linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+				 edata->lp_advertised);
+
+	if (eee_lp_advert & IGC_LP_EEE_100BT_MASK)
+		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+				 edata->lp_advertised);
+
+	/* EEE Link-Partner Ability 2 - reg 7.63 */
+	ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
+				    MMD_DEVADDR_SHIFT) |
+				    IGC_ANEG_EEE_LP_AB2,
+				    &eee_lp_advert);
+	if (ret_val) {
+		netdev_err(adapter->netdev,
+			   "Failed to read IEEE 7.63 register\n");
+		return -EINVAL;
+	}
+
+	if (eee_lp_advert & IGC_LP_EEE_2500BT_MASK)
+		linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+				 edata->lp_advertised);
+
 	eeer = rd32(IGC_EEER);
 
 	/* EEE status on negotiated link */
diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h
index c83c723f7c7e..bb6f37f5d3a5 100644
--- a/drivers/net/ethernet/intel/igc/igc_regs.h
+++ b/drivers/net/ethernet/intel/igc/igc_regs.h
@@ -310,6 +310,13 @@
 #define IGC_IPCNFG	0x0E38 /* Internal PHY Configuration */
 #define IGC_EEE_SU	0x0E34 /* EEE Setup */
 
+/* EEE ANeg Advertisement Register - reg 7.60 and reg 7.62 */
+#define IGC_ANEG_EEE_AB1	0x003c
+#define IGC_ANEG_EEE_AB2	0x003e
+/* EEE ANeg Link-Partner Advertisement Register - reg 7.61 and reg 7.63 */
+#define IGC_ANEG_EEE_LP_AB1	0x003d
+#define IGC_ANEG_EEE_LP_AB2	0x003f
+
 /* LTR registers */
 #define IGC_LTRC	0x01A0 /* Latency Tolerance Reporting Control */
 #define IGC_LTRMINV	0x5BB0 /* LTR Minimum Value */
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 4/6] igc: Move the MULTI GBT AN Control Register to _regs file
  2024-08-30 21:04 [PATCH net-next 0/6][pull request] Intel Wired LAN Driver Updates 2024-08-30 (igc, e1000e, i40e) Tony Nguyen
                   ` (2 preceding siblings ...)
  2024-08-30 21:04 ` [PATCH net-next 3/6] igc: Add Energy Efficient Ethernet ability Tony Nguyen
@ 2024-08-30 21:04 ` Tony Nguyen
  2024-08-30 21:04 ` [PATCH net-next 5/6] e1000e: avoid failing the system during pm_suspend Tony Nguyen
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Tony Nguyen @ 2024-08-30 21:04 UTC (permalink / raw)
  To: davem, kuba, pabeni, edumazet, netdev
  Cc: Sasha Neftin, anthony.l.nguyen, vitaly.lifshits, dima.ruinskiy,
	Paul Menzel, Avigail Dahan

From: Sasha Neftin <sasha.neftin@intel.com>

MULTI GBT AN Control Register is IEEE Standard Register 7.32 (not a mask).
The right place should be in igc_reg.h file. In accordance with the
registers naming convention added IGC_' prefix.

Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Tested-by: Avigail Dahan <avigailx.dahan@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
 drivers/net/ethernet/intel/igc/igc_defines.h | 1 -
 drivers/net/ethernet/intel/igc/igc_phy.c     | 4 ++--
 drivers/net/ethernet/intel/igc/igc_regs.h    | 3 +++
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
index 6d6717ba4ffd..8e449904aa7d 100644
--- a/drivers/net/ethernet/intel/igc/igc_defines.h
+++ b/drivers/net/ethernet/intel/igc/igc_defines.h
@@ -178,7 +178,6 @@
 
 /* PHY GPY 211 registers */
 #define STANDARD_AN_REG_MASK	0x0007 /* MMD */
-#define ANEG_MULTIGBT_AN_CTRL	0x0020 /* MULTI GBT AN Control Register */
 #define MMD_DEVADDR_SHIFT	16     /* Shift MMD to higher bits */
 #define CR_2500T_FD_CAPS	0x0080 /* Advertise 2500T FD capability */
 
diff --git a/drivers/net/ethernet/intel/igc/igc_phy.c b/drivers/net/ethernet/intel/igc/igc_phy.c
index 861f37076861..2801e5f24df9 100644
--- a/drivers/net/ethernet/intel/igc/igc_phy.c
+++ b/drivers/net/ethernet/intel/igc/igc_phy.c
@@ -240,7 +240,7 @@ static s32 igc_phy_setup_autoneg(struct igc_hw *hw)
 		/* Read the MULTI GBT AN Control Register - reg 7.32 */
 		ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
 					    MMD_DEVADDR_SHIFT) |
-					    ANEG_MULTIGBT_AN_CTRL,
+					    IGC_ANEG_MULTIGBT_AN_CTRL,
 					    &aneg_multigbt_an_ctrl);
 
 		if (ret_val)
@@ -380,7 +380,7 @@ static s32 igc_phy_setup_autoneg(struct igc_hw *hw)
 		ret_val = phy->ops.write_reg(hw,
 					     (STANDARD_AN_REG_MASK <<
 					     MMD_DEVADDR_SHIFT) |
-					     ANEG_MULTIGBT_AN_CTRL,
+					     IGC_ANEG_MULTIGBT_AN_CTRL,
 					     aneg_multigbt_an_ctrl);
 
 	return ret_val;
diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h
index bb6f37f5d3a5..12ddc5793651 100644
--- a/drivers/net/ethernet/intel/igc/igc_regs.h
+++ b/drivers/net/ethernet/intel/igc/igc_regs.h
@@ -310,6 +310,9 @@
 #define IGC_IPCNFG	0x0E38 /* Internal PHY Configuration */
 #define IGC_EEE_SU	0x0E34 /* EEE Setup */
 
+/* MULTI GBT AN Control Register - reg. 7.32 */
+#define IGC_ANEG_MULTIGBT_AN_CTRL	0x0020
+
 /* EEE ANeg Advertisement Register - reg 7.60 and reg 7.62 */
 #define IGC_ANEG_EEE_AB1	0x003c
 #define IGC_ANEG_EEE_AB2	0x003e
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 5/6] e1000e: avoid failing the system during pm_suspend
  2024-08-30 21:04 [PATCH net-next 0/6][pull request] Intel Wired LAN Driver Updates 2024-08-30 (igc, e1000e, i40e) Tony Nguyen
                   ` (3 preceding siblings ...)
  2024-08-30 21:04 ` [PATCH net-next 4/6] igc: Move the MULTI GBT AN Control Register to _regs file Tony Nguyen
@ 2024-08-30 21:04 ` Tony Nguyen
  2024-08-30 21:04 ` [PATCH net-next 6/6] i40e: Add Energy Efficient Ethernet ability for X710 Base-T/KR/KX cards Tony Nguyen
  2024-09-03 20:40 ` [PATCH net-next 0/6][pull request] Intel Wired LAN Driver Updates 2024-08-30 (igc, e1000e, i40e) patchwork-bot+netdevbpf
  6 siblings, 0 replies; 12+ messages in thread
From: Tony Nguyen @ 2024-08-30 21:04 UTC (permalink / raw)
  To: davem, kuba, pabeni, edumazet, netdev
  Cc: Vitaly Lifshits, anthony.l.nguyen, sasha.neftin, dima.ruinskiy,
	Mor Bar-Gabay

From: Vitaly Lifshits <vitaly.lifshits@intel.com>

Occasionally when the system goes into pm_suspend, the suspend might fail
due to a PHY access error on the network adapter. Previously, this would
have caused the whole system to fail to go to a low power state.
An example of this was reported in the following Bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=205015

[ 1663.694828] e1000e 0000:00:19.0 eth0: Failed to disable ULP
[ 1664.731040] asix 2-3:1.0 eth1: link up, 100Mbps, full-duplex, lpa 0xC1E1
[ 1665.093513] e1000e 0000:00:19.0 eth0: Hardware Error
[ 1665.596760] e1000e 0000:00:19.0: pci_pm_resume+0x0/0x80 returned 0 after 2975399 usecs

and then the system never recovers from it, and all the following suspend failed due to this
[22909.393854] PM: pci_pm_suspend(): e1000e_pm_suspend+0x0/0x760 [e1000e] returns -2
[22909.393858] PM: dpm_run_callback(): pci_pm_suspend+0x0/0x160 returns -2
[22909.393861] PM: Device 0000:00:1f.6 failed to suspend async: error -2

This can be avoided by changing the return values of __e1000_shutdown and
e1000e_pm_suspend functions so that they always return 0 (success). This
is consistent with what other drivers do.

If the e1000e driver encounters a hardware error during suspend, potential
side effects include slightly higher power draw or non-working wake on
LAN. This is preferred to a system-level suspend failure, and a warning
message is written to the system log, so that the user can be aware that
the LAN controller experienced a problem during suspend.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=205015
Suggested-by: Dima Ruinskiy <dima.ruinskiy@intel.com>
Signed-off-by: Vitaly Lifshits <vitaly.lifshits@intel.com>
Tested-by: Mor Bar-Gabay <morx.bar.gabay@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
 drivers/net/ethernet/intel/e1000e/netdev.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 360ee26557f7..f103249b12fa 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -6671,8 +6671,10 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
 		if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
 			/* enable wakeup by the PHY */
 			retval = e1000_init_phy_wakeup(adapter, wufc);
-			if (retval)
-				return retval;
+			if (retval) {
+				e_err("Failed to enable wakeup\n");
+				goto skip_phy_configurations;
+			}
 		} else {
 			/* enable wakeup by the MAC */
 			ew32(WUFC, wufc);
@@ -6693,8 +6695,10 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
 			 * or broadcast.
 			 */
 			retval = e1000_enable_ulp_lpt_lp(hw, !runtime);
-			if (retval)
-				return retval;
+			if (retval) {
+				e_err("Failed to enable ULP\n");
+				goto skip_phy_configurations;
+			}
 		}
 	}
 
@@ -6726,6 +6730,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
 		hw->phy.ops.release(hw);
 	}
 
+skip_phy_configurations:
 	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
 	 * would have already happened in close and is redundant.
 	 */
@@ -6968,15 +6973,13 @@ static int e1000e_pm_suspend(struct device *dev)
 	e1000e_pm_freeze(dev);
 
 	rc = __e1000_shutdown(pdev, false);
-	if (rc) {
-		e1000e_pm_thaw(dev);
-	} else {
+	if (!rc) {
 		/* Introduce S0ix implementation */
 		if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS)
 			e1000e_s0ix_entry_flow(adapter);
 	}
 
-	return rc;
+	return 0;
 }
 
 static int e1000e_pm_resume(struct device *dev)
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 6/6] i40e: Add Energy Efficient Ethernet ability for X710 Base-T/KR/KX cards
  2024-08-30 21:04 [PATCH net-next 0/6][pull request] Intel Wired LAN Driver Updates 2024-08-30 (igc, e1000e, i40e) Tony Nguyen
                   ` (4 preceding siblings ...)
  2024-08-30 21:04 ` [PATCH net-next 5/6] e1000e: avoid failing the system during pm_suspend Tony Nguyen
@ 2024-08-30 21:04 ` Tony Nguyen
  2024-09-03 20:40 ` [PATCH net-next 0/6][pull request] Intel Wired LAN Driver Updates 2024-08-30 (igc, e1000e, i40e) patchwork-bot+netdevbpf
  6 siblings, 0 replies; 12+ messages in thread
From: Tony Nguyen @ 2024-08-30 21:04 UTC (permalink / raw)
  To: davem, kuba, pabeni, edumazet, netdev
  Cc: Aleksandr Loktionov, anthony.l.nguyen, Arkadiusz Kubalewski,
	Jacob Keller, Simon Horman, Pucha Himasekhar Reddy

From: Aleksandr Loktionov <aleksandr.loktionov@intel.com>

Add "EEE: Enabled/Disabled" to dmesg for supported X710 Base-T/KR/KX
cards. According to the IEEE standard report the EEE ability and the
EEE Link Partner ability. Use the kernel's 'ethtool_keee' structure
and report EEE link modes.

Example:
dmesg | grep 'NIC Link is'
ethtool --show-eee <device>

Before:
	NIC Link is Up, 10 Gbps Full Duplex, Flow Control: None

        Supported EEE link modes:  Not reported
        Advertised EEE link modes:  Not reported
        Link partner advertised EEE link modes:  Not reported

After:
	NIC Link is Up, 10 Gbps Full Duplex, Flow Control: None, EEE: Enabled

        Supported EEE link modes:  100baseT/Full
                                   1000baseT/Full
                                   10000baseT/Full
        Advertised EEE link modes:  100baseT/Full
                                    1000baseT/Full
                                    10000baseT/Full
        Link partner advertised EEE link modes:  100baseT/Full
                                                 1000baseT/Full
                                                 10000baseT/Full

Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e.h        |  1 +
 .../net/ethernet/intel/i40e/i40e_ethtool.c    | 36 ++++++++++++++++---
 drivers/net/ethernet/intel/i40e/i40e_main.c   | 24 +++++++++++--
 3 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index d546567e0286..2089a0e172bf 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -4,6 +4,7 @@
 #ifndef _I40E_H_
 #define _I40E_H_
 
+#include <linux/linkmode.h>
 #include <linux/pci.h>
 #include <linux/ptp_clock_kernel.h>
 #include <linux/types.h>
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 1d0d2e526adb..3a6bece623f4 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -5641,6 +5641,26 @@ static int i40e_get_module_eeprom(struct net_device *netdev,
 	return 0;
 }
 
+static void i40e_eee_capability_to_kedata_supported(__le16 eee_capability_,
+						    unsigned long *supported)
+{
+	const int eee_capability = le16_to_cpu(eee_capability_);
+	static const int lut[] = {
+		ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+		ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+		ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+		ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+		ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
+		ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
+		ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
+	};
+
+	linkmode_zero(supported);
+	for (unsigned int i = ARRAY_SIZE(lut); i--; )
+		if (eee_capability & BIT(i + 1))
+			linkmode_set_bit(lut[i], supported);
+}
+
 static int i40e_get_eee(struct net_device *netdev, struct ethtool_keee *edata)
 {
 	struct i40e_netdev_priv *np = netdev_priv(netdev);
@@ -5648,7 +5668,7 @@ static int i40e_get_eee(struct net_device *netdev, struct ethtool_keee *edata)
 	struct i40e_vsi *vsi = np->vsi;
 	struct i40e_pf *pf = vsi->back;
 	struct i40e_hw *hw = &pf->hw;
-	int status = 0;
+	int status;
 
 	/* Get initial PHY capabilities */
 	status = i40e_aq_get_phy_capabilities(hw, false, true, &phy_cfg, NULL);
@@ -5661,11 +5681,18 @@ static int i40e_get_eee(struct net_device *netdev, struct ethtool_keee *edata)
 	if (phy_cfg.eee_capability == 0)
 		return -EOPNOTSUPP;
 
+	i40e_eee_capability_to_kedata_supported(phy_cfg.eee_capability,
+						edata->supported);
+	linkmode_copy(edata->lp_advertised, edata->supported);
+
 	/* Get current configuration */
 	status = i40e_aq_get_phy_capabilities(hw, false, false, &phy_cfg, NULL);
 	if (status)
 		return -EAGAIN;
 
+	linkmode_zero(edata->advertised);
+	if (phy_cfg.eee_capability)
+		linkmode_copy(edata->advertised, edata->supported);
 	edata->eee_enabled = !!phy_cfg.eee_capability;
 	edata->tx_lpi_enabled = pf->stats.tx_lpi_status;
 
@@ -5681,10 +5708,11 @@ static int i40e_is_eee_param_supported(struct net_device *netdev,
 	struct i40e_vsi *vsi = np->vsi;
 	struct i40e_pf *pf = vsi->back;
 	struct i40e_ethtool_not_used {
-		u32 value;
+		bool value;
 		const char *name;
 	} param[] = {
-		{edata->tx_lpi_timer, "tx-timer"},
+		{!!(edata->advertised[0] & ~edata->supported[0]), "advertise"},
+		{!!edata->tx_lpi_timer, "tx-timer"},
 		{edata->tx_lpi_enabled != pf->stats.tx_lpi_status, "tx-lpi"}
 	};
 	int i;
@@ -5710,7 +5738,7 @@ static int i40e_set_eee(struct net_device *netdev, struct ethtool_keee *edata)
 	struct i40e_pf *pf = vsi->back;
 	struct i40e_hw *hw = &pf->hw;
 	__le16 eee_capability;
-	int status = 0;
+	int status;
 
 	/* Deny parameters we don't support */
 	if (i40e_is_eee_param_supported(netdev, edata))
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index cbcfada7b357..03205eb9f925 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -7264,6 +7264,26 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf)
 }
 #endif /* CONFIG_I40E_DCB */
 
+static void i40e_print_link_message_eee(struct i40e_vsi *vsi,
+					const char *speed, const char *fc)
+{
+	struct ethtool_keee kedata;
+
+	memzero_explicit(&kedata, sizeof(kedata));
+	if (vsi->netdev->ethtool_ops->get_eee)
+		vsi->netdev->ethtool_ops->get_eee(vsi->netdev, &kedata);
+
+	if (!linkmode_empty(kedata.supported))
+		netdev_info(vsi->netdev,
+			    "NIC Link is Up, %sbps Full Duplex, Flow Control: %s, EEE: %s\n",
+			    speed, fc,
+			    kedata.eee_enabled ? "Enabled" : "Disabled");
+	else
+		netdev_info(vsi->netdev,
+			    "NIC Link is Up, %sbps Full Duplex, Flow Control: %s\n",
+			    speed, fc);
+}
+
 /**
  * i40e_print_link_message - print link up or down
  * @vsi: the VSI for which link needs a message
@@ -7395,9 +7415,7 @@ void i40e_print_link_message(struct i40e_vsi *vsi, bool isup)
 			    "NIC Link is Up, %sbps Full Duplex, Requested FEC: %s, Negotiated FEC: %s, Autoneg: %s, Flow Control: %s\n",
 			    speed, req_fec, fec, an, fc);
 	} else {
-		netdev_info(vsi->netdev,
-			    "NIC Link is Up, %sbps Full Duplex, Flow Control: %s\n",
-			    speed, fc);
+		i40e_print_link_message_eee(vsi, speed, fc);
 	}
 
 }
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 3/6] igc: Add Energy Efficient Ethernet ability
  2024-08-30 21:04 ` [PATCH net-next 3/6] igc: Add Energy Efficient Ethernet ability Tony Nguyen
@ 2024-09-03 19:49   ` Jakub Kicinski
  2024-09-05  7:07     ` Lifshits, Vitaly
  0 siblings, 1 reply; 12+ messages in thread
From: Jakub Kicinski @ 2024-09-03 19:49 UTC (permalink / raw)
  To: Tony Nguyen
  Cc: davem, pabeni, edumazet, netdev, Sasha Neftin, vitaly.lifshits,
	dima.ruinskiy, Avigail Dahan

On Fri, 30 Aug 2024 14:04:45 -0700 Tony Nguyen wrote:
> Example:
> ethtool --show-eee <device>

You're only adding get support or am I misreading?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 0/6][pull request] Intel Wired LAN Driver Updates 2024-08-30 (igc, e1000e, i40e)
  2024-08-30 21:04 [PATCH net-next 0/6][pull request] Intel Wired LAN Driver Updates 2024-08-30 (igc, e1000e, i40e) Tony Nguyen
                   ` (5 preceding siblings ...)
  2024-08-30 21:04 ` [PATCH net-next 6/6] i40e: Add Energy Efficient Ethernet ability for X710 Base-T/KR/KX cards Tony Nguyen
@ 2024-09-03 20:40 ` patchwork-bot+netdevbpf
  6 siblings, 0 replies; 12+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-09-03 20:40 UTC (permalink / raw)
  To: Tony Nguyen; +Cc: davem, kuba, pabeni, edumazet, netdev

Hello:

This series was applied to netdev/net-next.git (main)
by Tony Nguyen <anthony.l.nguyen@intel.com>:

On Fri, 30 Aug 2024 14:04:42 -0700 you wrote:
> This series contains updates to igc, e1000e, and i40 drivers.
> 
> Kurt Kanzenbach adds support for MQPRIO offloads and stops unintended,
> excess interrupts on igc.
> 
> Sasha adds reporting of EEE (Energy Efficient Ethernet) ability and
> moves a register define to a better suited file for igc.
> 
> [...]

Here is the summary with links:
  - [net-next,1/6] igc: Add MQPRIO offload support
    https://git.kernel.org/netdev/net-next/c/9f3297511dae
  - [net-next,2/6] igc: Get rid of spurious interrupts
    https://git.kernel.org/netdev/net-next/c/8dcf2c212078
  - [net-next,3/6] igc: Add Energy Efficient Ethernet ability
    https://git.kernel.org/netdev/net-next/c/ad7dffae4e40
  - [net-next,4/6] igc: Move the MULTI GBT AN Control Register to _regs file
    https://git.kernel.org/netdev/net-next/c/f9cb5e01cc4e
  - [net-next,5/6] e1000e: avoid failing the system during pm_suspend
    https://git.kernel.org/netdev/net-next/c/0a6ad4d9e169
  - [net-next,6/6] i40e: Add Energy Efficient Ethernet ability for X710 Base-T/KR/KX cards
    https://git.kernel.org/netdev/net-next/c/0568ee1198f8

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 2/6] igc: Get rid of spurious interrupts
  2024-08-30 21:04 ` [PATCH net-next 2/6] igc: Get rid of spurious interrupts Tony Nguyen
@ 2024-09-05  6:16   ` Ruinskiy, Dima
  2024-09-05  9:44     ` Kurt Kanzenbach
  0 siblings, 1 reply; 12+ messages in thread
From: Ruinskiy, Dima @ 2024-09-05  6:16 UTC (permalink / raw)
  To: Tony Nguyen, davem, kuba, pabeni, edumazet, netdev
  Cc: Kurt Kanzenbach, sasha.neftin, vitaly.lifshits,
	maciej.fijalkowski, magnus.karlsson, ast, daniel, hawk,
	john.fastabend, bpf, bigeasy, Vinicius Costa Gomes, Simon Horman,
	Mor Bar-Gabay

On 31/08/2024 0:04, Tony Nguyen wrote:
> - wr32(IGC_ICS, IGC_ICS_RXDMT0);
> + struct igc_ring *rx_ring = adapter->rx_ring[0];
> +
> + if (test_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags)) {
> + clear_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
> + wr32(IGC_ICS, IGC_ICS_RXDMT0);
> + }
I have some concerns specifically about this code (Legacy/MSI interrupt 
case). The code only checks the IGC_RING_FLAG_RX_ALLOC_FAILED flag of 
ring 0. What if the failure was on another ring? It seems proper to 
iterate over all Rx rings in the adapter (I believe igc can have up to 4).


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 3/6] igc: Add Energy Efficient Ethernet ability
  2024-09-03 19:49   ` Jakub Kicinski
@ 2024-09-05  7:07     ` Lifshits, Vitaly
  0 siblings, 0 replies; 12+ messages in thread
From: Lifshits, Vitaly @ 2024-09-05  7:07 UTC (permalink / raw)
  To: Jakub Kicinski, Nguyen, Anthony L
  Cc: davem@davemloft.net, pabeni@redhat.com, edumazet@google.com,
	netdev@vger.kernel.org, Neftin, Sasha, Ruinskiy, Dima,
	Dahan, AvigailX


On 9/3/2024 10:49 PM, Jakub Kicinski wrote:
> On Fri, 30 Aug 2024 14:04:45 -0700 Tony Nguyen wrote:
>> Example:
>> ethtool --show-eee <device>
> You're only adding get support or am I misreading?
I am answering on Sasha's behalf, yes you are correct, he only added get 
support.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 2/6] igc: Get rid of spurious interrupts
  2024-09-05  6:16   ` Ruinskiy, Dima
@ 2024-09-05  9:44     ` Kurt Kanzenbach
  0 siblings, 0 replies; 12+ messages in thread
From: Kurt Kanzenbach @ 2024-09-05  9:44 UTC (permalink / raw)
  To: Ruinskiy, Dima, Tony Nguyen, davem, kuba, pabeni, edumazet,
	netdev
  Cc: sasha.neftin, vitaly.lifshits, maciej.fijalkowski,
	magnus.karlsson, ast, daniel, hawk, john.fastabend, bpf, bigeasy,
	Vinicius Costa Gomes, Simon Horman, Mor Bar-Gabay

[-- Attachment #1: Type: text/plain, Size: 822 bytes --]

On Thu Sep 05 2024, Dima Ruinskiy wrote:
> On 31/08/2024 0:04, Tony Nguyen wrote:
>> - wr32(IGC_ICS, IGC_ICS_RXDMT0);
>> + struct igc_ring *rx_ring = adapter->rx_ring[0];
>> +
>> + if (test_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags)) {
>> + clear_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
>> + wr32(IGC_ICS, IGC_ICS_RXDMT0);
>> + }
> I have some concerns specifically about this code (Legacy/MSI interrupt 
> case). The code only checks the IGC_RING_FLAG_RX_ALLOC_FAILED flag of 
> ring 0. What if the failure was on another ring? It seems proper to 
> iterate over all Rx rings in the adapter (I believe igc can have up to 4).

In case of Legacy/MSI only one vector, one rx queue and one tx queue is
utilized. The MSI-X code has to check for all rings, which it does.

Thanks,
Kurt

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 861 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2024-09-05  9:44 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-30 21:04 [PATCH net-next 0/6][pull request] Intel Wired LAN Driver Updates 2024-08-30 (igc, e1000e, i40e) Tony Nguyen
2024-08-30 21:04 ` [PATCH net-next 1/6] igc: Add MQPRIO offload support Tony Nguyen
2024-08-30 21:04 ` [PATCH net-next 2/6] igc: Get rid of spurious interrupts Tony Nguyen
2024-09-05  6:16   ` Ruinskiy, Dima
2024-09-05  9:44     ` Kurt Kanzenbach
2024-08-30 21:04 ` [PATCH net-next 3/6] igc: Add Energy Efficient Ethernet ability Tony Nguyen
2024-09-03 19:49   ` Jakub Kicinski
2024-09-05  7:07     ` Lifshits, Vitaly
2024-08-30 21:04 ` [PATCH net-next 4/6] igc: Move the MULTI GBT AN Control Register to _regs file Tony Nguyen
2024-08-30 21:04 ` [PATCH net-next 5/6] e1000e: avoid failing the system during pm_suspend Tony Nguyen
2024-08-30 21:04 ` [PATCH net-next 6/6] i40e: Add Energy Efficient Ethernet ability for X710 Base-T/KR/KX cards Tony Nguyen
2024-09-03 20:40 ` [PATCH net-next 0/6][pull request] Intel Wired LAN Driver Updates 2024-08-30 (igc, e1000e, i40e) patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).