Commit 6e7e2e7e authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-dsa-lantiq_gswip-code-improvements'

Martin Schiller says:

====================
net: dsa: lantiq_gswip: code improvements

This patchset for the lantiq_gswip driver is a collection of minor fixes
and coding improvements by Martin Blumenstingl without any real changes
in the actual functionality.
====================

Link: https://lore.kernel.org/r/20240611135434.3180973-1-ms@dev.tdt.de


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents cf157f33 3b0a95ed
Loading
Loading
Loading
Loading
+202 −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/lantiq,gswip.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Lantiq GSWIP Ethernet switches

allOf:
  - $ref: dsa.yaml#/$defs/ethernet-ports

maintainers:
  - Hauke Mehrtens <hauke@hauke-m.de>

properties:
  compatible:
    enum:
      - lantiq,xrx200-gswip
      - lantiq,xrx300-gswip
      - lantiq,xrx330-gswip

  reg:
    minItems: 3
    maxItems: 3

  reg-names:
    items:
      - const: switch
      - const: mdio
      - const: mii

  mdio:
    $ref: /schemas/net/mdio.yaml#
    unevaluatedProperties: false

    properties:
      compatible:
        const: lantiq,xrx200-mdio

    required:
      - compatible

  gphy-fw:
    type: object
    properties:
      '#address-cells':
        const: 1

      '#size-cells':
        const: 0

      compatible:
        items:
          - enum:
              - lantiq,xrx200-gphy-fw
              - lantiq,xrx300-gphy-fw
              - lantiq,xrx330-gphy-fw
          - const: lantiq,gphy-fw

      lantiq,rcu:
        $ref: /schemas/types.yaml#/definitions/phandle
        description: phandle to the RCU syscon

    patternProperties:
      "^gphy@[0-9a-f]{1,2}$":
        type: object

        additionalProperties: false

        properties:
          reg:
            minimum: 0
            maximum: 255
            description:
              Offset of the GPHY firmware register in the RCU register range

          resets:
            items:
              - description: GPHY reset line

          reset-names:
            items:
              - const: gphy

        required:
          - reg

    required:
      - compatible
      - lantiq,rcu

    additionalProperties: false

required:
  - compatible
  - reg

unevaluatedProperties: false

