[PATCH net-next 1/2] net: lan743x: set interrupt moderation timer based on link speed
From: Dhanushkalyan G <hidden>
Date: 2026-08-03 12:48:58
Also in:
lkml
Subsystem:
microchip lan743x ethernet driver, networking drivers, the rest · Maintainers:
Bryan Whitehead, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
From: Thangaraj Samynathan <Thangaraj.S@microchip.com> 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 <Thangaraj.S@microchip.com> Signed-off-by: Dhanushkalyan G <redacted> --- 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