[PATCH net-next 1/2] net: lan743x: set interrupt moderation timer based on link speed

Dhanushkalyan G <[email protected]>
Newsgroups gmane.linux.network,gmane.linux.kernel
Message-ID <[email protected]>
From: Thangaraj Samynathan <[email protected]>

The driver programs a single fixed interrupt moderation timer into every
INT_MOD_CFG register at interrupt open, regardless of the negotiated link
speed. A fixed value is a poor trade-off across the supported speed
range: it is too coarse at low speeds and not aggressive enough at 2.5G.

Set the moderation timer as a function of the negotiated link speed in
the MAC link-up path: 64 us at 2.5G, 150 us at 1G, and 330 us at
100M/10M. The interrupt-vector-to-timer mapping (INT_MOD_MAP) is static,
so it stays programmed once at interrupt open; only the timer value
(INT_MOD_CFG) is updated, from the new lan743x_config_int_mod() helper,
when the link comes up.

Signed-off-by: Thangaraj Samynathan <[email protected]>
Signed-off-by: Dhanushkalyan G <[email protected]>
---
 drivers/net/ethernet/microchip/lan743x_main.c | 51 ++++++++++++++-----
 drivers/net/ethernet/microchip/lan743x_main.h |  5 +-
 2 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
index f3332417162e..20d6a48ca0bb 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -627,18 +627,12 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter)
 		lan743x_csr_write(adapter, INT_VEC_EN_SET,
 				  INT_VEC_EN_(0));
 
+	/* The interrupt-vector-to-moderation-timer mapping is static, so
+	 * program it once here. The timer values themselves are set later
+	 * (per link speed) via lan743x_config_int_mod().
+	 */
 	if (!(adapter->csr.flags & LAN743X_CSR_FLAG_IS_A0)) {
-		lan743x_csr_write(adapter, INT_MOD_CFG0, LAN743X_INT_MOD);
-		lan743x_csr_write(adapter, INT_MOD_CFG1, LAN743X_INT_MOD);
-		lan743x_csr_write(adapter, INT_MOD_CFG2, LAN743X_INT_MOD);
-		lan743x_csr_write(adapter, INT_MOD_CFG3, LAN743X_INT_MOD);
-		lan743x_csr_write(adapter, INT_MOD_CFG4, LAN743X_INT_MOD);
-		lan743x_csr_write(adapter, INT_MOD_CFG5, LAN743X_INT_MOD);
-		lan743x_csr_write(adapter, INT_MOD_CFG6, LAN743X_INT_MOD);
-		lan743x_csr_write(adapter, INT_MOD_CFG7, LAN743X_INT_MOD);
 		if (adapter->is_pci11x1x) {
-			lan743x_csr_write(adapter, INT_MOD_CFG8, LAN743X_INT_MOD);
-			lan743x_csr_write(adapter, INT_MOD_CFG9, LAN743X_INT_MOD);
 			lan743x_csr_write(adapter, INT_MOD_MAP0, 0x00007654);
 			lan743x_csr_write(adapter, INT_MOD_MAP1, 0x00003210);
 		} else {
@@ -3036,6 +3030,28 @@ static void lan743x_phylink_mac_link_down(struct phylink_config *config,
 	netif_tx_stop_all_queues(netdev);
 }
 
+/* Program the interrupt moderation timer value into the per-vector
+ * INT_MOD_CFG registers. Only the timer value is written here; the vector
+ * mapping (INT_MOD_MAP) is static and is set once at interrupt open.
+ */
+static void lan743x_config_int_mod(struct lan743x_adapter *adapter, u32 int_mod)
+{
+	if (!(adapter->csr.flags & LAN743X_CSR_FLAG_IS_A0)) {
+		lan743x_csr_write(adapter, INT_MOD_CFG0, int_mod);
+		lan743x_csr_write(adapter, INT_MOD_CFG1, int_mod);
+		lan743x_csr_write(adapter, INT_MOD_CFG2, int_mod);
+		lan743x_csr_write(adapter, INT_MOD_CFG3, int_mod);
+		lan743x_csr_write(adapter, INT_MOD_CFG4, int_mod);
+		lan743x_csr_write(adapter, INT_MOD_CFG5, int_mod);
+		lan743x_csr_write(adapter, INT_MOD_CFG6, int_mod);
+		lan743x_csr_write(adapter, INT_MOD_CFG7, int_mod);
+		if (adapter->is_pci11x1x) {
+			lan743x_csr_write(adapter, INT_MOD_CFG8, int_mod);
+			lan743x_csr_write(adapter, INT_MOD_CFG9, int_mod);
+		}
+	}
+}
+
 static void lan743x_phylink_mac_link_up(struct phylink_config *config,
 					struct phy_device *phydev,
 					unsigned int link_an_mode,
@@ -3045,6 +3061,7 @@ static void lan743x_phylink_mac_link_up(struct phylink_config *config,
 {
 	struct net_device *netdev = to_net_dev(config->dev);
 	struct lan743x_adapter *adapter = netdev_priv(netdev);
+	u32 int_mod;
 	int mac_cr;
 	u8 cap;
 
@@ -3053,12 +3070,18 @@ static void lan743x_phylink_mac_link_up(struct phylink_config *config,
 	 * Resulting value corresponds to SPEED_10
 	 */
 	mac_cr &= ~(MAC_CR_CFG_H_ | MAC_CR_CFG_L_);
-	if (speed == SPEED_2500)
+	if (speed == SPEED_2500) {
 		mac_cr |= MAC_CR_CFG_H_ | MAC_CR_CFG_L_;
-	else if (speed == SPEED_1000)
+		int_mod = LAN743X_INT_MOD_2_5G;
+	} else if (speed == SPEED_1000) {
 		mac_cr |= MAC_CR_CFG_H_;
-	else if (speed == SPEED_100)
+		int_mod = LAN743X_INT_MOD_1G;
+	} else if (speed == SPEED_100) {
 		mac_cr |= MAC_CR_CFG_L_;
+		int_mod = LAN743X_INT_MOD_100M;
+	} else {
+		int_mod = LAN743X_INT_MOD_10M;
+	}
 
 	if (duplex == DUPLEX_FULL)
 		mac_cr |= MAC_CR_DPX_;
@@ -3067,6 +3090,8 @@ static void lan743x_phylink_mac_link_up(struct phylink_config *config,
 
 	lan743x_csr_write(adapter, MAC_CR, mac_cr);
 
+	lan743x_config_int_mod(adapter, int_mod);
+
 	lan743x_ptp_update_latency(adapter, speed);
 
 	/* Flow Control operation */
diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h
index 160d94a7cee6..c4a3de7fe107 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.h
+++ b/drivers/net/ethernet/microchip/lan743x_main.h
@@ -861,7 +861,10 @@ struct lan743x_adapter;
 #define LAN743X_USED_RX_CHANNELS	(4)
 #define LAN743X_USED_TX_CHANNELS	(1)
 #define PCI11X1X_USED_TX_CHANNELS	(4)
-#define LAN743X_INT_MOD	(400)
+#define LAN743X_INT_MOD_2_5G		(64)
+#define LAN743X_INT_MOD_1G		(150)
+#define LAN743X_INT_MOD_100M		(330)
+#define LAN743X_INT_MOD_10M		(330)
 
 #if (LAN743X_USED_RX_CHANNELS > LAN743X_MAX_RX_CHANNELS)
 #error Invalid LAN743X_USED_RX_CHANNELS
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.