[PATCH] net: davinci_emac: Fix interrupt pacing disable
From: Maxim Kiselev <hidden>
Date: 2021-11-01 09:38:01
Also in:
linux-omap, lkml
Subsystem:
networking drivers, the rest, ti ethernet switch driver (cpsw) · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
This patch allows to use 0 for `coal->rx_coalesce_usecs` param to
disable rx irq coalescing.
Previously we could enable rx irq coalescing via ethtool
(For ex: `ethtool -C eth0 rx-usecs 2000`) but we couldn't disable
it because this part rejects 0 value:
if (!coal->rx_coalesce_usecs)
return -EINVAL;
Fixes: 84da2658a619 ("TI DaVinci EMAC : Implement interrupt pacing
functionality.")
Signed-off-by: Maxim Kiselev <redacted>
---
drivers/net/ethernet/ti/davinci_emac.c | 77 ++++++++++++++------------
1 file changed, 41 insertions(+), 36 deletions(-)
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index e8291d8488391..a3a02c4e5eb68 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c@@ -417,46 +417,47 @@ static int emac_set_coalesce(struct net_device *ndev, struct netlink_ext_ack *extack) { struct emac_priv *priv = netdev_priv(ndev); - u32 int_ctrl, num_interrupts = 0; + u32 int_ctrl = 0, num_interrupts = 0; u32 prescale = 0, addnl_dvdr = 1, coal_intvl = 0; - if (!coal->rx_coalesce_usecs) - return -EINVAL; - coal_intvl = coal->rx_coalesce_usecs; switch (priv->version) { case EMAC_VERSION_2: - int_ctrl = emac_ctrl_read(EMAC_DM646X_CMINTCTRL); - prescale = priv->bus_freq_mhz * 4; - - if (coal_intvl < EMAC_DM646X_CMINTMIN_INTVL) - coal_intvl = EMAC_DM646X_CMINTMIN_INTVL; - - if (coal_intvl > EMAC_DM646X_CMINTMAX_INTVL) { - /* - * Interrupt pacer works with 4us Pulse, we can - * throttle further by dilating the 4us pulse. - */ - addnl_dvdr = EMAC_DM646X_INTPRESCALE_MASK / prescale; - - if (addnl_dvdr > 1) { - prescale *= addnl_dvdr; - if (coal_intvl > (EMAC_DM646X_CMINTMAX_INTVL - * addnl_dvdr)) - coal_intvl = (EMAC_DM646X_CMINTMAX_INTVL - * addnl_dvdr); - } else { - addnl_dvdr = 1; - coal_intvl = EMAC_DM646X_CMINTMAX_INTVL; + if (coal->rx_coalesce_usecs) { + int_ctrl = emac_ctrl_read(EMAC_DM646X_CMINTCTRL); + prescale = priv->bus_freq_mhz * 4; + + if (coal_intvl < EMAC_DM646X_CMINTMIN_INTVL) + coal_intvl = EMAC_DM646X_CMINTMIN_INTVL; + + if (coal_intvl > EMAC_DM646X_CMINTMAX_INTVL) { + /* + * Interrupt pacer works with 4us Pulse, we can + * throttle further by dilating the 4us pulse. + */ + addnl_dvdr = + EMAC_DM646X_INTPRESCALE_MASK / prescale; + + if (addnl_dvdr > 1) { + prescale *= addnl_dvdr; + if (coal_intvl > (EMAC_DM646X_CMINTMAX_INTVL + * addnl_dvdr)) + coal_intvl = (EMAC_DM646X_CMINTMAX_INTVL + * addnl_dvdr); + } else { + addnl_dvdr = 1; + coal_intvl = EMAC_DM646X_CMINTMAX_INTVL; + } } - } - num_interrupts = (1000 * addnl_dvdr) / coal_intvl; + num_interrupts = (1000 * addnl_dvdr) / coal_intvl; + + int_ctrl |= EMAC_DM646X_INTPACEEN; + int_ctrl &= (~EMAC_DM646X_INTPRESCALE_MASK); + int_ctrl |= (prescale & EMAC_DM646X_INTPRESCALE_MASK); + } - int_ctrl |= EMAC_DM646X_INTPACEEN; - int_ctrl &= (~EMAC_DM646X_INTPRESCALE_MASK); - int_ctrl |= (prescale & EMAC_DM646X_INTPRESCALE_MASK); emac_ctrl_write(EMAC_DM646X_CMINTCTRL, int_ctrl); emac_ctrl_write(EMAC_DM646X_CMRXINTMAX, num_interrupts);
@@ -466,17 +467,21 @@ static int emac_set_coalesce(struct net_device *ndev, default: int_ctrl = emac_ctrl_read(EMAC_CTRL_EWINTTCNT); int_ctrl &= (~EMAC_DM644X_EWINTCNT_MASK); - prescale = coal_intvl * priv->bus_freq_mhz; - if (prescale > EMAC_DM644X_EWINTCNT_MASK) { - prescale = EMAC_DM644X_EWINTCNT_MASK; - coal_intvl = prescale / priv->bus_freq_mhz; + + if (coal->rx_coalesce_usecs) { + prescale = coal_intvl * priv->bus_freq_mhz; + if (prescale > EMAC_DM644X_EWINTCNT_MASK) { + prescale = EMAC_DM644X_EWINTCNT_MASK; + coal_intvl = prescale / priv->bus_freq_mhz; + } } + emac_ctrl_write(EMAC_CTRL_EWINTTCNT, (int_ctrl | prescale)); break; } - printk(KERN_INFO"Set coalesce to %d usecs.\n", coal_intvl); + netdev_info(ndev, "Set coalesce to %d usecs.\n", coal_intvl); priv->coal_intvl = coal_intvl; return 0;
--
2.30.2