From: Jiawen Wu <jiawenwu@trustnetic.com>
To: netdev@vger.kernel.org
Cc: Mengyuan Lou <mengyuanlou@net-swift.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Russell King <linux@armlinux.org.uk>,
Simon Horman <horms@kernel.org>,
Michal Swiatkowski <michal.swiatkowski@linux.intel.com>,
Jacob Keller <jacob.e.keller@intel.com>,
Kees Cook <kees@kernel.org>, Joe Damato <joe@dama.to>,
Larysa Zaremba <larysa.zaremba@intel.com>,
Abdun Nihaal <abdun.nihaal@gmail.com>,
Breno Leitao <leitao@debian.org>,
Jiawen Wu <jiawenwu@trustnetic.com>
Subject: [PATCH net-next v7 9/9] net: libwx: improve flow control setting
Date: Tue, 7 Apr 2026 10:56:16 +0800 [thread overview]
Message-ID: <20260407025616.33652-10-jiawenwu@trustnetic.com> (raw)
In-Reply-To: <20260407025616.33652-1-jiawenwu@trustnetic.com>
Save the current mode of flow control, and enhance the statistics of
pause frames.
The received pause frames are divided into XON and XOFF to be counted.
And due to the hardware defect of SP devices, XON packets cannot be
trasmitted correctly, so Tx XON pause is disabled by default for those
devices.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
.../net/ethernet/wangxun/libwx/wx_ethtool.c | 2 +-
drivers/net/ethernet/wangxun/libwx/wx_hw.c | 46 +++++++++++++++++--
drivers/net/ethernet/wangxun/libwx/wx_type.h | 19 +++++++-
3 files changed, 61 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
index 6adb8cbcad1f..5df971aca9e3 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
+++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
@@ -211,7 +211,7 @@ void wx_get_pause_stats(struct net_device *netdev,
hwstats = &wx->stats;
stats->tx_pause_frames = hwstats->lxontxc + hwstats->lxofftxc;
- stats->rx_pause_frames = hwstats->lxonoffrxc;
+ stats->rx_pause_frames = hwstats->lxonrxc + hwstats->lxoffrxc;
}
EXPORT_SYMBOL(wx_get_pause_stats);
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c
index 57d6671ec618..d3772d01e00b 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_hw.c
+++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.c
@@ -2774,6 +2774,15 @@ int wx_fc_enable(struct wx *wx, bool tx_pause, bool rx_pause)
}
}
+ if (rx_pause && tx_pause)
+ wx->fc.mode = wx_fc_full;
+ else if (rx_pause)
+ wx->fc.mode = wx_fc_rx_pause;
+ else if (tx_pause)
+ wx->fc.mode = wx_fc_tx_pause;
+ else
+ wx->fc.mode = wx_fc_none;
+
/* Disable any previous flow control settings */
mflcn_reg = rd32(wx, WX_MAC_RX_FLOW_CTRL);
mflcn_reg &= ~WX_MAC_RX_FLOW_CTRL_RFE;
@@ -2792,7 +2801,9 @@ int wx_fc_enable(struct wx *wx, bool tx_pause, bool rx_pause)
/* Set up and enable Rx high/low water mark thresholds, enable XON. */
if (tx_pause && wx->fc.high_water) {
- fcrtl = (wx->fc.low_water << 10) | WX_RDB_RFCL_XONE;
+ fcrtl = (wx->fc.low_water << 10);
+ if (wx->mac.type != wx_mac_sp)
+ fcrtl |= WX_RDB_RFCL_XONE;
wr32(wx, WX_RDB_RFCL, fcrtl);
fcrth = (wx->fc.high_water << 10) | WX_RDB_RFCH_XOFFE;
} else {
@@ -2833,6 +2844,21 @@ int wx_fc_enable(struct wx *wx, bool tx_pause, bool rx_pause)
}
EXPORT_SYMBOL(wx_fc_enable);
+static void wx_update_xoff_rx_lfc(struct wx *wx)
+{
+ struct wx_hw_stats *hwstats = &wx->stats;
+
+ if (wx->fc.mode != wx_fc_full &&
+ wx->fc.mode != wx_fc_rx_pause)
+ return;
+
+ if (wx->mac.type >= wx_mac_aml)
+ hwstats->lxoffrxc += rd32_wrap(wx, WX_MAC_LXOFFRXC_AML,
+ &wx->last_stats.lxoffrxc);
+ else
+ hwstats->lxoffrxc += rd64(wx, WX_MAC_LXOFFRXC);
+}
+
/**
* wx_update_stats - Update the board statistics counters.
* @wx: board private structure
@@ -2887,6 +2913,8 @@ void wx_update_stats(struct wx *wx)
wx->restart_queue = restart_queue;
wx->tx_busy = tx_busy;
+ wx_update_xoff_rx_lfc(wx);
+
hwstats->gprc += rd32(wx, WX_RDM_PKT_CNT);
hwstats->gptc += rd32(wx, WX_TDM_PKT_CNT);
hwstats->gorc += rd64(wx, WX_RDM_BYTE_CNT_LSB);
@@ -2901,7 +2929,11 @@ void wx_update_stats(struct wx *wx)
hwstats->mptc += rd64(wx, WX_TX_MC_FRAMES_GOOD_L);
hwstats->roc += rd32(wx, WX_RX_OVERSIZE_FRAMES_GOOD);
hwstats->ruc += rd32(wx, WX_RX_UNDERSIZE_FRAMES_GOOD);
- hwstats->lxonoffrxc += rd32(wx, WX_MAC_LXONOFFRXC);
+ if (wx->mac.type >= wx_mac_aml)
+ hwstats->lxonrxc += rd32_wrap(wx, WX_MAC_LXONRXC_AML,
+ &wx->last_stats.lxonrxc);
+ else
+ hwstats->lxonrxc += rd32(wx, WX_MAC_LXONRXC);
hwstats->lxontxc += rd32(wx, WX_RDB_LXONTXC);
hwstats->lxofftxc += rd32(wx, WX_RDB_LXOFFTXC);
hwstats->o2bgptc += rd32(wx, WX_TDM_OS2BMC_CNT);
@@ -2958,7 +2990,15 @@ void wx_clear_hw_cntrs(struct wx *wx)
rd64(wx, WX_RX_LEN_ERROR_FRAMES_L);
rd32(wx, WX_RDB_LXONTXC);
rd32(wx, WX_RDB_LXOFFTXC);
- rd32(wx, WX_MAC_LXONOFFRXC);
+ if (wx->mac.type >= wx_mac_aml) {
+ wr32(wx, WX_MAC_LXONRXC_AML, 0);
+ wr32(wx, WX_MAC_LXOFFRXC_AML, 0);
+ wx->last_stats.lxonrxc = 0;
+ wx->last_stats.lxoffrxc = 0;
+ } else {
+ rd32(wx, WX_MAC_LXONRXC);
+ rd64(wx, WX_MAC_LXOFFRXC);
+ }
}
EXPORT_SYMBOL(wx_clear_hw_cntrs);
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h
index 3c5a351974dd..0da5565ee4ff 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_type.h
+++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h
@@ -79,7 +79,10 @@
#define WX_RX_LEN_ERROR_FRAMES_L 0x11978
#define WX_RX_UNDERSIZE_FRAMES_GOOD 0x11938
#define WX_RX_OVERSIZE_FRAMES_GOOD 0x1193C
-#define WX_MAC_LXONOFFRXC 0x11E0C
+#define WX_MAC_LXOFFRXC 0x11988
+#define WX_MAC_LXONRXC 0x11E0C
+#define WX_MAC_LXOFFRXC_AML 0x11F80
+#define WX_MAC_LXONRXC_AML 0x11F84
/*********************** Receive DMA registers **************************/
#define WX_RDM_VF_RE(_i) (0x12004 + ((_i) * 4))
@@ -1148,9 +1151,18 @@ enum wx_isb_idx {
WX_ISB_MAX
};
+/* Flow Control Settings */
+enum wx_fc_mode {
+ wx_fc_none = 0,
+ wx_fc_rx_pause,
+ wx_fc_tx_pause,
+ wx_fc_full
+};
+
struct wx_fc_info {
u32 high_water; /* Flow Ctrl High-water */
u32 low_water; /* Flow Ctrl Low-water */
+ enum wx_fc_mode mode; /* Flow Control Mode */
};
/* Statistics counters collected by the MAC */
@@ -1167,7 +1179,8 @@ struct wx_hw_stats {
u64 mptc;
u64 roc;
u64 ruc;
- u64 lxonoffrxc;
+ u64 lxonrxc;
+ u64 lxoffrxc;
u64 lxontxc;
u64 lxofftxc;
u64 o2bgptc;
@@ -1184,6 +1197,8 @@ struct wx_hw_stats {
struct wx_last_stats {
u32 qmprc[128];
+ u32 lxoffrxc;
+ u32 lxonrxc;
};
enum wx_state {
--
2.48.1
next prev parent reply other threads:[~2026-04-07 2:57 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-07 2:56 [PATCH net-next v7 0/9] Wangxun improvement Jiawen Wu
2026-04-07 2:56 ` [PATCH net-next v7 1/9] net: ngbe: remove netdev->ethtool->wol_enabled setting Jiawen Wu
2026-04-07 2:56 ` [PATCH net-next v7 2/9] net: ngbe: move the WOL functions to libwx Jiawen Wu
2026-04-07 2:56 ` [PATCH net-next v7 3/9] net: ngbe: remove redundant macros Jiawen Wu
2026-04-07 2:56 ` [PATCH net-next v7 4/9] net: wangxun: replace busy-wait reset flag with kernel mutex Jiawen Wu
2026-04-07 2:56 ` [PATCH net-next v7 5/9] net: wangxun: move ethtool_ops.set_channels into libwx Jiawen Wu
2026-04-07 2:56 ` [PATCH net-next v7 6/9] net: wangxun: reorder timer and work sync cancellations Jiawen Wu
2026-04-07 2:56 ` [PATCH net-next v7 7/9] net: wangxun: schedule hardware stats update in watchdog Jiawen Wu
2026-04-07 2:56 ` [PATCH net-next v7 8/9] net: libwx: wrap-around and reset qmprc counter Jiawen Wu
2026-04-07 2:56 ` Jiawen Wu [this message]
2026-04-12 15:50 ` [PATCH net-next v7 0/9] Wangxun improvement patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260407025616.33652-10-jiawenwu@trustnetic.com \
--to=jiawenwu@trustnetic.com \
--cc=abdun.nihaal@gmail.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=jacob.e.keller@intel.com \
--cc=joe@dama.to \
--cc=kees@kernel.org \
--cc=kuba@kernel.org \
--cc=larysa.zaremba@intel.com \
--cc=leitao@debian.org \
--cc=linux@armlinux.org.uk \
--cc=mengyuanlou@net-swift.com \
--cc=michal.swiatkowski@linux.intel.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox