Commit 5cb3ab50 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'support-mt7531-on-bpi-r2-pro'

Frank Wunderlich says:

====================
Support mt7531 on BPI-R2 Pro

This Series add Support for the mt7531 switch on Bananapi R2 Pro board.

This board uses port5 of the switch to conect to the gmac0 of the
rk3568 SoC.

Currently CPU-Port is hardcoded in the mt7530 driver to port 6.

Compared to v1 the reset-Patch was dropped as it was not needed and
CPU-Port-changes are completely rewriten based on suggestions/code from
Vladimir Oltean (many thanks to this).
In DTS Patch i only dropped the status-property that was not
needed/ignored by driver.

Due to the Changes i also made a regression test on mt7623 bpi-r2
(mt7623 soc + mt7530) and bpi-r64 (mt7622 soc + mt7531) with cpu-
port 6. Tests were done directly (ipv4 config on dsa user port)
and with vlan-aware bridge including vlan that was tagged outgoing
on dsa user port.
====================

Link: https://lore.kernel.org/r/20220610170541.8643-1-linux@fw-web.de


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 68d54289 c1804463
Loading
Loading
Loading
Loading
+404 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/dsa/mediatek,mt7530.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Mediatek MT7530 Ethernet switch

maintainers:
  - Sean Wang <sean.wang@mediatek.com>
  - Landen Chao <Landen.Chao@mediatek.com>
  - DENG Qingfang <dqfext@gmail.com>

description: |
  Port 5 of mt7530 and mt7621 switch is muxed between:
  1. GMAC5: GMAC5 can interface with another external MAC or PHY.
  2. PHY of port 0 or port 4: PHY interfaces with an external MAC like 2nd GMAC
     of the SOC. Used in many setups where port 0/4 becomes the WAN port.
     Note: On a MT7621 SOC with integrated switch: 2nd GMAC can only connected to
       GMAC5 when the gpios for RGMII2 (GPIO 22-33) are not used and not
       connected to external component!

  Port 5 modes/configurations:
  1. Port 5 is disabled and isolated: An external phy can interface to the 2nd
     GMAC of the SOC.
     In the case of a build-in MT7530 switch, port 5 shares the RGMII bus with 2nd
     GMAC and an optional external phy. Mind the GPIO/pinctl settings of the SOC!
  2. Port 5 is muxed to PHY of port 0/4: Port 0/4 interfaces with 2nd GMAC.
     It is a simple MAC to PHY interface, port 5 needs to be setup for xMII mode
     and RGMII delay.
  3. Port 5 is muxed to GMAC5 and can interface to an external phy.
     Port 5 becomes an extra switch port.
     Only works on platform where external phy TX<->RX lines are swapped.
     Like in the Ubiquiti ER-X-SFP.
  4. Port 5 is muxed to GMAC5 and interfaces with the 2nd GAMC as 2nd CPU port.
     Currently a 2nd CPU port is not supported by DSA code.

  Depending on how the external PHY is wired:
  1. normal: The PHY can only connect to 2nd GMAC but not to the switch
  2. swapped: RGMII TX, RX are swapped; external phy interface with the switch as
     a ethernet port. But can't interface to the 2nd GMAC.

    Based on the DT the port 5 mode is configured.

  Driver tries to lookup the phy-handle of the 2nd GMAC of the master device.
  When phy-handle matches PHY of port 0 or 4 then port 5 set-up as mode 2.
  phy-mode must be set, see also example 2 below!
  * mt7621: phy-mode = "rgmii-txid";
  * mt7623: phy-mode = "rgmii";

  CPU-Ports need a phy-mode property:
    Allowed values on mt7530 and mt7621:
      - "rgmii"
      - "trgmii"
    On mt7531:
      - "1000base-x"
      - "2500base-x"
      - "rgmii"
      - "sgmii"


