[PATCH net-next v11 1/7] net: dsa: motorcomm: initialize dsa_switch based on chipid
From: Kyle Switch
Date: Fri Oct 02 2026 - 13:37:38 EST
Replace the hardcoded chip handling in yt92xx_register_switch() with a
data-driven loopup based on the chip ID.
Reviewed-by: Andrew Lunn <andrew@xxxxxxx>
Signed-off-by: Kyle Switch <kyle.switch@xxxxxxxxxxxxxx>
---
drivers/net/dsa/motorcomm/chip.c | 73 ++++++++++++++++++++++++++++----
drivers/net/dsa/motorcomm/chip.h | 19 +++++++++
2 files changed, 84 insertions(+), 8 deletions(-)
diff --git a/drivers/net/dsa/motorcomm/chip.c b/drivers/net/dsa/motorcomm/chip.c
index 3ff2de383157..79422def16ff 100644
--- a/drivers/net/dsa/motorcomm/chip.c
+++ b/drivers/net/dsa/motorcomm/chip.c
@@ -4397,6 +4397,67 @@ static const struct dsa_switch_ops yt921x_dsa_switch_ops = {
.setup = yt921x_dsa_setup,
};
+static const struct yt92xx_series yt92xx_series_table[] = {
+ [YT92XX_MODE_YT921X] = {
+ .name = "YT921x",
+ .max_ports = YT921X_PORT_NUM,
+ .num_lag_ids = YT921X_LAG_NUM,
+ .ageing_time_min = 1 * 5000,
+ .ageing_time_max = U16_MAX * 5000,
+ .dscp_prio_mapping_is_global = true,
+ .assisted_learning_on_cpu_port = true,
+ .switch_ops = &yt921x_dsa_switch_ops,
+ .mac_ops = &yt921x_phylink_mac_ops
+ },
+};
+
+static const struct yt92xx_series *yt92xx_series_lookup(u32 major)
+{
+ if (major == YT9215_MAJOR || major == YT9218_MAJOR)
+ return &yt92xx_series_table[YT92XX_MODE_YT921X];
+ else
+ return NULL;
+}
+
+static int yt92xx_register_switch(struct dsa_switch *ds)
+{
+ struct yt921x_priv *priv = to_yt921x_priv(ds);
+ struct device *dev = to_device(priv);
+ const struct yt92xx_series *series;
+ u32 chipid;
+ u32 major;
+ int res;
+
+ mutex_lock(&priv->reg_lock);
+ res = yt921x_reg_read(priv, YT921X_CHIP_ID, &chipid);
+ mutex_unlock(&priv->reg_lock);
+ if (res) {
+ dev_err(dev, "Unexpected chipid 0x%x\n", chipid);
+ return res;
+ }
+
+ major = FIELD_GET(YT921X_CHIP_ID_MAJOR, chipid);
+ series = yt92xx_series_lookup(major);
+ if (!series) {
+ dev_err(dev, "Undefined series info for the corresponding major\n");
+ return -ENODEV;
+ }
+ priv->series = series;
+
+ ds->assisted_learning_on_cpu_port =
+ priv->series->assisted_learning_on_cpu_port;
+ ds->dscp_prio_mapping_is_global =
+ priv->series->dscp_prio_mapping_is_global;
+ ds->ageing_time_min = priv->series->ageing_time_min;
+ ds->ageing_time_max = priv->series->ageing_time_max;
+ ds->num_lag_ids = priv->series->num_lag_ids;
+ ds->num_ports = priv->series->max_ports;
+ ds->ops = priv->series->switch_ops;
+ ds->phylink_mac_ops = priv->series->mac_ops;
+
+ return 0;
+}
+
static void yt921x_mdio_shutdown(struct mdio_device *mdiodev)
{
struct yt921x_priv *priv = mdiodev_get_drvdata(mdiodev);
@@ -4445,6 +4506,7 @@ static int yt921x_mdio_probe(struct mdio_device *mdiodev)
struct yt921x_reg_mdio *mdio;
struct yt921x_priv *priv;
struct dsa_switch *ds;
+ int res;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -4472,15 +4534,10 @@ static int yt921x_mdio_probe(struct mdio_device *mdiodev)
ds = &priv->ds;
ds->dev = dev;
- ds->assisted_learning_on_cpu_port = true;
- ds->dscp_prio_mapping_is_global = true;
ds->priv = priv;
- ds->ops = &yt921x_dsa_switch_ops;
- ds->ageing_time_min = 1 * 5000;
- ds->ageing_time_max = U16_MAX * 5000;
- ds->phylink_mac_ops = &yt921x_phylink_mac_ops;
- ds->num_lag_ids = YT921X_LAG_NUM;
- ds->num_ports = YT921X_PORT_NUM;
+ res = yt92xx_register_switch(ds);
+ if (res)
+ return res;
mdiodev_set_drvdata(mdiodev, priv);
diff --git a/drivers/net/dsa/motorcomm/chip.h b/drivers/net/dsa/motorcomm/chip.h
index 28e4f26f9cc4..69176995090a 100644
--- a/drivers/net/dsa/motorcomm/chip.h
+++ b/drivers/net/dsa/motorcomm/chip.h
@@ -955,9 +955,28 @@ struct yt921x_info {
u16 serdes_mask;
};
+enum yt92xx_mode {
+ YT92XX_MODE_YT921X,
+ YT92XX_MODE_YT922X,
+ YT92XX_MODE_MAX,
+};
+
+struct yt92xx_series {
+ const char *name;
+ unsigned int max_ports;
+ unsigned int num_lag_ids;
+ unsigned int ageing_time_min;
+ unsigned int ageing_time_max;
+ u32 dscp_prio_mapping_is_global;
+ u32 assisted_learning_on_cpu_port;
+ const struct dsa_switch_ops *switch_ops;
+ const struct phylink_mac_ops *mac_ops;
+};
+
struct yt921x_priv {
struct dsa_switch ds;
+ const struct yt92xx_series *series;
const struct yt921x_info *info;
unsigned int meter_slot_ns;
unsigned int port_shape_slot_ns;
--
2.25.1