From: David Yang <mmyangfl@gmail.com>
To: netdev@vger.kernel.org
Cc: David Yang <mmyangfl@gmail.com>, Andrew Lunn <andrew@lunn.ch>,
Vladimir Oltean <olteanv@gmail.com>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH net-next v3 2/4] net: dsa: yt921x: Refactor long register helpers
Date: Wed, 8 Apr 2026 00:05:54 +0800 [thread overview]
Message-ID: <20260407160559.1747616-3-mmyangfl@gmail.com> (raw)
In-Reply-To: <20260407160559.1747616-1-mmyangfl@gmail.com>
Dealing long registers with u64 is good, until you realize there are
longer 96-bit registers.
Refactor reg64 helpers with u32 arrays, so they are aligned with further
reg96 helpers. We do not keep the u64 implement to avoid duplicated
wrappers, although it looks better when we deal with reg64 *only*.
Helpers for reg96 should be added when they are actually used to avoid
function unused warnings.
Signed-off-by: David Yang <mmyangfl@gmail.com>
---
drivers/net/dsa/yt921x.c | 161 ++++++++++++++++++++++++++-------------
drivers/net/dsa/yt921x.h | 36 ++++-----
2 files changed, 128 insertions(+), 69 deletions(-)
diff --git a/drivers/net/dsa/yt921x.c b/drivers/net/dsa/yt921x.c
index 87139448bec3..de6aa5835616 100644
--- a/drivers/net/dsa/yt921x.c
+++ b/drivers/net/dsa/yt921x.c
@@ -255,63 +255,121 @@ 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);
}
-/* Some registers, like VLANn_CTRL, should always be written in 64-bit, even if
- * you are to write only the lower / upper 32 bits.
+/* Some registers, like VLANn_CTRL, should always be written whole, even if you
+ * only want to write parts of 32 bits.
*
- * There is no such restriction for reading, but we still provide 64-bit read
- * wrappers so that we always handle u64 values.
+ * There is no such restriction for reading, but we still provide the read
+ * wrapper so that we can handle them consistently.
*/
-static int yt921x_reg64_read(struct yt921x_priv *priv, u32 reg, u64 *valp)
+static int
+yt921x_regs_read(struct yt921x_priv *priv, u32 reg, u32 *vals,
+ unsigned int num_regs)
{
- u32 lo;
- u32 hi;
int res;
- res = yt921x_reg_read(priv, reg, &lo);
- if (res)
- return res;
- res = yt921x_reg_read(priv, reg + 4, &hi);
- if (res)
- return res;
+ for (unsigned int i = 0; i < num_regs; i++) {
+ res = yt921x_reg_read(priv, reg + 4 * i, &vals[i]);
+ if (res)
+ return res;
+ }
+
+ return 0;
+}
+
+static int
+yt921x_regs_write(struct yt921x_priv *priv, u32 reg, const u32 *vals,
+ unsigned int num_regs)
+{
+ int res;
+
+ for (unsigned int i = 0; i < num_regs; i++) {
+ res = yt921x_reg_write(priv, reg + 4 * i, vals[i]);
+ if (res)
+ return res;
+ }
- *valp = ((u64)hi << 32) | lo;
return 0;
}
-static int yt921x_reg64_write(struct yt921x_priv *priv, u32 reg, u64 val)
+static int
+yt921x_regs_update_bits(struct yt921x_priv *priv, u32 reg, const u32 *masks,
+ const u32 *vals, unsigned int num_regs)
{
+ bool changed = false;
+ u32 vs[4];
int res;
- res = yt921x_reg_write(priv, reg, (u32)val);
+ BUILD_BUG_ON(num_regs > ARRAY_SIZE(vs));
+
+ res = yt921x_regs_read(priv, reg, vs, num_regs);
if (res)
return res;
- return yt921x_reg_write(priv, reg + 4, (u32)(val >> 32));
+
+ for (unsigned int i = 0; i < num_regs; i++) {
+ u32 u = vs[i];
+
+ u &= ~masks[i];
+ u |= vals[i];
+ if (u != vs[i])
+ changed = true;
+
+ vs[i] = u;
+ }
+
+ if (!changed)
+ return 0;
+
+ return yt921x_regs_write(priv, reg, vs, num_regs);
}
static int
-yt921x_reg64_update_bits(struct yt921x_priv *priv, u32 reg, u64 mask, u64 val)
+yt921x_regs_clear_bits(struct yt921x_priv *priv, u32 reg, const u32 *masks,
+ unsigned int num_regs)
{
+ bool changed = false;
+ u32 vs[4];
int res;
- u64 v;
- u64 u;
- res = yt921x_reg64_read(priv, reg, &v);
+ BUILD_BUG_ON(num_regs > ARRAY_SIZE(vs));
+
+ res = yt921x_regs_read(priv, reg, vs, num_regs);
if (res)
return res;
- u = v;
- u &= ~mask;
- u |= val;
- if (u == v)
+ for (unsigned int i = 0; i < num_regs; i++) {
+ u32 u = vs[i];
+
+ u &= ~masks[i];
+ if (u != vs[i])
+ changed = true;
+
+ vs[i] = u;
+ }
+
+ if (!changed)
return 0;
- return yt921x_reg64_write(priv, reg, u);
+ return yt921x_regs_write(priv, reg, vs, num_regs);
+}
+
+static int
+yt921x_reg64_write(struct yt921x_priv *priv, u32 reg, const u32 *vals)
+{
+ return yt921x_regs_write(priv, reg, vals, 2);
}
-static int yt921x_reg64_clear_bits(struct yt921x_priv *priv, u32 reg, u64 mask)
+static int
+yt921x_reg64_update_bits(struct yt921x_priv *priv, u32 reg, const u32 *masks,
+ const u32 *vals)
{
- return yt921x_reg64_update_bits(priv, reg, mask, 0);
+ return yt921x_regs_update_bits(priv, reg, masks, vals, 2);
+}
+
+static int
+yt921x_reg64_clear_bits(struct yt921x_priv *priv, u32 reg, const u32 *masks)
+{
+ return yt921x_regs_clear_bits(priv, reg, masks, 2);
}
static int yt921x_reg_mdio_read(void *context, u32 reg, u32 *valp)
@@ -1844,33 +1902,31 @@ yt921x_vlan_filtering(struct yt921x_priv *priv, int port, bool vlan_filtering)
return 0;
}
-static int
-yt921x_vlan_del(struct yt921x_priv *priv, int port, u16 vid)
+static int yt921x_vlan_del(struct yt921x_priv *priv, int port, u16 vid)
{
- u64 mask64;
+ u32 masks[2];
- mask64 = YT921X_VLAN_CTRL_PORTS(port) |
- YT921X_VLAN_CTRL_UNTAG_PORTn(port);
+ masks[0] = YT921X_VLAN_CTRLa_PORTn(port);
+ masks[1] = YT921X_VLAN_CTRLb_UNTAG_PORTn(port);
- return yt921x_reg64_clear_bits(priv, YT921X_VLANn_CTRL(vid), mask64);
+ return yt921x_reg64_clear_bits(priv, YT921X_VLANn_CTRL(vid), masks);
}
static int
yt921x_vlan_add(struct yt921x_priv *priv, int port, u16 vid, bool untagged)
{
- u64 mask64;
- u64 ctrl64;
+ u32 masks[2];
+ u32 ctrls[2];
- mask64 = YT921X_VLAN_CTRL_PORTn(port) |
- YT921X_VLAN_CTRL_PORTS(priv->cpu_ports_mask);
- ctrl64 = mask64;
+ masks[0] = YT921X_VLAN_CTRLa_PORTn(port) |
+ YT921X_VLAN_CTRLa_PORTS(priv->cpu_ports_mask);
+ ctrls[0] = masks[0];
- mask64 |= YT921X_VLAN_CTRL_UNTAG_PORTn(port);
- if (untagged)
- ctrl64 |= YT921X_VLAN_CTRL_UNTAG_PORTn(port);
+ masks[1] = YT921X_VLAN_CTRLb_UNTAG_PORTn(port);
+ ctrls[1] = untagged ? masks[1] : 0;
return yt921x_reg64_update_bits(priv, YT921X_VLANn_CTRL(vid),
- mask64, ctrl64);
+ masks, ctrls);
}
static int
@@ -2318,8 +2374,8 @@ yt921x_dsa_vlan_msti_set(struct dsa_switch *ds, struct dsa_bridge bridge,
const struct switchdev_vlan_msti *msti)
{
struct yt921x_priv *priv = to_yt921x_priv(ds);
- u64 mask64;
- u64 ctrl64;
+ u32 masks[2];
+ u32 ctrls[2];
int res;
if (!msti->vid)
@@ -2327,12 +2383,14 @@ yt921x_dsa_vlan_msti_set(struct dsa_switch *ds, struct dsa_bridge bridge,
if (!msti->msti || msti->msti >= YT921X_MSTI_NUM)
return -EINVAL;
- mask64 = YT921X_VLAN_CTRL_STP_ID_M;
- ctrl64 = YT921X_VLAN_CTRL_STP_ID(msti->msti);
+ masks[0] = 0;
+ ctrls[0] = 0;
+ masks[1] = YT921X_VLAN_CTRLb_STP_ID_M;
+ ctrls[1] = YT921X_VLAN_CTRLb_STP_ID(msti->msti);
mutex_lock(&priv->reg_lock);
res = yt921x_reg64_update_bits(priv, YT921X_VLANn_CTRL(msti->vid),
- mask64, ctrl64);
+ masks, ctrls);
mutex_unlock(&priv->reg_lock);
return res;
@@ -3084,7 +3142,7 @@ static int yt921x_chip_setup_dsa(struct yt921x_priv *priv)
{
struct dsa_switch *ds = &priv->ds;
unsigned long cpu_ports_mask;
- u64 ctrl64;
+ u32 ctrls[2];
u32 ctrl;
int port;
int res;
@@ -3145,8 +3203,9 @@ static int yt921x_chip_setup_dsa(struct yt921x_priv *priv)
/* Tagged VID 0 should be treated as untagged, which confuses the
* hardware a lot
*/
- ctrl64 = YT921X_VLAN_CTRL_LEARN_DIS | YT921X_VLAN_CTRL_PORTS_M;
- res = yt921x_reg64_write(priv, YT921X_VLANn_CTRL(0), ctrl64);
+ ctrls[0] = YT921X_VLAN_CTRLa_LEARN_DIS | YT921X_VLAN_CTRLa_PORTS_M;
+ ctrls[1] = 0;
+ res = yt921x_reg64_write(priv, YT921X_VLANn_CTRL(0), ctrls);
if (res)
return res;
diff --git a/drivers/net/dsa/yt921x.h b/drivers/net/dsa/yt921x.h
index 3f129b8d403f..4989d87c2492 100644
--- a/drivers/net/dsa/yt921x.h
+++ b/drivers/net/dsa/yt921x.h
@@ -429,24 +429,24 @@ enum yt921x_app_selector {
#define YT921X_FDB_HW_FLUSH_ON_LINKDOWN BIT(0)
#define YT921X_VLANn_CTRL(vlan) (0x188000 + 8 * (vlan))
-#define YT921X_VLAN_CTRL_UNTAG_PORTS_M GENMASK_ULL(50, 40)
-#define YT921X_VLAN_CTRL_UNTAG_PORTS(x) FIELD_PREP(YT921X_VLAN_CTRL_UNTAG_PORTS_M, (x))
-#define YT921X_VLAN_CTRL_UNTAG_PORTn(port) BIT_ULL((port) + 40)
-#define YT921X_VLAN_CTRL_STP_ID_M GENMASK_ULL(39, 36)
-#define YT921X_VLAN_CTRL_STP_ID(x) FIELD_PREP(YT921X_VLAN_CTRL_STP_ID_M, (x))
-#define YT921X_VLAN_CTRL_SVLAN_EN BIT_ULL(35)
-#define YT921X_VLAN_CTRL_FID_M GENMASK_ULL(34, 23)
-#define YT921X_VLAN_CTRL_FID(x) FIELD_PREP(YT921X_VLAN_CTRL_FID_M, (x))
-#define YT921X_VLAN_CTRL_LEARN_DIS BIT_ULL(22)
-#define YT921X_VLAN_CTRL_PRIO_EN BIT_ULL(21)
-#define YT921X_VLAN_CTRL_PRIO_M GENMASK_ULL(20, 18)
-#define YT921X_VLAN_CTRL_PRIO(x) FIELD_PREP(YT921X_VLAN_CTRL_PRIO_M, (x))
-#define YT921X_VLAN_CTRL_PORTS_M GENMASK_ULL(17, 7)
-#define YT921X_VLAN_CTRL_PORTS(x) FIELD_PREP(YT921X_VLAN_CTRL_PORTS_M, (x))
-#define YT921X_VLAN_CTRL_PORTn(port) BIT_ULL((port) + 7)
-#define YT921X_VLAN_CTRL_BYPASS_1X_AC BIT_ULL(6)
-#define YT921X_VLAN_CTRL_METER_EN BIT_ULL(5)
-#define YT921X_VLAN_CTRL_METER_ID_M GENMASK_ULL(4, 0)
+#define YT921X_VLAN_CTRLb_UNTAG_PORTS_M GENMASK(18, 8)
+#define YT921X_VLAN_CTRLb_UNTAG_PORTS(x) FIELD_PREP(YT921X_VLAN_CTRLb_UNTAG_PORTS_M, (x))
+#define YT921X_VLAN_CTRLb_UNTAG_PORTn(port) BIT((port) + 8)
+#define YT921X_VLAN_CTRLb_STP_ID_M GENMASK(7, 4)
+#define YT921X_VLAN_CTRLb_STP_ID(x) FIELD_PREP(YT921X_VLAN_CTRLb_STP_ID_M, (x))
+#define YT921X_VLAN_CTRLb_SVLAN_EN BIT(3)
+#define YT921X_VLAN_CTRLab_FID_M GENMASK_ULL(34, 23)
+#define YT921X_VLAN_CTRLab_FID(x) FIELD_PREP(YT921X_VLAN_CTRLab_FID_M, (x))
+#define YT921X_VLAN_CTRLa_LEARN_DIS BIT(22)
+#define YT921X_VLAN_CTRLa_PRIO_EN BIT(21)
+#define YT921X_VLAN_CTRLa_PRIO_M GENMASK(20, 18)
+#define YT921X_VLAN_CTRLa_PRIO(x) FIELD_PREP(YT921X_VLAN_CTRLa_PRIO_M, (x))
+#define YT921X_VLAN_CTRLa_PORTS_M GENMASK(17, 7)
+#define YT921X_VLAN_CTRLa_PORTS(x) FIELD_PREP(YT921X_VLAN_CTRLa_PORTS_M, (x))
+#define YT921X_VLAN_CTRLa_PORTn(port) BIT((port) + 7)
+#define YT921X_VLAN_CTRLa_BYPASS_1X_AC BIT(6)
+#define YT921X_VLAN_CTRLa_METER_EN BIT(5)
+#define YT921X_VLAN_CTRLa_METER_ID_M GENMASK(4, 0)
#define YT921X_TPID_IGRn(x) (0x210000 + 4 * (x)) /* [0, 3] */
#define YT921X_TPID_IGR_TPID_M GENMASK(15, 0)
--
2.53.0
next prev parent reply other threads:[~2026-04-07 16:10 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-07 16:05 [PATCH net-next v3 0/4] net: dsa: yt921x: Add port police/tbf support David Yang
2026-04-07 16:05 ` [PATCH net-next v3 1/4] net: dsa: pass extack to user tc policers David Yang
2026-04-07 16:05 ` David Yang [this message]
2026-04-07 16:05 ` [PATCH net-next v3 3/4] net: dsa: yt921x: Add port police support David Yang
2026-04-07 16:05 ` [PATCH net-next v3 4/4] net: dsa: yt921x: Add port qdisc tbf support David Yang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260407160559.1747616-3-mmyangfl@gmail.com \
--to=mmyangfl@gmail.com \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox