[PATCH net-next v5 1/6] net: dsa: motorcomm: refactor registration path for upcoming switch families
From: Kyle Switch
Date: Fri Sep 04 2026 - 06:26:25 EST
Introduce yt92xx_series_info 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 | 82 +++++++++++++++++++++++++++-----
drivers/net/dsa/motorcomm/chip.h | 20 ++++++++
2 files changed, 91 insertions(+), 11 deletions(-)
diff --git a/drivers/net/dsa/motorcomm/chip.c b/drivers/net/dsa/motorcomm/chip.c
index d663af010f43..557a0e07d8d7 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_info yt92xx_series_info_table[] = {
+ [YT921X] = {
+ .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_info *yt92xx_series_lookup_info(u32 major)
+{
+ enum yt92xx_mode mode = YT_MAX;
+ int i;
+
+ if (major == YT9215_MAJOR || major == YT9218_MAJOR)
+ mode = YT921X;
+
+ for (i = 0; i < ARRAY_SIZE(yt92xx_series_info_table); ++i)
+ if (yt92xx_series_info_table[i].mode == mode)
+ return &yt92xx_series_info_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_info *series_info;
+ 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_info = yt92xx_series_lookup_info(major);
+ if (!series_info)
+ return -ENODEV;
+ priv->series_info = series_info;
+
+ ds->assisted_learning_on_cpu_port =
+ priv->series_info->assisted_learning_on_cpu_port;
+ ds->dscp_prio_mapping_is_global =
+ priv->series_info->dscp_prio_mapping_is_global;
+ ds->ageing_time_min = priv->series_info->ageing_time_min;
+ ds->ageing_time_max = priv->series_info->ageing_time_max;
+ ds->num_lag_ids = priv->series_info->num_lag_ids;
+ ds->num_ports = priv->series_info->max_ports;
+ ds->ops = priv->series_info->switch_ops;
+ ds->phylink_mac_ops = priv->series_info->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,11 @@ static int yt921x_mdio_probe(struct mdio_device *mdiodev)
}
static const struct of_device_id yt921x_of_match[] = {
- { .compatible = "motorcomm,yt9215" },
- {}
+ {
+ .compatible = "motorcomm,yt9215",
+ .data = &yt92xx_series_info_table[YT921X],
+ },
+ { /* 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..65f9e6234678 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 {
+ YT921X,
+ YT922X,
+ YT_MAX,
+};
+
+struct yt92xx_series_info {
+ 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_info *series_info;
const struct yt921x_info *info;
unsigned int meter_slot_ns;
unsigned int port_shape_slot_ns;
--
2.25.1