linux/drivers/net/dsa/mv88e6xxx
Vladimir Oltean f66a6a69f9 net: dsa: permit cross-chip bridging between all trees in the system
One way of utilizing DSA is by cascading switches which do not all have
compatible taggers. Consider the following real-life topology:

      +---------------------------------------------------------------+
      | LS1028A                                                       |
      |               +------------------------------+                |
      |               |      DSA master for Felix    |                |
      |               |(internal ENETC port 2: eno2))|                |
      |  +------------+------------------------------+-------------+  |
      |  | Felix embedded L2 switch                                |  |
      |  |                                                         |  |
      |  | +--------------+   +--------------+   +--------------+  |  |
      |  | |DSA master for|   |DSA master for|   |DSA master for|  |  |
      |  | |  SJA1105 1   |   |  SJA1105 2   |   |  SJA1105 3   |  |  |
      |  | |(Felix port 1)|   |(Felix port 2)|   |(Felix port 3)|  |  |
      +--+-+--------------+---+--------------+---+--------------+--+--+

+-----------------------+ +-----------------------+ +-----------------------+
|   SJA1105 switch 1    | |   SJA1105 switch 2    | |   SJA1105 switch 3    |
+-----+-----+-----+-----+ +-----+-----+-----+-----+ +-----+-----+-----+-----+
|sw1p0|sw1p1|sw1p2|sw1p3| |sw2p0|sw2p1|sw2p2|sw2p3| |sw3p0|sw3p1|sw3p2|sw3p3|
+-----+-----+-----+-----+ +-----+-----+-----+-----+ +-----+-----+-----+-----+

The above can be described in the device tree as follows (obviously not
complete):

mscc_felix {
	dsa,member = <0 0>;
	ports {
		port@4 {
			ethernet = <&enetc_port2>;
		};
	};
};

sja1105_switch1 {
	dsa,member = <1 1>;
	ports {
		port@4 {
			ethernet = <&mscc_felix_port1>;
		};
	};
};

sja1105_switch2 {
	dsa,member = <2 2>;
	ports {
		port@4 {
			ethernet = <&mscc_felix_port2>;
		};
	};
};

sja1105_switch3 {
	dsa,member = <3 3>;
	ports {
		port@4 {
			ethernet = <&mscc_felix_port3>;
		};
	};
};

Basically we instantiate one DSA switch tree for every hardware switch
in the system, but we still give them globally unique switch IDs (will
come back to that later). Having 3 disjoint switch trees makes the
tagger drivers "just work", because net devices are registered for the
3 Felix DSA master ports, and they are also DSA slave ports to the ENETC
port. So packets received on the ENETC port are stripped of their
stacked DSA tags one by one.

Currently, hardware bridging between ports on the same sja1105 chip is
possible, but switching between sja1105 ports on different chips is
handled by the software bridge. This is fine, but we can do better.

In fact, the dsa_8021q tag used by sja1105 is compatible with cascading.
In other words, a sja1105 switch can correctly parse and route a packet
containing a dsa_8021q tag. So if we could enable hardware bridging on
the Felix DSA master ports, cross-chip bridging could be completely
offloaded.

Such as system would be used as follows:

ip link add dev br0 type bridge && ip link set dev br0 up
for port in sw0p0 sw0p1 sw0p2 sw0p3 \
	    sw1p0 sw1p1 sw1p2 sw1p3 \
	    sw2p0 sw2p1 sw2p2 sw2p3; do
	ip link set dev $port master br0
done

The above makes switching between ports on the same row be performed in
hardware, and between ports on different rows in software. Now assume
the Felix switch ports are called swp0, swp1, swp2. By running the
following extra commands:

ip link add dev br1 type bridge && ip link set dev br1 up
for port in swp0 swp1 swp2; do
	ip link set dev $port master br1
done

the CPU no longer sees packets which traverse sja1105 switch boundaries
and can be forwarded directly by Felix. The br1 bridge would not be used
for any sort of traffic termination.

For this to work, we need to give drivers an opportunity to listen for
bridging events on DSA trees other than their own, and pass that other
tree index as argument. I have made the assumption, for the moment, that
the other existing DSA notifiers don't need to be broadcast to other
trees. That assumption might turn out to be incorrect. But in the
meantime, introduce a dsa_broadcast function, similar in purpose to
dsa_port_notify, which is used only by the bridging notifiers.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2020-05-10 19:52:33 -07:00
..
Kconfig net: Make PTP-specific drivers depend on PTP_1588_CLOCK 2020-05-01 15:27:51 -07:00
Makefile net: dsa: mv88e6xxx: update code operating on hidden registers 2019-08-27 21:42:16 -07:00
chip.c net: dsa: permit cross-chip bridging between all trees in the system 2020-05-10 19:52:33 -07:00
chip.h net: dsa: mv88e6xxx: remove port_link_state functions 2020-03-15 17:11:12 -07:00
global1.c net: dsa: mv88e6xxx: Fix masking of egress port 2020-02-27 12:29:09 -08:00
global1.h net: dsa: mv88e6xxx: Preserve priority when setting CPU port. 2020-01-06 13:35:11 -08:00
global1_atu.c net: dsa: mv88e6xxx: Unique ATU and VTU IRQ names 2020-01-06 18:30:15 -08:00
global1_vtu.c net: dsa: mv88e6xxx: Unique ATU and VTU IRQ names 2020-01-06 18:30:15 -08:00
global2.c net: dsa: mv88e6xxx: fix lockup on warm boot 2020-02-29 21:46:08 -08:00
global2.h net: dsa: mv8e6xxx: Fix stub function parameters 2019-11-06 21:42:53 -08:00
global2_avb.c net: dsa: mv88e6xxx: wait for AVB Busy bit 2019-08-11 21:27:15 -07:00
global2_scratch.c net: dsa: mv88e6xxx: remove wait and update routines 2019-08-11 21:27:15 -07:00
hwtstamp.c net: dsa: mv88e6xxx: introduce helpers for handling chip->reg_lock 2019-06-23 11:11:11 -07:00
hwtstamp.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
phy.c net: dsa: mv88e6xxx: introduce helpers for handling chip->reg_lock 2019-06-23 11:11:11 -07:00
phy.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
port.c net: dsa: mv88e6xxx: remove port_link_state functions 2020-03-15 17:11:12 -07:00
port.h net: dsa: mv88e6xxx: remove port_link_state functions 2020-03-15 17:11:12 -07:00
port_hidden.c net: dsa: mv88e6xxx: update code operating on hidden registers 2019-08-27 21:42:16 -07:00
ptp.c mv88e6xxx: Reject requests to enable time stamping on both edges. 2019-11-15 12:48:32 -08:00
ptp.h net: dsa: mv88e6xxx: add PTP support for MV88E6250 family 2019-08-02 17:58:53 -07:00
serdes.c net: dsa: mv88e6xxx: 88e6390 10G serdes support 2020-05-01 15:40:15 -07:00
serdes.h net: dsa: mv88e6xxx: 88e6390 10G serdes support 2020-05-01 15:40:15 -07:00
smi.c net: dsa: mv88e6xxx: add delay in direct SMI wait 2019-08-11 21:27:15 -07:00
smi.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00