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

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
Loading
Loading
Loading
Loading
+27 −48
Original line number Original line Diff line number Diff line
@@ -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)
		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)
	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)
		 */
		 */
		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)
{
{
	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)


	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)
{
{
	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)
		}
		}
	}
	}


	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)
	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)
{
{
	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);