[PATCH net-next v6 1/6] net: dsa: motorcomm: initialize dsa_switch based on chipid
From: Kyle Switch
Date: Tue Sep 08 2026 - 04:43:04 EST
Introduce yt92xx_series structure to hold private data
for different switch families, replacing hardcoded logic
in probe(). This makes the driver more extensible for
future switch support.
Signed-off-by: Kyle Switch <kyle.switch@xxxxxxxxxxxxxx>
---
drivers/net/dsa/motorcomm/chip.c | 81 +++++++++++++++++++++++++++-----
drivers/net/dsa/motorcomm/chip.h | 20 ++++++++
2 files changed, 90 insertions(+), 11 deletions(-)
diff --git a/drivers/net/dsa/motorcomm/chip.c b/drivers/net/dsa/motorcomm/chip.c
index d663af010f43..ffed823f26a8 100644
--- a/drivers/net/dsa/motorcomm/chip.c
+++ b/drivers/net/dsa/motorcomm/chip.c
@@ -4679,6 +4679,68 @@ 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] = {
+ .mode = 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)
+{
+ enum yt92xx_mode mode = YT92XX_MODE_MAX;
+ int i;
+
+ if (major == YT9215_MAJOR || major == YT9218_MAJOR)
+ mode = YT92XX_MODE_YT921X;
+
+ for (i = 0; i < ARRAY_SIZE(yt92xx_series_table); ++i)
+ if (yt92xx_series_table[i].mode == mode)
+ return &yt92xx_series_table[i];
+
+ return NULL;
+}
+
+static int yt92xx_register_switch(struct dsa_switch *ds)
+{
+ struct yt921x_priv *priv = to_yt921x_priv(ds);
+ const struct yt92xx_series *series;
+ u32 chipid;
+ u32 major;
+ int res;
+
+ res = yt921x_reg_read(priv, YT921X_CHIP_ID, &chipid);
+ if (res)
+ return res;
+
+ major = FIELD_GET(YT921X_CHIP_ID_MAJOR, chipid);
+ series = yt92xx_series_lookup(major);
+ if (!series)
+ 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);
@@ -4727,6 +4789,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)
@@ -4754,15 +4817,9 @@ 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);
@@ -4770,8 +4827,10 @@ static int yt921x_mdio_probe(struct mdio_device *mdiodev)
}
static const struct of_device_id yt921x_of_match[] = {
- { .compatible = "motorcomm,yt9215" },
- {}
+ {
+ .compatible = "motorcomm,yt9215",
+ },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, yt921x_of_match);
diff --git a/drivers/net/dsa/motorcomm/chip.h b/drivers/net/dsa/motorcomm/chip.h
index 83cd454955dd..c446aea449ed 100644
--- a/drivers/net/dsa/motorcomm/chip.h
+++ b/drivers/net/dsa/motorcomm/chip.h
@@ -960,9 +960,29 @@ struct yt921x_reg_ops {
int (*write)(void *context, u32 reg, u32 val);
};
+enum yt92xx_mode {
+ YT92XX_MODE_YT921X,
+ YT92XX_MODE_YT922X,
+ YT92XX_MODE_MAX,
+};
+
+struct yt92xx_series {
+ enum yt92xx_mode mode;
+ 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