examples:
  - |
    switch@e108000 {
            compatible = "lantiq,xrx200-gswip";
            reg = <0xe108000 0x3100>,  /* switch */
                  <0xe10b100 0xd8>,    /* mdio */
                  <0xe10b1d8 0x130>;   /* mii */
            dsa,member = <0 0>;

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

                    port@0 {
                            reg = <0>;
                            label = "lan3";
                            phy-mode = "rgmii";
                            phy-handle = <&phy0>;
                    };

                    port@1 {
                            reg = <1>;
                            label = "lan4";
                            phy-mode = "rgmii";
                            phy-handle = <&phy1>;
                    };

                    port@2 {
                            reg = <2>;
                            label = "lan2";
                            phy-mode = "internal";
                            phy-handle = <&phy11>;
                    };

                    port@4 {
                            reg = <4>;
                            label = "lan1";
                            phy-mode = "internal";
                            phy-handle = <&phy13>;
                    };

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

                    port@6 {
                            reg = <0x6>;
                            phy-mode = "internal";
                            ethernet = <&eth0>;

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

            mdio {
                    #address-cells = <1>;
                    #size-cells = <0>;
                    compatible = "lantiq,xrx200-mdio";

                    phy0: ethernet-phy@0 {
                            reg = <0x0>;
                    };
                    phy1: ethernet-phy@1 {
                            reg = <0x1>;
                    };
                    phy5: ethernet-phy@5 {
                            reg = <0x5>;
                    };
                    phy11: ethernet-phy@11 {
                            reg = <0x11>;
                    };
                    phy13: ethernet-phy@13 {
                            reg = <0x13>;
                    };
            };

            gphy-fw {
                    #address-cells = <1>;
                    #size-cells = <0>;
                    compatible = "lantiq,xrx200-gphy-fw", "lantiq,gphy-fw";
                    lantiq,rcu = <&rcu0>;

                    gphy@20 {
                            reg = <0x20>;

                            resets = <&reset0 31 30>;
                            reset-names = "gphy";
                    };

                    gphy@68 {
                            reg = <0x68>;

                            resets = <&reset0 29 28>;
                            reset-names = "gphy";
                    };
            };
    };
+0 −146
Original line number Diff line number Diff line
Lantiq GSWIP Ethernet switches
==================================

Required properties for GSWIP core:

- compatible	: "lantiq,xrx200-gswip" for the embedded GSWIP in the
		  xRX200 SoC
		  "lantiq,xrx300-gswip" for the embedded GSWIP in the
		  xRX300 SoC
		  "lantiq,xrx330-gswip" for the embedded GSWIP in the
		  xRX330 SoC
- reg		: memory range of the GSWIP core registers
		: memory range of the GSWIP MDIO registers
		: memory range of the GSWIP MII registers

See Documentation/devicetree/bindings/net/dsa/dsa.txt for a list of
additional required and optional properties.


Required properties for MDIO bus:
- compatible	: "lantiq,xrx200-mdio" for the MDIO bus inside the GSWIP
		  core of the xRX200 SoC and the PHYs connected to it.

See Documentation/devicetree/bindings/net/mdio.txt for a list of additional
required and optional properties.


Required properties for GPHY firmware loading:
- compatible	: "lantiq,xrx200-gphy-fw", "lantiq,gphy-fw"
		  "lantiq,xrx300-gphy-fw", "lantiq,gphy-fw"
		  "lantiq,xrx330-gphy-fw", "lantiq,gphy-fw"
		  for the loading of the firmware into the embedded
		  GPHY core of the SoC.
- lantiq,rcu	: reference to the rcu syscon

The GPHY firmware loader has a list of GPHY entries, one for each
embedded GPHY

- reg		: Offset of the GPHY firmware register in the RCU
		  register range
- resets	: list of resets of the embedded GPHY
- reset-names	: list of names of the resets

Example:

Ethernet switch on the VRX200 SoC:

switch@e108000 {
	#address-cells = <1>;
	#size-cells = <0>;
	compatible = "lantiq,xrx200-gswip";
	reg = <	0xe108000 0x3100	/* switch */
		0xe10b100 0xd8		/* mdio */
		0xe10b1d8 0x130		/* mii */
		>;
	dsa,member = <0 0>;

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

		port@0 {
			reg = <0>;
			label = "lan3";
			phy-mode = "rgmii";
			phy-handle = <&phy0>;
		};

		port@1 {
			reg = <1>;
			label = "lan4";
			phy-mode = "rgmii";
			phy-handle = <&phy1>;
		};

		port@2 {
			reg = <2>;
			label = "lan2";
			phy-mode = "internal";
			phy-handle = <&phy11>;
		};

		port@4 {
			reg = <4>;
			label = "lan1";
			phy-mode = "internal";
			phy-handle = <&phy13>;
		};

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

		port@6 {
			reg = <0x6>;
			ethernet = <&eth0>;
		};
	};

	mdio {
		#address-cells = <1>;
		#size-cells = <0>;
		compatible = "lantiq,xrx200-mdio";
		reg = <0>;

		phy0: ethernet-phy@0 {
			reg = <0x0>;
		};
		phy1: ethernet-phy@1 {
			reg = <0x1>;
		};
		phy5: ethernet-phy@5 {
			reg = <0x5>;
		};
		phy11: ethernet-phy@11 {
			reg = <0x11>;
		};
		phy13: ethernet-phy@13 {
			reg = <0x13>;
		};
	};

	gphy-fw {
		compatible = "lantiq,xrx200-gphy-fw", "lantiq,gphy-fw";
		lantiq,rcu = <&rcu0>;
		#address-cells = <1>;
		#size-cells = <0>;

		gphy@20 {
			reg = <0x20>;

			resets = <&reset0 31 30>;
			reset-names = "gphy";
		};

		gphy@68 {
			reg = <0x68>;

			resets = <&reset0 29 28>;
			reset-names = "gphy";
		};
	};
};
+1 −0
Original line number Diff line number Diff line
@@ -12449,6 +12449,7 @@ LANTIQ / INTEL Ethernet drivers
M:	Hauke Mehrtens <hauke@hauke-m.de>
L:	netdev@vger.kernel.org
S:	Maintained
F:	Documentation/devicetree/bindings/net/dsa/lantiq,gswip.yaml
F:	drivers/net/dsa/lantiq_gswip.c
F:	drivers/net/dsa/lantiq_pce.h
F:	drivers/net/ethernet/lantiq_xrx200.c
+55 −68
Original line number Diff line number Diff line
@@ -236,7 +236,9 @@
#define GSWIP_TABLE_ACTIVE_VLAN		0x01
#define GSWIP_TABLE_VLAN_MAPPING	0x02
#define GSWIP_TABLE_MAC_BRIDGE		0x0b
#define  GSWIP_TABLE_MAC_BRIDGE_STATIC	0x01	/* Static not, aging entry */
#define  GSWIP_TABLE_MAC_BRIDGE_KEY3_FID	GENMASK(5, 0)	/* Filtering identifier */
#define  GSWIP_TABLE_MAC_BRIDGE_VAL0_PORT	GENMASK(7, 4)	/* Port on learned entries */
#define  GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC	BIT(0)		/* Static, non-aging entry */