properties:
  compatible:
    enum:
      - mediatek,mt7530
      - mediatek,mt7531
      - mediatek,mt7621

  core-supply:
    description:
      Phandle to the regulator node necessary for the core power.

  "#gpio-cells":
    const: 2

  gpio-controller:
    type: boolean
    description:
      if defined, MT7530's LED controller will run on GPIO mode.

  "#interrupt-cells":
    const: 1

  interrupt-controller: true

  interrupts:
    maxItems: 1

  io-supply:
    description:
      Phandle to the regulator node necessary for the I/O power.
      See Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
      for details for the regulator setup on these boards.

  mediatek,mcm:
    type: boolean
    description:
      if defined, indicates that either MT7530 is the part on multi-chip
      module belong to MT7623A has or the remotely standalone chip as the
      function MT7623N reference board provided for.

  reset-gpios:
    maxItems: 1

  reset-names:
    const: mcm

  resets:
    description:
      Phandle pointing to the system reset controller with line index for
      the ethsys.
    maxItems: 1

patternProperties:
  "^(ethernet-)?ports$":
    type: object

    patternProperties:
      "^(ethernet-)?port@[0-9]+$":
        type: object
        description: Ethernet switch ports

        unevaluatedProperties: false

        properties:
          reg:
            description:
              Port address described must be 5 or 6 for CPU port and from 0
              to 5 for user ports.

        allOf:
          - $ref: dsa-port.yaml#
          - if:
              properties:
                label:
                  items:
                    - const: cpu
            then:
              required:
                - reg
                - phy-mode

required:
  - compatible
  - reg

allOf:
  - $ref: "dsa.yaml#"
  - if:
      required:
        - mediatek,mcm
    then:
      required:
        - resets
        - reset-names

  - dependencies:
      interrupt-controller: [ interrupts ]

  - if:
      properties:
        compatible:
          items:
            - const: mediatek,mt7530
    then:
      required:
        - core-supply
        - io-supply

unevaluatedProperties: false

