The chip supports only frame limits 0, 4, 8, .. 60 internally. Returning EINVAL for all val % 4 != 0 seems to be a little bit too unfriendly to the user. Therefore round up the frame limit to the next supported value. In addition round up the time limit, else a very low limit could be rounded down to 0, and interpreted as "ignore value" by the chip.
Signed-off-by: Heiner Kallweit <hkallwe...@gmail.com> --- drivers/net/ethernet/realtek/r8169_main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index a95615684..fe95c47e7 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -1909,21 +1909,21 @@ static int rtl_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) * - then user does `ethtool -C eth0 rx-usecs 100` * * since ethtool sends to kernel whole ethtool_coalesce - * settings, if we do not handle rx_usecs=!0, rx_frames=1 - * we'll reject it below in `frames % 4 != 0`. + * settings, if we want to ignore rx_frames then it has + * to be set to 0. */ if (p->frames == 1) { p->frames = 0; } - units = p->usecs * 1000 / scale; - if (p->frames > RTL_COALESCE_FRAME_MAX || p->frames % 4) - return -EINVAL; + units = DIV_ROUND_UP(p->usecs * 1000, scale); + if (p->frames > RTL_COALESCE_FRAME_MAX) + return -ERANGE; w <<= RTL_COALESCE_SHIFT; w |= units; w <<= RTL_COALESCE_SHIFT; - w |= p->frames >> 2; + w |= DIV_ROUND_UP(p->frames, 4); } rtl_lock_work(tp); -- 2.26.2