From patchwork Mon Nov 6 23:02:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Lunn X-Patchwork-Id: 834990 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yW7Q5491cz9sCZ for ; Tue, 7 Nov 2017 10:03:09 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752054AbdKFXDH (ORCPT ); Mon, 6 Nov 2017 18:03:07 -0500 Received: from vps0.lunn.ch ([185.16.172.187]:45244 "EHLO vps0.lunn.ch" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752028AbdKFXDG (ORCPT ); Mon, 6 Nov 2017 18:03:06 -0500 Received: from andrew by vps0.lunn.ch with local (Exim 4.84_2) (envelope-from ) id 1eBqPc-0005hu-Kq; Tue, 07 Nov 2017 00:02:36 +0100 From: Andrew Lunn To: David Miller Cc: netdev , Vivien Didelot , Florian Fainelli , Andrew Lunn Subject: [PATCH v2 net-next 6/6] net: dsa: mv88e6xxx: Flood broadcast frames in hardware Date: Tue, 7 Nov 2017 00:02:31 +0100 Message-Id: <1510009351-21875-7-git-send-email-andrew@lunn.ch> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1510009351-21875-1-git-send-email-andrew@lunn.ch> References: <1510009351-21875-1-git-send-email-andrew@lunn.ch> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org By default, the switch does not flood broadcast frames. Instead the broadcast address is unknown in the ATU, so the frame gets forwarded out the cpu port. The software bridge then floods it back to the individual switch ports which are members of the bridge. Add an ATU entry in the switch so that it floods broadcast frames out ports, rather than have the software bridge do it. Also, send a copy out the cpu port and any dsa ports. Rely on the port vectors to prevent broadcast frames leaking between bridges, and separated ports. Additionally, when a VLAN is added, a new FID is allocated. This represents a new table of ATU entries. A broadcast entry is added to the new FID. With offload_fwd_mark being set, the software bridge will not flood the frames it receives back to the switch. Signed-off-by: Andrew Lunn --- v2: ++port -> port++ use temporary variable to avoid long line --- drivers/net/dsa/mv88e6xxx/chip.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 263b714a5ae3..6dd5fdfeafcf 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -1252,6 +1252,29 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port, return mv88e6xxx_g1_atu_loadpurge(chip, vlan.fid, &entry); } +static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port, + u16 vid) +{ + const char broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + u8 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC; + + return mv88e6xxx_port_db_load_purge(chip, port, broadcast, vid, state); +} + +static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid) +{ + int port; + int err; + + for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { + err = mv88e6xxx_port_add_broadcast(chip, port, vid); + if (err) + return err; + } + + return 0; +} + static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port, u16 vid, u8 member) { @@ -1264,7 +1287,11 @@ static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port, vlan.member[port] = member; - return mv88e6xxx_vtu_loadpurge(chip, &vlan); + err = mv88e6xxx_vtu_loadpurge(chip, &vlan); + if (err) + return err; + + return mv88e6xxx_broadcast_setup(chip, vid); } static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, @@ -2049,6 +2076,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds) if (err) goto unlock; + err = mv88e6xxx_broadcast_setup(chip, 0); + if (err) + goto unlock; + err = mv88e6xxx_pot_setup(chip); if (err) goto unlock;