examples:
  - |
    #include <dt-bindings/gpio/gpio.h>
    mdio {
        #address-cells = <1>;
        #size-cells = <0>;
        switch@0 {
            compatible = "mediatek,mt7530";
            reg = <0>;

            core-supply = <&mt6323_vpa_reg>;
            io-supply = <&mt6323_vemc3v3_reg>;
            reset-gpios = <&pio 33 GPIO_ACTIVE_HIGH>;

            ethernet-ports {
                #address-cells = <1>;
                #size-cells = <0>;
                port@0 {
                    reg = <0>;
                    label = "lan0";
                };

                port@1 {
                    reg = <1>;
                    label = "lan1";
                };

                port@2 {
                    reg = <2>;
                    label = "lan2";
                };

                port@3 {
                    reg = <3>;
                    label = "lan3";
                };

                port@4 {
                    reg = <4>;
                    label = "wan";
                };

                port@6 {
                    reg = <6>;
                    label = "cpu";
                    ethernet = <&gmac0>;
                    phy-mode = "trgmii";
                    fixed-link {
                        speed = <1000>;
                        full-duplex;
                    };
                };
            };
        };
    };

  - |
    //Example 2: MT7621: Port 4 is WAN port: 2nd GMAC -> Port 5 -> PHY port 4.

    ethernet {
        #address-cells = <1>;
        #size-cells = <0>;
        gmac0: mac@0 {
            compatible = "mediatek,eth-mac";
            reg = <0>;
            phy-mode = "rgmii";

            fixed-link {
                speed = <1000>;
                full-duplex;
                pause;
            };
        };

        gmac1: mac@1 {
            compatible = "mediatek,eth-mac";
            reg = <1>;
            phy-mode = "rgmii-txid";
            phy-handle = <&phy4>;
        };

        mdio: mdio-bus {
            #address-cells = <1>;
            #size-cells = <0>;

            /* Internal phy */
            phy4: ethernet-phy@4 {
                reg = <4>;
            };

            mt7530: switch@1f {
                compatible = "mediatek,mt7621";
                reg = <0x1f>;
                mediatek,mcm;

                resets = <&rstctrl 2>;
                reset-names = "mcm";

                ethernet-ports {
                    #address-cells = <1>;
                    #size-cells = <0>;

                    port@0 {
                        reg = <0>;
                        label = "lan0";
                    };

                    port@1 {
                        reg = <1>;
                        label = "lan1";
                    };

                    port@2 {
                        reg = <2>;
                        label = "lan2";
                    };

                    port@3 {
                        reg = <3>;
                        label = "lan3";
                    };

                    /* Commented out. Port 4 is handled by 2nd GMAC.
                    port@4 {
                        reg = <4>;
                        label = "lan4";
                    };
                    */

                    port@6 {
                        reg = <6>;
                        label = "cpu";
                        ethernet = <&gmac0>;
                        phy-mode = "rgmii";

                        fixed-link {
                            speed = <1000>;
                            full-duplex;
                            pause;
                        };
                    };
                };
            };
        };
    };

  - |
    //Example 3: MT7621: Port 5 is connected to external PHY: Port 5 -> external PHY.

    ethernet {
        #address-cells = <1>;
        #size-cells = <0>;
        gmac_0: mac@0 {
            compatible = "mediatek,eth-mac";
            reg = <0>;
            phy-mode = "rgmii";

            fixed-link {
                speed = <1000>;
                full-duplex;
                pause;
            };
        };

        mdio0: mdio-bus {
            #address-cells = <1>;
            #size-cells = <0>;

            /* External phy */
            ephy5: ethernet-phy@7 {
                reg = <7>;
            };

            switch@1f {
                compatible = "mediatek,mt7621";
                reg = <0x1f>;
                mediatek,mcm;

                resets = <&rstctrl 2>;
                reset-names = "mcm";

                ethernet-ports {
                    #address-cells = <1>;
                    #size-cells = <0>;

                    port@0 {
                        reg = <0>;
                        label = "lan0";
                    };

                    port@1 {
                        reg = <1>;
                        label = "lan1";
                    };

                    port@2 {
                        reg = <2>;
                        label = "lan2";
                    };

                    port@3 {
                        reg = <3>;
                        label = "lan3";
                    };

                    port@4 {
                        reg = <4>;
                        label = "lan4";
                    };

                    port@5 {
                        reg = <5>;
                        label = "lan5";
                        phy-mode = "rgmii";
                        phy-handle = <&ephy5>;
                    };

                    cpu_port0: port@6 {
                        reg = <6>;
                        label = "cpu";
                        ethernet = <&gmac_0>;
                        phy-mode = "rgmii";

                        fixed-link {
                            speed = <1000>;
                            full-duplex;
                            pause;
                        };
                    };
                };
            };
        };
    };
+0 −327
Original line number Diff line number Diff line
Mediatek MT7530 Ethernet switch
================================

Required properties:

- compatible: may be compatible = "mediatek,mt7530"
	or compatible = "mediatek,mt7621"
	or compatible = "mediatek,mt7531"
- #address-cells: Must be 1.
- #size-cells: Must be 0.
- mediatek,mcm: Boolean; if defined, indicates that either MT7530 is the part
	on multi-chip module belong to MT7623A has or the remotely standalone
	chip as the function MT7623N reference board provided for.

If compatible mediatek,mt7530 is set then the following properties are required

- core-supply: Phandle to the regulator node necessary for the core power.
- io-supply: Phandle to the regulator node necessary for the I/O power.
	See Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
	for details for the regulator setup on these boards.

If the property mediatek,mcm isn't defined, following property is required

- reset-gpios: Should be a gpio specifier for a reset line.

Else, following properties are required

- resets : Phandle pointing to the system reset controller with
	line index for the ethsys.
- reset-names : Should be set to "mcm".

Required properties for the child nodes within ports container:

- reg: Port address described must be 6 for CPU port and from 0 to 5 for
	user ports.
- phy-mode: String, the following values are acceptable for port labeled
	"cpu":
	If compatible mediatek,mt7530 or mediatek,mt7621 is set,
	must be either "trgmii" or "rgmii"
	If compatible mediatek,mt7531 is set,
	must be either "sgmii", "1000base-x" or "2500base-x"

