Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6d045db authored by Florian Fainelli's avatar Florian Fainelli Committed by David S. Miller
Browse files

net: dsa: bcm_sf2: add port_enable/disable callbacks



The SF2 switch driver is already architected around per-port
enable/disable callbacks, so we just need a slight update to our
existing bcm_sf2_port_setup() resp. bcm_sf2_port_disable() functions to
be suitable as callbacks for port_enable/port_disable.

We need to shuffle a little the code that does the per-port VLAN
configuration/isolation since ports can now be brought up/down
separately, so we need to make sure that IMP (CPU, management) port is
always included in that specific port setup.

Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7de1557c
Loading
Loading
Loading
Loading
+40 −20
Original line number Original line Diff line number Diff line
@@ -135,10 +135,29 @@ static char *bcm_sf2_sw_probe(struct device *host_dev, int sw_addr)
	return "Broadcom Starfighter 2";
	return "Broadcom Starfighter 2";
}
}


static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
static void bcm_sf2_imp_vlan_setup(struct dsa_switch *ds, int cpu_port)
{
{
	struct bcm_sf2_priv *priv = ds_to_priv(ds);
	struct bcm_sf2_priv *priv = ds_to_priv(ds);
	unsigned int i;
	unsigned int i;
	u32 reg;

	/* Enable the IMP Port to be in the same VLAN as the other ports
	 * on a per-port basis such that we only have Port i and IMP in
	 * the same VLAN.
	 */
	for (i = 0; i < priv->hw_params.num_ports; i++) {
		if (!((1 << i) & ds->phys_port_mask))
			continue;

		reg = core_readl(priv, CORE_PORT_VLAN_CTL_PORT(i));
		reg |= (1 << cpu_port);
		core_writel(priv, reg, CORE_PORT_VLAN_CTL_PORT(i));
	}
}

static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
{
	struct bcm_sf2_priv *priv = ds_to_priv(ds);
	u32 reg, val;
	u32 reg, val;


	/* Enable the port memories */
	/* Enable the port memories */
@@ -199,24 +218,13 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
	reg = core_readl(priv, CORE_STS_OVERRIDE_IMP);
	reg = core_readl(priv, CORE_STS_OVERRIDE_IMP);
	reg |= (MII_SW_OR | LINK_STS);
	reg |= (MII_SW_OR | LINK_STS);
	core_writel(priv, reg, CORE_STS_OVERRIDE_IMP);
	core_writel(priv, reg, CORE_STS_OVERRIDE_IMP);

	/* Enable the IMP Port to be in the same VLAN as the other ports
	 * on a per-port basis such that we only have Port i and IMP in
	 * the same VLAN.
	 */
	for (i = 0; i < priv->hw_params.num_ports; i++) {
		if (!((1 << i) & ds->phys_port_mask))
			continue;

		reg = core_readl(priv, CORE_PORT_VLAN_CTL_PORT(i));
		reg |= (1 << port);
		core_writel(priv, reg, CORE_PORT_VLAN_CTL_PORT(i));
	}
}
}


static void bcm_sf2_port_setup(struct dsa_switch *ds, int port)
static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
			      struct phy_device *phy)
{
{
	struct bcm_sf2_priv *priv = ds_to_priv(ds);
	struct bcm_sf2_priv *priv = ds_to_priv(ds);
	s8 cpu_port = ds->dst[ds->index].cpu_port;
	u32 reg;
	u32 reg;


	/* Clear the memory power down */
	/* Clear the memory power down */
@@ -236,9 +244,14 @@ static void bcm_sf2_port_setup(struct dsa_switch *ds, int port)
	reg &= ~PORT_VLAN_CTRL_MASK;
	reg &= ~PORT_VLAN_CTRL_MASK;
	reg |= (1 << port);
	reg |= (1 << port);
	core_writel(priv, reg, CORE_PORT_VLAN_CTL_PORT(port));
	core_writel(priv, reg, CORE_PORT_VLAN_CTL_PORT(port));

	bcm_sf2_imp_vlan_setup(ds, cpu_port);

	return 0;
}
}


