From nobody Sat Sep 26 07:14:52 2026 Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8E1B14BA9E1 for ; Thu, 3 Sep 2026 14:38:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788446287; cv=none; b=UymMPQbr++Gp0+mRHXPTVdqW17I4p+/lCLv46suYd1neRROvDK076/aVcAiQww5hr0LJa/8DgvqjRZjamQpah09Rtq8RZNjVzz/HgoOiUxAu+l7a9HYrKP6henkQqmWZPTTPGzxNfFkL7mZRGP9ynucR2qHXFpuyJGeMtGR2LrM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788446287; c=relaxed/simple; bh=gDJiWaW6lxs3366GKB3up0/70WXQ5iDEwZOQlljINvY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZlRC+r8UkZgby0qDwLv0QCVJ5tgec3YZ2S+td8vSQJRRkRePTD3Uo34R1tUbVuvfU/Wa5a9BIIRe3vLouXiu3JGH6WdZoMtOu8F/1wpdPGFRHTFeUoNDLZKiir4iQQntq3xlSJxM8AVmx0t1nN/YLadnocc7cfbSqIT0UApeXG8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=fhjlzwTv; arc=none smtp.client-ip=209.85.216.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fhjlzwTv" Received: by mail-pj1-f41.google.com with SMTP id 98e67ed59e1d1-39675172593so2340839a91.2 for ; Thu, 03 Sep 2026 07:38:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788446277; x=1789051077; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=VCNogTYxl+vxXz3OKPCJPf5sqX9EU7IOn+BtxDiBJ6k=; b=fhjlzwTvtNxr8nvsZUh0TCw8oRDIWYDOi8S+HDcM/TDuj2k3hS2tApWbnUXcT/0KYQ DLJ59J12zQVHpV2KAIzcOjBVgoq/5P7cwolRCdIzfeND5AaKTrpINfnnwOM8eyr1wwt8 yNJ/9So8s9Wc/LYTsT4POYvAr9Ti3EbDo0QyIyEQuRPN2OjPShaEqWMPkC1WfaTG4y0p AxGeEvbmiEQsvzZbTAiiEKpETQMFmzEJtQ7s1AOAuHTdUH7d0VbT8iHsMl2OmQJidjJO iWzkimM8gwidH/TctfkWRu9CpD7QexK2x1tjBwry8czYMK3ZbB0MpedYgT1F+HsdKNWz 64zg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788446277; x=1789051077; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=VCNogTYxl+vxXz3OKPCJPf5sqX9EU7IOn+BtxDiBJ6k=; b=tFLOA3xXl9iPlRtwTcDUGX22VVTh4875FxnmFyWV7iWNPz+ORmyNcKToqbQ6RJrrlA MqAMaT8X9sOX1r6KZ4c6Fs9PQp/4XVegeChAFq5KWCrbRXGtXM5oR7fB8J9Cl8of2S8t C7Rn8lYsk3JlHMPp1LCmkRjMm3oHh4D3D0yw4bZWT91Y+TE4oR8XJopd9hDneA0F+rhH 8gQgMjoiEH0PSbYF2HIZRuu0A27XMeVRDj1VTNPmwCLaB3vRzCBPDIyDpLIjpWdnMVZQ VXulD0dVZ9x1oj2OhJ7xvzsquqmNPpHvLnUhih4FuJNOYeJmnOTwVXGiOGfcBKMP/0KB KSCA== X-Forwarded-Encrypted: i=1; AKwUvBxbokzLK8w7w471FT/MQqR1rs8hdl2NNr2YXOg3+Q6qRQNvg/NPMsy2CBJkkR3UJ6SNvyKDbcKFbpSCBJY=@vger.kernel.org X-Gm-Message-State: AFuF++l9eKP9JjaypncJMOh+wicQmwN/Vt6npGRIDLM7NX/yLzyVhLxD JvNyvqKlXRCVb06EQ/Y05fhL6MiORyiTyo4/26bqGkMYU+1DqGhB0vN5 X-Gm-Gg: AYBFou1HDf8/155HNYdX0yWvC2N47r/ef9nuZgCNd9/4t4iMMcCjIOlm4wnh4JbsXjS GSl6/lzy/64fhxxA+r4p2r/r10JX5kuBOfz3GfB9spK5//OrH/YpQh1COkqLR88DU4kGktS4Iix ytTf3qGzw10fuYZdQ53xQMfUJXZWg4+/82kYuXDBVbj+1lh5Rhn/S1PUHx1tfMTCU4FXd5GsDYY Ao1Tx/S7lVG2TJY7VNwh1iq2qFVWGFb6mGUv96vut8CV2y+9iXdl+X7hrsMo1lIQ0uZpDWP8OF4 Hf60cW3jVocrDXHDAqQraljSnFAtmm2uArZSoNFsioHtVm7Em6wH7dWrkqAGK0pYWk3ZDuHUaBW C86H4ZJ/3FqezjMTm6FiESXFBP1lXZfjQecU2AUARaDjv2cK2CcJOCrY7X0NA8utdzEhSYNoUbf h2DRIYyS/aANmCHXo3OgHO8OTN9KNcW8yh6ixgMVqLQkND9JiIsVBr6wcQs6okuNUnzw/Q1gZXo grvprTodcavrOo= X-Received: by 2002:a17:90b:5824:b0:38e:bfe:81e9 with SMTP id 98e67ed59e1d1-39aedf66687mr21495784a91.1.1788446276954; Thu, 03 Sep 2026 07:37:56 -0700 (PDT) Received: from d.home.yangfl.dn42 ([2a09:bac5:661d:3050::4d0:16]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-39ae9087d3dsm2741889a91.3.2026.09.03.07.37.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Sep 2026 07:37:56 -0700 (PDT) From: David Yang To: netdev@vger.kernel.org Cc: David Yang , Andrew Lunn , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , linux-kernel@vger.kernel.org Subject: [PATCH net-next 1/4] net: dsa: motorcomm: Split MIB module Date: Thu, 3 Sep 2026 22:35:06 +0800 Message-ID: <20260903143514.532023-2-mmyangfl@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903143514.532023-1-mmyangfl@gmail.com> References: <20260903143514.532023-1-mmyangfl@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" yt922x is going to use a different MIB scheme, split it to reduce the length of chip.c. Signed-off-by: David Yang --- drivers/net/dsa/motorcomm/Makefile | 1 + drivers/net/dsa/motorcomm/chip.c | 366 +--------------------------- drivers/net/dsa/motorcomm/chip.h | 63 ----- drivers/net/dsa/motorcomm/mib.c | 373 +++++++++++++++++++++++++++++ drivers/net/dsa/motorcomm/mib.h | 98 ++++++++ 5 files changed, 474 insertions(+), 427 deletions(-) create mode 100644 drivers/net/dsa/motorcomm/mib.c create mode 100644 drivers/net/dsa/motorcomm/mib.h diff --git a/drivers/net/dsa/motorcomm/Makefile b/drivers/net/dsa/motorcomm= /Makefile index aeb12cb91f93..5c2d34ec05fc 100644 --- a/drivers/net/dsa/motorcomm/Makefile +++ b/drivers/net/dsa/motorcomm/Makefile @@ -2,4 +2,5 @@ obj-$(CONFIG_NET_DSA_YT921X) +=3D yt921x.o yt921x-objs :=3D chip.o yt921x-$(CONFIG_NET_DSA_YT921X_LEDS) +=3D leds.o +yt921x-objs +=3D mib.o yt921x-objs +=3D smi.o diff --git a/drivers/net/dsa/motorcomm/chip.c b/drivers/net/dsa/motorcomm/c= hip.c index d663af010f43..77440bf5fa7a 100644 --- a/drivers/net/dsa/motorcomm/chip.c +++ b/drivers/net/dsa/motorcomm/chip.c @@ -27,75 +27,9 @@ =20 #include "chip.h" #include "leds.h" +#include "mib.h" #include "smi.h" =20 -struct yt921x_mib_desc { - unsigned int size; - unsigned int offset; - const char *name; -}; - -#define MIB_DESC(_size, _offset, _name) \ - {_size, _offset, _name} - -/* Must agree with yt921x_mib - * - * Unstructured fields (name !=3D NULL) will appear in get_ethtool_stats(), - * structured go to their *_stats() methods, but we need their sizes and o= ffsets - * to perform 32bit MIB overflow wraparound. - */ -static const struct yt921x_mib_desc yt921x_mib_descs[] =3D { - MIB_DESC(1, YT921X_MIB_DATA_RX_BROADCAST, NULL), - MIB_DESC(1, YT921X_MIB_DATA_RX_PAUSE, NULL), - MIB_DESC(1, YT921X_MIB_DATA_RX_MULTICAST, NULL), - MIB_DESC(1, YT921X_MIB_DATA_RX_CRC_ERR, NULL), - - MIB_DESC(1, YT921X_MIB_DATA_RX_ALIGN_ERR, NULL), - MIB_DESC(1, YT921X_MIB_DATA_RX_UNDERSIZE_ERR, NULL), - MIB_DESC(1, YT921X_MIB_DATA_RX_FRAG_ERR, NULL), - MIB_DESC(1, YT921X_MIB_DATA_RX_PKT_SZ_64, NULL), - - MIB_DESC(1, YT921X_MIB_DATA_RX_PKT_SZ_65_TO_127, NULL), - MIB_DESC(1, YT921X_MIB_DATA_RX_PKT_SZ_128_TO_255, NULL), - MIB_DESC(1, YT921X_MIB_DATA_RX_PKT_SZ_256_TO_511, NULL), - MIB_DESC(1, YT921X_MIB_DATA_RX_PKT_SZ_512_TO_1023, NULL), - - MIB_DESC(1, YT921X_MIB_DATA_RX_PKT_SZ_1024_TO_1518, NULL), - MIB_DESC(1, YT921X_MIB_DATA_RX_PKT_SZ_1519_TO_MAX, NULL), - MIB_DESC(2, YT921X_MIB_DATA_RX_GOOD_BYTES, NULL), - - MIB_DESC(2, YT921X_MIB_DATA_RX_BAD_BYTES, "RxBadBytes"), - MIB_DESC(1, YT921X_MIB_DATA_RX_OVERSIZE_ERR, NULL), - - MIB_DESC(1, YT921X_MIB_DATA_RX_DROPPED, NULL), - MIB_DESC(1, YT921X_MIB_DATA_TX_BROADCAST, NULL), - MIB_DESC(1, YT921X_MIB_DATA_TX_PAUSE, NULL), - MIB_DESC(1, YT921X_MIB_DATA_TX_MULTICAST, NULL), - - MIB_DESC(1, YT921X_MIB_DATA_TX_UNDERSIZE_ERR, NULL), - MIB_DESC(1, YT921X_MIB_DATA_TX_PKT_SZ_64, NULL), - MIB_DESC(1, YT921X_MIB_DATA_TX_PKT_SZ_65_TO_127, NULL), - MIB_DESC(1, YT921X_MIB_DATA_TX_PKT_SZ_128_TO_255, NULL), - - MIB_DESC(1, YT921X_MIB_DATA_TX_PKT_SZ_256_TO_511, NULL), - MIB_DESC(1, YT921X_MIB_DATA_TX_PKT_SZ_512_TO_1023, NULL), - MIB_DESC(1, YT921X_MIB_DATA_TX_PKT_SZ_1024_TO_1518, NULL), - MIB_DESC(1, YT921X_MIB_DATA_TX_PKT_SZ_1519_TO_MAX, NULL), - - MIB_DESC(2, YT921X_MIB_DATA_TX_GOOD_BYTES, NULL), - MIB_DESC(1, YT921X_MIB_DATA_TX_COLLISION, NULL), - - MIB_DESC(1, YT921X_MIB_DATA_TX_EXCESSIVE_COLLISION, NULL), - MIB_DESC(1, YT921X_MIB_DATA_TX_MULTIPLE_COLLISION, NULL), - MIB_DESC(1, YT921X_MIB_DATA_TX_SINGLE_COLLISION, NULL), - MIB_DESC(1, YT921X_MIB_DATA_TX_PKT, NULL), - - MIB_DESC(1, YT921X_MIB_DATA_TX_DEFERRED, NULL), - MIB_DESC(1, YT921X_MIB_DATA_TX_LATE_COLLISION, NULL), - MIB_DESC(1, YT921X_MIB_DATA_RX_OAM, "RxOAM"), - MIB_DESC(1, YT921X_MIB_DATA_TX_OAM, "TxOAM"), -}; - struct yt921x_info { const char *name; u16 major; @@ -154,14 +88,6 @@ static const struct yt921x_info yt921x_infos[] =3D { =20 #define YT921X_VID_UNWARE 4095 =20 -/* The interval should be small enough to avoid overflow of 32bit MIBs. - * - * Until we can read MIBs from stats64 call directly (i.e. sleep - * there), we have to poll stats more frequently then it is actually neede= d. - * For overflow protection, normally, 100 sec interval should have been OK. - */ -#define YT921X_STATS_INTERVAL_JIFFIES (3 * HZ) - struct yt921x_reg_mdio { struct mii_bus *bus; int addr; @@ -544,294 +470,6 @@ yt921x_mbus_ext_init(struct yt921x_priv *priv, struct= device_node *mnp) return 0; } =20 -/* Read and handle overflow of 32bit MIBs. MIB buffer must be zeroed befor= e. */ -static int yt921x_read_mib(struct yt921x_priv *priv, int port) -{ - struct yt921x_port *pp =3D &priv->ports[port]; - struct device *dev =3D to_device(priv); - struct yt921x_mib *mib =3D &pp->mib; - int res =3D 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. - */ - - for (size_t i =3D 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) { - const struct yt921x_mib_desc *desc =3D &yt921x_mib_descs[i]; - u32 reg =3D YT921X_MIBn_DATA0(port) + desc->offset; - u64 *valp =3D &((u64 *)mib)[i]; - u32 val0; - u64 val; - - res =3D yt921x_reg_read(priv, reg, &val0); - if (res) - break; - - if (desc->size <=3D 1) { - u64 old_val =3D *valp; - - val =3D (old_val & ~(u64)U32_MAX) | val0; - if (val < old_val) - val +=3D 1ull << 32; - } else { - u32 val1; - - res =3D yt921x_reg_read(priv, reg + 4, &val1); - if (res) - break; - val =3D ((u64)val1 << 32) | val0; - } - - WRITE_ONCE(*valp, val); - } - - pp->rx_frames =3D 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 =3D 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; - - if (res) - dev_err(dev, "Failed to %s port %d: %i\n", "read stats for", - port, res); - return res; -} - -static void yt921x_poll_mib(struct work_struct *work) -{ - struct yt921x_port *pp =3D container_of_const(work, struct yt921x_port, - mib_read.work); - struct yt921x_priv *priv =3D (void *)(pp - pp->index) - - offsetof(struct yt921x_priv, ports); - unsigned long delay =3D YT921X_STATS_INTERVAL_JIFFIES; - int port =3D pp->index; - int res; - - mutex_lock(&priv->reg_lock); - res =3D yt921x_read_mib(priv, port); - mutex_unlock(&priv->reg_lock); - if (res) - delay *=3D 4; - - schedule_delayed_work(&pp->mib_read, delay); -} - -static void -yt921x_dsa_get_strings(struct dsa_switch *ds, int port, u32 stringset, - uint8_t *data) -{ - if (stringset !=3D ETH_SS_STATS) - return; - - for (size_t i =3D 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) { - const struct yt921x_mib_desc *desc =3D &yt921x_mib_descs[i]; - - if (desc->name) - ethtool_puts(&data, desc->name); - } -} - -static void -yt921x_dsa_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *da= ta) -{ - struct yt921x_priv *priv =3D to_yt921x_priv(ds); - struct yt921x_port *pp =3D &priv->ports[port]; - struct yt921x_mib *mib =3D &pp->mib; - size_t j; - - mutex_lock(&priv->reg_lock); - yt921x_read_mib(priv, port); - mutex_unlock(&priv->reg_lock); - - j =3D 0; - for (size_t i =3D 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) { - const struct yt921x_mib_desc *desc =3D &yt921x_mib_descs[i]; - - if (!desc->name) - continue; - - data[j] =3D ((u64 *)mib)[i]; - j++; - } -} - -static int yt921x_dsa_get_sset_count(struct dsa_switch *ds, int port, int = sset) -{ - int cnt =3D 0; - - if (sset !=3D ETH_SS_STATS) - return 0; - - for (size_t i =3D 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) { - const struct yt921x_mib_desc *desc =3D &yt921x_mib_descs[i]; - - if (desc->name) - cnt++; - } - - return cnt; -} - -static void -yt921x_dsa_get_eth_mac_stats(struct dsa_switch *ds, int port, - struct ethtool_eth_mac_stats *mac_stats) -{ - struct yt921x_priv *priv =3D to_yt921x_priv(ds); - struct yt921x_port *pp =3D &priv->ports[port]; - struct yt921x_mib *mib =3D &pp->mib; - - mutex_lock(&priv->reg_lock); - yt921x_read_mib(priv, port); - mutex_unlock(&priv->reg_lock); - - mac_stats->FramesTransmittedOK =3D pp->tx_frames; - mac_stats->SingleCollisionFrames =3D mib->tx_single_collisions; - mac_stats->MultipleCollisionFrames =3D mib->tx_multiple_collisions; - mac_stats->FramesReceivedOK =3D pp->rx_frames; - mac_stats->FrameCheckSequenceErrors =3D mib->rx_crc_errors; - mac_stats->AlignmentErrors =3D mib->rx_alignment_errors; - mac_stats->OctetsTransmittedOK =3D mib->tx_good_bytes; - mac_stats->FramesWithDeferredXmissions =3D mib->tx_deferred; - mac_stats->LateCollisions =3D mib->tx_late_collisions; - mac_stats->FramesAbortedDueToXSColls =3D mib->tx_aborted_errors; - /* mac_stats->FramesLostDueToIntMACXmitError */ - /* mac_stats->CarrierSenseErrors */ - mac_stats->OctetsReceivedOK =3D mib->rx_good_bytes; - /* mac_stats->FramesLostDueToIntMACRcvError */ - mac_stats->MulticastFramesXmittedOK =3D mib->tx_multicast; - mac_stats->BroadcastFramesXmittedOK =3D mib->tx_broadcast; - /* mac_stats->FramesWithExcessiveDeferral */ - mac_stats->MulticastFramesReceivedOK =3D mib->rx_multicast; - mac_stats->BroadcastFramesReceivedOK =3D mib->rx_broadcast; - /* mac_stats->InRangeLengthErrors */ - /* mac_stats->OutOfRangeLengthField */ - mac_stats->FrameTooLongErrors =3D mib->rx_oversize_errors; -} - -static void -yt921x_dsa_get_eth_ctrl_stats(struct dsa_switch *ds, int port, - struct ethtool_eth_ctrl_stats *ctrl_stats) -{ - struct yt921x_priv *priv =3D to_yt921x_priv(ds); - struct yt921x_port *pp =3D &priv->ports[port]; - struct yt921x_mib *mib =3D &pp->mib; - - mutex_lock(&priv->reg_lock); - yt921x_read_mib(priv, port); - mutex_unlock(&priv->reg_lock); - - ctrl_stats->MACControlFramesTransmitted =3D mib->tx_pause; - ctrl_stats->MACControlFramesReceived =3D mib->rx_pause; - /* ctrl_stats->UnsupportedOpcodesReceived */ -} - -static const struct ethtool_rmon_hist_range yt921x_rmon_ranges[] =3D { - { 0, 64 }, - { 65, 127 }, - { 128, 255 }, - { 256, 511 }, - { 512, 1023 }, - { 1024, 1518 }, - { 1519, YT921X_FRAME_SIZE_MAX }, - {} -}; - -static void -yt921x_dsa_get_rmon_stats(struct dsa_switch *ds, int port, - struct ethtool_rmon_stats *rmon_stats, - const struct ethtool_rmon_hist_range **ranges) -{ - struct yt921x_priv *priv =3D to_yt921x_priv(ds); - struct yt921x_port *pp =3D &priv->ports[port]; - struct yt921x_mib *mib =3D &pp->mib; - - mutex_lock(&priv->reg_lock); - yt921x_read_mib(priv, port); - mutex_unlock(&priv->reg_lock); - - *ranges =3D yt921x_rmon_ranges; - - rmon_stats->undersize_pkts =3D mib->rx_undersize_errors; - rmon_stats->oversize_pkts =3D mib->rx_oversize_errors; - rmon_stats->fragments =3D mib->rx_alignment_errors; - /* rmon_stats->jabbers */ - - rmon_stats->hist[0] =3D mib->rx_64byte; - rmon_stats->hist[1] =3D mib->rx_65_127byte; - rmon_stats->hist[2] =3D mib->rx_128_255byte; - rmon_stats->hist[3] =3D mib->rx_256_511byte; - rmon_stats->hist[4] =3D mib->rx_512_1023byte; - rmon_stats->hist[5] =3D mib->rx_1024_1518byte; - rmon_stats->hist[6] =3D mib->rx_jumbo; - - rmon_stats->hist_tx[0] =3D mib->tx_64byte; - rmon_stats->hist_tx[1] =3D mib->tx_65_127byte; - rmon_stats->hist_tx[2] =3D mib->tx_128_255byte; - rmon_stats->hist_tx[3] =3D mib->tx_256_511byte; - rmon_stats->hist_tx[4] =3D mib->tx_512_1023byte; - rmon_stats->hist_tx[5] =3D mib->tx_1024_1518byte; - rmon_stats->hist_tx[6] =3D mib->tx_jumbo; -} - -static void -yt921x_dsa_get_stats64(struct dsa_switch *ds, int port, - struct rtnl_link_stats64 *stats) -{ - struct yt921x_priv *priv =3D to_yt921x_priv(ds); - struct yt921x_port *pp =3D &priv->ports[port]; - struct yt921x_mib *mib =3D &pp->mib; - - stats->rx_length_errors =3D mib->rx_undersize_errors + - mib->rx_fragment_errors; - stats->rx_over_errors =3D mib->rx_oversize_errors; - stats->rx_crc_errors =3D mib->rx_crc_errors; - stats->rx_frame_errors =3D mib->rx_alignment_errors; - /* stats->rx_fifo_errors */ - /* stats->rx_missed_errors */ - - stats->tx_aborted_errors =3D mib->tx_aborted_errors; - /* stats->tx_carrier_errors */ - stats->tx_fifo_errors =3D mib->tx_undersize_errors; - /* stats->tx_heartbeat_errors */ - stats->tx_window_errors =3D mib->tx_late_collisions; - - stats->rx_packets =3D pp->rx_frames; - stats->tx_packets =3D pp->tx_frames; - stats->rx_bytes =3D mib->rx_good_bytes - ETH_FCS_LEN * stats->rx_packets; - stats->tx_bytes =3D mib->tx_good_bytes - ETH_FCS_LEN * stats->tx_packets; - stats->rx_errors =3D stats->rx_length_errors + stats->rx_over_errors + - stats->rx_crc_errors + stats->rx_frame_errors; - stats->tx_errors =3D stats->tx_aborted_errors + stats->tx_fifo_errors + - stats->tx_window_errors; - stats->rx_dropped =3D mib->rx_dropped; - /* stats->tx_dropped */ - stats->multicast =3D mib->rx_multicast; - stats->collisions =3D mib->tx_collisions; -} - -static void -yt921x_dsa_get_pause_stats(struct dsa_switch *ds, int port, - struct ethtool_pause_stats *pause_stats) -{ - struct yt921x_priv *priv =3D to_yt921x_priv(ds); - struct yt921x_port *pp =3D &priv->ports[port]; - struct yt921x_mib *mib =3D &pp->mib; - - mutex_lock(&priv->reg_lock); - yt921x_read_mib(priv, port); - mutex_unlock(&priv->reg_lock); - - pause_stats->tx_pause_frames =3D mib->tx_pause; - pause_stats->rx_pause_frames =3D mib->rx_pause; -} - static int yt921x_set_eee(struct yt921x_priv *priv, int port, struct ethtool_keee *e) { @@ -4749,7 +4387,7 @@ static int yt921x_mdio_probe(struct mdio_device *mdio= dev) struct yt921x_port *pp =3D &priv->ports[i]; =20 pp->index =3D i; - INIT_DELAYED_WORK(&pp->mib_read, yt921x_poll_mib); + INIT_DELAYED_WORK(&pp->mib_read, yt921x_mib_poll); } =20 ds =3D &priv->ds; diff --git a/drivers/net/dsa/motorcomm/chip.h b/drivers/net/dsa/motorcomm/c= hip.h index 83cd454955dd..84c7065b1cd4 100644 --- a/drivers/net/dsa/motorcomm/chip.h +++ b/drivers/net/dsa/motorcomm/chip.h @@ -167,69 +167,6 @@ #define YT921X_EEE_CTRL 0xb0000 #define YT921X_EEE_CTRL_ENn(port) BIT(port) =20 -#define YT921X_MIB_CTRL 0xc0004 -#define YT921X_MIB_CTRL_CLEAN BIT(30) -#define YT921X_MIB_CTRL_PORT_M GENMASK(6, 3) -#define YT921X_MIB_CTRL_PORT(x) FIELD_PREP(YT921X_MIB_CTRL_PORT_M, (x)) -#define YT921X_MIB_CTRL_ONE_PORT BIT(1) -#define YT921X_MIB_CTRL_ALL_PORT BIT(0) -#define YT921X_MIBn_DATA0(port) (0xc0100 + 0x100 * (port)) -#define YT921X_MIBn_DATAm(port, x) (YT921X_MIBn_DATA0(port) + 4 * (x)) -#define YT921X_MIB_DATA_RX_BROADCAST 0x00 -#define YT921X_MIB_DATA_RX_PAUSE 0x04 -#define YT921X_MIB_DATA_RX_MULTICAST 0x08 -#define YT921X_MIB_DATA_RX_CRC_ERR 0x0c - -#define YT921X_MIB_DATA_RX_ALIGN_ERR 0x10 -#define YT921X_MIB_DATA_RX_UNDERSIZE_ERR 0x14 -#define YT921X_MIB_DATA_RX_FRAG_ERR 0x18 -#define YT921X_MIB_DATA_RX_PKT_SZ_64 0x1c - -#define YT921X_MIB_DATA_RX_PKT_SZ_65_TO_127 0x20 -#define YT921X_MIB_DATA_RX_PKT_SZ_128_TO_255 0x24 -#define YT921X_MIB_DATA_RX_PKT_SZ_256_TO_511 0x28 -#define YT921X_MIB_DATA_RX_PKT_SZ_512_TO_1023 0x2c - -#define YT921X_MIB_DATA_RX_PKT_SZ_1024_TO_1518 0x30 -#define YT921X_MIB_DATA_RX_PKT_SZ_1519_TO_MAX 0x34 -/* 0x38: unused */ -#define YT921X_MIB_DATA_RX_GOOD_BYTES 0x3c - -/* 0x40: 64 bytes */ -#define YT921X_MIB_DATA_RX_BAD_BYTES 0x44 -/* 0x48: 64 bytes */ -#define YT921X_MIB_DATA_RX_OVERSIZE_ERR 0x4c - -#define YT921X_MIB_DATA_RX_DROPPED 0x50 -#define YT921X_MIB_DATA_TX_BROADCAST 0x54 -#define YT921X_MIB_DATA_TX_PAUSE 0x58 -#define YT921X_MIB_DATA_TX_MULTICAST 0x5c - -#define YT921X_MIB_DATA_TX_UNDERSIZE_ERR 0x60 -#define YT921X_MIB_DATA_TX_PKT_SZ_64 0x64 -#define YT921X_MIB_DATA_TX_PKT_SZ_65_TO_127 0x68 -#define YT921X_MIB_DATA_TX_PKT_SZ_128_TO_255 0x6c - -#define YT921X_MIB_DATA_TX_PKT_SZ_256_TO_511 0x70 -#define YT921X_MIB_DATA_TX_PKT_SZ_512_TO_1023 0x74 -#define YT921X_MIB_DATA_TX_PKT_SZ_1024_TO_1518 0x78 -#define YT921X_MIB_DATA_TX_PKT_SZ_1519_TO_MAX 0x7c - -/* 0x80: unused */ -#define YT921X_MIB_DATA_TX_GOOD_BYTES 0x84 -/* 0x88: 64 bytes */ -#define YT921X_MIB_DATA_TX_COLLISION 0x8c - -#define YT921X_MIB_DATA_TX_EXCESSIVE_COLLISION 0x90 -#define YT921X_MIB_DATA_TX_MULTIPLE_COLLISION 0x94 -#define YT921X_MIB_DATA_TX_SINGLE_COLLISION 0x98 -#define YT921X_MIB_DATA_TX_PKT 0x9c - -#define YT921X_MIB_DATA_TX_DEFERRED 0xa0 -#define YT921X_MIB_DATA_TX_LATE_COLLISION 0xa4 -#define YT921X_MIB_DATA_RX_OAM 0xa8 -#define YT921X_MIB_DATA_TX_OAM 0xac - #define YT921X_EDATA_CTRL 0xe0000 #define YT921X_EDATA_CTRL_ADDR_M GENMASK(15, 8) #define YT921X_EDATA_CTRL_ADDR(x) FIELD_PREP(YT921X_EDATA_CTRL_ADDR_M,= (x)) diff --git a/drivers/net/dsa/motorcomm/mib.c b/drivers/net/dsa/motorcomm/mi= b.c new file mode 100644 index 000000000000..74728b1ed777 --- /dev/null +++ b/drivers/net/dsa/motorcomm/mib.c @@ -0,0 +1,373 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2026 David Yang + */ + +#include "chip.h" +#include "mib.h" +#include "smi.h" + +struct yt921x_mib_desc { + unsigned char size; + unsigned char offset; + const char *name; +}; + +#define MIB_DESC(_size, _offset, _name) {_size, _offset, _name} + +/* Must agree with yt921x_mib + * + * Unstructured fields (name !=3D NULL) will appear in get_ethtool_stats(), + * structured go to their *_stats() methods, but we need their sizes and o= ffsets + * to perform 32bit MIB overflow wraparound. + */ +static const struct yt921x_mib_desc yt921x_mib_descs[] =3D { + MIB_DESC(1, YT921X_MIB_DATA_RX_BROADCAST, NULL), + MIB_DESC(1, YT921X_MIB_DATA_RX_PAUSE, NULL), + MIB_DESC(1, YT921X_MIB_DATA_RX_MULTICAST, NULL), + MIB_DESC(1, YT921X_MIB_DATA_RX_CRC_ERR, NULL), + + MIB_DESC(1, YT921X_MIB_DATA_RX_ALIGN_ERR, NULL), + MIB_DESC(1, YT921X_MIB_DATA_RX_UNDERSIZE_ERR, NULL), + MIB_DESC(1, YT921X_MIB_DATA_RX_FRAG_ERR, NULL), + MIB_DESC(1, YT921X_MIB_DATA_RX_PKT_SZ_64, NULL), + + MIB_DESC(1, YT921X_MIB_DATA_RX_PKT_SZ_65_TO_127, NULL), + MIB_DESC(1, YT921X_MIB_DATA_RX_PKT_SZ_128_TO_255, NULL), + MIB_DESC(1, YT921X_MIB_DATA_RX_PKT_SZ_256_TO_511, NULL), + MIB_DESC(1, YT921X_MIB_DATA_RX_PKT_SZ_512_TO_1023, NULL), + + MIB_DESC(1, YT921X_MIB_DATA_RX_PKT_SZ_1024_TO_1518, NULL), + MIB_DESC(1, YT921X_MIB_DATA_RX_PKT_SZ_1519_TO_MAX, NULL), + MIB_DESC(2, YT921X_MIB_DATA_RX_GOOD_BYTES, NULL), + + MIB_DESC(2, YT921X_MIB_DATA_RX_BAD_BYTES, "RxBadBytes"), + MIB_DESC(1, YT921X_MIB_DATA_RX_OVERSIZE_ERR, NULL), + + MIB_DESC(1, YT921X_MIB_DATA_RX_DROPPED, NULL), + MIB_DESC(1, YT921X_MIB_DATA_TX_BROADCAST, NULL), + MIB_DESC(1, YT921X_MIB_DATA_TX_PAUSE, NULL), + MIB_DESC(1, YT921X_MIB_DATA_TX_MULTICAST, NULL), + + MIB_DESC(1, YT921X_MIB_DATA_TX_UNDERSIZE_ERR, NULL), + MIB_DESC(1, YT921X_MIB_DATA_TX_PKT_SZ_64, NULL), + MIB_DESC(1, YT921X_MIB_DATA_TX_PKT_SZ_65_TO_127, NULL), + MIB_DESC(1, YT921X_MIB_DATA_TX_PKT_SZ_128_TO_255, NULL), + + MIB_DESC(1, YT921X_MIB_DATA_TX_PKT_SZ_256_TO_511, NULL), + MIB_DESC(1, YT921X_MIB_DATA_TX_PKT_SZ_512_TO_1023, NULL), + MIB_DESC(1, YT921X_MIB_DATA_TX_PKT_SZ_1024_TO_1518, NULL), + MIB_DESC(1, YT921X_MIB_DATA_TX_PKT_SZ_1519_TO_MAX, NULL), + + MIB_DESC(2, YT921X_MIB_DATA_TX_GOOD_BYTES, NULL), + MIB_DESC(1, YT921X_MIB_DATA_TX_COLLISION, NULL), + + MIB_DESC(1, YT921X_MIB_DATA_TX_EXCESSIVE_COLLISION, NULL), + MIB_DESC(1, YT921X_MIB_DATA_TX_MULTIPLE_COLLISION, NULL), + MIB_DESC(1, YT921X_MIB_DATA_TX_SINGLE_COLLISION, NULL), + MIB_DESC(1, YT921X_MIB_DATA_TX_PKT, NULL), + + MIB_DESC(1, YT921X_MIB_DATA_TX_DEFERRED, NULL), + MIB_DESC(1, YT921X_MIB_DATA_TX_LATE_COLLISION, NULL), + MIB_DESC(1, YT921X_MIB_DATA_RX_OAM, "RxOAM"), + MIB_DESC(1, YT921X_MIB_DATA_TX_OAM, "TxOAM"), +}; + +/* The interval should be small enough to avoid overflow of 32bit MIBs. + * + * Until we can read MIBs from stats64 call directly (i.e. sleep + * there), we have to poll stats more frequently then it is actually neede= d. + * For overflow protection, normally, 100 sec interval should have been OK. + */ +#define YT921X_STATS_INTERVAL_JIFFIES (3 * HZ) + +#define to_yt921x_priv(_ds) container_of_const(_ds, struct yt921x_priv, ds) +#define to_device(priv) ((priv)->ds.dev) + +/* Read and handle overflow of 32bit MIBs. MIB buffer must be zeroed befor= e. */ +static int yt921x_mib_read(struct yt921x_priv *priv, int port) +{ + struct yt921x_port *pp =3D &priv->ports[port]; + struct device *dev =3D to_device(priv); + struct yt921x_mib *mib =3D &pp->mib; + int res =3D 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. + */ + + for (size_t i =3D 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) { + const struct yt921x_mib_desc *desc =3D &yt921x_mib_descs[i]; + u32 reg =3D YT921X_MIBn_DATA0(port) + desc->offset; + u64 *valp =3D &((u64 *)mib)[i]; + u32 val0; + u64 val; + + res =3D yt921x_reg_read(priv, reg, &val0); + if (res) + break; + + if (desc->size <=3D 1) { + u64 old_val =3D *valp; + + val =3D (old_val & ~(u64)U32_MAX) | val0; + if (val < old_val) + val +=3D 1ull << 32; + } else { + u32 val1; + + res =3D yt921x_reg_read(priv, reg + 4, &val1); + if (res) + break; + val =3D ((u64)val1 << 32) | val0; + } + + WRITE_ONCE(*valp, val); + } + + pp->rx_frames =3D 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 =3D 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; + + if (res) + dev_err(dev, "Failed to %s port %d: %i\n", "read stats for", + port, res); + return res; +} + +void yt921x_mib_poll(struct work_struct *work) +{ + struct yt921x_port *pp =3D container_of_const(work, struct yt921x_port, + mib_read.work); + struct yt921x_priv *priv =3D (void *)(pp - pp->index) - + offsetof(struct yt921x_priv, ports); + unsigned long delay =3D YT921X_STATS_INTERVAL_JIFFIES; + int port =3D pp->index; + int res; + + mutex_lock(&priv->reg_lock); + res =3D yt921x_mib_read(priv, port); + mutex_unlock(&priv->reg_lock); + if (res) + delay *=3D 4; + + schedule_delayed_work(&pp->mib_read, delay); +} + +void +yt921x_dsa_get_strings(struct dsa_switch *ds, int port, u32 stringset, + uint8_t *data) +{ + if (stringset !=3D ETH_SS_STATS) + return; + + for (size_t i =3D 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) { + const struct yt921x_mib_desc *desc =3D &yt921x_mib_descs[i]; + + if (desc->name) + ethtool_puts(&data, desc->name); + } +} + +void +yt921x_dsa_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *da= ta) +{ + struct yt921x_priv *priv =3D to_yt921x_priv(ds); + struct yt921x_port *pp =3D &priv->ports[port]; + struct yt921x_mib *mib =3D &pp->mib; + size_t j; + + mutex_lock(&priv->reg_lock); + yt921x_mib_read(priv, port); + mutex_unlock(&priv->reg_lock); + + j =3D 0; + for (size_t i =3D 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) { + const struct yt921x_mib_desc *desc =3D &yt921x_mib_descs[i]; + + if (!desc->name) + continue; + + data[j] =3D ((u64 *)mib)[i]; + j++; + } +} + +int yt921x_dsa_get_sset_count(struct dsa_switch *ds, int port, int sset) +{ + int cnt =3D 0; + + if (sset !=3D ETH_SS_STATS) + return 0; + + for (size_t i =3D 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) { + const struct yt921x_mib_desc *desc =3D &yt921x_mib_descs[i]; + + if (desc->name) + cnt++; + } + + return cnt; +} + +void +yt921x_dsa_get_eth_mac_stats(struct dsa_switch *ds, int port, + struct ethtool_eth_mac_stats *mac_stats) +{ + struct yt921x_priv *priv =3D to_yt921x_priv(ds); + struct yt921x_port *pp =3D &priv->ports[port]; + struct yt921x_mib *mib =3D &pp->mib; + + mutex_lock(&priv->reg_lock); + yt921x_mib_read(priv, port); + mutex_unlock(&priv->reg_lock); + + mac_stats->FramesTransmittedOK =3D pp->tx_frames; + mac_stats->SingleCollisionFrames =3D mib->tx_single_collisions; + mac_stats->MultipleCollisionFrames =3D mib->tx_multiple_collisions; + mac_stats->FramesReceivedOK =3D pp->rx_frames; + mac_stats->FrameCheckSequenceErrors =3D mib->rx_crc_errors; + mac_stats->AlignmentErrors =3D mib->rx_alignment_errors; + mac_stats->OctetsTransmittedOK =3D mib->tx_good_bytes; + mac_stats->FramesWithDeferredXmissions =3D mib->tx_deferred; + mac_stats->LateCollisions =3D mib->tx_late_collisions; + mac_stats->FramesAbortedDueToXSColls =3D mib->tx_aborted_errors; + /* mac_stats->FramesLostDueToIntMACXmitError */ + /* mac_stats->CarrierSenseErrors */ + mac_stats->OctetsReceivedOK =3D mib->rx_good_bytes; + /* mac_stats->FramesLostDueToIntMACRcvError */ + mac_stats->MulticastFramesXmittedOK =3D mib->tx_multicast; + mac_stats->BroadcastFramesXmittedOK =3D mib->tx_broadcast; + /* mac_stats->FramesWithExcessiveDeferral */ + mac_stats->MulticastFramesReceivedOK =3D mib->rx_multicast; + mac_stats->BroadcastFramesReceivedOK =3D mib->rx_broadcast; + /* mac_stats->InRangeLengthErrors */ + /* mac_stats->OutOfRangeLengthField */ + mac_stats->FrameTooLongErrors =3D mib->rx_oversize_errors; +} + +void +yt921x_dsa_get_eth_ctrl_stats(struct dsa_switch *ds, int port, + struct ethtool_eth_ctrl_stats *ctrl_stats) +{ + struct yt921x_priv *priv =3D to_yt921x_priv(ds); + struct yt921x_port *pp =3D &priv->ports[port]; + struct yt921x_mib *mib =3D &pp->mib; + + mutex_lock(&priv->reg_lock); + yt921x_mib_read(priv, port); + mutex_unlock(&priv->reg_lock); + + ctrl_stats->MACControlFramesTransmitted =3D mib->tx_pause; + ctrl_stats->MACControlFramesReceived =3D mib->rx_pause; + /* ctrl_stats->UnsupportedOpcodesReceived */ +} + +static const struct ethtool_rmon_hist_range yt921x_rmon_ranges[] =3D { + { 0, 64 }, + { 65, 127 }, + { 128, 255 }, + { 256, 511 }, + { 512, 1023 }, + { 1024, 1518 }, + { 1519, YT921X_FRAME_SIZE_MAX }, + {} +}; + +void +yt921x_dsa_get_rmon_stats(struct dsa_switch *ds, int port, + struct ethtool_rmon_stats *rmon_stats, + const struct ethtool_rmon_hist_range **ranges) +{ + struct yt921x_priv *priv =3D to_yt921x_priv(ds); + struct yt921x_port *pp =3D &priv->ports[port]; + struct yt921x_mib *mib =3D &pp->mib; + + mutex_lock(&priv->reg_lock); + yt921x_mib_read(priv, port); + mutex_unlock(&priv->reg_lock); + + *ranges =3D yt921x_rmon_ranges; + + rmon_stats->undersize_pkts =3D mib->rx_undersize_errors; + rmon_stats->oversize_pkts =3D mib->rx_oversize_errors; + rmon_stats->fragments =3D mib->rx_alignment_errors; + /* rmon_stats->jabbers */ + + rmon_stats->hist[0] =3D mib->rx_64byte; + rmon_stats->hist[1] =3D mib->rx_65_127byte; + rmon_stats->hist[2] =3D mib->rx_128_255byte; + rmon_stats->hist[3] =3D mib->rx_256_511byte; + rmon_stats->hist[4] =3D mib->rx_512_1023byte; + rmon_stats->hist[5] =3D mib->rx_1024_1518byte; + rmon_stats->hist[6] =3D mib->rx_jumbo; + + rmon_stats->hist_tx[0] =3D mib->tx_64byte; + rmon_stats->hist_tx[1] =3D mib->tx_65_127byte; + rmon_stats->hist_tx[2] =3D mib->tx_128_255byte; + rmon_stats->hist_tx[3] =3D mib->tx_256_511byte; + rmon_stats->hist_tx[4] =3D mib->tx_512_1023byte; + rmon_stats->hist_tx[5] =3D mib->tx_1024_1518byte; + rmon_stats->hist_tx[6] =3D mib->tx_jumbo; +} + +void +yt921x_dsa_get_stats64(struct dsa_switch *ds, int port, + struct rtnl_link_stats64 *stats) +{ + struct yt921x_priv *priv =3D to_yt921x_priv(ds); + struct yt921x_port *pp =3D &priv->ports[port]; + struct yt921x_mib *mib =3D &pp->mib; + + stats->rx_length_errors =3D mib->rx_undersize_errors + + mib->rx_fragment_errors; + stats->rx_over_errors =3D mib->rx_oversize_errors; + stats->rx_crc_errors =3D mib->rx_crc_errors; + stats->rx_frame_errors =3D mib->rx_alignment_errors; + /* stats->rx_fifo_errors */ + /* stats->rx_missed_errors */ + + stats->tx_aborted_errors =3D mib->tx_aborted_errors; + /* stats->tx_carrier_errors */ + stats->tx_fifo_errors =3D mib->tx_undersize_errors; + /* stats->tx_heartbeat_errors */ + stats->tx_window_errors =3D mib->tx_late_collisions; + + stats->rx_packets =3D pp->rx_frames; + stats->tx_packets =3D pp->tx_frames; + stats->rx_bytes =3D mib->rx_good_bytes - ETH_FCS_LEN * stats->rx_packets; + stats->tx_bytes =3D mib->tx_good_bytes - ETH_FCS_LEN * stats->tx_packets; + stats->rx_errors =3D stats->rx_length_errors + stats->rx_over_errors + + stats->rx_crc_errors + stats->rx_frame_errors; + stats->tx_errors =3D stats->tx_aborted_errors + stats->tx_fifo_errors + + stats->tx_window_errors; + stats->rx_dropped =3D mib->rx_dropped; + /* stats->tx_dropped */ + stats->multicast =3D mib->rx_multicast; + stats->collisions =3D mib->tx_collisions; +} + +void +yt921x_dsa_get_pause_stats(struct dsa_switch *ds, int port, + struct ethtool_pause_stats *pause_stats) +{ + struct yt921x_priv *priv =3D to_yt921x_priv(ds); + struct yt921x_port *pp =3D &priv->ports[port]; + struct yt921x_mib *mib =3D &pp->mib; + + mutex_lock(&priv->reg_lock); + yt921x_mib_read(priv, port); + mutex_unlock(&priv->reg_lock); + + pause_stats->tx_pause_frames =3D mib->tx_pause; + pause_stats->rx_pause_frames =3D mib->rx_pause; +} diff --git a/drivers/net/dsa/motorcomm/mib.h b/drivers/net/dsa/motorcomm/mi= b.h new file mode 100644 index 000000000000..c6728366df6e --- /dev/null +++ b/drivers/net/dsa/motorcomm/mib.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2026 David Yang + */ + +#ifndef _YT_MIB_H +#define _YT_MIB_H + +#include + +#define YT921X_MIB_CTRL 0xc0004 +#define YT921X_MIB_CTRL_CLEAN BIT(30) +#define YT921X_MIB_CTRL_PORT_M GENMASK(6, 3) +#define YT921X_MIB_CTRL_PORT(x) FIELD_PREP(YT921X_MIB_CTRL_PORT_M, (x)) +#define YT921X_MIB_CTRL_ONE_PORT BIT(1) +#define YT921X_MIB_CTRL_ALL_PORT BIT(0) +#define YT921X_MIBn_DATA0(port) (0xc0100 + 0x100 * (port)) +#define YT921X_MIBn_DATAm(port, x) (YT921X_MIBn_DATA0(port) + 4 * (x)) +#define YT921X_MIB_DATA_RX_BROADCAST 0x00 +#define YT921X_MIB_DATA_RX_PAUSE 0x04 +#define YT921X_MIB_DATA_RX_MULTICAST 0x08 +#define YT921X_MIB_DATA_RX_CRC_ERR 0x0c + +#define YT921X_MIB_DATA_RX_ALIGN_ERR 0x10 +#define YT921X_MIB_DATA_RX_UNDERSIZE_ERR 0x14 +#define YT921X_MIB_DATA_RX_FRAG_ERR 0x18 +#define YT921X_MIB_DATA_RX_PKT_SZ_64 0x1c + +#define YT921X_MIB_DATA_RX_PKT_SZ_65_TO_127 0x20 +#define YT921X_MIB_DATA_RX_PKT_SZ_128_TO_255 0x24 +#define YT921X_MIB_DATA_RX_PKT_SZ_256_TO_511 0x28 +#define YT921X_MIB_DATA_RX_PKT_SZ_512_TO_1023 0x2c + +#define YT921X_MIB_DATA_RX_PKT_SZ_1024_TO_1518 0x30 +#define YT921X_MIB_DATA_RX_PKT_SZ_1519_TO_MAX 0x34 +/* 0x38: unused */ +#define YT921X_MIB_DATA_RX_GOOD_BYTES 0x3c + +/* 0x40: 64 bytes */ +#define YT921X_MIB_DATA_RX_BAD_BYTES 0x44 +/* 0x48: 64 bytes */ +#define YT921X_MIB_DATA_RX_OVERSIZE_ERR 0x4c + +#define YT921X_MIB_DATA_RX_DROPPED 0x50 +#define YT921X_MIB_DATA_TX_BROADCAST 0x54 +#define YT921X_MIB_DATA_TX_PAUSE 0x58 +#define YT921X_MIB_DATA_TX_MULTICAST 0x5c + +#define YT921X_MIB_DATA_TX_UNDERSIZE_ERR 0x60 +#define YT921X_MIB_DATA_TX_PKT_SZ_64 0x64 +#define YT921X_MIB_DATA_TX_PKT_SZ_65_TO_127 0x68 +#define YT921X_MIB_DATA_TX_PKT_SZ_128_TO_255 0x6c + +#define YT921X_MIB_DATA_TX_PKT_SZ_256_TO_511 0x70 +#define YT921X_MIB_DATA_TX_PKT_SZ_512_TO_1023 0x74 +#define YT921X_MIB_DATA_TX_PKT_SZ_1024_TO_1518 0x78 +#define YT921X_MIB_DATA_TX_PKT_SZ_1519_TO_MAX 0x7c + +/* 0x80: unused */ +#define YT921X_MIB_DATA_TX_GOOD_BYTES 0x84 +/* 0x88: 64 bytes */ +#define YT921X_MIB_DATA_TX_COLLISION 0x8c + +#define YT921X_MIB_DATA_TX_EXCESSIVE_COLLISION 0x90 +#define YT921X_MIB_DATA_TX_MULTIPLE_COLLISION 0x94 +#define YT921X_MIB_DATA_TX_SINGLE_COLLISION 0x98 +#define YT921X_MIB_DATA_TX_PKT 0x9c + +#define YT921X_MIB_DATA_TX_DEFERRED 0xa0 +#define YT921X_MIB_DATA_TX_LATE_COLLISION 0xa4 +#define YT921X_MIB_DATA_RX_OAM 0xa8 +#define YT921X_MIB_DATA_TX_OAM 0xac + +void yt921x_mib_poll(struct work_struct *work); +void +yt921x_dsa_get_strings(struct dsa_switch *ds, int port, u32 stringset, + uint8_t *data); +void +yt921x_dsa_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *da= ta); +int yt921x_dsa_get_sset_count(struct dsa_switch *ds, int port, int sset); +void +yt921x_dsa_get_eth_mac_stats(struct dsa_switch *ds, int port, + struct ethtool_eth_mac_stats *mac_stats); +void +yt921x_dsa_get_eth_ctrl_stats(struct dsa_switch *ds, int port, + struct ethtool_eth_ctrl_stats *ctrl_stats); +void +yt921x_dsa_get_rmon_stats(struct dsa_switch *ds, int port, + struct ethtool_rmon_stats *rmon_stats, + const struct ethtool_rmon_hist_range **ranges); +void +yt921x_dsa_get_stats64(struct dsa_switch *ds, int port, + struct rtnl_link_stats64 *stats); +void +yt921x_dsa_get_pause_stats(struct dsa_switch *ds, int port, + struct ethtool_pause_stats *pause_stats); + +#endif --=20 2.53.0 From nobody Sat Sep 26 07:14:52 2026 Received: from mail-pj1-f54.google.com (mail-pj1-f54.google.com [209.85.216.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 887694BCAA4 for ; Thu, 3 Sep 2026 14:38:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788446292; cv=none; b=RSCoWUwitjXBTQF3r2CXXPPvF+xDERuKi2ftt6Kwob2RAyVNYu4Hm5fU+NbhLSxtwcFhOJBZnPxGaOteI1cgdSzoD6izqz4vHIg/haRs2IX+pO/dG/iPj6qO/WE9xo/H5WaZqUIEV0TmyX1v2Yw4VXys/CicoPmbtBxW7LHASOQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788446292; c=relaxed/simple; bh=lrHGsnMu75xl8v76dJVetLK23k6vmOupMrZqyuDZRuY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u/0bM4J+Etvqbk8QJwg34Y0Ht/hmmrc6X1cCwLdJA32vXJRSkUlnP2ixXgyG+Wlu23s7NRFM6XJGRtprCnY+emg+nHWKcV18uFx68F/asH8CA1S/abzAHIH48sBeEwyqircD0svBsihEeM/7oRs8TsntRJ+4fS8RzldWFRwgFVo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=qSjAXr0r; arc=none smtp.client-ip=209.85.216.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qSjAXr0r" Received: by mail-pj1-f54.google.com with SMTP id 98e67ed59e1d1-381b831d535so3956635a91.0 for ; Thu, 03 Sep 2026 07:38:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788446282; x=1789051082; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=NcD5uN5fp5EswiCHXuiZ4B8QQTZVN5ZDP+x7PcjVnFA=; b=qSjAXr0rV3h0VC2y1/g5SuslndMREpUnoU5e4EDxoJTfDHlmTvdFGHjrMuQAJan0NJ yfUfgew8dvDC8XqEuE4L/KZzYr8scw38MqwJQWV6Kfcad4mUKqh591zge96L26BR0Ur8 F5c7GC6QqEOUJ2fiHHQlkXlDeZ0vy9yAgXXEVP557lMQF0VTRK6q/5g4cb8buYdwIOUl De82q8pDf/6DLDbbOXl8bPvtK05ZPln9mmd+Ef6SgRPE/osMC1TqcTxrx8GEtM9L2Dej 62MrC8nYVU12All6RAsEZ2clzb5JIaPC7DUTcdQlOVjlljH5OJOeBagxtDyR5+AEuidK 72Lw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788446282; x=1789051082; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=NcD5uN5fp5EswiCHXuiZ4B8QQTZVN5ZDP+x7PcjVnFA=; b=Lfh29zgUzInJ8cISiSeJWnpcSDJqQLNQP820W6jw9JuN90oPBeibuD/1LpdANwhkUL HFQ09BVzmH9o9fkWHYUjRN12yZlZOviH/ZlJXNgfSSF+Q8RdGZq2dOpqZP5Dt2zowz7G LEHm8otT0sdAH1bIXhieLJFHdMXzm1W2lai1z4PcSo5Jt2HE5u8kHFXOP6tKUhzKvU4j 3AHCDdfUcuF5MJND9vriwEcqQqwQmHpa1jhCEZR5Cq5ljoPLdARwwB7fYy11SLq7+0li Wc4u3uAa0ixvv1qd8SCWfA0QyEPKT4LBWRY8jMrtqaqQsfcYpqc+cFEKZyys/On/Wm0c zm/A== X-Forwarded-Encrypted: i=1; AKwUvByLU8U2cjj9pgefO+7g9azryw2M2QvkplEvWraD0ksG+t0DjwJJSzGP6wVRma1Jcpd4Ilz/yRVAFW/Eq38=@vger.kernel.org X-Gm-Message-State: AFuF++ktVPKVPiPYNBu19PqS7fvw72ngGKkU0smB7csEV9pyIxam+u0w qz8r0+/4KKrss7pgay13w8KrZIFtkYFZYw+ma9zbxf4Czlm7geDFiDloIrGIlw== X-Gm-Gg: AYBFou1EwyfIO+MDsjtg+EBPtTM6VPBi2jI8W2Ul6vF1QSlBhCTBVZwLPbORL53qHnw Q9EXoneheVtpWtdTvh+N0KUQXDfyplRbEPvhxbPUVI5mFcqdvpuXcoGivyGxjuejTd22ZjtDYnT gvfu5u5iPHdz+BPFEUiOZAucMm8Bsmf5jFEVTV38MUB3q9iBE/qwqwmTJ+HPEul9uqh6t8hmUYO 8BXy8bY3SJf4WT8I/rp6Gbcqg8zvKa96KgNiYuc6UvQ1JjL5H9ddxI2RZLKkNBhKScyTBjJe6tl IW4V8hA+1SXTkot/A98z+5SkU+xi4Pg0ODqFsXg4KnrxDLz6vZq0pv/dK16b4C3KUzPXOXnJ9Uq UcpGKDavbb3FHOTpcye6ErzxRo3YrXjyTBpzNI7AvI6NyyEja7Z27Aae1BYRfAjGNxKDnVrgVv7 qlPUUBMhOTlsjpy2VYB98Db20nOKWhPBhkMFWFtcPzmlR495ibVgMujEGshrfCJILM5/PSCNp64 0KYn8bFVuanWJY= X-Received: by 2002:a17:90b:1845:b0:396:6344:3b63 with SMTP id 98e67ed59e1d1-39b22e6bb12mr202436a91.2.1788446281446; Thu, 03 Sep 2026 07:38:01 -0700 (PDT) Received: from d.home.yangfl.dn42 ([2a09:bac5:661d:3050::4d0:16]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-39ae9087d3dsm2741889a91.3.2026.09.03.07.37.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Sep 2026 07:38:01 -0700 (PDT) From: David Yang To: netdev@vger.kernel.org Cc: David Yang , Andrew Lunn , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , linux-kernel@vger.kernel.org Subject: [PATCH net-next 2/4] net: dsa: motorcomm: Split MIB buffers Date: Thu, 3 Sep 2026 22:35:07 +0800 Message-ID: <20260903143514.532023-3-mmyangfl@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903143514.532023-1-mmyangfl@gmail.com> References: <20260903143514.532023-1-mmyangfl@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" With MIB improvement introduced later, struct yt921x_priv will be over 20k which is not very good for a single kmalloc(). Dynamically allocate the MIB structures to reduce the size of struct yt921x_priv, and do not waste memory on dummy ports. Signed-off-by: David Yang --- drivers/net/dsa/motorcomm/chip.c | 42 +++++++++++++++---- drivers/net/dsa/motorcomm/chip.h | 63 ++-------------------------- drivers/net/dsa/motorcomm/mib.c | 70 ++++++++++++++++++++++++-------- drivers/net/dsa/motorcomm/mib.h | 61 ++++++++++++++++++++++++++++ 4 files changed, 150 insertions(+), 86 deletions(-) diff --git a/drivers/net/dsa/motorcomm/chip.c b/drivers/net/dsa/motorcomm/c= hip.c index 77440bf5fa7a..d8520c38f9c7 100644 --- a/drivers/net/dsa/motorcomm/chip.c +++ b/drivers/net/dsa/motorcomm/chip.c @@ -3591,11 +3591,14 @@ yt921x_phylink_mac_link_down(struct phylink_config = *config, unsigned int mode, { struct dsa_port *dp =3D dsa_phylink_to_port(config); struct yt921x_priv *priv =3D to_yt921x_priv(dp->ds); + struct yt921x_mib *pm; int port =3D dp->index; int res; =20 /* No need to sync; port control block is hold until device remove */ - cancel_delayed_work(&priv->ports[port].mib_read); + pm =3D priv->ports[port].mib; + if (pm) + cancel_delayed_work(&pm->work); =20 mutex_lock(&priv->reg_lock); res =3D yt921x_port_down(priv, port); @@ -3614,6 +3617,7 @@ yt921x_phylink_mac_link_up(struct phylink_config *con= fig, { struct dsa_port *dp =3D dsa_phylink_to_port(config); struct yt921x_priv *priv =3D to_yt921x_priv(dp->ds); + struct yt921x_mib *pm; int port =3D dp->index; int res; =20 @@ -3626,7 +3630,9 @@ yt921x_phylink_mac_link_up(struct phylink_config *con= fig, dev_err(dp->ds->dev, "Failed to %s port %d: %i\n", "bring up", port, res); =20 - schedule_delayed_work(&priv->ports[port].mib_read, 0); + pm =3D priv->ports[port].mib; + if (pm) + schedule_delayed_work(&pm->work, 0); } =20 static void @@ -3746,11 +3752,35 @@ yt921x_dsa_get_tag_protocol(struct dsa_switch *ds, = int port, return DSA_TAG_PROTO_YT921X; } =20 +static void yt921x_dsa_port_teardown(struct dsa_switch *ds, int port) +{ + struct yt921x_priv *priv =3D to_yt921x_priv(ds); + struct yt921x_port *pp =3D &priv->ports[port]; + struct yt921x_mib *pm =3D pp->mib; + + if (pm) + disable_delayed_work_sync(&pm->work); +} + static int yt921x_dsa_port_setup(struct dsa_switch *ds, int port) { struct yt921x_priv *priv =3D to_yt921x_priv(ds); + struct yt921x_port *pp =3D &priv->ports[port]; + struct device *dev =3D to_device(priv); + struct yt921x_mib *pm =3D pp->mib; int res; =20 + if (!pm && !(BIT(port) & (priv->info->internal_mask | + priv->info->external_mask))) { + pm =3D devm_kzalloc(dev, sizeof(*pm), GFP_KERNEL); + if (!pm) + return -ENOMEM; + pp->mib =3D pm; + + pm->port =3D pp; + INIT_DELAYED_WORK(&pm->work, yt921x_mib_poll); + } + mutex_lock(&priv->reg_lock); res =3D yt921x_port_setup(priv, port); mutex_unlock(&priv->reg_lock); @@ -4305,6 +4335,7 @@ static const struct dsa_switch_ops yt921x_dsa_switch_= ops =3D { /* port */ .get_tag_protocol =3D yt921x_dsa_get_tag_protocol, .phylink_get_caps =3D yt921x_dsa_phylink_get_caps, + .port_teardown =3D yt921x_dsa_port_teardown, .port_setup =3D yt921x_dsa_port_setup, #if IS_ENABLED(CONFIG_DCB) /* dscp */ @@ -4334,12 +4365,6 @@ static void yt921x_mdio_remove(struct mdio_device *m= diodev) if (!priv) return; =20 - for (size_t i =3D ARRAY_SIZE(priv->ports); i-- > 0; ) { - struct yt921x_port *pp =3D &priv->ports[i]; - - disable_delayed_work_sync(&pp->mib_read); - } - dsa_unregister_switch(&priv->ds); =20 for (unsigned int i =3D 0; i < ARRAY_SIZE(priv->acl_blks); i++) { @@ -4387,7 +4412,6 @@ static int yt921x_mdio_probe(struct mdio_device *mdio= dev) struct yt921x_port *pp =3D &priv->ports[i]; =20 pp->index =3D i; - INIT_DELAYED_WORK(&pp->mib_read, yt921x_mib_poll); } =20 ds =3D &priv->ds; diff --git a/drivers/net/dsa/motorcomm/chip.h b/drivers/net/dsa/motorcomm/c= hip.h index 84c7065b1cd4..ce2015026849 100644 --- a/drivers/net/dsa/motorcomm/chip.h +++ b/drivers/net/dsa/motorcomm/chip.h @@ -798,58 +798,6 @@ enum yt921x_fdb_entry_status { #define yt921x_port_is_internal(port) ((port) < 8) #define yt921x_port_is_external(port) ((port) =3D=3D 8 || (port) =3D=3D 9) =20 -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; -}; - struct yt921x_acl_entry { u32 key[2]; u32 mask[2]; @@ -873,13 +821,8 @@ struct yt921x_acl_blk { struct yt921x_port { unsigned char index; =20 - bool hairpin; - bool isolated; - - struct delayed_work mib_read; - struct yt921x_mib mib; - u64 rx_frames; - u64 tx_frames; + bool hairpin:1; + bool isolated:1; =20 #if IS_ENABLED(CONFIG_NET_DSA_YT921X_LEDS) unsigned char led_duty; @@ -890,6 +833,8 @@ struct yt921x_port { =20 struct yt921x_led *leds[YT921X_LED_GROUP_NUM]; #endif + + struct yt921x_mib *mib; }; =20 struct yt921x_reg_ops { diff --git a/drivers/net/dsa/motorcomm/mib.c b/drivers/net/dsa/motorcomm/mi= b.c index 74728b1ed777..ee76cdf216e6 100644 --- a/drivers/net/dsa/motorcomm/mib.c +++ b/drivers/net/dsa/motorcomm/mib.c @@ -89,9 +89,12 @@ static int yt921x_mib_read(struct yt921x_priv *priv, int= port) { struct yt921x_port *pp =3D &priv->ports[port]; struct device *dev =3D to_device(priv); - struct yt921x_mib *mib =3D &pp->mib; + struct yt921x_mib *pm =3D pp->mib; + struct yt921x_mib_stats *mib; int res =3D 0; =20 + mib =3D &pm->stats; + /* 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. @@ -129,11 +132,11 @@ static int yt921x_mib_read(struct yt921x_priv *priv, = int port) WRITE_ONCE(*valp, val); } =20 - pp->rx_frames =3D mib->rx_64byte + mib->rx_65_127byte + + pm->rx_frames =3D 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 =3D mib->tx_64byte + mib->tx_65_127byte + + pm->tx_frames =3D 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; @@ -146,10 +149,11 @@ static int yt921x_mib_read(struct yt921x_priv *priv, = int port) =20 void yt921x_mib_poll(struct work_struct *work) { - struct yt921x_port *pp =3D container_of_const(work, struct yt921x_port, - mib_read.work); - struct yt921x_priv *priv =3D (void *)(pp - pp->index) - - offsetof(struct yt921x_priv, ports); + struct yt921x_mib *pm =3D container_of_const(work, struct yt921x_mib, + work.work); + struct yt921x_port *pp =3D pm->port; + struct yt921x_priv *priv =3D container_of_const(pp, struct yt921x_priv, + ports[pp->index]); unsigned long delay =3D YT921X_STATS_INTERVAL_JIFFIES; int port =3D pp->index; int res; @@ -160,7 +164,7 @@ void yt921x_mib_poll(struct work_struct *work) if (res) delay *=3D 4; =20 - schedule_delayed_work(&pp->mib_read, delay); + schedule_delayed_work(&pm->work, delay); } =20 void @@ -183,9 +187,14 @@ yt921x_dsa_get_ethtool_stats(struct dsa_switch *ds, in= t port, uint64_t *data) { struct yt921x_priv *priv =3D to_yt921x_priv(ds); struct yt921x_port *pp =3D &priv->ports[port]; - struct yt921x_mib *mib =3D &pp->mib; + struct yt921x_mib *pm =3D pp->mib; + struct yt921x_mib_stats *mib; size_t j; =20 + if (!pm) + return; + mib =3D &pm->stats; + mutex_lock(&priv->reg_lock); yt921x_mib_read(priv, port); mutex_unlock(&priv->reg_lock); @@ -225,16 +234,21 @@ yt921x_dsa_get_eth_mac_stats(struct dsa_switch *ds, i= nt port, { struct yt921x_priv *priv =3D to_yt921x_priv(ds); struct yt921x_port *pp =3D &priv->ports[port]; - struct yt921x_mib *mib =3D &pp->mib; + struct yt921x_mib *pm =3D pp->mib; + struct yt921x_mib_stats *mib; + + if (!pm) + return; + mib =3D &pm->stats; =20 mutex_lock(&priv->reg_lock); yt921x_mib_read(priv, port); mutex_unlock(&priv->reg_lock); =20 - mac_stats->FramesTransmittedOK =3D pp->tx_frames; + mac_stats->FramesTransmittedOK =3D pm->tx_frames; mac_stats->SingleCollisionFrames =3D mib->tx_single_collisions; mac_stats->MultipleCollisionFrames =3D mib->tx_multiple_collisions; - mac_stats->FramesReceivedOK =3D pp->rx_frames; + mac_stats->FramesReceivedOK =3D pm->rx_frames; mac_stats->FrameCheckSequenceErrors =3D mib->rx_crc_errors; mac_stats->AlignmentErrors =3D mib->rx_alignment_errors; mac_stats->OctetsTransmittedOK =3D mib->tx_good_bytes; @@ -261,7 +275,12 @@ yt921x_dsa_get_eth_ctrl_stats(struct dsa_switch *ds, i= nt port, { struct yt921x_priv *priv =3D to_yt921x_priv(ds); struct yt921x_port *pp =3D &priv->ports[port]; - struct yt921x_mib *mib =3D &pp->mib; + struct yt921x_mib *pm =3D pp->mib; + struct yt921x_mib_stats *mib; + + if (!pm) + return; + mib =3D &pm->stats; =20 mutex_lock(&priv->reg_lock); yt921x_mib_read(priv, port); @@ -290,7 +309,12 @@ yt921x_dsa_get_rmon_stats(struct dsa_switch *ds, int p= ort, { struct yt921x_priv *priv =3D to_yt921x_priv(ds); struct yt921x_port *pp =3D &priv->ports[port]; - struct yt921x_mib *mib =3D &pp->mib; + struct yt921x_mib *pm =3D pp->mib; + struct yt921x_mib_stats *mib; + + if (!pm) + return; + mib =3D &pm->stats; =20 mutex_lock(&priv->reg_lock); yt921x_mib_read(priv, port); @@ -326,7 +350,12 @@ yt921x_dsa_get_stats64(struct dsa_switch *ds, int port, { struct yt921x_priv *priv =3D to_yt921x_priv(ds); struct yt921x_port *pp =3D &priv->ports[port]; - struct yt921x_mib *mib =3D &pp->mib; + struct yt921x_mib *pm =3D pp->mib; + struct yt921x_mib_stats *mib; + + if (!pm) + return; + mib =3D &pm->stats; =20 stats->rx_length_errors =3D mib->rx_undersize_errors + mib->rx_fragment_errors; @@ -342,8 +371,8 @@ yt921x_dsa_get_stats64(struct dsa_switch *ds, int port, /* stats->tx_heartbeat_errors */ stats->tx_window_errors =3D mib->tx_late_collisions; =20 - stats->rx_packets =3D pp->rx_frames; - stats->tx_packets =3D pp->tx_frames; + stats->rx_packets =3D pm->rx_frames; + stats->tx_packets =3D pm->tx_frames; stats->rx_bytes =3D mib->rx_good_bytes - ETH_FCS_LEN * stats->rx_packets; stats->tx_bytes =3D mib->tx_good_bytes - ETH_FCS_LEN * stats->tx_packets; stats->rx_errors =3D stats->rx_length_errors + stats->rx_over_errors + @@ -362,7 +391,12 @@ yt921x_dsa_get_pause_stats(struct dsa_switch *ds, int = port, { struct yt921x_priv *priv =3D to_yt921x_priv(ds); struct yt921x_port *pp =3D &priv->ports[port]; - struct yt921x_mib *mib =3D &pp->mib; + struct yt921x_mib *pm =3D pp->mib; + struct yt921x_mib_stats *mib; + + if (!pm) + return; + mib =3D &pm->stats; =20 mutex_lock(&priv->reg_lock); yt921x_mib_read(priv, port); diff --git a/drivers/net/dsa/motorcomm/mib.h b/drivers/net/dsa/motorcomm/mi= b.h index c6728366df6e..cfad0665baae 100644 --- a/drivers/net/dsa/motorcomm/mib.h +++ b/drivers/net/dsa/motorcomm/mib.h @@ -71,6 +71,67 @@ #define YT921X_MIB_DATA_RX_OAM 0xa8 #define YT921X_MIB_DATA_TX_OAM 0xac =20 +struct yt921x_mib_stats { + 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; +}; + +struct yt921x_mib { + struct yt921x_port *port; + + struct delayed_work work; + struct yt921x_mib_stats stats; + u64 rx_frames; + u64 tx_frames; +}; + void yt921x_mib_poll(struct work_struct *work); void yt921x_dsa_get_strings(struct dsa_switch *ds, int port, u32 stringset, --=20 2.53.0 From nobody Sat Sep 26 07:14:52 2026 Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 89CD44BC029 for ; Thu, 3 Sep 2026 14:38:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788446296; cv=none; b=V2lM7eyDRzD2uY9aWRBzj7jkMnBKWQx63dtlfhV8goz1u9/xAm5y5/eMEuLOVvUlz42eM8fbeSMirjelgJ7cUDQildxyBajuKXZ0SLI3fiU4StRamLAXwj4/ZOubntV0rbY17bezjocDG6MrJ7u+FZq7Jux27S3RT42Vh0TFUO8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788446296; c=relaxed/simple; bh=guNcGvme9pNH+ZREWpHwq587dQe1vgHh7nY2c/h7XNw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=e+k9n7SuebA8w/0HLnlnz+lfoPphvti9toVWQe8d0o8mQnOaD8AGbdEOiHkbGEiQMgCrIKszlvRfhwUntXsigCspLENOQzOVBSqiWXvsSbmEVUVZYp+BL/CIsV5XTCYUI/2D+WWrrdylYxIQcHW8ij6SIOG7nybqLSYzqvbKMCI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Yql/8Cuh; arc=none smtp.client-ip=209.85.216.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Yql/8Cuh" Received: by mail-pj1-f41.google.com with SMTP id 98e67ed59e1d1-395cf2535acso1239748a91.1 for ; Thu, 03 Sep 2026 07:38:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788446286; x=1789051086; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=sy8LbnDRxw75nK0zcS8DY2JP7kyh+cC4gS7xcoC6dgw=; b=Yql/8CuhA6IyhHxw4VVn75iC2Jppv1obROeLP/N1Q+/K3Wvkfo5RASFU5ApPZ6jFMs 6s7njla3IHOm5YhDungha6cmN3QOeE+7CogI6VbU7FEgw+TH9Lm+Gm2uLYTncUPgyNOC O3b+nH65pwemP2yLC666uZcGw5ojzDjX4i5fdR7j5Tnuz4u8X3XwpKF8yFNNsziAjnEA 4Wy1KEy/Ke8RkZcvQSP54phEh63lnLTcd6Y6AxEzfRZyhRSgfzpg4EE7HmMNO22ORg6n 83F7w3wVYY6QnoxF+5CNfiD+v4J13kZyvmpTh3OyJVsjHs4NtiZ3IwZ0RptiJ6wWtp6s qz8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788446286; x=1789051086; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=sy8LbnDRxw75nK0zcS8DY2JP7kyh+cC4gS7xcoC6dgw=; b=kWeOijDOD8NJomEoIQcG/CigZm5sj1i6G7DYoZFpFasRL3cDEl705MQ0c7x5153xFs 1u9uJiHt4QKfKWyGqnUTLadXAJVvtymYOWGh9VPcGmDX4nJeB8NthmfHVF0z02ecqi00 GGbdeemmTP5hnuTvszJ/7MVUmTLSkszfpJWXEakHCHvvXdc0SvfraT+ZoF368QkxqyRE VOgDU7+SvLdAcfJJ6dirwIzzfRrv3KAUOi49QZnjZHLNN2syvfiAOEmX/Ig6qJDQn40d pxyR0SFSNMLH9bGYA53egusDDegPa1aswyrGKaH1HjBTD7ty9WiW6uDqmNaDHu3Le6Gj Ttsw== X-Forwarded-Encrypted: i=1; AKwUvBxaH4/xyu2tiTZOnC7D5El1m1DcbNFbi0UqXIXWEB3yxtH6P1ZHXZqtIB17Xk9uGvSrK3FLaKDWlSReI4Y=@vger.kernel.org X-Gm-Message-State: AFuF++lmUCm76YubuyW11HS5vtcCyOVijle8lkI+KFj2hvBQuhk3dd15 RldNCB41HgaG+ESdiKEHS1h1FBP4kVkD4LdQoKWQPUe/OGwi8W/0uaGY X-Gm-Gg: AYBFou35nubpgq6XJhBu5CqyfeFF9BD5qeM9fDje0IDPo9ZyHXH/LNeXnumiL1cCVbV mecZ8c2WhYBagB+j5AoRojMlJEI2AUeuJyIXCnPS+HYyRUCIkNDNQME25ZOUqX02pZS3p1Bt6s5 rzOGYArwvMUZHz/StkIofHxKhwIwglM17KQB8umhfWKhtC5Z2hWGB2TRTEaErRIw3ArPea0YNEv 1nlE/wgyG+zZ+09o8xNjU9NtiDMCkFtwBFDgVzCs9Act6YIq3/aixBLn/JatJhw3iFI/x6NRErl WQv9oeRxS6KnSXCjeiyXyEDnCmURtCsYNbpo50jUyOZuJEOSU6onRgbEdEfKSuVT8GwYwfU8ruz IySzl5qCvMtwAQga3XH628LcbwjuYatkhoucW0qOaZUhGg9HhHq9u1M5Wl8gMcVYUME8xv6kLRH VueoLCoJQImEbmC8EpvSG40FoEGnkDBuNjbWG8wz4jiyWYv0EUzmiAatFmJtSZ/lqoqn7Jzk727 zPOtecMDQFdC1Sd1b7jOEq2ucUa X-Received: by 2002:a17:90b:3cc3:b0:398:9bd3:d6d4 with SMTP id 98e67ed59e1d1-39b132d819emr3400707a91.14.1788446284881; Thu, 03 Sep 2026 07:38:04 -0700 (PDT) Received: from d.home.yangfl.dn42 ([2a09:bac5:661d:3050::4d0:16]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-39ae9087d3dsm2741889a91.3.2026.09.03.07.38.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Sep 2026 07:38:04 -0700 (PDT) From: David Yang To: netdev@vger.kernel.org Cc: David Yang , Andrew Lunn , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , linux-kernel@vger.kernel.org Subject: [PATCH net-next 3/4] net: dsa: motorcomm: Use u64_stats_t for MIB stats Date: Thu, 3 Sep 2026 22:35:08 +0800 Message-ID: <20260903143514.532023-4-mmyangfl@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903143514.532023-1-mmyangfl@gmail.com> References: <20260903143514.532023-1-mmyangfl@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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/motorcomm/chip.c | 2 + drivers/net/dsa/motorcomm/mib.c | 196 +++++++++++++++++-------------- drivers/net/dsa/motorcomm/mib.h | 110 +++++++++-------- 3 files changed, 172 insertions(+), 136 deletions(-) diff --git a/drivers/net/dsa/motorcomm/chip.c b/drivers/net/dsa/motorcomm/c= hip.c index d8520c38f9c7..b4059053ef15 100644 --- a/drivers/net/dsa/motorcomm/chip.c +++ b/drivers/net/dsa/motorcomm/chip.c @@ -19,6 +19,7 @@ #include #include #include +#include =20 #include #include @@ -3778,6 +3779,7 @@ static int yt921x_dsa_port_setup(struct dsa_switch *d= s, int port) pp->mib =3D pm; =20 pm->port =3D pp; + u64_stats_init(&pm->syncp); INIT_DELAYED_WORK(&pm->work, yt921x_mib_poll); } =20 diff --git a/drivers/net/dsa/motorcomm/mib.c b/drivers/net/dsa/motorcomm/mi= b.c index ee76cdf216e6..73b2a9f52996 100644 --- a/drivers/net/dsa/motorcomm/mib.c +++ b/drivers/net/dsa/motorcomm/mib.c @@ -91,22 +91,16 @@ static int yt921x_mib_read(struct yt921x_priv *priv, in= t port) struct device *dev =3D to_device(priv); struct yt921x_mib *pm =3D pp->mib; struct yt921x_mib_stats *mib; + u64 *buf =3D pm->data; + u64 rx_frames; + u64 tx_frames; int res =3D 0; =20 mib =3D &pm->stats; =20 - /* 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. - */ - for (size_t i =3D 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) { const struct yt921x_mib_desc *desc =3D &yt921x_mib_descs[i]; u32 reg =3D YT921X_MIBn_DATA0(port) + desc->offset; - u64 *valp =3D &((u64 *)mib)[i]; u32 val0; u64 val; =20 @@ -115,7 +109,7 @@ static int yt921x_mib_read(struct yt921x_priv *priv, in= t port) break; =20 if (desc->size <=3D 1) { - u64 old_val =3D *valp; + u64 old_val =3D buf[i]; =20 val =3D (old_val & ~(u64)U32_MAX) | val0; if (val < old_val) @@ -129,17 +123,29 @@ static int yt921x_mib_read(struct yt921x_priv *priv, = int port) val =3D ((u64)val1 << 32) | val0; } =20 - WRITE_ONCE(*valp, val); + buf[i] =3D val; } =20 - pm->rx_frames =3D 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; - pm->tx_frames =3D 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; + u64_stats_update_begin(&pm->syncp); + for (size_t i =3D 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) + u64_stats_set(&((u64_stats_t *)mib)[i], buf[i]); + rx_frames =3D u64_stats_read(&mib->rx_64byte) + + u64_stats_read(&mib->rx_65_127byte) + + u64_stats_read(&mib->rx_128_255byte) + + u64_stats_read(&mib->rx_256_511byte) + + u64_stats_read(&mib->rx_512_1023byte) + + u64_stats_read(&mib->rx_1024_1518byte) + + u64_stats_read(&mib->rx_jumbo); + tx_frames =3D u64_stats_read(&mib->tx_64byte) + + u64_stats_read(&mib->tx_65_127byte) + + u64_stats_read(&mib->tx_128_255byte) + + u64_stats_read(&mib->tx_256_511byte) + + u64_stats_read(&mib->tx_512_1023byte) + + u64_stats_read(&mib->tx_1024_1518byte) + + u64_stats_read(&mib->tx_jumbo); + u64_stats_set(&pm->rx_frames, rx_frames); + u64_stats_set(&pm->tx_frames, tx_frames); + u64_stats_update_end(&pm->syncp); =20 if (res) dev_err(dev, "Failed to %s port %d: %i\n", "read stats for", @@ -189,15 +195,17 @@ yt921x_dsa_get_ethtool_stats(struct dsa_switch *ds, i= nt port, uint64_t *data) struct yt921x_port *pp =3D &priv->ports[port]; struct yt921x_mib *pm =3D pp->mib; struct yt921x_mib_stats *mib; + u64 *buf; size_t j; =20 if (!pm) return; mib =3D &pm->stats; + buf =3D pm->data; =20 mutex_lock(&priv->reg_lock); + yt921x_mib_read(priv, port); - mutex_unlock(&priv->reg_lock); =20 j =3D 0; for (size_t i =3D 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) { @@ -206,9 +214,11 @@ yt921x_dsa_get_ethtool_stats(struct dsa_switch *ds, in= t port, uint64_t *data) if (!desc->name) continue; =20 - data[j] =3D ((u64 *)mib)[i]; + data[j] =3D buf[i]; j++; } + + mutex_unlock(&priv->reg_lock); } =20 int yt921x_dsa_get_sset_count(struct dsa_switch *ds, int port, int sset) @@ -242,31 +252,33 @@ yt921x_dsa_get_eth_mac_stats(struct dsa_switch *ds, i= nt port, mib =3D &pm->stats; =20 mutex_lock(&priv->reg_lock); + yt921x_mib_read(priv, port); - mutex_unlock(&priv->reg_lock); =20 - mac_stats->FramesTransmittedOK =3D pm->tx_frames; - mac_stats->SingleCollisionFrames =3D mib->tx_single_collisions; - mac_stats->MultipleCollisionFrames =3D mib->tx_multiple_collisions; - mac_stats->FramesReceivedOK =3D pm->rx_frames; - mac_stats->FrameCheckSequenceErrors =3D mib->rx_crc_errors; - mac_stats->AlignmentErrors =3D mib->rx_alignment_errors; - mac_stats->OctetsTransmittedOK =3D mib->tx_good_bytes; - mac_stats->FramesWithDeferredXmissions =3D mib->tx_deferred; - mac_stats->LateCollisions =3D mib->tx_late_collisions; - mac_stats->FramesAbortedDueToXSColls =3D mib->tx_aborted_errors; + mac_stats->FramesTransmittedOK =3D u64_stats_read(&pm->tx_frames); + mac_stats->SingleCollisionFrames =3D u64_stats_read(&mib->tx_single_colli= sions); + mac_stats->MultipleCollisionFrames =3D u64_stats_read(&mib->tx_multiple_c= ollisions); + mac_stats->FramesReceivedOK =3D u64_stats_read(&pm->rx_frames); + mac_stats->FrameCheckSequenceErrors =3D u64_stats_read(&mib->rx_crc_error= s); + mac_stats->AlignmentErrors =3D u64_stats_read(&mib->rx_alignment_errors); + mac_stats->OctetsTransmittedOK =3D u64_stats_read(&mib->tx_good_bytes); + mac_stats->FramesWithDeferredXmissions =3D u64_stats_read(&mib->tx_deferr= ed); + mac_stats->LateCollisions =3D u64_stats_read(&mib->tx_late_collisions); + mac_stats->FramesAbortedDueToXSColls =3D u64_stats_read(&mib->tx_aborted_= errors); /* mac_stats->FramesLostDueToIntMACXmitError */ /* mac_stats->CarrierSenseErrors */ - mac_stats->OctetsReceivedOK =3D mib->rx_good_bytes; + mac_stats->OctetsReceivedOK =3D u64_stats_read(&mib->rx_good_bytes); /* mac_stats->FramesLostDueToIntMACRcvError */ - mac_stats->MulticastFramesXmittedOK =3D mib->tx_multicast; - mac_stats->BroadcastFramesXmittedOK =3D mib->tx_broadcast; + mac_stats->MulticastFramesXmittedOK =3D u64_stats_read(&mib->tx_multicast= ); + mac_stats->BroadcastFramesXmittedOK =3D u64_stats_read(&mib->tx_broadcast= ); /* mac_stats->FramesWithExcessiveDeferral */ - mac_stats->MulticastFramesReceivedOK =3D mib->rx_multicast; - mac_stats->BroadcastFramesReceivedOK =3D mib->rx_broadcast; + mac_stats->MulticastFramesReceivedOK =3D u64_stats_read(&mib->rx_multicas= t); + mac_stats->BroadcastFramesReceivedOK =3D u64_stats_read(&mib->rx_broadcas= t); /* mac_stats->InRangeLengthErrors */ /* mac_stats->OutOfRangeLengthField */ - mac_stats->FrameTooLongErrors =3D mib->rx_oversize_errors; + mac_stats->FrameTooLongErrors =3D u64_stats_read(&mib->rx_oversize_errors= ); + + mutex_unlock(&priv->reg_lock); } =20 void @@ -283,12 +295,14 @@ yt921x_dsa_get_eth_ctrl_stats(struct dsa_switch *ds, = int port, mib =3D &pm->stats; =20 mutex_lock(&priv->reg_lock); + yt921x_mib_read(priv, port); - mutex_unlock(&priv->reg_lock); =20 - ctrl_stats->MACControlFramesTransmitted =3D mib->tx_pause; - ctrl_stats->MACControlFramesReceived =3D mib->rx_pause; + ctrl_stats->MACControlFramesTransmitted =3D u64_stats_read(&mib->tx_pause= ); + ctrl_stats->MACControlFramesReceived =3D u64_stats_read(&mib->rx_pause); /* ctrl_stats->UnsupportedOpcodesReceived */ + + mutex_unlock(&priv->reg_lock); } =20 static const struct ethtool_rmon_hist_range yt921x_rmon_ranges[] =3D { @@ -317,31 +331,33 @@ yt921x_dsa_get_rmon_stats(struct dsa_switch *ds, int = port, mib =3D &pm->stats; =20 mutex_lock(&priv->reg_lock); + yt921x_mib_read(priv, port); - mutex_unlock(&priv->reg_lock); =20 *ranges =3D yt921x_rmon_ranges; =20 - rmon_stats->undersize_pkts =3D mib->rx_undersize_errors; - rmon_stats->oversize_pkts =3D mib->rx_oversize_errors; - rmon_stats->fragments =3D mib->rx_alignment_errors; + rmon_stats->undersize_pkts =3D u64_stats_read(&mib->rx_undersize_errors); + rmon_stats->oversize_pkts =3D u64_stats_read(&mib->rx_oversize_errors); + rmon_stats->fragments =3D u64_stats_read(&mib->rx_alignment_errors); /* rmon_stats->jabbers */ =20 - rmon_stats->hist[0] =3D mib->rx_64byte; - rmon_stats->hist[1] =3D mib->rx_65_127byte; - rmon_stats->hist[2] =3D mib->rx_128_255byte; - rmon_stats->hist[3] =3D mib->rx_256_511byte; - rmon_stats->hist[4] =3D mib->rx_512_1023byte; - rmon_stats->hist[5] =3D mib->rx_1024_1518byte; - rmon_stats->hist[6] =3D mib->rx_jumbo; - - rmon_stats->hist_tx[0] =3D mib->tx_64byte; - rmon_stats->hist_tx[1] =3D mib->tx_65_127byte; - rmon_stats->hist_tx[2] =3D mib->tx_128_255byte; - rmon_stats->hist_tx[3] =3D mib->tx_256_511byte; - rmon_stats->hist_tx[4] =3D mib->tx_512_1023byte; - rmon_stats->hist_tx[5] =3D mib->tx_1024_1518byte; - rmon_stats->hist_tx[6] =3D mib->tx_jumbo; + rmon_stats->hist[0] =3D u64_stats_read(&mib->rx_64byte); + rmon_stats->hist[1] =3D u64_stats_read(&mib->rx_65_127byte); + rmon_stats->hist[2] =3D u64_stats_read(&mib->rx_128_255byte); + rmon_stats->hist[3] =3D u64_stats_read(&mib->rx_256_511byte); + rmon_stats->hist[4] =3D u64_stats_read(&mib->rx_512_1023byte); + rmon_stats->hist[5] =3D u64_stats_read(&mib->rx_1024_1518byte); + rmon_stats->hist[6] =3D u64_stats_read(&mib->rx_jumbo); + + rmon_stats->hist_tx[0] =3D u64_stats_read(&mib->tx_64byte); + rmon_stats->hist_tx[1] =3D u64_stats_read(&mib->tx_65_127byte); + rmon_stats->hist_tx[2] =3D u64_stats_read(&mib->tx_128_255byte); + rmon_stats->hist_tx[3] =3D u64_stats_read(&mib->tx_256_511byte); + rmon_stats->hist_tx[4] =3D u64_stats_read(&mib->tx_512_1023byte); + rmon_stats->hist_tx[5] =3D u64_stats_read(&mib->tx_1024_1518byte); + rmon_stats->hist_tx[6] =3D u64_stats_read(&mib->tx_jumbo); + + mutex_unlock(&priv->reg_lock); } =20 void @@ -352,37 +368,45 @@ yt921x_dsa_get_stats64(struct dsa_switch *ds, int por= t, struct yt921x_port *pp =3D &priv->ports[port]; struct yt921x_mib *pm =3D pp->mib; struct yt921x_mib_stats *mib; + unsigned int start; =20 if (!pm) return; mib =3D &pm->stats; =20 - stats->rx_length_errors =3D mib->rx_undersize_errors + - mib->rx_fragment_errors; - stats->rx_over_errors =3D mib->rx_oversize_errors; - stats->rx_crc_errors =3D mib->rx_crc_errors; - stats->rx_frame_errors =3D mib->rx_alignment_errors; - /* stats->rx_fifo_errors */ - /* stats->rx_missed_errors */ - - stats->tx_aborted_errors =3D mib->tx_aborted_errors; - /* stats->tx_carrier_errors */ - stats->tx_fifo_errors =3D mib->tx_undersize_errors; - /* stats->tx_heartbeat_errors */ - stats->tx_window_errors =3D mib->tx_late_collisions; - - stats->rx_packets =3D pm->rx_frames; - stats->tx_packets =3D pm->tx_frames; - stats->rx_bytes =3D mib->rx_good_bytes - ETH_FCS_LEN * stats->rx_packets; - stats->tx_bytes =3D mib->tx_good_bytes - ETH_FCS_LEN * stats->tx_packets; + do { + start =3D u64_stats_fetch_begin(&pm->syncp); + + stats->rx_length_errors =3D u64_stats_read(&mib->rx_undersize_errors) + + u64_stats_read(&mib->rx_fragment_errors); + stats->rx_over_errors =3D u64_stats_read(&mib->rx_oversize_errors); + stats->rx_crc_errors =3D u64_stats_read(&mib->rx_crc_errors); + stats->rx_frame_errors =3D u64_stats_read(&mib->rx_alignment_errors); + /* stats->rx_fifo_errors */ + /* stats->rx_missed_errors */ + + stats->tx_aborted_errors =3D u64_stats_read(&mib->tx_aborted_errors); + /* stats->tx_carrier_errors */ + stats->tx_fifo_errors =3D u64_stats_read(&mib->tx_undersize_errors); + /* stats->tx_heartbeat_errors */ + stats->tx_window_errors =3D u64_stats_read(&mib->tx_late_collisions); + + stats->rx_packets =3D u64_stats_read(&pm->rx_frames); + stats->tx_packets =3D u64_stats_read(&pm->tx_frames); + stats->rx_bytes =3D u64_stats_read(&mib->rx_good_bytes) - + ETH_FCS_LEN * stats->rx_packets; + stats->tx_bytes =3D u64_stats_read(&mib->tx_good_bytes) - + ETH_FCS_LEN * stats->tx_packets; + stats->rx_dropped =3D u64_stats_read(&mib->rx_dropped); + /* stats->tx_dropped */ + stats->multicast =3D u64_stats_read(&mib->rx_multicast); + stats->collisions =3D u64_stats_read(&mib->tx_collisions); + } while (u64_stats_fetch_retry(&pm->syncp, start)); + stats->rx_errors =3D stats->rx_length_errors + stats->rx_over_errors + stats->rx_crc_errors + stats->rx_frame_errors; stats->tx_errors =3D stats->tx_aborted_errors + stats->tx_fifo_errors + stats->tx_window_errors; - stats->rx_dropped =3D mib->rx_dropped; - /* stats->tx_dropped */ - stats->multicast =3D mib->rx_multicast; - stats->collisions =3D mib->tx_collisions; } =20 void @@ -399,9 +423,11 @@ yt921x_dsa_get_pause_stats(struct dsa_switch *ds, int = port, mib =3D &pm->stats; =20 mutex_lock(&priv->reg_lock); + yt921x_mib_read(priv, port); - mutex_unlock(&priv->reg_lock); =20 - pause_stats->tx_pause_frames =3D mib->tx_pause; - pause_stats->rx_pause_frames =3D mib->rx_pause; + pause_stats->tx_pause_frames =3D u64_stats_read(&mib->tx_pause); + pause_stats->rx_pause_frames =3D u64_stats_read(&mib->rx_pause); + + mutex_unlock(&priv->reg_lock); } diff --git a/drivers/net/dsa/motorcomm/mib.h b/drivers/net/dsa/motorcomm/mi= b.h index cfad0665baae..33992a5f9bdc 100644 --- a/drivers/net/dsa/motorcomm/mib.h +++ b/drivers/net/dsa/motorcomm/mib.h @@ -6,6 +6,8 @@ #ifndef _YT_MIB_H #define _YT_MIB_H =20 +#include + #include =20 #define YT921X_MIB_CTRL 0xc0004 @@ -72,64 +74,70 @@ #define YT921X_MIB_DATA_TX_OAM 0xac =20 struct yt921x_mib_stats { - 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; + 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; }; =20 +#define YT921X_MIB_NUM (sizeof(struct yt921x_mib_stats) / sizeof(u64_stats= _t)) + struct yt921x_mib { struct yt921x_port *port; =20 struct delayed_work work; + struct u64_stats_sync syncp; + /* protected by syncp OR priv->reg_lock */ struct yt921x_mib_stats stats; - u64 rx_frames; - u64 tx_frames; + u64_stats_t rx_frames; + u64_stats_t tx_frames; + /* protected by priv->reg_lock */ + u64 data[YT921X_MIB_NUM]; }; =20 void yt921x_mib_poll(struct work_struct *work); --=20 2.53.0 From nobody Sat Sep 26 07:14:52 2026 Received: from mail-pg1-f170.google.com (mail-pg1-f170.google.com [209.85.215.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A5E6C4BA9FD for ; Thu, 3 Sep 2026 14:38:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788446298; cv=none; b=BVfl+tn1Akj2964sBYIYxcep8PBxRaVdeNHDRL6YUqdlm4PxHmZsQQNlpkYJRUxkcx2RKNAQhQTiSUChJxHJc0U1q4momAh8WBSOlzcmKAT/ItuAnQumzOqna8sQ+L6Rwe9mUgHfWqRZDqvwYNMvJ3Yf0OWOQxMeMCGQMz//ftM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788446298; c=relaxed/simple; bh=kOvpmlyWClc2Bza3wXQ2lfrkpZSO8egW7JGEuQb3cdo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=s2PNUH2D5TQPlNQJumkAvVHcTVFh6WEJFA+cVFcO/Izv/f8UyemOZYi+lqlPGWtB1irvFRdu2BqDi7/4ouFW8D/O92EHmlQuV3l/zyXF15X2BZLA2bMISQSxXj2qhSA0BaX+1ddKg+rrqDD4h50anuhhF3m5pORelC0h0nN20VU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=O4So+RlD; arc=none smtp.client-ip=209.85.215.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="O4So+RlD" Received: by mail-pg1-f170.google.com with SMTP id 41be03b00d2f7-cc1c8d4a959so1974429a12.3 for ; Thu, 03 Sep 2026 07:38:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788446290; x=1789051090; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=8LSRJMb0iTwvInt2ft5DxEiXftUD8BefOLSSFLLUPsU=; b=O4So+RlDeumNarLmsJX8ereOSCVe/Sjj0z8olD003jpsRXBO23vPiGMux/CbeDcfV1 7s+cw1OKHOwYBwt6l5f93r9wqeG1YK3Q95UhFHGXRf5XjmK965OkqdRPjVNbo9gLgbps 83tUtq7mcP4buBxH38w1rT4T022iep5aOhIp2jWRfasxfPomR6s7x9uRMyJIPGVyRkc9 Yfi9dpoQCyZQJwudaExvsNvFjL50sXe022gaWGF7FBMkRn94M+CnCiLYzFlDuodfTXyQ s9lUoCJeCk5ZD7+Jtwz8SQGLXrNDnVka+EaQGvfV5Nt3PgWQlwlXGD6l3VyzjrhrpgHM mi4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788446290; x=1789051090; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=8LSRJMb0iTwvInt2ft5DxEiXftUD8BefOLSSFLLUPsU=; b=K8+hzbEY6UK88GCuuf3CNwO1nkHnl5B4wzCzpH3EDGgBTnTCh4ihxjueUnldvkO/Pc aGBOHFaZb2SOMntiaHjnz15IikMzfBQSWPRIbrdh44UoakmBL5ai1oJqil4dmQa2ArQm acFdtOl/MiZa62drgTHfjD1cfxvdZeb9/ldhMXsNcw4pHaoXpoOauel7idfkO+8u8ApI uoAOQ6R3ZOJT3gyNf1QhTfJImbqR1EmF7CUfnrvA8Czab9sCTzHfJMXTvCnKJ9JJ8mLB JwetI1zfh005RS+BdS8yzhh0gFgJlo/Eix7LcOOf5zpbMwx6CubB1Ld2JTZwFWs81Tew xZww== X-Forwarded-Encrypted: i=1; AKwUvBzb5YC3JQWE2va6VwYO1774hnK3FQ/d7lYRELZEkZ5R/GS+y8HxoIwM86PBQtQCyecijKpXmqc954rIcOQ=@vger.kernel.org X-Gm-Message-State: AFuF++l6QeUT3CC8uV3JhubZxsT/DXKUAlEwTbZcQV+rW2dwPWzoAFz6 sy4hEQessRxwp7Cfypqn6lTian0DYBvrbBcFHLssqnaLGfShKJwD56ZF X-Gm-Gg: AYBFou1q+GOMGjlmaFPL8xBCoI9H24Yo9hSSbRaVzzF7/jrObjYcYvLAe45qlQt+yhc wvL0R9fe3yikzBUCrVx7L525LgEHaX4r8ELnXzrt6O294PuDfE+gwKZzocFzPA+vMt8zZGYMGc0 CP2zlnmzFZjdOWdcwZ0yG6VEfMfep/vDyaQ5BcHHNoSjJaSeqJJWvSaunYW30mU126Cxb1hUVbe iPCcN08xE/qaXbqM5sxq99t7ND5Jgs+ssvMnqgZjZYgBjyXi1oYuMyjejZyGq8ltJT0dmcaj2p/ Xa6SkSVlmczlCQYE7uY+lB6qAeFETqpIKmkvsCJ4F499o4hj9zF2rRdA8bMNh1zEP+fT621XDnv CtaBNdZa9n9UAy/Eht6KZF6RPiXjbWGyh92w1L9GsQEneVqkzkpnCHQZDcLeMw8+2/GrSYN3QZF X9PnmEX+/JIVO2Cw57/RTYwdIBrt/qblF5HwgIyI/71cFKXcNMVNXw5AHHaEq58KkWDGXegXbcz BAvIMKwe+tWMuc= X-Received: by 2002:a17:90b:4e8f:b0:395:f0e8:9e13 with SMTP id 98e67ed59e1d1-39b22cb977emr258795a91.7.1788446290301; Thu, 03 Sep 2026 07:38:10 -0700 (PDT) Received: from d.home.yangfl.dn42 ([2a09:bac5:661d:3050::4d0:16]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-39ae9087d3dsm2741889a91.3.2026.09.03.07.38.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Sep 2026 07:38:09 -0700 (PDT) From: David Yang To: netdev@vger.kernel.org Cc: David Yang , Andrew Lunn , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , linux-kernel@vger.kernel.org Subject: [PATCH net-next 4/4] net: dsa: motorcomm: Use safe 64-bit counter reader Date: Thu, 3 Sep 2026 22:35:09 +0800 Message-ID: <20260903143514.532023-5-mmyangfl@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260903143514.532023-1-mmyangfl@gmail.com> References: <20260903143514.532023-1-mmyangfl@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 64-bit counter registers are read as two separate 32-bit transactions. If the low word wraps from about 0xffffffff to a small value while the high word increments between the two transactions, the recombined value becomes ((new_high << 32) | old_low), producing a spurious ~4 GiB jump. Use a safe counter reader for this. Signed-off-by: David Yang --- drivers/net/dsa/motorcomm/mib.c | 21 +++++++++------------ drivers/net/dsa/motorcomm/smi.c | 30 ++++++++++++++++++++++++++++++ drivers/net/dsa/motorcomm/smi.h | 2 ++ 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/drivers/net/dsa/motorcomm/mib.c b/drivers/net/dsa/motorcomm/mi= b.c index 73b2a9f52996..30478ce71c10 100644 --- a/drivers/net/dsa/motorcomm/mib.c +++ b/drivers/net/dsa/motorcomm/mib.c @@ -101,29 +101,26 @@ static int yt921x_mib_read(struct yt921x_priv *priv, = int port) for (size_t i =3D 0; i < ARRAY_SIZE(yt921x_mib_descs); i++) { const struct yt921x_mib_desc *desc =3D &yt921x_mib_descs[i]; u32 reg =3D YT921X_MIBn_DATA0(port) + desc->offset; - u32 val0; - u64 val; - - res =3D yt921x_reg_read(priv, reg, &val0); - if (res) - break; =20 if (desc->size <=3D 1) { u64 old_val =3D buf[i]; + u32 val0; + u64 val; + + res =3D yt921x_reg_read(priv, reg, &val0); + if (res) + break; =20 val =3D (old_val & ~(u64)U32_MAX) | val0; if (val < old_val) val +=3D 1ull << 32; - } else { - u32 val1; =20 - res =3D yt921x_reg_read(priv, reg + 4, &val1); + buf[i] =3D val; + } else { + res =3D yt921x_counter_read(priv, reg, &buf[i]); if (res) break; - val =3D ((u64)val1 << 32) | val0; } - - buf[i] =3D val; } =20 u64_stats_update_begin(&pm->syncp); diff --git a/drivers/net/dsa/motorcomm/smi.c b/drivers/net/dsa/motorcomm/sm= i.c index bf3adfd64165..27086602997b 100644 --- a/drivers/net/dsa/motorcomm/smi.c +++ b/drivers/net/dsa/motorcomm/smi.c @@ -63,6 +63,36 @@ int yt921x_reg_update_bits(struct yt921x_priv *priv, u32= reg, u32 mask, u32 val) return yt921x_reg_write(priv, reg, u); } =20 +/* Reliably read a 64bit counter */ +int yt921x_counter_read(struct yt921x_priv *priv, u32 reg, u64 *valp) +{ + u32 old_lo; + int res; + u32 hi; + u32 lo; + + res =3D yt921x_reg_read(priv, reg, &old_lo); + if (res) + return res; + + for (int i =3D 0; i < 16; i++) { + res =3D yt921x_reg_read(priv, reg + 4, &hi); + if (res) + return res; + res =3D yt921x_reg_read(priv, reg, &lo); + if (res) + return res; + + if (lo >=3D old_lo) { + *valp =3D ((u64)hi << 32) | lo; + return 0; + } + old_lo =3D lo; + } + + return -ETIMEDOUT; +} + static int yt921x_regs_read(struct yt921x_priv *priv, u32 reg, u32 *vals, unsigned int num_regs) diff --git a/drivers/net/dsa/motorcomm/smi.h b/drivers/net/dsa/motorcomm/sm= i.h index 212e20f71d80..d34240548af7 100644 --- a/drivers/net/dsa/motorcomm/smi.h +++ b/drivers/net/dsa/motorcomm/smi.h @@ -35,6 +35,8 @@ yt921x_reg_toggle_bits(struct yt921x_priv *priv, u32 reg,= u32 mask, bool set) return yt921x_reg_update_bits(priv, reg, mask, !set ? 0 : mask); } =20 +int yt921x_counter_read(struct yt921x_priv *priv, u32 reg, u64 *valp); + /* Some multi-word registers, like VLANn_CTRL, should be treated as a sing= le * long register. More specifically, writes to parts of its words won't be= come * visible, until the last word is written. --=20 2.53.0