]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: dsa: lantiq: allow arbitrary MII registers
authorDaniel Golle <daniel@makrotopia.org>
Thu, 22 Jan 2026 16:39:09 +0000 (16:39 +0000)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 27 Jan 2026 10:52:44 +0000 (11:52 +0100)
The Lantiq GSWIP and MaxLinear GSW1xx drivers are currently relying on a
hard-coded mapping of MII ports to their respective MII_CFG and MII_PCDU
registers and only allow applying an offset to the port index.

While this is sufficient for the currently supported hardware, the very
similar Intel GSW150 (aka. Lantiq PEB7084) cannot be described using
this arrangement.

Introduce two arrays to specify the MII_CFG and MII_PCDU registers for
each port, replacing the current bitmap used to safeguard MII ports as
well as the port index offset.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://patch.msgid.link/63fc01195196384f5e244a0ce9ec2ae3a6c08fe3.1769099517.git.daniel@makrotopia.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/dsa/lantiq/lantiq_gswip.c
drivers/net/dsa/lantiq/lantiq_gswip.h
drivers/net/dsa/lantiq/lantiq_gswip_common.c
drivers/net/dsa/lantiq/mxl-gsw1xx.c

index b094001a7c8057b6bf401bcaca92239c50178bbb..0377fc0079b54c08aaa0818f6c1cc181424d5653 100644 (file)
@@ -463,10 +463,22 @@ static void gswip_shutdown(struct platform_device *pdev)
 }
 
 static const struct gswip_hw_info gswip_xrx200 = {
-       .max_ports = 7,
+       .max_ports = GSWIP_MAX_PORTS,
        .allowed_cpu_ports = BIT(6),
-       .mii_ports = BIT(0) | BIT(1) | BIT(5),
-       .mii_port_reg_offset = 0,
+       .mii_cfg = {
+               [0] = GSWIP_MII_CFGp(0),
+               [1] = GSWIP_MII_CFGp(1),
+               [2 ... 4] = -1,
+               [5] = GSWIP_MII_CFGp(5),
+               [6] = -1,
+       },
+       .mii_pcdu = {
+               [0] = GSWIP_MII_PCDU0,
+               [1] = GSWIP_MII_PCDU1,
+               [2 ... 4] = -1,
+               [5] = GSWIP_MII_PCDU5,
+               [6] = -1,
+       },
        .phylink_get_caps = gswip_xrx200_phylink_get_caps,
        .pce_microcode = &gswip_pce_microcode,
        .pce_microcode_size = ARRAY_SIZE(gswip_pce_microcode),
@@ -474,10 +486,20 @@ static const struct gswip_hw_info gswip_xrx200 = {
 };
 
 static const struct gswip_hw_info gswip_xrx300 = {
-       .max_ports = 7,
+       .max_ports = GSWIP_MAX_PORTS,
        .allowed_cpu_ports = BIT(6),
-       .mii_ports = BIT(0) | BIT(5),
-       .mii_port_reg_offset = 0,
+       .mii_cfg = {
+               [0] = GSWIP_MII_CFGp(0),
+               [1 ... 4] = -1,
+               [5] = GSWIP_MII_CFGp(5),
+               [6] = -1,
+       },
+       .mii_pcdu = {
+               [0] = GSWIP_MII_PCDU0,
+               [1 ... 4] = -1,
+               [5] = GSWIP_MII_PCDU5,
+               [6] = -1,
+       },
        .phylink_get_caps = gswip_xrx300_phylink_get_caps,
        .pce_microcode = &gswip_pce_microcode,
        .pce_microcode_size = ARRAY_SIZE(gswip_pce_microcode),
index 8fc4c7cc5283a86037524903d77948fc49e52ae2..bc3686faad0d63959f1cc217c4e58f769964c671 100644 (file)
 
 #define GSWIP_VLAN_UNAWARE_PVID        0
 
+#define GSWIP_MAX_PORTS                7
+
 struct gswip_pce_microcode {
        u16 val_3;
        u16 val_2;
@@ -253,8 +255,8 @@ struct gswip_pce_microcode {
 struct gswip_hw_info {
        int max_ports;
        unsigned int allowed_cpu_ports;
-       unsigned int mii_ports;
-       int mii_port_reg_offset;
+       s16 mii_cfg[GSWIP_MAX_PORTS];
+       s16 mii_pcdu[GSWIP_MAX_PORTS];
        bool supports_2500m;
        const struct gswip_pce_microcode (*pce_microcode)[];
        size_t pce_microcode_size;
index 17a61e445f00f2bed6de30afe4449733c9d481c7..0e8eedf64d3a3965ed4c4e6bafdae33a5096619c 100644 (file)
@@ -118,15 +118,11 @@ static u32 gswip_switch_r_timeout(struct gswip_priv *priv, u32 offset,
 static void gswip_mii_mask_cfg(struct gswip_priv *priv, u32 mask, u32 set,
                               int port)
 {
-       int reg_port;
-
        /* MII_CFG register only exists for MII ports */
-       if (!(priv->hw_info->mii_ports & BIT(port)))
+       if (priv->hw_info->mii_cfg[port] == -1)
                return;
 
-       reg_port = port + priv->hw_info->mii_port_reg_offset;
-
-       regmap_write_bits(priv->mii, GSWIP_MII_CFGp(reg_port), mask,
+       regmap_write_bits(priv->mii, priv->hw_info->mii_cfg[port], mask,
                          set);
 }
 
@@ -610,28 +606,13 @@ static void gswip_mii_delay_setup(struct gswip_priv *priv, struct dsa_port *dp,
        u32 tx_delay = GSWIP_MII_PCDU_TXDLY_DEFAULT;
        u32 rx_delay = GSWIP_MII_PCDU_RXDLY_DEFAULT;
        struct device_node *port_dn = dp->dn;
-       u16 mii_pcdu_reg;
 
        /* As MII_PCDU registers only exist for MII ports, silently return
         * unless the port is an MII port
         */
-       if (!(priv->hw_info->mii_ports & BIT(dp->index)))
+       if (priv->hw_info->mii_pcdu[dp->index] == -1)
                return;
 
-       switch (dp->index + priv->hw_info->mii_port_reg_offset) {
-       case 0:
-               mii_pcdu_reg = GSWIP_MII_PCDU0;
-               break;
-       case 1:
-               mii_pcdu_reg = GSWIP_MII_PCDU1;
-               break;
-       case 5:
-               mii_pcdu_reg = GSWIP_MII_PCDU5;
-               break;
-       default:
-               return;
-       }
-
        /* legacy code to set default delays according to the interface mode */
        switch (interface) {
        case PHY_INTERFACE_MODE_RGMII_ID:
@@ -652,7 +633,7 @@ static void gswip_mii_delay_setup(struct gswip_priv *priv, struct dsa_port *dp,
        of_property_read_u32(port_dn, "rx-internal-delay-ps", &rx_delay);
        of_property_read_u32(port_dn, "tx-internal-delay-ps", &tx_delay);
 
-       regmap_write_bits(priv->mii, mii_pcdu_reg,
+       regmap_write_bits(priv->mii, priv->hw_info->mii_pcdu[dp->index],
                          GSWIP_MII_PCDU_TXDLY_MASK |
                          GSWIP_MII_PCDU_RXDLY_MASK,
                          GSWIP_MII_PCDU_TXDLY(tx_delay) |
index 6afc7539fefbebe5225466288490708efc108ec0..c9cc277e382c2644da429e38abe533358659117f 100644 (file)
@@ -739,8 +739,16 @@ static void gsw1xx_shutdown(struct mdio_device *mdiodev)
 static const struct gswip_hw_info gsw12x_data = {
        .max_ports              = GSW1XX_PORTS,
        .allowed_cpu_ports      = BIT(GSW1XX_MII_PORT) | BIT(GSW1XX_SGMII_PORT),
-       .mii_ports              = BIT(GSW1XX_MII_PORT),
-       .mii_port_reg_offset    = -GSW1XX_MII_PORT,
+       .mii_cfg = {
+               [0 ... GSW1XX_MII_PORT - 1] = -1,
+               [GSW1XX_MII_PORT] = GSWIP_MII_CFGp(0),
+               [GSW1XX_MII_PORT + 1 ... GSWIP_MAX_PORTS - 1] = -1,
+       },
+       .mii_pcdu = {
+               [0 ... GSW1XX_MII_PORT - 1] = -1,
+               [GSW1XX_MII_PORT] = GSWIP_MII_PCDU0,
+               [GSW1XX_MII_PORT + 1 ... GSWIP_MAX_PORTS - 1] = -1,
+       },
        .mac_select_pcs         = gsw1xx_phylink_mac_select_pcs,
        .phylink_get_caps       = &gsw1xx_phylink_get_caps,
        .supports_2500m         = true,
@@ -753,8 +761,16 @@ static const struct gswip_hw_info gsw12x_data = {
 static const struct gswip_hw_info gsw140_data = {
        .max_ports              = GSW1XX_PORTS,
        .allowed_cpu_ports      = BIT(GSW1XX_MII_PORT) | BIT(GSW1XX_SGMII_PORT),
-       .mii_ports              = BIT(GSW1XX_MII_PORT),
-       .mii_port_reg_offset    = -GSW1XX_MII_PORT,
+       .mii_cfg = {
+               [0 ... GSW1XX_MII_PORT - 1] = -1,
+               [GSW1XX_MII_PORT] = GSWIP_MII_CFGp(0),
+               [GSW1XX_MII_PORT + 1 ... GSWIP_MAX_PORTS - 1] = -1,
+       },
+       .mii_pcdu = {
+               [0 ... GSW1XX_MII_PORT - 1] = -1,
+               [GSW1XX_MII_PORT] = GSWIP_MII_PCDU0,
+               [GSW1XX_MII_PORT + 1 ... GSWIP_MAX_PORTS - 1] = -1,
+       },
        .mac_select_pcs         = gsw1xx_phylink_mac_select_pcs,
        .phylink_get_caps       = &gsw1xx_phylink_get_caps,
        .supports_2500m         = true,
@@ -767,8 +783,16 @@ static const struct gswip_hw_info gsw140_data = {
 static const struct gswip_hw_info gsw141_data = {
        .max_ports              = GSW1XX_PORTS,
        .allowed_cpu_ports      = BIT(GSW1XX_MII_PORT) | BIT(GSW1XX_SGMII_PORT),
-       .mii_ports              = BIT(GSW1XX_MII_PORT),
-       .mii_port_reg_offset    = -GSW1XX_MII_PORT,
+       .mii_cfg = {
+               [0 ... GSW1XX_MII_PORT - 1] = -1,
+               [GSW1XX_MII_PORT] = GSWIP_MII_CFGp(0),
+               [GSW1XX_MII_PORT + 1 ... GSWIP_MAX_PORTS - 1] = -1,
+       },
+       .mii_pcdu = {
+               [0 ... GSW1XX_MII_PORT - 1] = -1,
+               [GSW1XX_MII_PORT] = GSWIP_MII_PCDU0,
+               [GSW1XX_MII_PORT + 1 ... GSWIP_MAX_PORTS - 1] = -1,
+       },
        .mac_select_pcs         = gsw1xx_phylink_mac_select_pcs,
        .phylink_get_caps       = gsw1xx_phylink_get_caps,
        .port_setup             = gsw1xx_port_setup,