From 909fb9ae322154648d7354bcf7cdd0f705fb67f1 Mon Sep 17 00:00:00 2001 From: Egil Hjelmeland Date: Tue, 31 Oct 2017 15:48:00 +0100 Subject: net: dsa: lan9303: Transmit using ALR when unicast lan9303_xmit_use_arl() introduced in previous patch set is wrong. The chip flood broadcast and unknown multicast frames. The effect is that broadcasts and multicasts are duplicated on egress. It is not possible to configure the chip to direct unknown multicasts to CPU port only. This means that only unicast frames can be transmitted using ALR lookup. Signed-off-by: Egil Hjelmeland Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- net/dsa/tag_lan9303.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/dsa/tag_lan9303.c b/net/dsa/tag_lan9303.c index 64092325aac3..537ca991fafe 100644 --- a/net/dsa/tag_lan9303.c +++ b/net/dsa/tag_lan9303.c @@ -46,7 +46,7 @@ /* Decide whether to transmit using ALR lookup, or transmit directly to * port using tag. ALR learning is performed only when using ALR lookup. - * If the two external ports are bridged and the packet is not STP BPDU, + * If the two external ports are bridged and the frame is unicast, * then use ALR lookup to allow ALR learning on CPU port. * Otherwise transmit directly to port with STP state override. * See also: lan9303_separate_ports() and lan9303.pdf 6.4.10.1 @@ -55,7 +55,7 @@ static int lan9303_xmit_use_arl(struct dsa_port *dp, u8 *dest_addr) { struct lan9303 *chip = dp->ds->priv; - return chip->is_bridged && !ether_addr_equal(dest_addr, eth_stp_addr); + return chip->is_bridged && !is_multicast_ether_addr(dest_addr); } static struct sk_buff *lan9303_xmit(struct sk_buff *skb, struct net_device *dev) -- cgit v1.2.3 From e9292f2c03851ef81bef38579a0ee9c42140e586 Mon Sep 17 00:00:00 2001 From: Egil Hjelmeland Date: Tue, 31 Oct 2017 15:48:01 +0100 Subject: net: dsa: lan9303: Add STP ALR entry on port 0 STP BPDUs arriving on user ports must sent to CPU port only, for processing by the SW bridge. Add an ALR entry with STP state override to fix that. Signed-off-by: Egil Hjelmeland Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/lan9303-core.c | 2 ++ include/linux/dsa/lan9303.h | 2 ++ net/dsa/tag_lan9303.c | 1 - 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c index 4c412bd52319..c4afc8f1a66d 100644 --- a/drivers/net/dsa/lan9303-core.c +++ b/drivers/net/dsa/lan9303-core.c @@ -773,6 +773,7 @@ static int lan9303_separate_ports(struct lan9303 *chip) { int ret; + lan9303_alr_del_port(chip, eth_stp_addr, 0); ret = lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_MIRROR, LAN9303_SWE_PORT_MIRROR_SNIFFER_PORT0 | LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT1 | @@ -797,6 +798,7 @@ static void lan9303_bridge_ports(struct lan9303 *chip) lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_STATE, chip->swe_port_state); + lan9303_alr_add_port(chip, eth_stp_addr, 0, true); } static int lan9303_handle_reset(struct lan9303 *chip) diff --git a/include/linux/dsa/lan9303.h b/include/linux/dsa/lan9303.h index 05d8d136baab..b2110e69630f 100644 --- a/include/linux/dsa/lan9303.h +++ b/include/linux/dsa/lan9303.h @@ -34,3 +34,5 @@ struct lan9303 { **/ struct lan9303_alr_cache_entry alr_cache[LAN9303_NUM_ALR_RECORDS]; }; + +#define eth_stp_addr eth_reserved_addr_base diff --git a/net/dsa/tag_lan9303.c b/net/dsa/tag_lan9303.c index 537ca991fafe..18f45cd9f625 100644 --- a/net/dsa/tag_lan9303.c +++ b/net/dsa/tag_lan9303.c @@ -42,7 +42,6 @@ #define LAN9303_TAG_LEN 4 # define LAN9303_TAG_TX_USE_ALR BIT(3) # define LAN9303_TAG_TX_STP_OVERRIDE BIT(4) -#define eth_stp_addr eth_reserved_addr_base /* Decide whether to transmit using ALR lookup, or transmit directly to * port using tag. ALR learning is performed only when using ALR lookup. -- cgit v1.2.3 From f849772915e5501c25f69f4815daa8cd86194634 Mon Sep 17 00:00:00 2001 From: Egil Hjelmeland Date: Tue, 31 Oct 2017 15:48:02 +0100 Subject: net: dsa: lan9303: lan9303_rcv set skb->offload_fwd_mark The chip flood broadcast and unknown multicast frames. On receive set skb->offload_fwd_mark to prevent the SW from flooding to the same ports. One exception: Because the ALR is set up to forward STP BPDUs only to CPU, the SW bridge should flood STP BPDUs if local STP is not enabled. This is archived by not setting skb->offload_fwd_mark on STP BPDUs. Signed-off-by: Egil Hjelmeland Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- net/dsa/tag_lan9303.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/dsa/tag_lan9303.c b/net/dsa/tag_lan9303.c index 18f45cd9f625..e526c8967b98 100644 --- a/net/dsa/tag_lan9303.c +++ b/net/dsa/tag_lan9303.c @@ -126,6 +126,8 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev, skb_pull_rcsum(skb, 2 + 2); memmove(skb->data - ETH_HLEN, skb->data - (ETH_HLEN + LAN9303_TAG_LEN), 2 * ETH_ALEN); + skb->offload_fwd_mark = !ether_addr_equal(skb->data - ETH_HLEN, + eth_stp_addr); return skb; } -- cgit v1.2.3