Port 5 of mt7530 and mt7621 switch is muxed between:
1. GMAC5: GMAC5 can interface with another external MAC or PHY.
2. PHY of port 0 or port 4: PHY interfaces with an external MAC like 2nd GMAC
   of the SOC. Used in many setups where port 0/4 becomes the WAN port.
   Note: On a MT7621 SOC with integrated switch: 2nd GMAC can only connected to
	 GMAC5 when the gpios for RGMII2 (GPIO 22-33) are not used and not
	 connected to external component!

Port 5 modes/configurations:
1. Port 5 is disabled and isolated: An external phy can interface to the 2nd
   GMAC of the SOC.
   In the case of a build-in MT7530 switch, port 5 shares the RGMII bus with 2nd
   GMAC and an optional external phy. Mind the GPIO/pinctl settings of the SOC!
2. Port 5 is muxed to PHY of port 0/4: Port 0/4 interfaces with 2nd GMAC.
   It is a simple MAC to PHY interface, port 5 needs to be setup for xMII mode
   and RGMII delay.
3. Port 5 is muxed to GMAC5 and can interface to an external phy.
   Port 5 becomes an extra switch port.
   Only works on platform where external phy TX<->RX lines are swapped.
   Like in the Ubiquiti ER-X-SFP.
4. Port 5 is muxed to GMAC5 and interfaces with the 2nd GAMC as 2nd CPU port.
   Currently a 2nd CPU port is not supported by DSA code.

Depending on how the external PHY is wired:
1. normal: The PHY can only connect to 2nd GMAC but not to the switch
2. swapped: RGMII TX, RX are swapped; external phy interface with the switch as
   a ethernet port. But can't interface to the 2nd GMAC.

Based on the DT the port 5 mode is configured.

Driver tries to lookup the phy-handle of the 2nd GMAC of the master device.
When phy-handle matches PHY of port 0 or 4 then port 5 set-up as mode 2.
phy-mode must be set, see also example 2 below!
 * mt7621: phy-mode = "rgmii-txid";
 * mt7623: phy-mode = "rgmii";

Optional properties:

- gpio-controller: Boolean; if defined, MT7530's LED controller will run on
	GPIO mode.
- #gpio-cells: Must be 2 if gpio-controller is defined.
- interrupt-controller: Boolean; Enables the internal interrupt controller.

If interrupt-controller is defined, the following properties are required.

- #interrupt-cells: Must be 1.
- interrupts: Parent interrupt for the interrupt controller.

See Documentation/devicetree/bindings/net/dsa/dsa.txt for a list of additional
required, optional properties and how the integrated switch subnodes must
be specified.

Example:

	&mdio0 {
		switch@0 {
			compatible = "mediatek,mt7530";
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <0>;

			core-supply = <&mt6323_vpa_reg>;
			io-supply = <&mt6323_vemc3v3_reg>;
			reset-gpios = <&pio 33 0>;

			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				reg = <0>;
				port@0 {
					reg = <0>;
					label = "lan0";
				};

				port@1 {
					reg = <1>;
					label = "lan1";
				};

				port@2 {
					reg = <2>;
					label = "lan2";
				};

				port@3 {
					reg = <3>;
					label = "lan3";
				};

				port@4 {
					reg = <4>;
					label = "wan";
				};

				port@6 {
					reg = <6>;
					label = "cpu";
					ethernet = <&gmac0>;
					phy-mode = "trgmii";
					fixed-link {
						speed = <1000>;
						full-duplex;
					};
				};
			};
		};
	};

Example 2: MT7621: Port 4 is WAN port: 2nd GMAC -> Port 5 -> PHY port 4.

