Sometimes we might get error from the underlying bus, but the return type of the function is void, so an error message is desired here. There are many instances of the same pattern, refactor it. Signed-off-by: David Yang --- drivers/net/dsa/yt921x.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/net/dsa/yt921x.c b/drivers/net/dsa/yt921x.c index 98e8915dd6c2..77864dcbb6c5 100644 --- a/drivers/net/dsa/yt921x.c +++ b/drivers/net/dsa/yt921x.c @@ -185,6 +185,12 @@ struct yt921x_reg_mdio { #define to_yt921x_priv(_ds) container_of_const(_ds, struct yt921x_priv, ds) #define to_device(priv) ((priv)->ds.dev) +static void +print_port_err(const struct device *dev, int port, int res, const char *action) +{ + dev_err(dev, "Failed to %s port %d: %i\n", action, port, res); +} + static int yt921x_reg_read(struct yt921x_priv *priv, u32 reg, u32 *valp) { WARN_ON(!mutex_is_locked(&priv->reg_lock)); @@ -721,8 +727,7 @@ static int yt921x_read_mib(struct yt921x_priv *priv, int port) mib->tx_jumbo; if (res) - dev_err(dev, "Failed to %s port %d: %i\n", "read stats for", - port, res); + print_port_err(dev, port, res, "read stats for"); return res; } @@ -1102,8 +1107,7 @@ yt921x_dsa_port_mirror_del(struct dsa_switch *ds, int port, mutex_unlock(&priv->reg_lock); if (res) - dev_err(dev, "Failed to %s port %d: %i\n", "unmirror", - port, res); + print_port_err(dev, port, res, "unmirror"); } static int @@ -1690,8 +1694,7 @@ static void yt921x_dsa_port_fast_age(struct dsa_switch *ds, int port) mutex_unlock(&priv->reg_lock); if (res) - dev_err(dev, "Failed to %s port %d: %i\n", "clear FDB for", - port, res); + print_port_err(dev, port, res, "clear FDB for"); } static int @@ -2266,8 +2269,7 @@ yt921x_dsa_port_bridge_leave(struct dsa_switch *ds, int port, mutex_unlock(&priv->reg_lock); if (res) - dev_err(dev, "Failed to %s port %d: %i\n", "unbridge", - port, res); + print_port_err(dev, port, res, "unbridge"); } static int @@ -2399,8 +2401,7 @@ yt921x_dsa_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) mutex_unlock(&priv->reg_lock); if (res) - dev_err(dev, "Failed to %s port %d: %i\n", "set STP state for", - port, res); + print_port_err(dev, port, res, "set STP state for"); } static int __maybe_unused @@ -2738,8 +2739,7 @@ yt921x_phylink_mac_link_down(struct phylink_config *config, unsigned int mode, mutex_unlock(&priv->reg_lock); if (res) - dev_err(dp->ds->dev, "Failed to %s port %d: %i\n", "bring down", - port, res); + print_port_err(dp->ds->dev, port, res, "bring down"); } static void @@ -2759,8 +2759,7 @@ yt921x_phylink_mac_link_up(struct phylink_config *config, mutex_unlock(&priv->reg_lock); if (res) - dev_err(dp->ds->dev, "Failed to %s port %d: %i\n", "bring up", - port, res); + print_port_err(dp->ds->dev, port, res, "bring up"); schedule_delayed_work(&priv->ports[port].mib_read, 0); } @@ -2779,8 +2778,7 @@ yt921x_phylink_mac_config(struct phylink_config *config, unsigned int mode, mutex_unlock(&priv->reg_lock); if (res) - dev_err(dp->ds->dev, "Failed to %s port %d: %i\n", "config", - port, res); + print_port_err(dp->ds->dev, port, res, "config"); } static void -- 2.51.0 This patch is a prerequisite for another patch. It does not change the behavior on the success path. Signed-off-by: David Yang --- drivers/net/dsa/yt921x.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/dsa/yt921x.c b/drivers/net/dsa/yt921x.c index 77864dcbb6c5..c72a74ed29cf 100644 --- a/drivers/net/dsa/yt921x.c +++ b/drivers/net/dsa/yt921x.c @@ -717,6 +717,11 @@ static int yt921x_read_mib(struct yt921x_priv *priv, int port) WRITE_ONCE(*valp, val); } + if (res) { + print_port_err(dev, port, res, "read stats for"); + return res; + } + pp->rx_frames = mib->rx_64byte + mib->rx_65_127byte + mib->rx_128_255byte + mib->rx_256_511byte + mib->rx_512_1023byte + mib->rx_1024_1518byte + @@ -726,9 +731,7 @@ static int yt921x_read_mib(struct yt921x_priv *priv, int port) mib->tx_512_1023byte + mib->tx_1024_1518byte + mib->tx_jumbo; - if (res) - print_port_err(dev, port, res, "read stats for"); - return res; + return 0; } static void yt921x_poll_mib(struct work_struct *work) -- 2.51.0 64-bit variables might not be atomic on 32-bit architectures, and could lead to load/store tearing. Use u64_stats_t to ensure consistency. Signed-off-by: David Yang --- drivers/net/dsa/yt921x.c | 198 +++++++++++++++++++++++---------------- drivers/net/dsa/yt921x.h | 114 ++++++++++++---------- 2 files changed, 179 insertions(+), 133 deletions(-) diff --git a/drivers/net/dsa/yt921x.c b/drivers/net/dsa/yt921x.c index c72a74ed29cf..e22bd5b6eab9 100644 --- a/drivers/net/dsa/yt921x.c +++ b/drivers/net/dsa/yt921x.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -676,22 +677,20 @@ yt921x_mbus_ext_init(struct yt921x_priv *priv, struct device_node *mnp) static int yt921x_read_mib(struct yt921x_priv *priv, int port) { struct yt921x_port *pp = &priv->ports[port]; + struct yt921x_mib *mib_new = &pp->mib_new; struct device *dev = to_device(priv); struct yt921x_mib *mib = &pp->mib; + u64 rx_frames; + u64 tx_frames; int res = 0; - /* Reading of yt921x_port::mib is not protected by a lock and it's vain - * to keep its consistency, since we have to read registers one by one - * and there is no way to make a snapshot of MIB stats. - * - * Writing (by this function only) is and should be protected by - * reg_lock. + /* u64_stats_read/set is redundant for mib_new, but I don't want to + * declare a plain u64 yt921x_mib variant. */ for (size_t i = 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) { const struct yt921x_mib_desc *desc = &yt921x_mib_descs[i]; u32 reg = YT921X_MIBn_DATA0(port) + desc->offset; - u64 *valp = &((u64 *)mib)[i]; u32 val0; u64 val; @@ -700,7 +699,7 @@ static int yt921x_read_mib(struct yt921x_priv *priv, int port) break; if (desc->size <= 1) { - u64 old_val = *valp; + u64 old_val = u64_stats_read(&mib->stats[i]); val = (old_val & ~(u64)U32_MAX) | val0; if (val < old_val) @@ -714,7 +713,7 @@ static int yt921x_read_mib(struct yt921x_priv *priv, int port) val = ((u64)val1 << 32) | val0; } - WRITE_ONCE(*valp, val); + u64_stats_set(&mib_new->stats[i], val); } if (res) { @@ -722,14 +721,29 @@ static int yt921x_read_mib(struct yt921x_priv *priv, int port) return res; } - pp->rx_frames = mib->rx_64byte + mib->rx_65_127byte + - mib->rx_128_255byte + mib->rx_256_511byte + - mib->rx_512_1023byte + mib->rx_1024_1518byte + - mib->rx_jumbo; - pp->tx_frames = mib->tx_64byte + mib->tx_65_127byte + - mib->tx_128_255byte + mib->tx_256_511byte + - mib->tx_512_1023byte + mib->tx_1024_1518byte + - mib->tx_jumbo; + rx_frames = u64_stats_read(&mib_new->rx_64byte) + + u64_stats_read(&mib_new->rx_65_127byte) + + u64_stats_read(&mib_new->rx_128_255byte) + + u64_stats_read(&mib_new->rx_256_511byte) + + u64_stats_read(&mib_new->rx_512_1023byte) + + u64_stats_read(&mib_new->rx_1024_1518byte) + + u64_stats_read(&mib_new->rx_jumbo); + tx_frames = u64_stats_read(&mib_new->tx_64byte) + + u64_stats_read(&mib_new->tx_65_127byte) + + u64_stats_read(&mib_new->tx_128_255byte) + + u64_stats_read(&mib_new->tx_256_511byte) + + u64_stats_read(&mib_new->tx_512_1023byte) + + u64_stats_read(&mib_new->tx_1024_1518byte) + + u64_stats_read(&mib_new->tx_jumbo); + + u64_stats_update_begin(&pp->syncp); + for (size_t i = 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) { + u64_stats_set(&mib->stats[i], + u64_stats_read(&mib_new->stats[i])); + } + u64_stats_set(&pp->rx_frames, rx_frames); + u64_stats_set(&pp->tx_frames, tx_frames); + u64_stats_update_end(&pp->syncp); return 0; } @@ -774,11 +788,12 @@ yt921x_dsa_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data) struct yt921x_priv *priv = to_yt921x_priv(ds); struct yt921x_port *pp = &priv->ports[port]; struct yt921x_mib *mib = &pp->mib; + unsigned int start; size_t j; mutex_lock(&priv->reg_lock); + yt921x_read_mib(priv, port); - mutex_unlock(&priv->reg_lock); j = 0; for (size_t i = 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) { @@ -787,9 +802,11 @@ yt921x_dsa_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data) if (!desc->name) continue; - data[j] = ((u64 *)mib)[i]; + data[j] = u64_stats_read(&((u64_stats_t *)mib)[i]); j++; } + + mutex_unlock(&priv->reg_lock); } static int yt921x_dsa_get_sset_count(struct dsa_switch *ds, int port, int sset) @@ -818,31 +835,33 @@ yt921x_dsa_get_eth_mac_stats(struct dsa_switch *ds, int port, struct yt921x_mib *mib = &pp->mib; mutex_lock(&priv->reg_lock); + yt921x_read_mib(priv, port); - mutex_unlock(&priv->reg_lock); - mac_stats->FramesTransmittedOK = pp->tx_frames; - mac_stats->SingleCollisionFrames = mib->tx_single_collisions; - mac_stats->MultipleCollisionFrames = mib->tx_multiple_collisions; - mac_stats->FramesReceivedOK = pp->rx_frames; - mac_stats->FrameCheckSequenceErrors = mib->rx_crc_errors; - mac_stats->AlignmentErrors = mib->rx_alignment_errors; - mac_stats->OctetsTransmittedOK = mib->tx_good_bytes; - mac_stats->FramesWithDeferredXmissions = mib->tx_deferred; - mac_stats->LateCollisions = mib->tx_late_collisions; - mac_stats->FramesAbortedDueToXSColls = mib->tx_aborted_errors; + mac_stats->FramesTransmittedOK = u64_stats_read(&pp->tx_frames); + mac_stats->SingleCollisionFrames = u64_stats_read(&mib->tx_single_collisions); + mac_stats->MultipleCollisionFrames = u64_stats_read(&mib->tx_multiple_collisions); + mac_stats->FramesReceivedOK = u64_stats_read(&pp->rx_frames); + mac_stats->FrameCheckSequenceErrors = u64_stats_read(&mib->rx_crc_errors); + mac_stats->AlignmentErrors = u64_stats_read(&mib->rx_alignment_errors); + mac_stats->OctetsTransmittedOK = u64_stats_read(&mib->tx_good_bytes); + mac_stats->FramesWithDeferredXmissions = u64_stats_read(&mib->tx_deferred); + mac_stats->LateCollisions = u64_stats_read(&mib->tx_late_collisions); + mac_stats->FramesAbortedDueToXSColls = u64_stats_read(&mib->tx_aborted_errors); /* mac_stats->FramesLostDueToIntMACXmitError */ /* mac_stats->CarrierSenseErrors */ - mac_stats->OctetsReceivedOK = mib->rx_good_bytes; + mac_stats->OctetsReceivedOK = u64_stats_read(&mib->rx_good_bytes); /* mac_stats->FramesLostDueToIntMACRcvError */ - mac_stats->MulticastFramesXmittedOK = mib->tx_multicast; - mac_stats->BroadcastFramesXmittedOK = mib->tx_broadcast; + mac_stats->MulticastFramesXmittedOK = u64_stats_read(&mib->tx_multicast); + mac_stats->BroadcastFramesXmittedOK = u64_stats_read(&mib->tx_broadcast); /* mac_stats->FramesWithExcessiveDeferral */ - mac_stats->MulticastFramesReceivedOK = mib->rx_multicast; - mac_stats->BroadcastFramesReceivedOK = mib->rx_broadcast; + mac_stats->MulticastFramesReceivedOK = u64_stats_read(&mib->rx_multicast); + mac_stats->BroadcastFramesReceivedOK = u64_stats_read(&mib->rx_broadcast); /* mac_stats->InRangeLengthErrors */ /* mac_stats->OutOfRangeLengthField */ - mac_stats->FrameTooLongErrors = mib->rx_oversize_errors; + mac_stats->FrameTooLongErrors = u64_stats_read(&mib->rx_oversize_errors); + + mutex_unlock(&priv->reg_lock); } static void @@ -854,12 +873,14 @@ yt921x_dsa_get_eth_ctrl_stats(struct dsa_switch *ds, int port, struct yt921x_mib *mib = &pp->mib; mutex_lock(&priv->reg_lock); + yt921x_read_mib(priv, port); - mutex_unlock(&priv->reg_lock); - ctrl_stats->MACControlFramesTransmitted = mib->tx_pause; - ctrl_stats->MACControlFramesReceived = mib->rx_pause; + ctrl_stats->MACControlFramesTransmitted = u64_stats_read(&mib->tx_pause); + ctrl_stats->MACControlFramesReceived = u64_stats_read(&mib->rx_pause); /* ctrl_stats->UnsupportedOpcodesReceived */ + + mutex_unlock(&priv->reg_lock); } static const struct ethtool_rmon_hist_range yt921x_rmon_ranges[] = { @@ -883,31 +904,33 @@ yt921x_dsa_get_rmon_stats(struct dsa_switch *ds, int port, struct yt921x_mib *mib = &pp->mib; mutex_lock(&priv->reg_lock); + yt921x_read_mib(priv, port); - mutex_unlock(&priv->reg_lock); *ranges = yt921x_rmon_ranges; - rmon_stats->undersize_pkts = mib->rx_undersize_errors; - rmon_stats->oversize_pkts = mib->rx_oversize_errors; - rmon_stats->fragments = mib->rx_alignment_errors; + rmon_stats->undersize_pkts = u64_stats_read(&mib->rx_undersize_errors); + rmon_stats->oversize_pkts = u64_stats_read(&mib->rx_oversize_errors); + rmon_stats->fragments = u64_stats_read(&mib->rx_alignment_errors); /* rmon_stats->jabbers */ - rmon_stats->hist[0] = mib->rx_64byte; - rmon_stats->hist[1] = mib->rx_65_127byte; - rmon_stats->hist[2] = mib->rx_128_255byte; - rmon_stats->hist[3] = mib->rx_256_511byte; - rmon_stats->hist[4] = mib->rx_512_1023byte; - rmon_stats->hist[5] = mib->rx_1024_1518byte; - rmon_stats->hist[6] = mib->rx_jumbo; + rmon_stats->hist[0] = u64_stats_read(&mib->rx_64byte); + rmon_stats->hist[1] = u64_stats_read(&mib->rx_65_127byte); + rmon_stats->hist[2] = u64_stats_read(&mib->rx_128_255byte); + rmon_stats->hist[3] = u64_stats_read(&mib->rx_256_511byte); + rmon_stats->hist[4] = u64_stats_read(&mib->rx_512_1023byte); + rmon_stats->hist[5] = u64_stats_read(&mib->rx_1024_1518byte); + rmon_stats->hist[6] = u64_stats_read(&mib->rx_jumbo); + + rmon_stats->hist_tx[0] = u64_stats_read(&mib->tx_64byte); + rmon_stats->hist_tx[1] = u64_stats_read(&mib->tx_65_127byte); + rmon_stats->hist_tx[2] = u64_stats_read(&mib->tx_128_255byte); + rmon_stats->hist_tx[3] = u64_stats_read(&mib->tx_256_511byte); + rmon_stats->hist_tx[4] = u64_stats_read(&mib->tx_512_1023byte); + rmon_stats->hist_tx[5] = u64_stats_read(&mib->tx_1024_1518byte); + rmon_stats->hist_tx[6] = u64_stats_read(&mib->tx_jumbo); - rmon_stats->hist_tx[0] = mib->tx_64byte; - rmon_stats->hist_tx[1] = mib->tx_65_127byte; - rmon_stats->hist_tx[2] = mib->tx_128_255byte; - rmon_stats->hist_tx[3] = mib->tx_256_511byte; - rmon_stats->hist_tx[4] = mib->tx_512_1023byte; - rmon_stats->hist_tx[5] = mib->tx_1024_1518byte; - rmon_stats->hist_tx[6] = mib->tx_jumbo; + mutex_unlock(&priv->reg_lock); } static void @@ -917,33 +940,41 @@ yt921x_dsa_get_stats64(struct dsa_switch *ds, int port, struct yt921x_priv *priv = to_yt921x_priv(ds); struct yt921x_port *pp = &priv->ports[port]; struct yt921x_mib *mib = &pp->mib; + unsigned int start; + + do { + start = u64_stats_fetch_begin(&pp->syncp); + + stats->rx_length_errors = u64_stats_read(&mib->rx_undersize_errors) + + u64_stats_read(&mib->rx_fragment_errors); + stats->rx_over_errors = u64_stats_read(&mib->rx_oversize_errors); + stats->rx_crc_errors = u64_stats_read(&mib->rx_crc_errors); + stats->rx_frame_errors = u64_stats_read(&mib->rx_alignment_errors); + /* stats->rx_fifo_errors */ + /* stats->rx_missed_errors */ + + stats->tx_aborted_errors = u64_stats_read(&mib->tx_aborted_errors); + /* stats->tx_carrier_errors */ + stats->tx_fifo_errors = u64_stats_read(&mib->tx_undersize_errors); + /* stats->tx_heartbeat_errors */ + stats->tx_window_errors = u64_stats_read(&mib->tx_late_collisions); + + stats->rx_packets = u64_stats_read(&pp->rx_frames); + stats->tx_packets = u64_stats_read(&pp->tx_frames); + stats->rx_bytes = u64_stats_read(&mib->rx_good_bytes) - + ETH_FCS_LEN * stats->rx_packets; + stats->tx_bytes = u64_stats_read(&mib->tx_good_bytes) - + ETH_FCS_LEN * stats->tx_packets; + stats->rx_dropped = u64_stats_read(&mib->rx_dropped); + /* stats->tx_dropped */ + stats->multicast = u64_stats_read(&mib->rx_multicast); + stats->collisions = u64_stats_read(&mib->tx_collisions); + } while (u64_stats_fetch_retry(&pp->syncp, start)); - stats->rx_length_errors = mib->rx_undersize_errors + - mib->rx_fragment_errors; - stats->rx_over_errors = mib->rx_oversize_errors; - stats->rx_crc_errors = mib->rx_crc_errors; - stats->rx_frame_errors = mib->rx_alignment_errors; - /* stats->rx_fifo_errors */ - /* stats->rx_missed_errors */ - - stats->tx_aborted_errors = mib->tx_aborted_errors; - /* stats->tx_carrier_errors */ - stats->tx_fifo_errors = mib->tx_undersize_errors; - /* stats->tx_heartbeat_errors */ - stats->tx_window_errors = mib->tx_late_collisions; - - stats->rx_packets = pp->rx_frames; - stats->tx_packets = pp->tx_frames; - stats->rx_bytes = mib->rx_good_bytes - ETH_FCS_LEN * stats->rx_packets; - stats->tx_bytes = mib->tx_good_bytes - ETH_FCS_LEN * stats->tx_packets; stats->rx_errors = stats->rx_length_errors + stats->rx_over_errors + stats->rx_crc_errors + stats->rx_frame_errors; stats->tx_errors = stats->tx_aborted_errors + stats->tx_fifo_errors + stats->tx_window_errors; - stats->rx_dropped = mib->rx_dropped; - /* stats->tx_dropped */ - stats->multicast = mib->rx_multicast; - stats->collisions = mib->tx_collisions; } static void @@ -955,11 +986,13 @@ yt921x_dsa_get_pause_stats(struct dsa_switch *ds, int port, struct yt921x_mib *mib = &pp->mib; mutex_lock(&priv->reg_lock); + yt921x_read_mib(priv, port); - mutex_unlock(&priv->reg_lock); - pause_stats->tx_pause_frames = mib->tx_pause; - pause_stats->rx_pause_frames = mib->rx_pause; + pause_stats->tx_pause_frames = u64_stats_read(&mib->tx_pause); + pause_stats->rx_pause_frames = u64_stats_read(&mib->rx_pause); + + mutex_unlock(&priv->reg_lock); } static int @@ -3421,6 +3454,7 @@ static int yt921x_mdio_probe(struct mdio_device *mdiodev) pp->index = i; INIT_DELAYED_WORK(&pp->mib_read, yt921x_poll_mib); + u64_stats_init(&pp->syncp); } ds = &priv->ds; diff --git a/drivers/net/dsa/yt921x.h b/drivers/net/dsa/yt921x.h index 3f129b8d403f..0f4231accf3e 100644 --- a/drivers/net/dsa/yt921x.h +++ b/drivers/net/dsa/yt921x.h @@ -6,6 +6,8 @@ #ifndef __YT921X_H #define __YT921X_H +#include + #include #define YT921X_SMI_SWITCHID_M GENMASK(3, 2) @@ -530,55 +532,61 @@ enum yt921x_fdb_entry_status { #define yt921x_port_is_external(port) (8 <= (port) && (port) < 9) struct yt921x_mib { - u64 rx_broadcast; - u64 rx_pause; - u64 rx_multicast; - u64 rx_crc_errors; - - u64 rx_alignment_errors; - u64 rx_undersize_errors; - u64 rx_fragment_errors; - u64 rx_64byte; - - u64 rx_65_127byte; - u64 rx_128_255byte; - u64 rx_256_511byte; - u64 rx_512_1023byte; - - u64 rx_1024_1518byte; - u64 rx_jumbo; - u64 rx_good_bytes; - - u64 rx_bad_bytes; - u64 rx_oversize_errors; - - u64 rx_dropped; - u64 tx_broadcast; - u64 tx_pause; - u64 tx_multicast; - - u64 tx_undersize_errors; - u64 tx_64byte; - u64 tx_65_127byte; - u64 tx_128_255byte; - - u64 tx_256_511byte; - u64 tx_512_1023byte; - u64 tx_1024_1518byte; - u64 tx_jumbo; - - u64 tx_good_bytes; - u64 tx_collisions; - - u64 tx_aborted_errors; - u64 tx_multiple_collisions; - u64 tx_single_collisions; - u64 tx_good; - - u64 tx_deferred; - u64 tx_late_collisions; - u64 rx_oam; - u64 tx_oam; + union { + struct { + u64_stats_t rx_broadcast; + u64_stats_t rx_pause; + u64_stats_t rx_multicast; + u64_stats_t rx_crc_errors; + + u64_stats_t rx_alignment_errors; + u64_stats_t rx_undersize_errors; + u64_stats_t rx_fragment_errors; + u64_stats_t rx_64byte; + + u64_stats_t rx_65_127byte; + u64_stats_t rx_128_255byte; + u64_stats_t rx_256_511byte; + u64_stats_t rx_512_1023byte; + + u64_stats_t rx_1024_1518byte; + u64_stats_t rx_jumbo; + u64_stats_t rx_good_bytes; + + u64_stats_t rx_bad_bytes; + u64_stats_t rx_oversize_errors; + + u64_stats_t rx_dropped; + u64_stats_t tx_broadcast; + u64_stats_t tx_pause; + u64_stats_t tx_multicast; + + u64_stats_t tx_undersize_errors; + u64_stats_t tx_64byte; + u64_stats_t tx_65_127byte; + u64_stats_t tx_128_255byte; + + u64_stats_t tx_256_511byte; + u64_stats_t tx_512_1023byte; + u64_stats_t tx_1024_1518byte; + u64_stats_t tx_jumbo; + + u64_stats_t tx_good_bytes; + u64_stats_t tx_collisions; + + u64_stats_t tx_aborted_errors; + u64_stats_t tx_multiple_collisions; + u64_stats_t tx_single_collisions; + u64_stats_t tx_good; + + u64_stats_t tx_deferred; + u64_stats_t tx_late_collisions; + u64_stats_t rx_oam; + u64_stats_t tx_oam; + }; + + u64_stats_t stats[39]; + }; }; struct yt921x_port { @@ -588,9 +596,13 @@ struct yt921x_port { bool isolated; struct delayed_work mib_read; + struct u64_stats_sync syncp; struct yt921x_mib mib; - u64 rx_frames; - u64 tx_frames; + u64_stats_t rx_frames; + u64_stats_t tx_frames; + + /* only used by read routine to avoid huge allocations on the stack */ + struct yt921x_mib mib_new; }; struct yt921x_reg_ops { -- 2.51.0