Commit 2960bb14 authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller

net: dsa: felix: use DSA port iteration helpers

Use the helpers that avoid the quadratic complexity associated with
calling dsa_to_port() indirectly: dsa_is_unused_port(),
dsa_is_cpu_port().
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 85ea0daa
...@@ -278,7 +278,8 @@ static int felix_setup_mmio_filtering(struct felix *felix) ...@@ -278,7 +278,8 @@ static int felix_setup_mmio_filtering(struct felix *felix)
struct ocelot_vcap_filter *tagging_rule; struct ocelot_vcap_filter *tagging_rule;
struct ocelot *ocelot = &felix->ocelot; struct ocelot *ocelot = &felix->ocelot;
struct dsa_switch *ds = felix->ds; struct dsa_switch *ds = felix->ds;
int cpu = -1, port, ret; struct dsa_port *dp;
int cpu = -1, ret;
tagging_rule = kzalloc(sizeof(struct ocelot_vcap_filter), GFP_KERNEL); tagging_rule = kzalloc(sizeof(struct ocelot_vcap_filter), GFP_KERNEL);
if (!tagging_rule) if (!tagging_rule)
...@@ -290,12 +291,10 @@ static int felix_setup_mmio_filtering(struct felix *felix) ...@@ -290,12 +291,10 @@ static int felix_setup_mmio_filtering(struct felix *felix)
return -ENOMEM; return -ENOMEM;
} }
for (port = 0; port < ocelot->num_phys_ports; port++) { dsa_switch_for_each_cpu_port(dp, ds) {
if (dsa_is_cpu_port(ds, port)) { cpu = dp->index;
cpu = port;
break; break;
} }
}
if (cpu < 0) { if (cpu < 0) {
kfree(tagging_rule); kfree(tagging_rule);
...@@ -401,14 +400,12 @@ static int felix_setup_tag_8021q(struct dsa_switch *ds, int cpu) ...@@ -401,14 +400,12 @@ static int felix_setup_tag_8021q(struct dsa_switch *ds, int cpu)
struct ocelot *ocelot = ds->priv; struct ocelot *ocelot = ds->priv;
struct felix *felix = ocelot_to_felix(ocelot); struct felix *felix = ocelot_to_felix(ocelot);
unsigned long cpu_flood; unsigned long cpu_flood;
int port, err; struct dsa_port *dp;
int err;
felix_8021q_cpu_port_init(ocelot, cpu); felix_8021q_cpu_port_init(ocelot, cpu);
for (port = 0; port < ds->num_ports; port++) { dsa_switch_for_each_available_port(dp, ds) {
if (dsa_is_unused_port(ds, port))
continue;
/* This overwrites ocelot_init(): /* This overwrites ocelot_init():
* Do not forward BPDU frames to the CPU port module, * Do not forward BPDU frames to the CPU port module,
* for 2 reasons: * for 2 reasons:
...@@ -421,7 +418,7 @@ static int felix_setup_tag_8021q(struct dsa_switch *ds, int cpu) ...@@ -421,7 +418,7 @@ static int felix_setup_tag_8021q(struct dsa_switch *ds, int cpu)
*/ */
ocelot_write_gix(ocelot, ocelot_write_gix(ocelot,
ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA(0), ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA(0),
ANA_PORT_CPU_FWD_BPDU_CFG, port); ANA_PORT_CPU_FWD_BPDU_CFG, dp->index);
} }
/* In tag_8021q mode, the CPU port module is unused, except for PTP /* In tag_8021q mode, the CPU port module is unused, except for PTP
...@@ -452,7 +449,8 @@ static void felix_teardown_tag_8021q(struct dsa_switch *ds, int cpu) ...@@ -452,7 +449,8 @@ static void felix_teardown_tag_8021q(struct dsa_switch *ds, int cpu)
{ {
struct ocelot *ocelot = ds->priv; struct ocelot *ocelot = ds->priv;
struct felix *felix = ocelot_to_felix(ocelot); struct felix *felix = ocelot_to_felix(ocelot);
int err, port; struct dsa_port *dp;
int err;
err = felix_teardown_mmio_filtering(felix); err = felix_teardown_mmio_filtering(felix);
if (err) if (err)
...@@ -461,17 +459,14 @@ static void felix_teardown_tag_8021q(struct dsa_switch *ds, int cpu) ...@@ -461,17 +459,14 @@ static void felix_teardown_tag_8021q(struct dsa_switch *ds, int cpu)
dsa_tag_8021q_unregister(ds); dsa_tag_8021q_unregister(ds);
for (port = 0; port < ds->num_ports; port++) { dsa_switch_for_each_available_port(dp, ds) {
if (dsa_is_unused_port(ds, port))
continue;
/* Restore the logic from ocelot_init: /* Restore the logic from ocelot_init:
* do not forward BPDU frames to the front ports. * do not forward BPDU frames to the front ports.
*/ */
ocelot_write_gix(ocelot, ocelot_write_gix(ocelot,
ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA(0xffff), ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA(0xffff),
ANA_PORT_CPU_FWD_BPDU_CFG, ANA_PORT_CPU_FWD_BPDU_CFG,
port); dp->index);
} }
felix_8021q_cpu_port_deinit(ocelot, cpu); felix_8021q_cpu_port_deinit(ocelot, cpu);
...@@ -1192,7 +1187,8 @@ static int felix_setup(struct dsa_switch *ds) ...@@ -1192,7 +1187,8 @@ static int felix_setup(struct dsa_switch *ds)
{ {
struct ocelot *ocelot = ds->priv; struct ocelot *ocelot = ds->priv;
struct felix *felix = ocelot_to_felix(ocelot); struct felix *felix = ocelot_to_felix(ocelot);
int port, err; struct dsa_port *dp;
int err;
err = felix_init_structs(felix, ds->num_ports); err = felix_init_structs(felix, ds->num_ports);
if (err) if (err)
...@@ -1211,30 +1207,24 @@ static int felix_setup(struct dsa_switch *ds) ...@@ -1211,30 +1207,24 @@ static int felix_setup(struct dsa_switch *ds)
} }
} }
for (port = 0; port < ds->num_ports; port++) { dsa_switch_for_each_available_port(dp, ds) {
if (dsa_is_unused_port(ds, port)) ocelot_init_port(ocelot, dp->index);
continue;
ocelot_init_port(ocelot, port);
/* Set the default QoS Classification based on PCP and DEI /* Set the default QoS Classification based on PCP and DEI
* bits of vlan tag. * bits of vlan tag.
*/ */
felix_port_qos_map_init(ocelot, port); felix_port_qos_map_init(ocelot, dp->index);
} }
err = ocelot_devlink_sb_register(ocelot); err = ocelot_devlink_sb_register(ocelot);
if (err) if (err)
goto out_deinit_ports; goto out_deinit_ports;
for (port = 0; port < ds->num_ports; port++) { dsa_switch_for_each_cpu_port(dp, ds) {
if (!dsa_is_cpu_port(ds, port))
continue;
/* The initial tag protocol is NPI which always returns 0, so /* The initial tag protocol is NPI which always returns 0, so
* there's no real point in checking for errors. * there's no real point in checking for errors.
*/ */
felix_set_tag_protocol(ds, port, felix->tag_proto); felix_set_tag_protocol(ds, dp->index, felix->tag_proto);
break; break;
} }
...@@ -1244,12 +1234,8 @@ static int felix_setup(struct dsa_switch *ds) ...@@ -1244,12 +1234,8 @@ static int felix_setup(struct dsa_switch *ds)
return 0; return 0;
out_deinit_ports: out_deinit_ports:
for (port = 0; port < ocelot->num_phys_ports; port++) { dsa_switch_for_each_available_port(dp, ds)
if (dsa_is_unused_port(ds, port)) ocelot_deinit_port(ocelot, dp->index);
continue;
ocelot_deinit_port(ocelot, port);
}
ocelot_deinit_timestamp(ocelot); ocelot_deinit_timestamp(ocelot);
ocelot_deinit(ocelot); ocelot_deinit(ocelot);
...@@ -1265,22 +1251,15 @@ static void felix_teardown(struct dsa_switch *ds) ...@@ -1265,22 +1251,15 @@ static void felix_teardown(struct dsa_switch *ds)
{ {
struct ocelot *ocelot = ds->priv; struct ocelot *ocelot = ds->priv;
struct felix *felix = ocelot_to_felix(ocelot); struct felix *felix = ocelot_to_felix(ocelot);
int port; struct dsa_port *dp;
for (port = 0; port < ds->num_ports; port++) {
if (!dsa_is_cpu_port(ds, port))
continue;
felix_del_tag_protocol(ds, port, felix->tag_proto); dsa_switch_for_each_cpu_port(dp, ds) {
felix_del_tag_protocol(ds, dp->index, felix->tag_proto);
break; break;
} }
for (port = 0; port < ocelot->num_phys_ports; port++) { dsa_switch_for_each_available_port(dp, ds)
if (dsa_is_unused_port(ds, port)) ocelot_deinit_port(ocelot, dp->index);
continue;
ocelot_deinit_port(ocelot, port);
}
ocelot_devlink_sb_unregister(ocelot); ocelot_devlink_sb_unregister(ocelot);
ocelot_deinit_timestamp(ocelot); ocelot_deinit_timestamp(ocelot);
......
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