&eth {
	gmac0: mac@0 {
		compatible = "mediatek,eth-mac";
		reg = <0>;
		phy-mode = "rgmii";

		fixed-link {
			speed = <1000>;
			full-duplex;
			pause;
		};
	};

	gmac1: mac@1 {
		compatible = "mediatek,eth-mac";
		reg = <1>;
		phy-mode = "rgmii-txid";
		phy-handle = <&phy4>;
	};

	mdio: mdio-bus {
		#address-cells = <1>;
		#size-cells = <0>;

		/* Internal phy */
		phy4: ethernet-phy@4 {
			reg = <4>;
		};

		mt7530: switch@1f {
			compatible = "mediatek,mt7621";
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <0x1f>;
			pinctrl-names = "default";
			mediatek,mcm;

			resets = <&rstctrl 2>;
			reset-names = "mcm";

			ports {
				#address-cells = <1>;
				#size-cells = <0>;

				port@0 {
					reg = <0>;
					label = "lan0";
				};

				port@1 {
					reg = <1>;
					label = "lan1";
				};

				port@2 {
					reg = <2>;
					label = "lan2";
				};

				port@3 {
					reg = <3>;
					label = "lan3";
				};

/* Commented out. Port 4 is handled by 2nd GMAC.
				port@4 {
					reg = <4>;
					label = "lan4";
				};
*/

				cpu_port0: port@6 {
					reg = <6>;
					label = "cpu";
					ethernet = <&gmac0>;
					phy-mode = "rgmii";

					fixed-link {
						speed = <1000>;
						full-duplex;
						pause;
					};
				};
			};
		};
	};
};

Example 3: MT7621: Port 5 is connected to external PHY: Port 5 -> external PHY.

&eth {
	gmac0: mac@0 {
		compatible = "mediatek,eth-mac";
		reg = <0>;
		phy-mode = "rgmii";

		fixed-link {
			speed = <1000>;
			full-duplex;
			pause;
		};
	};

	mdio: mdio-bus {
		#address-cells = <1>;
		#size-cells = <0>;

		/* External phy */
		ephy5: ethernet-phy@7 {
			reg = <7>;
		};

		mt7530: switch@1f {
			compatible = "mediatek,mt7621";
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <0x1f>;
			pinctrl-names = "default";
			mediatek,mcm;

			resets = <&rstctrl 2>;
			reset-names = "mcm";

			ports {
				#address-cells = <1>;
				#size-cells = <0>;

				port@0 {
					reg = <0>;
					label = "lan0";
				};

				port@1 {
					reg = <1>;
					label = "lan1";
				};

				port@2 {
					reg = <2>;
					label = "lan2";
				};

				port@3 {
					reg = <3>;
					label = "lan3";
				};

				port@4 {
					reg = <4>;
					label = "lan4";
				};

				port@5 {
					reg = <5>;
					label = "lan5";
					phy-mode = "rgmii";
					phy-handle = <&ephy5>;
				};

				cpu_port0: port@6 {
					reg = <6>;
					label = "cpu";
					ethernet = <&gmac0>;
					phy-mode = "rgmii";

					fixed-link {
						speed = <1000>;
						full-duplex;
						pause;
					};
				};
			};
		};
	};
};
+48 −0
Original line number Diff line number Diff line
@@ -394,6 +394,54 @@
	status = "disabled";
};

&mdio0 {
	#address-cells = <1>;
	#size-cells = <0>;

	switch@0 {
		compatible = "mediatek,mt7531";
		reg = <0>;

		ports {
			#address-cells = <1>;
			#size-cells = <0>;

			port@1 {
				reg = <1>;
				label = "lan0";
			};

			port@2 {
				reg = <2>;
				label = "lan1";
			};

			port@3 {
				reg = <3>;
				label = "lan2";
			};

			port@4 {
				reg = <4>;
				label = "lan3";
			};

			port@5 {
				reg = <5>;
				label = "cpu";
				ethernet = <&gmac0>;
				phy-mode = "rgmii";

				fixed-link {
					speed = <1000>;
					full-duplex;
					pause;
				};
			};
		};
	};
};

