mirror of
https://github.com/openwrt/openwrt.git
synced 2026-06-17 12:40:16 +04:00
d22ceb8d24
Add hardware TCP Large Receive Offload (LRO) support to the airoha_eth driver, leveraging the EN7581/AN7583 SoC's 8 dedicated LRO hardware queues mapped to RX queues 24–31. LRO hw offloading does not support Scatter-Gather (SG) so it is required to increase the page_pool allocation order to 2 for RX queues 24–31 (LRO queues). Performance comparison between GRO and hw LRO has been carried out using a 10Gbps NIC: GRO: ~2.7 Gbps LRO: ~8.1 Gbps Tested-by: Madhur Agrawal <madhur.agrawal@airoha.com> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Link: https://github.com/openwrt/openwrt/pull/23530 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
416 lines
15 KiB
Diff
416 lines
15 KiB
Diff
From 9652322e0b47eacfef497828f6476a2a3169fd13 Mon Sep 17 00:00:00 2001
|
|
Message-ID: <9652322e0b47eacfef497828f6476a2a3169fd13.1779351672.git.lorenzo@kernel.org>
|
|
From: Christian Marangi <ansuelsmth@gmail.com>
|
|
Date: Sat, 17 Jan 2026 14:46:12 +0100
|
|
Subject: [PATCH] net: airoha: Better handle MIB for GDM with multiple port
|
|
attached
|
|
|
|
In the context of a GDM that can have multiple port attached (GDM3/4)
|
|
the HW counter (MIB) are global for the GDM port. This cause duplicated
|
|
stats reported to the kernel for the related interface.
|
|
|
|
The SoC supports a split MIB feature where each counter is tracked based
|
|
on the relevant HW channel (NBQ) to account for this scenario and
|
|
provide a way to select the related counter on accessing the MIB
|
|
registers.
|
|
|
|
Enable this feature for GDM3 and GDM4 and configure the relevant HW
|
|
channel before updating the HW stats to report correct HW counter to the
|
|
kernel for the related interface.
|
|
|
|
Also move the stats struct from port to dev since HW counter are
|
|
now specific to the network interface instead of the GDM port.
|
|
|
|
Co-developed-by: Brown Huang <Brown.huang@airoha.com>
|
|
Signed-off-by: Brown Huang <Brown.huang@airoha.com>
|
|
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
|
---
|
|
drivers/net/ethernet/airoha/airoha_eth.c | 191 +++++++++++++----------
|
|
drivers/net/ethernet/airoha/airoha_eth.h | 7 +-
|
|
2 files changed, 112 insertions(+), 86 deletions(-)
|
|
|
|
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
|
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
|
@@ -612,6 +612,14 @@ static int airoha_fe_init(struct airoha_
|
|
airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX),
|
|
GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK);
|
|
|
|
+ /* Enable split for MIB counters for GDM3 and GDM4 */
|
|
+ airoha_fe_set(eth, REG_FE_GDM_MIB_CFG(AIROHA_GDM3_IDX),
|
|
+ FE_GDM_TX_MIB_SPLIT_EN_MASK |
|
|
+ FE_GDM_RX_MIB_SPLIT_EN_MASK);
|
|
+ airoha_fe_set(eth, REG_FE_GDM_MIB_CFG(AIROHA_GDM4_IDX),
|
|
+ FE_GDM_TX_MIB_SPLIT_EN_MASK |
|
|
+ FE_GDM_RX_MIB_SPLIT_EN_MASK);
|
|
+
|
|
airoha_fe_crsn_qsel_init(eth);
|
|
|
|
airoha_fe_clear(eth, REG_FE_CPORT_CFG, FE_CPORT_QUEUE_XFC_MASK);
|
|
@@ -1767,149 +1775,169 @@ static void airoha_qdma_stop_napi(struct
|
|
}
|
|
}
|
|
|
|
-static void airoha_update_hw_stats(struct airoha_gdm_dev *dev)
|
|
+static void airoha_dev_get_hw_stats(struct airoha_gdm_dev *dev)
|
|
{
|
|
struct airoha_gdm_port *port = dev->port;
|
|
struct airoha_eth *eth = dev->eth;
|
|
u32 val, i = 0;
|
|
|
|
- spin_lock(&port->stats.lock);
|
|
- u64_stats_update_begin(&port->stats.syncp);
|
|
+ u64_stats_update_begin(&dev->stats.syncp);
|
|
+
|
|
+ /* Read relevant MIB for GDM with multiple port attached */
|
|
+ if (port->id == AIROHA_GDM3_IDX || port->id == AIROHA_GDM4_IDX)
|
|
+ airoha_fe_rmw(eth, REG_FE_GDM_MIB_CFG(port->id),
|
|
+ FE_TX_MIB_ID_MASK | FE_RX_MIB_ID_MASK,
|
|
+ FIELD_PREP(FE_TX_MIB_ID_MASK, dev->nbq) |
|
|
+ FIELD_PREP(FE_RX_MIB_ID_MASK, dev->nbq));
|
|
|
|
/* TX */
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_H(port->id));
|
|
- port->stats.tx_ok_pkts += ((u64)val << 32);
|
|
+ dev->stats.tx_ok_pkts += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_L(port->id));
|
|
- port->stats.tx_ok_pkts += val;
|
|
+ dev->stats.tx_ok_pkts += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_H(port->id));
|
|
- port->stats.tx_ok_bytes += ((u64)val << 32);
|
|
+ dev->stats.tx_ok_bytes += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_L(port->id));
|
|
- port->stats.tx_ok_bytes += val;
|
|
+ dev->stats.tx_ok_bytes += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_DROP_CNT(port->id));
|
|
- port->stats.tx_drops += val;
|
|
+ dev->stats.tx_drops += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_BC_CNT(port->id));
|
|
- port->stats.tx_broadcast += val;
|
|
+ dev->stats.tx_broadcast += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_MC_CNT(port->id));
|
|
- port->stats.tx_multicast += val;
|
|
+ dev->stats.tx_multicast += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_RUNT_CNT(port->id));
|
|
- port->stats.tx_len[i] += val;
|
|
+ dev->stats.tx_len[i] += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_H(port->id));
|
|
- port->stats.tx_len[i] += ((u64)val << 32);
|
|
+ dev->stats.tx_len[i] += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_L(port->id));
|
|
- port->stats.tx_len[i++] += val;
|
|
+ dev->stats.tx_len[i++] += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_H(port->id));
|
|
- port->stats.tx_len[i] += ((u64)val << 32);
|
|
+ dev->stats.tx_len[i] += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_L(port->id));
|
|
- port->stats.tx_len[i++] += val;
|
|
+ dev->stats.tx_len[i++] += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_H(port->id));
|
|
- port->stats.tx_len[i] += ((u64)val << 32);
|
|
+ dev->stats.tx_len[i] += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_L(port->id));
|
|
- port->stats.tx_len[i++] += val;
|
|
+ dev->stats.tx_len[i++] += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_H(port->id));
|
|
- port->stats.tx_len[i] += ((u64)val << 32);
|
|
+ dev->stats.tx_len[i] += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_L(port->id));
|
|
- port->stats.tx_len[i++] += val;
|
|
+ dev->stats.tx_len[i++] += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_H(port->id));
|
|
- port->stats.tx_len[i] += ((u64)val << 32);
|
|
+ dev->stats.tx_len[i] += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_L(port->id));
|
|
- port->stats.tx_len[i++] += val;
|
|
+ dev->stats.tx_len[i++] += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_H(port->id));
|
|
- port->stats.tx_len[i] += ((u64)val << 32);
|
|
+ dev->stats.tx_len[i] += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_L(port->id));
|
|
- port->stats.tx_len[i++] += val;
|
|
+ dev->stats.tx_len[i++] += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_LONG_CNT(port->id));
|
|
- port->stats.tx_len[i++] += val;
|
|
+ dev->stats.tx_len[i++] += val;
|
|
|
|
/* RX */
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_H(port->id));
|
|
- port->stats.rx_ok_pkts += ((u64)val << 32);
|
|
+ dev->stats.rx_ok_pkts += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_L(port->id));
|
|
- port->stats.rx_ok_pkts += val;
|
|
+ dev->stats.rx_ok_pkts += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_H(port->id));
|
|
- port->stats.rx_ok_bytes += ((u64)val << 32);
|
|
+ dev->stats.rx_ok_bytes += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_L(port->id));
|
|
- port->stats.rx_ok_bytes += val;
|
|
+ dev->stats.rx_ok_bytes += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_DROP_CNT(port->id));
|
|
- port->stats.rx_drops += val;
|
|
+ dev->stats.rx_drops += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_BC_CNT(port->id));
|
|
- port->stats.rx_broadcast += val;
|
|
+ dev->stats.rx_broadcast += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_MC_CNT(port->id));
|
|
- port->stats.rx_multicast += val;
|
|
+ dev->stats.rx_multicast += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ERROR_DROP_CNT(port->id));
|
|
- port->stats.rx_errors += val;
|
|
+ dev->stats.rx_errors += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_CRC_ERR_CNT(port->id));
|
|
- port->stats.rx_crc_error += val;
|
|
+ dev->stats.rx_crc_error += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OVERFLOW_DROP_CNT(port->id));
|
|
- port->stats.rx_over_errors += val;
|
|
+ dev->stats.rx_over_errors += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_FRAG_CNT(port->id));
|
|
- port->stats.rx_fragment += val;
|
|
+ dev->stats.rx_fragment += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_JABBER_CNT(port->id));
|
|
- port->stats.rx_jabber += val;
|
|
+ dev->stats.rx_jabber += val;
|
|
|
|
i = 0;
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_RUNT_CNT(port->id));
|
|
- port->stats.rx_len[i] += val;
|
|
+ dev->stats.rx_len[i] += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_H(port->id));
|
|
- port->stats.rx_len[i] += ((u64)val << 32);
|
|
+ dev->stats.rx_len[i] += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_L(port->id));
|
|
- port->stats.rx_len[i++] += val;
|
|
+ dev->stats.rx_len[i++] += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_H(port->id));
|
|
- port->stats.rx_len[i] += ((u64)val << 32);
|
|
+ dev->stats.rx_len[i] += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_L(port->id));
|
|
- port->stats.rx_len[i++] += val;
|
|
+ dev->stats.rx_len[i++] += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_H(port->id));
|
|
- port->stats.rx_len[i] += ((u64)val << 32);
|
|
+ dev->stats.rx_len[i] += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_L(port->id));
|
|
- port->stats.rx_len[i++] += val;
|
|
+ dev->stats.rx_len[i++] += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_H(port->id));
|
|
- port->stats.rx_len[i] += ((u64)val << 32);
|
|
+ dev->stats.rx_len[i] += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_L(port->id));
|
|
- port->stats.rx_len[i++] += val;
|
|
+ dev->stats.rx_len[i++] += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_H(port->id));
|
|
- port->stats.rx_len[i] += ((u64)val << 32);
|
|
+ dev->stats.rx_len[i] += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_L(port->id));
|
|
- port->stats.rx_len[i++] += val;
|
|
+ dev->stats.rx_len[i++] += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_H(port->id));
|
|
- port->stats.rx_len[i] += ((u64)val << 32);
|
|
+ dev->stats.rx_len[i] += ((u64)val << 32);
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_L(port->id));
|
|
- port->stats.rx_len[i++] += val;
|
|
+ dev->stats.rx_len[i++] += val;
|
|
|
|
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_LONG_CNT(port->id));
|
|
- port->stats.rx_len[i++] += val;
|
|
+ dev->stats.rx_len[i++] += val;
|
|
+
|
|
+ u64_stats_update_end(&dev->stats.syncp);
|
|
+}
|
|
|
|
- /* reset mib counters */
|
|
- airoha_fe_set(eth, REG_FE_GDM_MIB_CLEAR(port->id),
|
|
+static void airoha_update_hw_stats(struct airoha_gdm_dev *dev)
|
|
+{
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
+ int i;
|
|
+
|
|
+ spin_lock(&port->stats_lock);
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(port->devs); i++) {
|
|
+ if (port->devs[i])
|
|
+ airoha_dev_get_hw_stats(port->devs[i]);
|
|
+ }
|
|
+
|
|
+ /* Reset MIB counters */
|
|
+ airoha_fe_set(dev->eth, REG_FE_GDM_MIB_CLEAR(port->id),
|
|
FE_GDM_MIB_RX_CLEAR_MASK | FE_GDM_MIB_TX_CLEAR_MASK);
|
|
|
|
- u64_stats_update_end(&port->stats.syncp);
|
|
- spin_unlock(&port->stats.lock);
|
|
+ spin_unlock(&port->stats_lock);
|
|
}
|
|
|
|
void airoha_set_port_mtu(struct airoha_eth *eth, struct airoha_gdm_port *port)
|
|
@@ -2237,23 +2265,22 @@ static void airoha_dev_get_stats64(struc
|
|
struct rtnl_link_stats64 *storage)
|
|
{
|
|
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
- struct airoha_gdm_port *port = dev->port;
|
|
unsigned int start;
|
|
|
|
airoha_update_hw_stats(dev);
|
|
do {
|
|
- start = u64_stats_fetch_begin(&port->stats.syncp);
|
|
- storage->rx_packets = port->stats.rx_ok_pkts;
|
|
- storage->tx_packets = port->stats.tx_ok_pkts;
|
|
- storage->rx_bytes = port->stats.rx_ok_bytes;
|
|
- storage->tx_bytes = port->stats.tx_ok_bytes;
|
|
- storage->multicast = port->stats.rx_multicast;
|
|
- storage->rx_errors = port->stats.rx_errors;
|
|
- storage->rx_dropped = port->stats.rx_drops;
|
|
- storage->tx_dropped = port->stats.tx_drops;
|
|
- storage->rx_crc_errors = port->stats.rx_crc_error;
|
|
- storage->rx_over_errors = port->stats.rx_over_errors;
|
|
- } while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
|
+ start = u64_stats_fetch_begin(&dev->stats.syncp);
|
|
+ storage->rx_packets = dev->stats.rx_ok_pkts;
|
|
+ storage->tx_packets = dev->stats.tx_ok_pkts;
|
|
+ storage->rx_bytes = dev->stats.rx_ok_bytes;
|
|
+ storage->tx_bytes = dev->stats.tx_ok_bytes;
|
|
+ storage->multicast = dev->stats.rx_multicast;
|
|
+ storage->rx_errors = dev->stats.rx_errors;
|
|
+ storage->rx_dropped = dev->stats.rx_drops;
|
|
+ storage->tx_dropped = dev->stats.tx_drops;
|
|
+ storage->rx_crc_errors = dev->stats.rx_crc_error;
|
|
+ storage->rx_over_errors = dev->stats.rx_over_errors;
|
|
+ } while (u64_stats_fetch_retry(&dev->stats.syncp, start));
|
|
}
|
|
|
|
static int airoha_dev_change_mtu(struct net_device *netdev, int mtu)
|
|
@@ -2651,20 +2678,19 @@ static void airoha_ethtool_get_mac_stats
|
|
struct ethtool_eth_mac_stats *stats)
|
|
{
|
|
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
- struct airoha_gdm_port *port = dev->port;
|
|
unsigned int start;
|
|
|
|
airoha_update_hw_stats(dev);
|
|
do {
|
|
- start = u64_stats_fetch_begin(&port->stats.syncp);
|
|
- stats->FramesTransmittedOK = port->stats.tx_ok_pkts;
|
|
- stats->OctetsTransmittedOK = port->stats.tx_ok_bytes;
|
|
- stats->MulticastFramesXmittedOK = port->stats.tx_multicast;
|
|
- stats->BroadcastFramesXmittedOK = port->stats.tx_broadcast;
|
|
- stats->FramesReceivedOK = port->stats.rx_ok_pkts;
|
|
- stats->OctetsReceivedOK = port->stats.rx_ok_bytes;
|
|
- stats->BroadcastFramesReceivedOK = port->stats.rx_broadcast;
|
|
- } while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
|
+ start = u64_stats_fetch_begin(&dev->stats.syncp);
|
|
+ stats->FramesTransmittedOK = dev->stats.tx_ok_pkts;
|
|
+ stats->OctetsTransmittedOK = dev->stats.tx_ok_bytes;
|
|
+ stats->MulticastFramesXmittedOK = dev->stats.tx_multicast;
|
|
+ stats->BroadcastFramesXmittedOK = dev->stats.tx_broadcast;
|
|
+ stats->FramesReceivedOK = dev->stats.rx_ok_pkts;
|
|
+ stats->OctetsReceivedOK = dev->stats.rx_ok_bytes;
|
|
+ stats->BroadcastFramesReceivedOK = dev->stats.rx_broadcast;
|
|
+ } while (u64_stats_fetch_retry(&dev->stats.syncp, start));
|
|
}
|
|
|
|
static const struct ethtool_rmon_hist_range airoha_ethtool_rmon_ranges[] = {
|
|
@@ -2684,8 +2710,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
|
const struct ethtool_rmon_hist_range **ranges)
|
|
{
|
|
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
- struct airoha_gdm_port *port = dev->port;
|
|
- struct airoha_hw_stats *hw_stats = &port->stats;
|
|
+ struct airoha_hw_stats *hw_stats = &dev->stats;
|
|
unsigned int start;
|
|
|
|
BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) !=
|
|
@@ -2698,7 +2723,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
|
do {
|
|
int i;
|
|
|
|
- start = u64_stats_fetch_begin(&port->stats.syncp);
|
|
+ start = u64_stats_fetch_begin(&dev->stats.syncp);
|
|
stats->fragments = hw_stats->rx_fragment;
|
|
stats->jabbers = hw_stats->rx_jabber;
|
|
for (i = 0; i < ARRAY_SIZE(airoha_ethtool_rmon_ranges) - 1;
|
|
@@ -2706,7 +2731,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
|
stats->hist[i] = hw_stats->rx_len[i];
|
|
stats->hist_tx[i] = hw_stats->tx_len[i];
|
|
}
|
|
- } while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
|
+ } while (u64_stats_fetch_retry(&dev->stats.syncp, start));
|
|
}
|
|
|
|
static int airoha_ethtool_set_priv_flags(struct net_device *netdev, u32 flags)
|
|
@@ -3714,6 +3739,7 @@ static int airoha_alloc_gdm_device(struc
|
|
|
|
netdev->dev.of_node = of_node_get(np);
|
|
dev = netdev_priv(netdev);
|
|
+ u64_stats_init(&dev->stats.syncp);
|
|
dev->dev = netdev;
|
|
dev->port = port;
|
|
dev->eth = eth;
|
|
@@ -3762,9 +3788,8 @@ static int airoha_alloc_gdm_port(struct
|
|
if (!port)
|
|
return -ENOMEM;
|
|
|
|
- u64_stats_init(&port->stats.syncp);
|
|
- spin_lock_init(&port->stats.lock);
|
|
port->id = id;
|
|
+ spin_lock_init(&port->stats_lock);
|
|
eth->ports[p] = port;
|
|
|
|
err = airoha_metadata_dst_alloc(port);
|
|
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
|
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
|
@@ -227,8 +227,6 @@ struct airoha_tx_irq_queue {
|
|
};
|
|
|
|
struct airoha_hw_stats {
|
|
- /* protect concurrent hw_stats accesses */
|
|
- spinlock_t lock;
|
|
struct u64_stats_sync syncp;
|
|
|
|
/* get_stats64 */
|
|
@@ -572,6 +570,8 @@ struct airoha_gdm_dev {
|
|
|
|
u32 flags;
|
|
int nbq;
|
|
+
|
|
+ struct airoha_hw_stats stats;
|
|
};
|
|
|
|
struct airoha_gdm_port {
|
|
@@ -579,7 +579,8 @@ struct airoha_gdm_port {
|
|
int id;
|
|
int users;
|
|
|
|
- struct airoha_hw_stats stats;
|
|
+ /* protect concurrent hw_stats accesses */
|
|
+ spinlock_t stats_lock;
|
|
|
|
struct metadata_dst *dsa_meta[AIROHA_MAX_DSA_PORTS];
|
|
};
|