#define XRX200_GPHY_FW_ALIGN	(16 * 1024)

@@ -653,14 +655,8 @@ static int gswip_add_single_port_br(struct gswip_priv *priv, int port, bool add)
	struct gswip_pce_table_entry vlan_active = {0,};
	struct gswip_pce_table_entry vlan_mapping = {0,};
	unsigned int cpu_port = priv->hw_info->cpu_port;
	unsigned int max_ports = priv->hw_info->max_ports;
	int err;

	if (port >= max_ports) {
		dev_err(priv->dev, "single port for %i supported\n", port);
		return -EIO;
	}

	vlan_active.index = port + 1;
	vlan_active.table = GSWIP_TABLE_ACTIVE_VLAN;
	vlan_active.key[0] = 0; /* vid */
@@ -695,13 +691,18 @@ static int gswip_port_enable(struct dsa_switch *ds, int port,
	struct gswip_priv *priv = ds->priv;
	int err;

	if (!dsa_is_user_port(ds, port))
		return 0;

	if (!dsa_is_cpu_port(ds, port)) {
		u32 mdio_phy = 0;

		err = gswip_add_single_port_br(priv, port, true);
		if (err)
			return err;

		if (phydev)
			mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK;

		gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy,
				GSWIP_MDIO_PHYp(port));
	}

	/* RMON Counter Enable for port */
@@ -714,16 +715,6 @@ static int gswip_port_enable(struct dsa_switch *ds, int port,
	gswip_switch_mask(priv, 0, GSWIP_SDMA_PCTRL_EN,
			  GSWIP_SDMA_PCTRLp(port));

	if (!dsa_is_cpu_port(ds, port)) {
		u32 mdio_phy = 0;

		if (phydev)
			mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK;

		gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy,
				GSWIP_MDIO_PHYp(port));
	}

	return 0;
}