&mdio1 {
	rgmii_phy1: ethernet-phy@0 {
		compatible = "ethernet-phy-ieee802.3-c22";
+53 −29
Original line number Diff line number Diff line
@@ -1038,6 +1038,7 @@ static int
mt7530_port_enable(struct dsa_switch *ds, int port,
		   struct phy_device *phy)
{
	struct dsa_port *dp = dsa_to_port(ds, port);
	struct mt7530_priv *priv = ds->priv;

	mutex_lock(&priv->reg_mutex);
@@ -1046,7 +1047,11 @@ mt7530_port_enable(struct dsa_switch *ds, int port,
	 * restore the port matrix if the port is the member of a certain
	 * bridge.
	 */
	priv->ports[port].pm |= PCR_MATRIX(BIT(MT7530_CPU_PORT));
	if (dsa_port_is_user(dp)) {
		struct dsa_port *cpu_dp = dp->cpu_dp;

		priv->ports[port].pm |= PCR_MATRIX(BIT(cpu_dp->index));
	}
	priv->ports[port].enable = true;
	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
		   priv->ports[port].pm);
@@ -1195,7 +1200,8 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port,
			struct netlink_ext_ack *extack)
{
	struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
	u32 port_bitmap = BIT(MT7530_CPU_PORT);
	struct dsa_port *cpu_dp = dp->cpu_dp;
	u32 port_bitmap = BIT(cpu_dp->index);
	struct mt7530_priv *priv = ds->priv;

	mutex_lock(&priv->reg_mutex);
@@ -1272,9 +1278,12 @@ mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port)
	 * the CPU port get out of VLAN filtering mode.
	 */
	if (all_user_ports_removed) {
		mt7530_write(priv, MT7530_PCR_P(MT7530_CPU_PORT),
		struct dsa_port *dp = dsa_to_port(ds, port);
		struct dsa_port *cpu_dp = dp->cpu_dp;

		mt7530_write(priv, MT7530_PCR_P(cpu_dp->index),
			     PCR_MATRIX(dsa_user_ports(priv->ds)));
		mt7530_write(priv, MT7530_PVC_P(MT7530_CPU_PORT), PORT_SPEC_TAG
		mt7530_write(priv, MT7530_PVC_P(cpu_dp->index), PORT_SPEC_TAG
			     | PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
	}
}
@@ -1312,6 +1321,7 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
			 struct dsa_bridge bridge)
{
	struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
	struct dsa_port *cpu_dp = dp->cpu_dp;
	struct mt7530_priv *priv = ds->priv;

	mutex_lock(&priv->reg_mutex);
@@ -1340,8 +1350,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
	 */
	if (priv->ports[port].enable)
		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
			   PCR_MATRIX(BIT(MT7530_CPU_PORT)));
	priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
			   PCR_MATRIX(BIT(cpu_dp->index)));
	priv->ports[port].pm = PCR_MATRIX(BIT(cpu_dp->index));

	/* When a port is removed from the bridge, the port would be set up
	 * back to the default as is at initial boot which is a VLAN-unaware
@@ -1508,6 +1518,9 @@ static int
mt7530_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
			   struct netlink_ext_ack *extack)
{
	struct dsa_port *dp = dsa_to_port(ds, port);
	struct dsa_port *cpu_dp = dp->cpu_dp;

	if (vlan_filtering) {
		/* The port is being kept as VLAN-unaware port when bridge is
		 * set up with vlan_filtering not being set, Otherwise, the
@@ -1515,7 +1528,7 @@ mt7530_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
		 * for becoming a VLAN-aware port.
		 */
		mt7530_port_set_vlan_aware(ds, port);
		mt7530_port_set_vlan_aware(ds, MT7530_CPU_PORT);
		mt7530_port_set_vlan_aware(ds, cpu_dp->index);
	} else {
		mt7530_port_set_vlan_unaware(ds, port);
	}
@@ -1527,11 +1540,11 @@ static void
mt7530_hw_vlan_add(struct mt7530_priv *priv,
		   struct mt7530_hw_vlan_entry *entry)
{
	struct dsa_port *dp = dsa_to_port(priv->ds, entry->port);
	u8 new_members;
	u32 val;

	new_members = entry->old_members | BIT(entry->port) |
		      BIT(MT7530_CPU_PORT);
	new_members = entry->old_members | BIT(entry->port);

	/* Validate the entry with independent learning, create egress tag per
	 * VLAN and joining the port as one of the port members.
@@ -1542,22 +1555,20 @@ mt7530_hw_vlan_add(struct mt7530_priv *priv,

	/* Decide whether adding tag or not for those outgoing packets from the
	 * port inside the VLAN.
	 */
	val = entry->untagged ? MT7530_VLAN_EGRESS_UNTAG :
				MT7530_VLAN_EGRESS_TAG;
	mt7530_rmw(priv, MT7530_VAWD2,
		   ETAG_CTRL_P_MASK(entry->port),
		   ETAG_CTRL_P(entry->port, val));

	/* CPU port is always taken as a tagged port for serving more than one
	 * CPU port is always taken as a tagged port for serving more than one
	 * VLANs across and also being applied with egress type stack mode for
	 * that VLAN tags would be appended after hardware special tag used as
	 * DSA tag.
	 */
	if (dsa_port_is_cpu(dp))
		val = MT7530_VLAN_EGRESS_STACK;
	else if (entry->untagged)
		val = MT7530_VLAN_EGRESS_UNTAG;
	else
		val = MT7530_VLAN_EGRESS_TAG;
	mt7530_rmw(priv, MT7530_VAWD2,
		   ETAG_CTRL_P_MASK(MT7530_CPU_PORT),
		   ETAG_CTRL_P(MT7530_CPU_PORT,
			       MT7530_VLAN_EGRESS_STACK));
		   ETAG_CTRL_P_MASK(entry->port),
		   ETAG_CTRL_P(entry->port, val));
}