static void bcm_sf2_port_disable(struct dsa_switch *ds, int port)
static void bcm_sf2_port_disable(struct dsa_switch *ds, int port,
				 struct phy_device *phy)
{
{
	struct bcm_sf2_priv *priv = ds_to_priv(ds);
	struct bcm_sf2_priv *priv = ds_to_priv(ds);
	u32 off, reg;
	u32 off, reg;
@@ -246,6 +259,11 @@ static void bcm_sf2_port_disable(struct dsa_switch *ds, int port)
	if (priv->wol_ports_mask & (1 << port))
	if (priv->wol_ports_mask & (1 << port))
		return;
		return;


	if (port == 7) {
		intrl2_1_mask_set(priv, P_IRQ_MASK(P7_IRQ_OFF));
		intrl2_1_writel(priv, P_IRQ_MASK(P7_IRQ_OFF), INTRL2_CPU_CLEAR);
	}

	if (dsa_is_cpu_port(ds, port))
	if (dsa_is_cpu_port(ds, port))
		off = CORE_IMP_CTL;
		off = CORE_IMP_CTL;
	else
	else
@@ -363,11 +381,11 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
	for (port = 0; port < priv->hw_params.num_ports; port++) {
	for (port = 0; port < priv->hw_params.num_ports; port++) {
		/* IMP port receives special treatment */
		/* IMP port receives special treatment */
		if ((1 << port) & ds->phys_port_mask)
		if ((1 << port) & ds->phys_port_mask)
			bcm_sf2_port_setup(ds, port);
			bcm_sf2_port_setup(ds, port, NULL);
		else if (dsa_is_cpu_port(ds, port))
		else if (dsa_is_cpu_port(ds, port))
			bcm_sf2_imp_setup(ds, port);
			bcm_sf2_imp_setup(ds, port);
		else
		else
			bcm_sf2_port_disable(ds, port);
			bcm_sf2_port_disable(ds, port, NULL);
	}
	}


	/* Include the pseudo-PHY address and the broadcast PHY address to
	/* Include the pseudo-PHY address and the broadcast PHY address to
@@ -638,7 +656,7 @@ static int bcm_sf2_sw_suspend(struct dsa_switch *ds)
	for (port = 0; port < DSA_MAX_PORTS; port++) {
	for (port = 0; port < DSA_MAX_PORTS; port++) {
		if ((1 << port) & ds->phys_port_mask ||
		if ((1 << port) & ds->phys_port_mask ||
		    dsa_is_cpu_port(ds, port))
		    dsa_is_cpu_port(ds, port))
			bcm_sf2_port_disable(ds, port);
			bcm_sf2_port_disable(ds, port, NULL);
	}
	}


	return 0;
	return 0;
@@ -694,7 +712,7 @@ static int bcm_sf2_sw_resume(struct dsa_switch *ds)


	for (port = 0; port < DSA_MAX_PORTS; port++) {
	for (port = 0; port < DSA_MAX_PORTS; port++) {
		if ((1 << port) & ds->phys_port_mask)
		if ((1 << port) & ds->phys_port_mask)
			bcm_sf2_port_setup(ds, port);
			bcm_sf2_port_setup(ds, port, NULL);
		else if (dsa_is_cpu_port(ds, port))
		else if (dsa_is_cpu_port(ds, port))
			bcm_sf2_imp_setup(ds, port);
			bcm_sf2_imp_setup(ds, port);
	}
	}
@@ -772,6 +790,8 @@ static struct dsa_switch_driver bcm_sf2_switch_driver = {
	.resume			= bcm_sf2_sw_resume,
	.resume			= bcm_sf2_sw_resume,
	.get_wol		= bcm_sf2_sw_get_wol,
	.get_wol		= bcm_sf2_sw_get_wol,
	.set_wol		= bcm_sf2_sw_set_wol,
	.set_wol		= bcm_sf2_sw_set_wol,
	.port_enable		= bcm_sf2_port_setup,
	.port_disable		= bcm_sf2_port_disable,
};
};


static int __init bcm_sf2_init(void)
static int __init bcm_sf2_init(void)