Commit dfa66921 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'Generic-adjustment-for-flow-dissector-in-DSA'

Vladimir Oltean says:

====================
Generic adjustment for flow dissector in DSA

This is the v2 of a series initially submitted in May:
https://www.spinics.net/lists/netdev/msg651866.html



The end goal is to get rid of the unintuitive code for the flow
dissector that currently exists in the taggers. It can all be replaced
by a single, common function.

Some background work needs to be done for that. Especially the ocelot
driver poses some problems, since it has a different tag length between
RX and TX, and I didn't want to make DSA aware of that, since I could
instead make the tag lengths equal.

Changes in v3:
- Added an optimization (08/15) that makes the generic case not need to
  call the .flow_dissect function pointer. Basically .flow_dissect now
  currently only exists for sja1105.
- Moved the .promisc_on_master property to the tagger structure.
- Added the .tail_tag property to the tagger structure.
- Disabled "suppresscc = all" from my .gitconfig.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 435be28b 300fd579
Loading
Loading
Loading
Loading
+26 −5
Original line number Diff line number Diff line
@@ -439,6 +439,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
	ocelot->vcap_is2_actions= felix->info->vcap_is2_actions;
	ocelot->vcap		= felix->info->vcap;
	ocelot->ops		= felix->info->ops;
	ocelot->inj_prefix	= OCELOT_TAG_PREFIX_SHORT;
	ocelot->xtr_prefix	= OCELOT_TAG_PREFIX_SHORT;

	port_phy_modes = kcalloc(num_phys_ports, sizeof(phy_interface_t),
				 GFP_KERNEL);
