RE: [PATCH net-next v4 2/5] net: wangxun: add Tx timeout process
From: Loktionov, Aleksandr <hidden>
Date: 2026-06-01 09:26:21
quoted hunk ↗ jump to hunk
-----Original Message----- From: Jiawen Wu <jiawenwu@trustnetic.com> Sent: Monday, June 1, 2026 9:22 AM To: netdev@vger.kernel.org Cc: Mengyuan Lou <mengyuanlou@net-swift.com>; Andrew Lunn [off-list ref]; David S. Miller [off-list ref]; Eric Dumazet [off-list ref]; Jakub Kicinski [off-list ref]; Paolo Abeni [off-list ref]; Richard Cochran [off-list ref]; Russell King [off-list ref]; Keller, Jacob E [off-list ref]; Michal Swiatkowski [off-list ref]; Simon Horman [off-list ref]; Kees Cook [off-list ref]; Zaremba, Larysa [off-list ref]; Ingo Molnar [off-list ref]; Joe Damato [off-list ref]; Breno Leitao [off-list ref]; Loktionov, Aleksandr [off-list ref]; Uwe Kleine-König (The Capable Hub) [off-list ref]; Johannes Berg [off-list ref]; Fabio Baltieri [off-list ref]; Jiawen Wu [off-list ref] Subject: [PATCH net-next v4 2/5] net: wangxun: add Tx timeout process Implement .ndo_tx_timeout to handle Tx side timeout event. When a Tx timeout event occur, it will trigger driver into reset process. The WX_HANG_CHECK_ARMED bit is set to indicate a potential hang. It will be cleared if a pause frame is received to avoid false hang detection caused by pause frames. Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com> --- drivers/net/ethernet/wangxun/libwx/Makefile | 2 +- drivers/net/ethernet/wangxun/libwx/wx_err.c | 170 ++++++++++++++++++ drivers/net/ethernet/wangxun/libwx/wx_err.h | 16 ++ drivers/net/ethernet/wangxun/libwx/wx_hw.c | 17 +- drivers/net/ethernet/wangxun/libwx/wx_lib.c | 37 ++++ drivers/net/ethernet/wangxun/libwx/wx_type.h | 19 +- drivers/net/ethernet/wangxun/ngbe/ngbe_main.c | 14 ++ .../net/ethernet/wangxun/txgbe/txgbe_main.c | 14 ++ 8 files changed, 284 insertions(+), 5 deletions(-) create mode 100644 drivers/net/ethernet/wangxun/libwx/wx_err.c create mode 100644 drivers/net/ethernet/wangxun/libwx/wx_err.hdiff --git a/drivers/net/ethernet/wangxun/libwx/Makefileb/drivers/net/ethernet/wangxun/libwx/Makefile index a71b0ad77de3..c8724bb129aa 100644--- a/drivers/net/ethernet/wangxun/libwx/Makefile +++ b/drivers/net/ethernet/wangxun/libwx/Makefile@@ -4,5 +4,5 @@ obj-$(CONFIG_LIBWX) += libwx.o -libwx-objs := wx_hw.o wx_lib.o wx_ethtool.o wx_ptp.o wx_mbx.owx_sriov.o +libwx-objs := wx_hw.o wx_lib.o wx_ethtool.o wx_ptp.o wx_mbx.o +wx_sriov.o wx_err.o libwx-objs += wx_vf.o wx_vf_lib.o wx_vf_common.o diff --git a/drivers/net/ethernet/wangxun/libwx/wx_err.c b/drivers/net/ethernet/wangxun/libwx/wx_err.c new file mode 100644 index 000000000000..982a438d009e--- /dev/null +++ b/drivers/net/ethernet/wangxun/libwx/wx_err.c@@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2015 - 2026 Beijing WangXun Technology Co., Ltd. */ +/* Copyright (c) 1999 - 2026 Intel Corporation. */ +
... Two functions with the same wx_check_tx_hang() name is not good, at least problems with greps and ctags.
+static void wx_check_tx_hang(struct wx *wx) { + int i; + + /* If we're down or resetting, just bail */ + if (!netif_running(wx->netdev) || + test_bit(WX_STATE_RESETTING, wx->state)) + return; + + /* Force detection of hung controller */ + if (netif_carrier_ok(wx->netdev)) { + for (i = 0; i < wx->num_tx_queues; i++) + set_bit(WX_TX_DETECT_HANG, wx->tx_ring[i]-quoted
state);+ } +} + +void wx_check_tx_hang_subtask(struct wx *wx) { + wx_watchdog_flush_tx(wx); + wx_check_tx_hang(wx); +} +EXPORT_SYMBOL(wx_check_tx_hang_subtask); +
...
quoted hunk ↗ jump to hunk
} /**diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.cb/drivers/net/ethernet/wangxun/libwx/wx_lib.c index d042567b8128..da4d9e229c9e 100644--- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c@@ -14,6 +14,7 @@ #include "wx_type.h" #include "wx_lib.h"
... Two functions with the same wx_check_tx_hang() name is not good, at least problems with greps and ctags.
+static bool wx_check_tx_hang(struct wx_ring *ring) { + u32 tx_done_old = ring->tx_stats.tx_done_old; + u32 tx_pending = wx_get_tx_pending(ring); + u32 tx_done = ring->stats.packets; + + if (!test_and_clear_bit(WX_TX_DETECT_HANG, ring->state)) + return false; + + if (tx_done_old == tx_done && tx_pending) + /* make sure it is true for two checks in a row */ + return test_and_set_bit(WX_HANG_CHECK_ARMED, ring-quoted
state);+ + /* update completed stats and continue */ + ring->tx_stats.tx_done_old = tx_done; + /* reset the countdown */ + clear_bit(WX_HANG_CHECK_ARMED, ring->state); + + return false; +} +
...
txgbe_remove_phy(txgbe); wx_free_isb_resources(wx); -- 2.51.0