@@ -731,9 +722,6 @@ static void gswip_port_disable(struct dsa_switch *ds, int port)
{
	struct gswip_priv *priv = ds->priv;

	if (!dsa_is_user_port(ds, port))
		return;

	gswip_switch_mask(priv, GSWIP_FDMA_PCTRL_EN, 0,
			  GSWIP_FDMA_PCTRLp(port));
	gswip_switch_mask(priv, GSWIP_SDMA_PCTRL_EN, 0,
@@ -792,7 +780,7 @@ static int gswip_port_vlan_filtering(struct dsa_switch *ds, int port,
	}

	if (vlan_filtering) {
		/* Use port based VLAN tag */
		/* Use tag based VLAN */
		gswip_switch_mask(priv,
				  GSWIP_PCE_VCTRL_VSR,
				  GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR |
@@ -801,7 +789,7 @@ static int gswip_port_vlan_filtering(struct dsa_switch *ds, int port,
		gswip_switch_mask(priv, GSWIP_PCE_PCTRL_0_TVM, 0,
				  GSWIP_PCE_PCTRL_0p(port));
	} else {
		/* Use port based VLAN tag */
		/* Use port based VLAN */
		gswip_switch_mask(priv,
				  GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR |
				  GSWIP_PCE_VCTRL_VEMR,
@@ -836,7 +824,7 @@ static int gswip_setup(struct dsa_switch *ds)

	err = gswip_pce_load_microcode(priv);
	if (err) {
		dev_err(priv->dev, "writing PCE microcode failed, %i", err);
		dev_err(priv->dev, "writing PCE microcode failed, %i\n", err);
		return err;
	}

@@ -898,8 +886,6 @@ static int gswip_setup(struct dsa_switch *ds)

	ds->mtu_enforcement_ingress = true;

	gswip_port_enable(ds, cpu_port, NULL);

	ds->configure_vlan_while_not_filtering = false;

	return 0;
@@ -1314,10 +1300,11 @@ static void gswip_port_fast_age(struct dsa_switch *ds, int port)
		if (!mac_bridge.valid)
			continue;

		if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_STATIC)
		if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC)
			continue;

		if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) != port)
		if (port != FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_VAL0_PORT,
				      mac_bridge.val[0]))
			continue;

		mac_bridge.valid = false;
@@ -1383,7 +1370,8 @@ static int gswip_port_fdb(struct dsa_switch *ds, int port,
	}

	if (fid == -1) {
		dev_err(priv->dev, "Port not part of a bridge\n");
		dev_err(priv->dev, "no FID found for bridge %s\n",
			bridge->name);
		return -EINVAL;
	}

@@ -1392,9 +1380,9 @@ static int gswip_port_fdb(struct dsa_switch *ds, int port,
	mac_bridge.key[0] = addr[5] | (addr[4] << 8);
	mac_bridge.key[1] = addr[3] | (addr[2] << 8);
	mac_bridge.key[2] = addr[1] | (addr[0] << 8);
	mac_bridge.key[3] = fid;
	mac_bridge.key[3] = FIELD_PREP(GSWIP_TABLE_MAC_BRIDGE_KEY3_FID, fid);
	mac_bridge.val[0] = add ? BIT(port) : 0; /* port map */
	mac_bridge.val[1] = GSWIP_TABLE_MAC_BRIDGE_STATIC;
	mac_bridge.val[1] = GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC;
	mac_bridge.valid = add;

	err = gswip_pce_table_entry_write(priv, &mac_bridge);
@@ -1423,7 +1411,7 @@ static int gswip_port_fdb_dump(struct dsa_switch *ds, int port,
{
	struct gswip_priv *priv = ds->priv;
	struct gswip_pce_table_entry mac_bridge = {0,};
	unsigned char addr[6];
	unsigned char addr[ETH_ALEN];
	int i;
	int err;

@@ -1448,14 +1436,15 @@ static int gswip_port_fdb_dump(struct dsa_switch *ds, int port,
		addr[2] = (mac_bridge.key[1] >> 8) & 0xff;
		addr[1] = mac_bridge.key[2] & 0xff;
		addr[0] = (mac_bridge.key[2] >> 8) & 0xff;
		if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_STATIC) {
		if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_VAL1_STATIC) {
			if (mac_bridge.val[0] & BIT(port)) {
				err = cb(addr, 0, true, data);
				if (err)
					return err;
			}
		} else {
			if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) == port) {
			if (port == FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_VAL0_PORT,
					      mac_bridge.val[0])) {
				err = cb(addr, 0, false, data);
				if (err)
					return err;
@@ -1474,12 +1463,11 @@ static int gswip_port_max_mtu(struct dsa_switch *ds, int port)
static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
{
	struct gswip_priv *priv = ds->priv;
	int cpu_port = priv->hw_info->cpu_port;

	/* CPU port always has maximum mtu of user ports, so use it to set
	 * switch frame size, including 8 byte special header.
	 */
	if (port == cpu_port) {
	if (dsa_is_cpu_port(ds, port)) {
		new_mtu += 8;
		gswip_switch_w(priv, VLAN_ETH_HLEN + new_mtu + ETH_FCS_LEN,
			       GSWIP_MAC_FLEN);
@@ -1516,6 +1504,7 @@ static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port,
	case 2:
	case 3:
	case 4:
	case 6:
		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
			  config->supported_interfaces);
		break;
@@ -1547,6 +1536,7 @@ static void gswip_xrx300_phylink_get_caps(struct dsa_switch *ds, int port,
	case 2:
	case 3:
	case 4:
	case 6:
		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
			  config->supported_interfaces);
		break;
@@ -1790,7 +1780,7 @@ static u32 gswip_bcm_ram_entry_read(struct gswip_priv *priv, u32 table,
	err = gswip_switch_r_timeout(priv, GSWIP_BM_RAM_CTRL,
				     GSWIP_BM_RAM_CTRL_BAS);
	if (err) {
		dev_err(priv->dev, "timeout while reading table: %u, index: %u",
		dev_err(priv->dev, "timeout while reading table: %u, index: %u\n",
			table, index);
		return 0;
	}
@@ -1929,11 +1919,9 @@ static int gswip_gphy_fw_load(struct gswip_priv *priv, struct gswip_gphy_fw *gph
	msleep(200);

	ret = request_firmware(&fw, gphy_fw->fw_name, dev);
	if (ret) {
		dev_err(dev, "failed to load firmware: %s, error: %i\n",
			gphy_fw->fw_name, ret);
		return ret;
	}
	if (ret)
		return dev_err_probe(dev, ret, "failed to load firmware: %s\n",
				     gphy_fw->fw_name);

	/* GPHY cores need the firmware code in a persistent and contiguous
	 * memory area with a 16 kB boundary aligned start address.
@@ -1946,9 +1934,9 @@ static int gswip_gphy_fw_load(struct gswip_priv *priv, struct gswip_gphy_fw *gph
		dev_addr = ALIGN(dma_addr, XRX200_GPHY_FW_ALIGN);
		memcpy(fw_addr, fw->data, fw->size);
	} else {
		dev_err(dev, "failed to alloc firmware memory\n");
		release_firmware(fw);
		return -ENOMEM;
		return dev_err_probe(dev, -ENOMEM,
				     "failed to alloc firmware memory\n");
	}

	release_firmware(fw);
@@ -1975,8 +1963,8 @@ static int gswip_gphy_fw_probe(struct gswip_priv *priv,

	gphy_fw->clk_gate = devm_clk_get(dev, gphyname);
	if (IS_ERR(gphy_fw->clk_gate)) {
		dev_err(dev, "Failed to lookup gate clock\n");
		return PTR_ERR(gphy_fw->clk_gate);
		return dev_err_probe(dev, PTR_ERR(gphy_fw->clk_gate),
				     "Failed to lookup gate clock\n");
	}

	ret = of_property_read_u32(gphy_fw_np, "reg", &gphy_fw->fw_addr_offset);
@@ -1996,8 +1984,8 @@ static int gswip_gphy_fw_probe(struct gswip_priv *priv,
		gphy_fw->fw_name = priv->gphy_fw_name_cfg->ge_firmware_name;
		break;
	default:
		dev_err(dev, "Unknown GPHY mode %d\n", gphy_mode);
		return -EINVAL;
		return dev_err_probe(dev, -EINVAL, "Unknown GPHY mode %d\n",
				     gphy_mode);
	}

	gphy_fw->reset = of_reset_control_array_get_exclusive(gphy_fw_np);
@@ -2019,7 +2007,7 @@ static void gswip_gphy_fw_remove(struct gswip_priv *priv,

	ret = regmap_write(priv->rcu_regmap, gphy_fw->fw_addr_offset, 0);
	if (ret)
		dev_err(priv->dev, "can not reset GPHY FW pointer");
		dev_err(priv->dev, "can not reset GPHY FW pointer\n");

	clk_disable_unprepare(gphy_fw->clk_gate);

@@ -2048,8 +2036,9 @@ static int gswip_gphy_fw_list(struct gswip_priv *priv,
			priv->gphy_fw_name_cfg = &xrx200a2x_gphy_data;
			break;
		default:
			dev_err(dev, "unknown GSWIP version: 0x%x", version);
			return -ENOENT;
			return dev_err_probe(dev, -ENOENT,
					     "unknown GSWIP version: 0x%x\n",
					     version);
		}
	}

@@ -2057,10 +2046,9 @@ static int gswip_gphy_fw_list(struct gswip_priv *priv,
	if (match && match->data)
		priv->gphy_fw_name_cfg = match->data;

	if (!priv->gphy_fw_name_cfg) {
		dev_err(dev, "GPHY compatible type not supported");
		return -ENOENT;
	}
	if (!priv->gphy_fw_name_cfg)
		return dev_err_probe(dev, -ENOENT,
				     "GPHY compatible type not supported\n");

	priv->num_gphy_fw = of_get_available_child_count(gphy_fw_list_np);
	if (!priv->num_gphy_fw)
@@ -2161,8 +2149,8 @@ static int gswip_probe(struct platform_device *pdev)
			return -EINVAL;
		break;
	default:
		dev_err(dev, "unknown GSWIP version: 0x%x", version);
		return -ENOENT;
		return dev_err_probe(dev, -ENOENT,
				     "unknown GSWIP version: 0x%x\n", version);
	}

	/* bring up the mdio bus */
@@ -2170,28 +2158,27 @@ static int gswip_probe(struct platform_device *pdev)
	if (gphy_fw_np) {
		err = gswip_gphy_fw_list(priv, gphy_fw_np, version);
		of_node_put(gphy_fw_np);
		if (err) {
			dev_err(dev, "gphy fw probe failed\n");
			return err;
		}
		if (err)
			return dev_err_probe(dev, err,
					     "gphy fw probe failed\n");
	}

	/* bring up the mdio bus */
	err = gswip_mdio(priv);
	if (err) {
		dev_err(dev, "mdio probe failed\n");
		dev_err_probe(dev, err, "mdio probe failed\n");
		goto gphy_fw_remove;
	}

	err = dsa_register_switch(priv->ds);
	if (err) {
		dev_err(dev, "dsa switch register failed: %i\n", err);
		dev_err_probe(dev, err, "dsa switch registration failed\n");
		goto gphy_fw_remove;
	}
	if (!dsa_is_cpu_port(priv->ds, priv->hw_info->cpu_port)) {
		dev_err(dev, "wrong CPU port defined, HW only supports port: %i",
		err = dev_err_probe(dev, -EINVAL,
				    "wrong CPU port defined, HW only supports port: %i\n",
				    priv->hw_info->cpu_port);
		err = -EINVAL;
		goto disable_switch;
	}