@@ -509,7 +511,7 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
			return PTR_ERR(target);
		}

		template = devm_kzalloc(ocelot->dev, OCELOT_TAG_LEN,
		template = devm_kzalloc(ocelot->dev, OCELOT_TOTAL_TAG_LEN,
					GFP_KERNEL);
		if (!template) {
			dev_err(ocelot->dev,
@@ -538,6 +540,28 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
	return 0;
}

/* The CPU port module is connected to the Node Processor Interface (NPI). This
 * is the mode through which frames can be injected from and extracted to an
 * external CPU, over Ethernet.
 */
static void felix_npi_port_init(struct ocelot *ocelot, int port)
{
	ocelot->npi = port;

	ocelot_write(ocelot, QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M |
		     QSYS_EXT_CPU_CFG_EXT_CPU_PORT(port),
		     QSYS_EXT_CPU_CFG);

	/* NPI port Injection/Extraction configuration */
	ocelot_fields_write(ocelot, port, SYS_PORT_MODE_INCL_XTR_HDR,
			    ocelot->xtr_prefix);
	ocelot_fields_write(ocelot, port, SYS_PORT_MODE_INCL_INJ_HDR,
			    ocelot->inj_prefix);

	/* Disable transmission of pause frames */
	ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, 0);
}

/* Hardware initialization done here so that we can allocate structures with
 * devm without fear of dsa_register_switch returning -EPROBE_DEFER and causing
 * us to allocate structures twice (leak memory) and map PCI memory twice
@@ -570,11 +594,8 @@ static int felix_setup(struct dsa_switch *ds)
	for (port = 0; port < ds->num_ports; port++) {
		ocelot_init_port(ocelot, port);

		/* Bring up the CPU port module and configure the NPI port */
		if (dsa_is_cpu_port(ds, port))
			ocelot_configure_cpu(ocelot, port,
					     OCELOT_TAG_PREFIX_NONE,
					     OCELOT_TAG_PREFIX_LONG);
			felix_npi_port_init(ocelot, port);

		/* Set the default QoS Classification based on PCP and DEI
		 * bits of vlan tag.
+10 −3
Original line number Diff line number Diff line
@@ -1155,6 +1155,8 @@ static void vsc9959_xmit_template_populate(struct ocelot *ocelot, int port)
	struct ocelot_port *ocelot_port = ocelot->ports[port];
	u8 *template = ocelot_port->xmit_template;
	u64 bypass, dest, src;
	__be32 *prefix;
	u8 *injection;

	/* Set the source port as the CPU port module and not the
	 * NPI port
@@ -1163,9 +1165,14 @@ static void vsc9959_xmit_template_populate(struct ocelot *ocelot, int port)
	dest = BIT(port);
	bypass = true;

	packing(template, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0);
	packing(template, &dest,    68,  56, OCELOT_TAG_LEN, PACK, 0);
	packing(template, &src,     46,  43, OCELOT_TAG_LEN, PACK, 0);
	injection = template + OCELOT_SHORT_PREFIX_LEN;
	prefix = (__be32 *)template;

	packing(injection, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0);
	packing(injection, &dest,    68,  56, OCELOT_TAG_LEN, PACK, 0);
	packing(injection, &src,     46,  43, OCELOT_TAG_LEN, PACK, 0);

	*prefix = cpu_to_be32(0x8880000a);
}

static const struct felix_info felix_info_vsc9959 = {
+10 −3
Original line number Diff line number Diff line
@@ -1003,6 +1003,8 @@ static void vsc9953_xmit_template_populate(struct ocelot *ocelot, int port)
	struct ocelot_port *ocelot_port = ocelot->ports[port];
	u8 *template = ocelot_port->xmit_template;
	u64 bypass, dest, src;
	__be32 *prefix;
	u8 *injection;

	/* Set the source port as the CPU port module and not the
	 * NPI port
@@ -1011,9 +1013,14 @@ static void vsc9953_xmit_template_populate(struct ocelot *ocelot, int port)
	dest = BIT(port);
	bypass = true;

	packing(template, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0);
	packing(template, &dest,    67,  57, OCELOT_TAG_LEN, PACK, 0);
	packing(template, &src,     46,  43, OCELOT_TAG_LEN, PACK, 0);
	injection = template + OCELOT_SHORT_PREFIX_LEN;
	prefix = (__be32 *)template;

	packing(injection, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0);
	packing(injection, &dest,    67,  57, OCELOT_TAG_LEN, PACK, 0);
	packing(injection, &src,     46,  43, OCELOT_TAG_LEN, PACK, 0);

	*prefix = cpu_to_be32(0x88800005);
}

static const struct felix_info seville_info_vsc9953 = {
+7 −33
Original line number Diff line number Diff line
@@ -1346,22 +1346,14 @@ void ocelot_init_port(struct ocelot *ocelot, int port)
}
EXPORT_SYMBOL(ocelot_init_port);

/* Configure and enable the CPU port module, which is a set of queues.
 * If @npi contains a valid port index, the CPU port module is connected
 * to the Node Processor Interface (NPI). This is the mode through which
 * frames can be injected from and extracted to an external CPU,
 * over Ethernet.
/* Configure and enable the CPU port module, which is a set of queues
 * accessible through register MMIO, frame DMA or Ethernet (in case
 * NPI mode is used).
 */
void ocelot_configure_cpu(struct ocelot *ocelot, int npi,
			  enum ocelot_tag_prefix injection,
			  enum ocelot_tag_prefix extraction)
static void ocelot_cpu_port_init(struct ocelot *ocelot)
{
	int cpu = ocelot->num_phys_ports;

	ocelot->npi = npi;
	ocelot->inj_prefix = injection;
	ocelot->xtr_prefix = extraction;

	/* The unicast destination PGID for the CPU port module is unused */
	ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, cpu);
	/* Instead set up a multicast destination PGID for traffic copied to
@@ -1373,31 +1365,13 @@ void ocelot_configure_cpu(struct ocelot *ocelot, int npi,
			 ANA_PORT_PORT_CFG_PORTID_VAL(cpu),
			 ANA_PORT_PORT_CFG, cpu);

	if (npi >= 0 && npi < ocelot->num_phys_ports) {
		ocelot_write(ocelot, QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M |
			     QSYS_EXT_CPU_CFG_EXT_CPU_PORT(npi),
			     QSYS_EXT_CPU_CFG);

		/* Enable NPI port */
		ocelot_fields_write(ocelot, npi,
				    QSYS_SWITCH_PORT_MODE_PORT_ENA, 1);
		/* NPI port Injection/Extraction configuration */
		ocelot_fields_write(ocelot, npi, SYS_PORT_MODE_INCL_XTR_HDR,
				    extraction);
		ocelot_fields_write(ocelot, npi, SYS_PORT_MODE_INCL_INJ_HDR,
				    injection);

		/* Disable transmission of pause frames */
		ocelot_fields_write(ocelot, npi, SYS_PAUSE_CFG_PAUSE_ENA, 0);
	}

	/* Enable CPU port module */
	ocelot_fields_write(ocelot, cpu, QSYS_SWITCH_PORT_MODE_PORT_ENA, 1);
	/* CPU port Injection/Extraction configuration */
	ocelot_fields_write(ocelot, cpu, SYS_PORT_MODE_INCL_XTR_HDR,
			    extraction);
			    ocelot->xtr_prefix);
	ocelot_fields_write(ocelot, cpu, SYS_PORT_MODE_INCL_INJ_HDR,
			    injection);
			    ocelot->inj_prefix);

	/* Configure the CPU port to be VLAN aware */
	ocelot_write_gix(ocelot, ANA_PORT_VLAN_CFG_VLAN_VID(0) |
@@ -1405,7 +1379,6 @@ void ocelot_configure_cpu(struct ocelot *ocelot, int npi,
				 ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1),
			 ANA_PORT_VLAN_CFG, cpu);
}
EXPORT_SYMBOL(ocelot_configure_cpu);

int ocelot_init(struct ocelot *ocelot)
{
@@ -1445,6 +1418,7 @@ int ocelot_init(struct ocelot *ocelot)
	ocelot_mact_init(ocelot);
	ocelot_vlan_init(ocelot);
	ocelot_vcap_init(ocelot);
	ocelot_cpu_port_init(ocelot);

	for (port = 0; port < ocelot->num_phys_ports; port++) {
		/* Clear all counters (5 groups) */
+3 −4
Original line number Diff line number Diff line
@@ -930,10 +930,6 @@ static int mscc_ocelot_init_ports(struct platform_device *pdev,
	if (!ocelot->ports)
		return -ENOMEM;

	/* No NPI port */
	ocelot_configure_cpu(ocelot, -1, OCELOT_TAG_PREFIX_NONE,
			     OCELOT_TAG_PREFIX_NONE);

	for_each_available_child_of_node(ports, portnp) {
		struct ocelot_port_private *priv;
		struct ocelot_port *ocelot_port;
@@ -1120,6 +1116,9 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
	ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys;
	ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions;
	ocelot->vcap = vsc7514_vcap_props;
	ocelot->inj_prefix = OCELOT_TAG_PREFIX_NONE;
	ocelot->xtr_prefix = OCELOT_TAG_PREFIX_NONE;
	ocelot->npi = -1;

	err = ocelot_init(ocelot);
	if (err)
Loading