Merge branch 'dsa-use-per-port-upstream-port'

Vivien Didelot says:

====================
net: dsa: use per-port upstream port

An upstream port is a local switch port used to reach a CPU port.

DSA still considers a unique CPU port in the whole switch fabric and
thus return a unique upstream port for a given switch. This is wrong in
a multiple CPU ports environment.

We are now switching to using the dedicated CPU port assigned to each
port in order to get rid of the deprecated unique tree CPU port.

This patchset makes the dsa_upstream_port() helper take a port argument
and goes one step closer complete support for multiple CPU ports.

Changes in v2:
  - reverse-christmas-tree-fy variables
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2017-12-05 18:01:34 -05:00
commit 8bf5438100
3 changed files with 46 additions and 25 deletions

View File

@ -1723,9 +1723,11 @@ static int mv88e6xxx_setup_message_port(struct mv88e6xxx_chip *chip, int port)
static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port)
{
bool flood = port == dsa_upstream_port(chip->ds);
struct dsa_switch *ds = chip->ds;
bool flood;
/* Upstream ports flood frames with unknown unicast or multicast DA */
flood = dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port);
if (chip->info->ops->port_set_egress_floods)
return chip->info->ops->port_set_egress_floods(chip, port,
flood, flood);
@ -1742,6 +1744,39 @@ static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
return 0;
}
static int mv88e6xxx_setup_upstream_port(struct mv88e6xxx_chip *chip, int port)
{
struct dsa_switch *ds = chip->ds;
int upstream_port;
int err;
upstream_port = dsa_upstream_port(ds, port);
if (chip->info->ops->port_set_upstream_port) {
err = chip->info->ops->port_set_upstream_port(chip, port,
upstream_port);
if (err)
return err;
}
if (port == upstream_port) {
if (chip->info->ops->set_cpu_port) {
err = chip->info->ops->set_cpu_port(chip,
upstream_port);
if (err)
return err;
}
if (chip->info->ops->set_egress_port) {
err = chip->info->ops->set_egress_port(chip,
upstream_port);
if (err)
return err;
}
}
return 0;
}
static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
{
struct dsa_switch *ds = chip->ds;
@ -1812,13 +1847,9 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
if (err)
return err;
reg = 0;
if (chip->info->ops->port_set_upstream_port) {
err = chip->info->ops->port_set_upstream_port(
chip, port, dsa_upstream_port(ds));
err = mv88e6xxx_setup_upstream_port(chip, port);
if (err)
return err;
}
err = mv88e6xxx_port_set_8021q_mode(chip, port,
MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED);
@ -1944,21 +1975,8 @@ static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds,
static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip)
{
struct dsa_switch *ds = chip->ds;
u32 upstream_port = dsa_upstream_port(ds);
int err;
if (chip->info->ops->set_cpu_port) {
err = chip->info->ops->set_cpu_port(chip, upstream_port);
if (err)
return err;
}
if (chip->info->ops->set_egress_port) {
err = chip->info->ops->set_egress_port(chip, upstream_port);
if (err)
return err;
}
/* Disable remote management, and set the switch's DSA device number. */
err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL2,
MV88E6XXX_G1_CTL2_MULTIPLE_CASCADE |

View File

@ -307,10 +307,13 @@ static inline unsigned int dsa_towards_port(struct dsa_switch *ds, int device,
}
/* Return the local port used to reach the dedicated CPU port */
static inline u8 dsa_upstream_port(struct dsa_switch *ds)
static inline unsigned int dsa_upstream_port(struct dsa_switch *ds, int port)
{
struct dsa_switch_tree *dst = ds->dst;
struct dsa_port *cpu_dp = dst->cpu_dp;
const struct dsa_port *dp = dsa_to_port(ds, port);
const struct dsa_port *cpu_dp = dp->cpu_dp;
if (!cpu_dp)
return port;
return dsa_towards_port(ds, cpu_dp->ds->index, cpu_dp->index);
}

View File

@ -241,7 +241,7 @@ static int dsa_tree_setup_default_cpu(struct dsa_switch_tree *dst)
for (port = 0; port < ds->num_ports; port++) {
dp = &ds->ports[port];
if (dsa_port_is_user(dp))
if (dsa_port_is_user(dp) || dsa_port_is_dsa(dp))
dp->cpu_dp = dst->cpu_dp;
}
}