static void
@@ -1576,11 +1587,7 @@ mt7530_hw_vlan_del(struct mt7530_priv *priv,
		return;
	}

	/* If certain member apart from CPU port is still alive in the VLAN,
	 * the entry would be kept valid. Otherwise, the entry is got to be
	 * disabled.
	 */
	if (new_members && new_members != BIT(MT7530_CPU_PORT)) {
	if (new_members) {
		val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) |
		      VLAN_VALID;
		mt7530_write(priv, MT7530_VAWD1, val);
@@ -2098,11 +2105,12 @@ static int
mt7530_setup(struct dsa_switch *ds)
{
	struct mt7530_priv *priv = ds->priv;
	struct device_node *dn = NULL;
	struct device_node *phy_node;
	struct device_node *mac_np;
	struct mt7530_dummy_poll p;
	phy_interface_t interface;
	struct device_node *dn;
	struct dsa_port *cpu_dp;
	u32 id, val;
	int ret, i;

@@ -2110,7 +2118,19 @@ mt7530_setup(struct dsa_switch *ds)
	 * controller also is the container for two GMACs nodes representing
	 * as two netdev instances.
	 */
	dn = dsa_to_port(ds, MT7530_CPU_PORT)->master->dev.of_node->parent;
	dsa_switch_for_each_cpu_port(cpu_dp, ds) {
		dn = cpu_dp->master->dev.of_node->parent;
		/* It doesn't matter which CPU port is found first,
		 * their masters should share the same parent OF node
		 */
		break;
	}

	if (!dn) {
		dev_err(ds->dev, "parent OF node of DSA master not found");
		return -EINVAL;
	}

	ds->assisted_learning_on_cpu_port = true;
	ds->mtu_enforcement_ingress = true;

@@ -2272,6 +2292,7 @@ mt7531_setup(struct dsa_switch *ds)
{
	struct mt7530_priv *priv = ds->priv;
	struct mt7530_dummy_poll p;
	struct dsa_port *cpu_dp;
	u32 val, id;
	int ret, i;

@@ -2344,8 +2365,11 @@ mt7531_setup(struct dsa_switch *ds)
				 CORE_PLL_GROUP4, val);

	/* BPDU to CPU port */
	dsa_switch_for_each_cpu_port(cpu_dp, ds) {
		mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK,
		   BIT(MT7530_CPU_PORT));
			   BIT(cpu_dp->index));
		break;
	}
	mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
		   MT753X_BPDU_CPU_ONLY);

+0 −1
Original line number Diff line number Diff line
@@ -8,7 +8,6 @@

#define MT7530_NUM_PORTS		7
#define MT7530_NUM_PHYS			5
#define MT7530_CPU_PORT			6
#define MT7530_NUM_FDB_RECORDS		2048
#define MT7530_ALL_MEMBERS		0xff