mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 03:24:19 +02:00
net: dsa: lantiq_gswip: prepare for more CPU port options
The MaxLinear GSW1xx series of switches support using either the (R)(G)MII interface on port 5 or the SGMII interface on port 4 to be used as CPU port. Prepare for supporting them by defining a mask of allowed CPU ports instead of a single port. Signed-off-by: Daniel Golle <daniel@makrotopia.org> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Link: https://patch.msgid.link/879c66672d26fe49c1f5d9aa40d8ebc0f31885ab.1755878232.git.daniel@makrotopia.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
fa1439a865
commit
2bec1c3836
|
|
@ -253,7 +253,7 @@
|
|||
|
||||
struct gswip_hw_info {
|
||||
int max_ports;
|
||||
int cpu_port;
|
||||
unsigned int allowed_cpu_ports;
|
||||
void (*phylink_get_caps)(struct dsa_switch *ds, int port,
|
||||
struct phylink_config *config);
|
||||
};
|
||||
|
|
@ -655,7 +655,6 @@ 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;
|
||||
int err;
|
||||
|
||||
vlan_active.index = port + 1;
|
||||
|
|
@ -675,7 +674,7 @@ static int gswip_add_single_port_br(struct gswip_priv *priv, int port, bool add)
|
|||
vlan_mapping.index = port + 1;
|
||||
vlan_mapping.table = GSWIP_TABLE_VLAN_MAPPING;
|
||||
vlan_mapping.val[0] = 0 /* vid */;
|
||||
vlan_mapping.val[1] = BIT(port) | BIT(cpu_port);
|
||||
vlan_mapping.val[1] = BIT(port) | dsa_cpu_ports(priv->ds);
|
||||
vlan_mapping.val[2] = 0;
|
||||
err = gswip_pce_table_entry_write(priv, &vlan_mapping);
|
||||
if (err) {
|
||||
|
|
@ -805,10 +804,10 @@ static int gswip_port_vlan_filtering(struct dsa_switch *ds, int port,
|
|||
|
||||
static int gswip_setup(struct dsa_switch *ds)
|
||||
{
|
||||
unsigned int cpu_ports = dsa_cpu_ports(ds);
|
||||
struct gswip_priv *priv = ds->priv;
|
||||
unsigned int cpu_port = priv->hw_info->cpu_port;
|
||||
int i;
|
||||
int err;
|
||||
struct dsa_port *cpu_dp;
|
||||
int err, i;
|
||||
|
||||
gswip_switch_w(priv, GSWIP_SWRES_R0, GSWIP_SWRES);
|
||||
usleep_range(5000, 10000);
|
||||
|
|
@ -830,9 +829,9 @@ static int gswip_setup(struct dsa_switch *ds)
|
|||
}
|
||||
|
||||
/* Default unknown Broadcast/Multicast/Unicast port maps */
|
||||
gswip_switch_w(priv, BIT(cpu_port), GSWIP_PCE_PMAP1);
|
||||
gswip_switch_w(priv, BIT(cpu_port), GSWIP_PCE_PMAP2);
|
||||
gswip_switch_w(priv, BIT(cpu_port), GSWIP_PCE_PMAP3);
|
||||
gswip_switch_w(priv, cpu_ports, GSWIP_PCE_PMAP1);
|
||||
gswip_switch_w(priv, cpu_ports, GSWIP_PCE_PMAP2);
|
||||
gswip_switch_w(priv, cpu_ports, GSWIP_PCE_PMAP3);
|
||||
|
||||
/* Deactivate MDIO PHY auto polling. Some PHYs as the AR8030 have an
|
||||
* interoperability problem with this auto polling mechanism because
|
||||
|
|
@ -861,13 +860,15 @@ static int gswip_setup(struct dsa_switch *ds)
|
|||
GSWIP_MII_CFG_EN | GSWIP_MII_CFG_ISOLATE,
|
||||
0, i);
|
||||
|
||||
/* enable special tag insertion on cpu port */
|
||||
gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_STEN,
|
||||
GSWIP_FDMA_PCTRLp(cpu_port));
|
||||
dsa_switch_for_each_cpu_port(cpu_dp, ds) {
|
||||
/* enable special tag insertion on cpu port */
|
||||
gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_STEN,
|
||||
GSWIP_FDMA_PCTRLp(cpu_dp->index));
|
||||
|
||||
/* accept special tag in ingress direction */
|
||||
gswip_switch_mask(priv, 0, GSWIP_PCE_PCTRL_0_INGRESS,
|
||||
GSWIP_PCE_PCTRL_0p(cpu_port));
|
||||
/* accept special tag in ingress direction */
|
||||
gswip_switch_mask(priv, 0, GSWIP_PCE_PCTRL_0_INGRESS,
|
||||
GSWIP_PCE_PCTRL_0p(cpu_dp->index));
|
||||
}
|
||||
|
||||
gswip_switch_mask(priv, 0, GSWIP_BM_QUEUE_GCTRL_GL_MOD,
|
||||
GSWIP_BM_QUEUE_GCTRL);
|
||||
|
|
@ -963,7 +964,6 @@ static int gswip_vlan_add_unaware(struct gswip_priv *priv,
|
|||
{
|
||||
struct gswip_pce_table_entry vlan_mapping = {0,};
|
||||
unsigned int max_ports = priv->hw_info->max_ports;
|
||||
unsigned int cpu_port = priv->hw_info->cpu_port;
|
||||
bool active_vlan_created = false;
|
||||
int idx = -1;
|
||||
int i;
|
||||
|
|
@ -1003,7 +1003,7 @@ static int gswip_vlan_add_unaware(struct gswip_priv *priv,
|
|||
}
|
||||
|
||||
/* Update the VLAN mapping entry and write it to the switch */
|
||||
vlan_mapping.val[1] |= BIT(cpu_port);
|
||||
vlan_mapping.val[1] |= dsa_cpu_ports(priv->ds);
|
||||
vlan_mapping.val[1] |= BIT(port);
|
||||
err = gswip_pce_table_entry_write(priv, &vlan_mapping);
|
||||
if (err) {
|
||||
|
|
@ -1025,7 +1025,7 @@ static int gswip_vlan_add_aware(struct gswip_priv *priv,
|
|||
{
|
||||
struct gswip_pce_table_entry vlan_mapping = {0,};
|
||||
unsigned int max_ports = priv->hw_info->max_ports;
|
||||
unsigned int cpu_port = priv->hw_info->cpu_port;
|
||||
unsigned int cpu_ports = dsa_cpu_ports(priv->ds);
|
||||
bool active_vlan_created = false;
|
||||
int idx = -1;
|
||||
int fid = -1;
|
||||
|
|
@ -1072,8 +1072,8 @@ static int gswip_vlan_add_aware(struct gswip_priv *priv,
|
|||
|
||||
vlan_mapping.val[0] = vid;
|
||||
/* Update the VLAN mapping entry and write it to the switch */
|
||||
vlan_mapping.val[1] |= BIT(cpu_port);
|
||||
vlan_mapping.val[2] |= BIT(cpu_port);
|
||||
vlan_mapping.val[1] |= cpu_ports;
|
||||
vlan_mapping.val[2] |= cpu_ports;
|
||||
vlan_mapping.val[1] |= BIT(port);
|
||||
if (untagged)
|
||||
vlan_mapping.val[2] &= ~BIT(port);
|
||||
|
|
@ -1100,7 +1100,6 @@ static int gswip_vlan_remove(struct gswip_priv *priv,
|
|||
{
|
||||
struct gswip_pce_table_entry vlan_mapping = {0,};
|
||||
unsigned int max_ports = priv->hw_info->max_ports;
|
||||
unsigned int cpu_port = priv->hw_info->cpu_port;
|
||||
int idx = -1;
|
||||
int i;
|
||||
int err;
|
||||
|
|
@ -1136,7 +1135,7 @@ static int gswip_vlan_remove(struct gswip_priv *priv,
|
|||
}
|
||||
|
||||
/* In case all ports are removed from the bridge, remove the VLAN */
|
||||
if ((vlan_mapping.val[1] & ~BIT(cpu_port)) == 0) {
|
||||
if (!(vlan_mapping.val[1] & ~dsa_cpu_ports(priv->ds))) {
|
||||
err = gswip_vlan_active_remove(priv, idx);
|
||||
if (err) {
|
||||
dev_err(priv->dev, "failed to write active VLAN: %d\n",
|
||||
|
|
@ -2078,6 +2077,30 @@ static int gswip_gphy_fw_list(struct gswip_priv *priv,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int gswip_validate_cpu_port(struct dsa_switch *ds)
|
||||
{
|
||||
struct gswip_priv *priv = ds->priv;
|
||||
struct dsa_port *cpu_dp;
|
||||
int cpu_port = -1;
|
||||
|
||||
dsa_switch_for_each_cpu_port(cpu_dp, ds) {
|
||||
if (cpu_port != -1)
|
||||
return dev_err_probe(ds->dev, -EINVAL,
|
||||
"only a single CPU port is supported\n");
|
||||
|
||||
cpu_port = cpu_dp->index;
|
||||
}
|
||||
|
||||
if (cpu_port == -1)
|
||||
return dev_err_probe(ds->dev, -EINVAL, "no CPU port defined\n");
|
||||
|
||||
if (BIT(cpu_port) & ~priv->hw_info->allowed_cpu_ports)
|
||||
return dev_err_probe(ds->dev, -EINVAL,
|
||||
"unsupported CPU port defined\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gswip_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np, *gphy_fw_np;
|
||||
|
|
@ -2160,12 +2183,10 @@ static int gswip_probe(struct platform_device *pdev)
|
|||
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)) {
|
||||
err = dev_err_probe(dev, -EINVAL,
|
||||
"wrong CPU port defined, HW only supports port: %i\n",
|
||||
priv->hw_info->cpu_port);
|
||||
|
||||
err = gswip_validate_cpu_port(priv->ds);
|
||||
if (err)
|
||||
goto disable_switch;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
|
|
@ -2214,13 +2235,13 @@ static void gswip_shutdown(struct platform_device *pdev)
|
|||
|
||||
static const struct gswip_hw_info gswip_xrx200 = {
|
||||
.max_ports = 7,
|
||||
.cpu_port = 6,
|
||||
.allowed_cpu_ports = BIT(6),
|
||||
.phylink_get_caps = gswip_xrx200_phylink_get_caps,
|
||||
};
|
||||
|
||||
static const struct gswip_hw_info gswip_xrx300 = {
|
||||
.max_ports = 7,
|
||||
.cpu_port = 6,
|
||||
.allowed_cpu_ports = BIT(6),
|
||||
.phylink_get_caps = gswip_xrx300_phylink_get_caps,
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user