Commit e324615b authored by David S. Miller's avatar David S. Miller

Merge branch 'dsa-define-port-types'

Vivien Didelot says:

====================
net: dsa: define port types

The DSA code currently has 3 bitmaps in the dsa_switch structure:
cpu_port_mask, dsa_port_mask and enabled_port_mask.

They are used to store the type of each switch port. This dates back
from when DSA didn't have a dsa_port structure to hold port-specific
data.

The dsa_switch structure is mainly used to communicate with DSA drivers
and must not contain such static data parsed from DTS or pdata, which
belongs the DSA core structures, such as dsa_switch_tree and dsa_port.

Also the enabled_port_mask is misleading, often misinterpreted as the
complement of disabled ports (thus including DSA and CPU ports), while
in fact it only masks the user ports.

A port can be of 3 types when it is not unused: "cpu" (interfacing with
a master device), "dsa" (interconnecting with another "dsa" port from
another switch chip), or "user" (user-facing port.)

This patchset first fixes the usage of DSA port type helpers, then
defines the DSA_PORT_TYPE_UNUSED, DSA_PORT_TYPE_CPU, DSA_PORT_TYPE_DSA,
and DSA_PORT_TYPE_USER port types, and finally removes the misleading
port bitmaps.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5bca178e 5749f0f3
...@@ -873,7 +873,7 @@ static int b53_setup(struct dsa_switch *ds) ...@@ -873,7 +873,7 @@ static int b53_setup(struct dsa_switch *ds)
for (port = 0; port < dev->num_ports; port++) { for (port = 0; port < dev->num_ports; port++) {
if (dsa_is_cpu_port(ds, port)) if (dsa_is_cpu_port(ds, port))
b53_enable_cpu_port(dev, port); b53_enable_cpu_port(dev, port);
else if (!(BIT(port) & ds->enabled_port_mask)) else if (dsa_is_unused_port(ds, port))
b53_disable_port(ds, port, NULL); b53_disable_port(ds, port, NULL);
} }
......
...@@ -652,8 +652,7 @@ static int bcm_sf2_sw_suspend(struct dsa_switch *ds) ...@@ -652,8 +652,7 @@ static int bcm_sf2_sw_suspend(struct dsa_switch *ds)
* bcm_sf2_sw_setup * bcm_sf2_sw_setup
*/ */
for (port = 0; port < DSA_MAX_PORTS; port++) { for (port = 0; port < DSA_MAX_PORTS; port++) {
if ((1 << port) & ds->enabled_port_mask || if (dsa_is_user_port(ds, port) || dsa_is_cpu_port(ds, port))
dsa_is_cpu_port(ds, port))
bcm_sf2_port_disable(ds, port, NULL); bcm_sf2_port_disable(ds, port, NULL);
} }
...@@ -676,7 +675,7 @@ static int bcm_sf2_sw_resume(struct dsa_switch *ds) ...@@ -676,7 +675,7 @@ static int bcm_sf2_sw_resume(struct dsa_switch *ds)
bcm_sf2_gphy_enable_set(ds, true); bcm_sf2_gphy_enable_set(ds, true);
for (port = 0; port < DSA_MAX_PORTS; port++) { for (port = 0; port < DSA_MAX_PORTS; port++) {
if ((1 << port) & ds->enabled_port_mask) if (dsa_is_user_port(ds, port))
bcm_sf2_port_setup(ds, port, NULL); 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);
...@@ -771,7 +770,7 @@ static void bcm_sf2_sw_configure_vlan(struct dsa_switch *ds) ...@@ -771,7 +770,7 @@ static void bcm_sf2_sw_configure_vlan(struct dsa_switch *ds)
bcm_sf2_vlan_op(priv, ARLA_VTBL_CMD_CLEAR); bcm_sf2_vlan_op(priv, ARLA_VTBL_CMD_CLEAR);
for (port = 0; port < priv->hw_params.num_ports; port++) { for (port = 0; port < priv->hw_params.num_ports; port++) {
if (!((1 << port) & ds->enabled_port_mask)) if (!dsa_is_user_port(ds, port))
continue; continue;
core_writel(priv, 1, CORE_DEFAULT_1Q_TAG_P(port)); core_writel(priv, 1, CORE_DEFAULT_1Q_TAG_P(port));
...@@ -786,7 +785,7 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds) ...@@ -786,7 +785,7 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
/* Enable all valid ports and disable those unused */ /* Enable all valid ports and disable those unused */
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->enabled_port_mask) if (dsa_is_user_port(ds, port))
bcm_sf2_port_setup(ds, port, NULL); 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);
......
...@@ -750,7 +750,7 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, ...@@ -750,7 +750,7 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port,
port_num = fs->ring_cookie / SF2_NUM_EGRESS_QUEUES; port_num = fs->ring_cookie / SF2_NUM_EGRESS_QUEUES;
if (fs->ring_cookie == RX_CLS_FLOW_DISC || if (fs->ring_cookie == RX_CLS_FLOW_DISC ||
!(BIT(port_num) & ds->enabled_port_mask) || !dsa_is_user_port(ds, port_num) ||
port_num >= priv->hw_params.num_ports) port_num >= priv->hw_params.num_ports)
return -EINVAL; return -EINVAL;
/* /*
......
...@@ -688,7 +688,7 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv, ...@@ -688,7 +688,7 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv,
* the switch * the switch
*/ */
mt7530_write(priv, MT7530_PCR_P(port), mt7530_write(priv, MT7530_PCR_P(port),
PCR_MATRIX(priv->ds->enabled_port_mask)); PCR_MATRIX(dsa_user_ports(priv->ds)));
return 0; return 0;
} }
...@@ -781,7 +781,7 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port, ...@@ -781,7 +781,7 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port,
* same bridge. If the port is disabled, port matrix is kept * same bridge. If the port is disabled, port matrix is kept
* and not being setup until the port becomes enabled. * and not being setup until the port becomes enabled.
*/ */
if (ds->enabled_port_mask & BIT(i) && i != port) { if (dsa_is_user_port(ds, i) && i != port) {
if (dsa_to_port(ds, i)->bridge_dev != bridge) if (dsa_to_port(ds, i)->bridge_dev != bridge)
continue; continue;
if (priv->ports[i].enable) if (priv->ports[i].enable)
...@@ -818,7 +818,7 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port, ...@@ -818,7 +818,7 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
* in the same bridge. If the port is disabled, port matrix * in the same bridge. If the port is disabled, port matrix
* is kept and not being setup until the port becomes enabled. * is kept and not being setup until the port becomes enabled.
*/ */
if (ds->enabled_port_mask & BIT(i) && i != port) { if (dsa_is_user_port(ds, i) && i != port) {
if (dsa_to_port(ds, i)->bridge_dev != bridge) if (dsa_to_port(ds, i)->bridge_dev != bridge)
continue; continue;
if (priv->ports[i].enable) if (priv->ports[i].enable)
......
...@@ -175,8 +175,7 @@ static int mv88e6060_setup_port(struct dsa_switch *ds, int p) ...@@ -175,8 +175,7 @@ static int mv88e6060_setup_port(struct dsa_switch *ds, int p)
*/ */
REG_WRITE(addr, PORT_VLAN_MAP, REG_WRITE(addr, PORT_VLAN_MAP,
((p & 0xf) << PORT_VLAN_MAP_DBNUM_SHIFT) | ((p & 0xf) << PORT_VLAN_MAP_DBNUM_SHIFT) |
(dsa_is_cpu_port(ds, p) ? (dsa_is_cpu_port(ds, p) ? dsa_user_ports(ds) :
ds->enabled_port_mask :
BIT(dsa_to_port(ds, p)->cpu_dp->index))); BIT(dsa_to_port(ds, p)->cpu_dp->index)));
/* Port Association Vector: when learning source addresses /* Port Association Vector: when learning source addresses
......
...@@ -1676,7 +1676,7 @@ static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port) ...@@ -1676,7 +1676,7 @@ static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)
if (dsa_is_dsa_port(chip->ds, port)) if (dsa_is_dsa_port(chip->ds, port))
return mv88e6xxx_set_port_mode_dsa(chip, port); return mv88e6xxx_set_port_mode_dsa(chip, port);
if (dsa_is_normal_port(chip->ds, port)) if (dsa_is_user_port(chip->ds, port))
return mv88e6xxx_set_port_mode_normal(chip, port); return mv88e6xxx_set_port_mode_normal(chip, port);
/* Setup CPU port mode depending on its supported tag format */ /* Setup CPU port mode depending on its supported tag format */
...@@ -2005,6 +2005,9 @@ static int mv88e6xxx_setup(struct dsa_switch *ds) ...@@ -2005,6 +2005,9 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
/* Setup Switch Port Registers */ /* Setup Switch Port Registers */
for (i = 0; i < mv88e6xxx_num_ports(chip); i++) { for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
if (dsa_is_unused_port(ds, i))
continue;
err = mv88e6xxx_setup_port(chip, i); err = mv88e6xxx_setup_port(chip, i);
if (err) if (err)
goto unlock; goto unlock;
......
...@@ -536,7 +536,7 @@ qca8k_setup(struct dsa_switch *ds) ...@@ -536,7 +536,7 @@ qca8k_setup(struct dsa_switch *ds)
/* Disable MAC by default on all user ports */ /* Disable MAC by default on all user ports */
for (i = 1; i < QCA8K_NUM_PORTS; i++) for (i = 1; i < QCA8K_NUM_PORTS; i++)
if (ds->enabled_port_mask & BIT(i)) if (dsa_is_user_port(ds, i))
qca8k_port_set_status(priv, i, 0); qca8k_port_set_status(priv, i, 0);
/* Forward all unknown frames to CPU port for Linux processing */ /* Forward all unknown frames to CPU port for Linux processing */
...@@ -551,12 +551,11 @@ qca8k_setup(struct dsa_switch *ds) ...@@ -551,12 +551,11 @@ qca8k_setup(struct dsa_switch *ds)
/* CPU port gets connected to all user ports of the switch */ /* CPU port gets connected to all user ports of the switch */
if (dsa_is_cpu_port(ds, i)) { if (dsa_is_cpu_port(ds, i)) {
qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT), qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
QCA8K_PORT_LOOKUP_MEMBER, QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
ds->enabled_port_mask);
} }
/* Invividual user ports get connected to CPU port only */ /* Invividual user ports get connected to CPU port only */
if (ds->enabled_port_mask & BIT(i)) { if (dsa_is_user_port(ds, i)) {
int shift = 16 * (i % 2); int shift = 16 * (i % 2);
qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
......
...@@ -180,6 +180,13 @@ struct dsa_port { ...@@ -180,6 +180,13 @@ struct dsa_port {
struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev, struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt); struct packet_type *pt);
enum {
DSA_PORT_TYPE_UNUSED = 0,
DSA_PORT_TYPE_CPU,
DSA_PORT_TYPE_DSA,
DSA_PORT_TYPE_USER,
} type;
struct dsa_switch *ds; struct dsa_switch *ds;
unsigned int index; unsigned int index;
const char *name; const char *name;
...@@ -233,9 +240,6 @@ struct dsa_switch { ...@@ -233,9 +240,6 @@ struct dsa_switch {
/* /*
* Slave mii_bus and devices for the individual ports. * Slave mii_bus and devices for the individual ports.
*/ */
u32 dsa_port_mask;
u32 cpu_port_mask;
u32 enabled_port_mask;
u32 phys_mii_mask; u32 phys_mii_mask;
struct mii_bus *slave_mii_bus; struct mii_bus *slave_mii_bus;
...@@ -254,24 +258,41 @@ struct dsa_switch { ...@@ -254,24 +258,41 @@ struct dsa_switch {
struct dsa_port ports[]; struct dsa_port ports[];
}; };
static inline const struct dsa_port *dsa_to_port(struct dsa_switch *ds, int p)
{
return &ds->ports[p];
}
static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p)
{
return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_UNUSED;
}
static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p) static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p)
{ {
return !!(ds->cpu_port_mask & (1 << p)); return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_CPU;
} }
static inline bool dsa_is_dsa_port(struct dsa_switch *ds, int p) static inline bool dsa_is_dsa_port(struct dsa_switch *ds, int p)
{ {
return !!((ds->dsa_port_mask) & (1 << p)); return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_DSA;
} }
static inline bool dsa_is_normal_port(struct dsa_switch *ds, int p) static inline bool dsa_is_user_port(struct dsa_switch *ds, int p)
{ {
return !dsa_is_cpu_port(ds, p) && !dsa_is_dsa_port(ds, p); return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_USER;
} }
static inline const struct dsa_port *dsa_to_port(struct dsa_switch *ds, int p) static inline u32 dsa_user_ports(struct dsa_switch *ds)
{ {
return &ds->ports[p]; u32 mask = 0;
int p;
for (p = 0; p < ds->num_ports; p++)
if (dsa_is_user_port(ds, p))
mask |= BIT(p);
return mask;
} }
static inline u8 dsa_upstream_port(struct dsa_switch *ds) static inline u8 dsa_upstream_port(struct dsa_switch *ds)
......
...@@ -201,7 +201,7 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -201,7 +201,7 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static bool dsa_is_port_initialized(struct dsa_switch *ds, int p) static bool dsa_is_port_initialized(struct dsa_switch *ds, int p)
{ {
return ds->enabled_port_mask & (1 << p) && ds->ports[p].slave; return dsa_is_user_port(ds, p) && ds->ports[p].slave;
} }
int dsa_switch_suspend(struct dsa_switch *ds) int dsa_switch_suspend(struct dsa_switch *ds)
......
...@@ -184,7 +184,7 @@ static int dsa_ds_complete(struct dsa_switch_tree *dst, struct dsa_switch *ds) ...@@ -184,7 +184,7 @@ static int dsa_ds_complete(struct dsa_switch_tree *dst, struct dsa_switch *ds)
if (err != 0) if (err != 0)
return err; return err;
ds->dsa_port_mask |= BIT(index); port->type = DSA_PORT_TYPE_DSA;
} }
return 0; return 0;
...@@ -312,7 +312,7 @@ static int dsa_ds_apply(struct dsa_switch_tree *dst, struct dsa_switch *ds) ...@@ -312,7 +312,7 @@ static int dsa_ds_apply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
* the slave MDIO bus driver rely on these values for probing PHY * the slave MDIO bus driver rely on these values for probing PHY
* devices or not * devices or not
*/ */
ds->phys_mii_mask = ds->enabled_port_mask; ds->phys_mii_mask |= dsa_user_ports(ds);
/* Add the switch to devlink before calling setup, so that setup can /* Add the switch to devlink before calling setup, so that setup can
* add dpipe tables * add dpipe tables
...@@ -499,11 +499,7 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index, ...@@ -499,11 +499,7 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index,
dst->cpu_dp->master = ethernet_dev; dst->cpu_dp->master = ethernet_dev;
} }
/* Initialize cpu_port_mask now for drv->setup() port->type = DSA_PORT_TYPE_CPU;
* to have access to a correct value, just like what
* net/dsa/dsa.c::dsa_switch_setup_one does.
*/
ds->cpu_port_mask |= BIT(index);
tag_protocol = ds->ops->get_tag_protocol(ds); tag_protocol = ds->ops->get_tag_protocol(ds);
tag_ops = dsa_resolve_tag_protocol(tag_protocol); tag_ops = dsa_resolve_tag_protocol(tag_protocol);
...@@ -538,11 +534,7 @@ static int dsa_ds_parse(struct dsa_switch_tree *dst, struct dsa_switch *ds) ...@@ -538,11 +534,7 @@ static int dsa_ds_parse(struct dsa_switch_tree *dst, struct dsa_switch *ds)
if (err) if (err)
return err; return err;
} else { } else {
/* Initialize enabled_port_mask now for drv->setup() port->type = DSA_PORT_TYPE_USER;
* to have access to a correct value, just like what
* net/dsa/dsa.c::dsa_switch_setup_one does.
*/
ds->enabled_port_mask |= BIT(index);
} }
} }
......
...@@ -101,6 +101,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, ...@@ -101,6 +101,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds,
struct dsa_chip_data *cd = ds->cd; struct dsa_chip_data *cd = ds->cd;
bool valid_name_found = false; bool valid_name_found = false;
int index = ds->index; int index = ds->index;
struct dsa_port *dp;
int i, ret; int i, ret;
/* /*
...@@ -109,6 +110,8 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, ...@@ -109,6 +110,8 @@ static int dsa_switch_setup_one(struct dsa_switch *ds,
for (i = 0; i < ds->num_ports; i++) { for (i = 0; i < ds->num_ports; i++) {
char *name; char *name;
dp = &ds->ports[i];
name = cd->port_names[i]; name = cd->port_names[i];
if (name == NULL) if (name == NULL)
continue; continue;
...@@ -121,11 +124,11 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, ...@@ -121,11 +124,11 @@ static int dsa_switch_setup_one(struct dsa_switch *ds,
} }
dst->cpu_dp = &ds->ports[i]; dst->cpu_dp = &ds->ports[i];
dst->cpu_dp->master = master; dst->cpu_dp->master = master;
ds->cpu_port_mask |= 1 << i; dp->type = DSA_PORT_TYPE_CPU;
} else if (!strcmp(name, "dsa")) { } else if (!strcmp(name, "dsa")) {
ds->dsa_port_mask |= 1 << i; dp->type = DSA_PORT_TYPE_DSA;
} else { } else {
ds->enabled_port_mask |= 1 << i; dp->type = DSA_PORT_TYPE_USER;
} }
valid_name_found = true; valid_name_found = true;
} }
...@@ -136,7 +139,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, ...@@ -136,7 +139,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds,
/* Make the built-in MII bus mask match the number of ports, /* Make the built-in MII bus mask match the number of ports,
* switch drivers can override this later * switch drivers can override this later
*/ */
ds->phys_mii_mask = ds->enabled_port_mask; ds->phys_mii_mask |= dsa_user_ports(ds);
/* /*
* If the CPU connects to this switch, set the switch tree * If the CPU connects to this switch, set the switch tree
...@@ -190,7 +193,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, ...@@ -190,7 +193,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds,
ds->ports[i].dn = cd->port_dn[i]; ds->ports[i].dn = cd->port_dn[i];
ds->ports[i].cpu_dp = dst->cpu_dp; ds->ports[i].cpu_dp = dst->cpu_dp;
if (!(ds->enabled_port_mask & (1 << i))) if (dsa_is_user_port(ds, i))
continue; continue;
ret = dsa_slave_create(&ds->ports[i], cd->port_names[i]); ret = dsa_slave_create(&ds->ports[i], cd->port_names[i]);
...@@ -258,7 +261,7 @@ static void dsa_switch_destroy(struct dsa_switch *ds) ...@@ -258,7 +261,7 @@ static void dsa_switch_destroy(struct dsa_switch *ds)
/* Destroy network devices for physical switch ports. */ /* Destroy network devices for physical switch ports. */
for (port = 0; port < ds->num_ports; port++) { for (port = 0; port < ds->num_ports; port++) {
if (!(ds->enabled_port_mask & (1 << port))) if (!dsa_is_user_port(ds, port))
continue; continue;
if (!ds->ports[port].slave) if (!ds->ports[port].slave)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment