Commit 3a262c71 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'rework-dsa-bridge-tx-forwarding-offload-api'

Vladimir Oltean says:

====================
Rework DSA bridge TX forwarding offload API

This change set is preparation work for DSA support of bridge FDB
isolation. It replaces struct net_device *dp->bridge_dev with a struct
dsa_bridge *dp->bridge that contains some extra information about that
bridge, like a unique number kept by DSA.

Up until now we computed that number only with the bridge TX forwarding
offload feature, but it will be needed for other features too, like for
isolation of FDB entries belonging to different bridges. Hardware
implementations vary, but one common pattern seems to be the presence of
a FID field which can be associated with that bridge number kept by DSA.
The idea was outlined here:
https://patchwork.kernel.org/project/netdevbpf/patch/20210818120150.892647-16-vladimir.oltean@nxp.com/
(the difference being that with this new proposal, drivers would not
need to call dsa_bridge_num_find, instead the bridge_num would be part
of the struct dsa_bridge :: num passed as argument).

No functional change is intended for drivers that don't already make use
of the bridge TX forwarding offload. I've tested the changes on the
felix, sja1105 and mv88e6xxx drivers, but nonetheless I'm copying all
DSA driver maintainers due to API changes that are taking place.

Compared to v1 and v2, the amount of patches is larger, but the contents
is mostly the same, just split up hopefully a bit better for review.
====================

Link: https://lore.kernel.org/r/20211206165758.1553882-1-vladimir.oltean@nxp.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 1fe5b012 857fdd74
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -1860,7 +1860,8 @@ int b53_mdb_del(struct dsa_switch *ds, int port,
}
EXPORT_SYMBOL(b53_mdb_del);

int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br)
int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
		bool *tx_fwd_offload)
{
	struct b53_device *dev = ds->priv;
	s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
@@ -1887,7 +1888,7 @@ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br)
	b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan);

	b53_for_each_port(dev, i) {
		if (dsa_to_port(ds, i)->bridge_dev != br)
		if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge))
			continue;

		/* Add this local port to the remote port VLAN control
@@ -1911,7 +1912,7 @@ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br)
}
EXPORT_SYMBOL(b53_br_join);

void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br)
void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge)
{
	struct b53_device *dev = ds->priv;
	struct b53_vlan *vl = &dev->vlans[0];
@@ -1923,7 +1924,7 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br)

	b53_for_each_port(dev, i) {
		/* Don't touch the remaining ports */
		if (dsa_to_port(ds, i)->bridge_dev != br)
		if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge))
			continue;

		b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), &reg);
+3 −2
Original line number Diff line number Diff line
@@ -324,8 +324,9 @@ void b53_get_strings(struct dsa_switch *ds, int port, u32 stringset,
void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data);
int b53_get_sset_count(struct dsa_switch *ds, int port, int sset);
void b53_get_ethtool_phy_stats(struct dsa_switch *ds, int port, uint64_t *data);
int b53_br_join(struct dsa_switch *ds, int port, struct net_device *bridge);
void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *bridge);
int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
		bool *tx_fwd_offload);
void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge);
void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state);
void b53_br_fast_age(struct dsa_switch *ds, int port);
int b53_br_flags_pre(struct dsa_switch *ds, int port,
+5 −4
Original line number Diff line number Diff line
@@ -167,19 +167,20 @@ static int dsa_loop_phy_write(struct dsa_switch *ds, int port,
}

static int dsa_loop_port_bridge_join(struct dsa_switch *ds, int port,
				     struct net_device *bridge)
				     struct dsa_bridge bridge,
				     bool *tx_fwd_offload)
{
	dev_dbg(ds->dev, "%s: port: %d, bridge: %s\n",
		__func__, port, bridge->name);
		__func__, port, bridge.dev->name);

	return 0;
}

static void dsa_loop_port_bridge_leave(struct dsa_switch *ds, int port,
				       struct net_device *bridge)
				       struct dsa_bridge bridge)
{
	dev_dbg(ds->dev, "%s: port: %d, bridge: %s\n",
		__func__, port, bridge->name);
		__func__, port, bridge.dev->name);
}

static void dsa_loop_port_stp_state_set(struct dsa_switch *ds, int port,
+3 −2
Original line number Diff line number Diff line
@@ -674,7 +674,8 @@ static int hellcreek_bridge_flags(struct dsa_switch *ds, int port,
}

static int hellcreek_port_bridge_join(struct dsa_switch *ds, int port,
				      struct net_device *br)
				      struct dsa_bridge bridge,
				      bool *tx_fwd_offload)
{
	struct hellcreek *hellcreek = ds->priv;

@@ -691,7 +692,7 @@ static int hellcreek_port_bridge_join(struct dsa_switch *ds, int port,
}

static void hellcreek_port_bridge_leave(struct dsa_switch *ds, int port,
					struct net_device *br)
					struct dsa_bridge bridge)
{
	struct hellcreek *hellcreek = ds->priv;

+4 −3
Original line number Diff line number Diff line
@@ -1103,12 +1103,13 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port)
}

static int lan9303_port_bridge_join(struct dsa_switch *ds, int port,
				    struct net_device *br)
				    struct dsa_bridge bridge,
				    bool *tx_fwd_offload)
{
	struct lan9303 *chip = ds->priv;

	dev_dbg(chip->dev, "%s(port %d)\n", __func__, port);
	if (dsa_to_port(ds, 1)->bridge_dev == dsa_to_port(ds, 2)->bridge_dev) {
	if (dsa_port_bridge_same(dsa_to_port(ds, 1), dsa_to_port(ds, 2))) {
		lan9303_bridge_ports(chip);
		chip->is_bridged = true;  /* unleash stp_state_set() */
	}
@@ -1117,7 +1118,7 @@ static int lan9303_port_bridge_join(struct dsa_switch *ds, int port,
}

static void lan9303_port_bridge_leave(struct dsa_switch *ds, int port,
				      struct net_device *br)
				      struct dsa_bridge bridge)
{
	struct lan9303 *chip = ds->priv;

Loading