From patchwork Mon Mar 21 10:14:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casper Andersson X-Patchwork-Id: 12787057 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BD75AC433FE for ; Mon, 21 Mar 2022 10:14:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346217AbiCUKQR (ORCPT ); Mon, 21 Mar 2022 06:16:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45882 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240075AbiCUKQQ (ORCPT ); Mon, 21 Mar 2022 06:16:16 -0400 Received: from mail-lf1-x135.google.com (mail-lf1-x135.google.com [IPv6:2a00:1450:4864:20::135]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ABE5F17A92 for ; Mon, 21 Mar 2022 03:14:50 -0700 (PDT) Received: by mail-lf1-x135.google.com with SMTP id w27so23790961lfa.5 for ; Mon, 21 Mar 2022 03:14:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:organization:content-transfer-encoding; bh=sejdDdw0jf50ab8MnHRj9m1lyNL06PYbtFnV1Pbd7hQ=; b=d5y2n5HUIMnQcnUa5Lnue8WAoAkMMeSq0DInq9aAFSdheQakyILVmqGf8fiMv6H385 WrPVaInoDPPGK1RgAYt/egkrjFT/gvUARFvwXI7U3WGKOnND+h0JuzIL0YK+cFWf50Vb mQn++8hl5cSRoK3SRV7SdLQA3KsdUXTGqhPkOXf4zHn+v4ZaAnZ6ApFKeUnOQTiaiYKK h5CehD589cBvMOUe1btDI/qCmPKPKV6dY7kHA58cFR6g9CMpa3BU1iy8JDxer1U8BpoY Lp4H7Dt9sPgqMSA6ni2t6No0UKpeA+y3xNcqbKj2S+l09O99RpGk8xdFVUBnmX4MgtQF p2AA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:organization:content-transfer-encoding; bh=sejdDdw0jf50ab8MnHRj9m1lyNL06PYbtFnV1Pbd7hQ=; b=l0rbpyHzZEW5IZ6HMWytuvX+JuydiWT9k0yuRy79oCq/f8hCDp/s6Guy+JpDocySHz +fE7Iy410pnySotUSf3u4+cLyqd7qABYLzNzJKTucpTPku4JSm7H7IpFGjRfEpAHqhoh n63xGgu8lmbuDGk3q23bFB81xnU7AWEvX38kU73MzCfD3vkbLAe1dj2+xS0FFOh9Tu+t PajEqiBBymO4doPnN/XcQyaAtmzx7sOa7dvsDbZDmTXnEzulWv70QjQOUKiI8/0kxffU xB9jsL3BHph1bjsR7VZVQHvK8ZOXBvC4XyVq1cEMDZkDt9G8Mlxqna8jqX93GMxG4Uez Xb0w== X-Gm-Message-State: AOAM530jeEx1xkdYsdu1LwOF2VgKnHJfWiX0Z9iB1V2AXoEVowAtUKN6 gAIKTiGYnXdqZj55jjkXZ+aaFugUwu6drg== X-Google-Smtp-Source: ABdhPJxIVSBtkR4yrkSPQXpcPy1HYjeLRYYbZTqhFJzlOyObTxaDnwy1kpIlAch2ntDjI7k1IVq9ww== X-Received: by 2002:a05:6512:308d:b0:448:6b44:5dde with SMTP id z13-20020a056512308d00b004486b445ddemr14093060lfd.224.1647857689010; Mon, 21 Mar 2022 03:14:49 -0700 (PDT) Received: from wse-c0155.labs.westermo.se (static-193-12-47-89.cust.tele2.se. [193.12.47.89]) by smtp.gmail.com with ESMTPSA id f11-20020a0565123b0b00b0044a2809c621sm361598lfv.29.2022.03.21.03.14.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Mar 2022 03:14:48 -0700 (PDT) From: Casper Andersson To: "David S. Miller" , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org Cc: Lars Povlsen , Steen Hegelund , UNGLinuxDriver@microchip.com Subject: [PATCH net-next 1/2] net: sparx5: Add arbiter for managing PGID table Date: Mon, 21 Mar 2022 11:14:45 +0100 Message-Id: <20220321101446.2372093-2-casper.casan@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220321101446.2372093-1-casper.casan@gmail.com> References: <20220321101446.2372093-1-casper.casan@gmail.com> MIME-Version: 1.0 Organization: Westermo Network Technologies AB Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The PGID (Port Group ID) table holds port masks for different purposes. The first 72 are reserved for port destination masks, flood masks, and CPU forwarding. The rest are shared between multicast, link aggregation, and virtualization profiles. The GLAG area is reserved to not be used by anything else, since it is a subset of the MCAST area. The arbiter keeps track of which entries are in use. You can ask for a free ID or give back one you are done using. Signed-off-by: Casper Andersson --- .../net/ethernet/microchip/sparx5/Makefile | 2 +- .../ethernet/microchip/sparx5/sparx5_main.c | 3 + .../ethernet/microchip/sparx5/sparx5_main.h | 21 +++++++ .../ethernet/microchip/sparx5/sparx5_pgid.c | 60 +++++++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c diff --git a/drivers/net/ethernet/microchip/sparx5/Makefile b/drivers/net/ethernet/microchip/sparx5/Makefile index e9dd348a6ebb..4402c3ed1dc5 100644 --- a/drivers/net/ethernet/microchip/sparx5/Makefile +++ b/drivers/net/ethernet/microchip/sparx5/Makefile @@ -8,4 +8,4 @@ obj-$(CONFIG_SPARX5_SWITCH) += sparx5-switch.o sparx5-switch-objs := sparx5_main.o sparx5_packet.o \ sparx5_netdev.o sparx5_phylink.o sparx5_port.o sparx5_mactable.o sparx5_vlan.o \ sparx5_switchdev.o sparx5_calendar.o sparx5_ethtool.o sparx5_fdma.o \ - sparx5_ptp.o + sparx5_ptp.o sparx5_pgid.o diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c index 5f7c7030ce03..01be7bd84181 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c @@ -626,6 +626,9 @@ static int sparx5_start(struct sparx5 *sparx5) /* Init MAC table, ageing */ sparx5_mact_init(sparx5); + /* Init PGID table arbitrator */ + sparx5_pgid_init(sparx5); + /* Setup VLANs */ sparx5_vlan_init(sparx5); diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h index df68a0891029..e97fa091c740 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h @@ -66,6 +66,12 @@ enum sparx5_vlan_port_type { #define PGID_BCAST (PGID_BASE + 6) #define PGID_CPU (PGID_BASE + 7) +#define PGID_TABLE_SIZE 3290 + +#define PGID_MCAST_START 65 +#define PGID_GLAG_START 833 +#define PGID_GLAG_END 1088 + #define IFH_LEN 9 /* 36 bytes */ #define NULL_VID 0 #define SPX5_MACT_PULL_DELAY (2 * HZ) @@ -271,6 +277,8 @@ struct sparx5 { struct mutex ptp_lock; /* lock for ptp interface state */ u16 ptp_skbs; int ptp_irq; + /* PGID allocation map */ + u8 pgid_map[PGID_TABLE_SIZE]; }; /* sparx5_switchdev.c */ @@ -359,6 +367,19 @@ void sparx5_ptp_txtstamp_release(struct sparx5_port *port, struct sk_buff *skb); irqreturn_t sparx5_ptp_irq_handler(int irq, void *args); +/* sparx5_pgid.c */ +enum sparx5_pgid_type { + SPX5_PGID_FREE, + SPX5_PGID_RESERVED, + SPX5_PGID_MULTICAST, + SPX5_PGID_GLAG +}; + +void sparx5_pgid_init(struct sparx5 *spx5); +int sparx5_pgid_alloc_glag(struct sparx5 *spx5, u16 *idx); +int sparx5_pgid_alloc_mcast(struct sparx5 *spx5, u16 *idx); +int sparx5_pgid_free(struct sparx5 *spx5, u16 idx); + /* Clock period in picoseconds */ static inline u32 sparx5_clk_period(enum sparx5_core_clockfreq cclock) { diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c b/drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c new file mode 100644 index 000000000000..90366fcb9958 --- /dev/null +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include "sparx5_main.h" + +void sparx5_pgid_init(struct sparx5 *spx5) +{ + int i; + + for (i = 0; i < PGID_TABLE_SIZE; i++) + spx5->pgid_map[i] = SPX5_PGID_FREE; + + /* Reserved for unicast, flood control, broadcast, and CPU. + * These cannot be freed. + */ + for (i = 0; i <= PGID_CPU; i++) + spx5->pgid_map[i] = SPX5_PGID_RESERVED; +} + +int sparx5_pgid_alloc_glag(struct sparx5 *spx5, u16 *idx) +{ + int i; + + for (i = PGID_GLAG_START; i <= PGID_GLAG_END; i++) + if (spx5->pgid_map[i] == SPX5_PGID_FREE) { + spx5->pgid_map[i] = SPX5_PGID_GLAG; + *idx = i; + return 0; + } + + return -EBUSY; +} + +int sparx5_pgid_alloc_mcast(struct sparx5 *spx5, u16 *idx) +{ + int i; + + for (i = PGID_MCAST_START; i < PGID_TABLE_SIZE; i++) { + if (i == PGID_GLAG_START) + i = PGID_GLAG_END + 1; + + if (spx5->pgid_map[i] == SPX5_PGID_FREE) { + spx5->pgid_map[i] = SPX5_PGID_MULTICAST; + *idx = i; + return 0; + } + } + + return -EBUSY; +} + +int sparx5_pgid_free(struct sparx5 *spx5, u16 idx) +{ + if (idx <= PGID_CPU || idx >= PGID_TABLE_SIZE) + return -EINVAL; + + if (spx5->pgid_map[idx] == SPX5_PGID_FREE) + return -EINVAL; + + spx5->pgid_map[idx] = SPX5_PGID_FREE; + return 0; +} From patchwork Mon Mar 21 10:14:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casper Andersson X-Patchwork-Id: 12787058 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AE1CAC433F5 for ; Mon, 21 Mar 2022 10:14:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346222AbiCUKQS (ORCPT ); Mon, 21 Mar 2022 06:16:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346124AbiCUKQQ (ORCPT ); Mon, 21 Mar 2022 06:16:16 -0400 Received: from mail-lj1-x229.google.com (mail-lj1-x229.google.com [IPv6:2a00:1450:4864:20::229]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 65B6017A97 for ; Mon, 21 Mar 2022 03:14:51 -0700 (PDT) Received: by mail-lj1-x229.google.com with SMTP id r22so19109120ljd.4 for ; Mon, 21 Mar 2022 03:14:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:organization:content-transfer-encoding; bh=YHGKjU83F4eAdszFq5z81FKn0UfX6FcBTWb0VAmYVoE=; b=oDO6Frt5UKTDV4aefFyCvdj+jveCK6xxf2rnTeohlgh+xWsqcyXk9q0xMg7rrduBVu 7sHUvD8LvHjYxK8xu01SecdINeXZwOl/fBFzLJHcS9EKwlsfSR/bQhgZ/rLTjYTRWup9 JU8W56Pro5+rDStlhlwkoKg95yS7EDPj1NVg6chYsd6gIe2Dzc8nev3Exeio5h5WTy1/ 8to2ARdNfJAfETmO7/HkwZauloovbh7URHQ7t1IwhvuiGa+5Mqj4P991NrDStPeNtsER CFZ4cK0EhdfQ3ejjjBwmDyD0JfDG4PYWgeSi9NVAbDc5ARi9jbD0ucYCEylgNh9bmIn0 Va3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:organization:content-transfer-encoding; bh=YHGKjU83F4eAdszFq5z81FKn0UfX6FcBTWb0VAmYVoE=; b=IrGq2L2Sl+JQDvr0vUm4Mrp3AWoDPZzJJQ3fyZg9OUMUHVcVCmJs612tZa0iZYz6Hd /RezfFGNtKnWu4BctIj2sFrbklurBKU3xQy5Gg/eq5RQcwwaNFMcqqGBhSoey8TBAZCb EBnSx8Ysbh0km2GMgWsdWCdEsZ5yHMdkS9jhZDP2O4+ZiTsqP1zYKOpd7wi8L2QsN/mG PkZrQHeC++lOK8s3cor0jI9luNLzTVQgVlDQYtmnIkqxZQ1U+RniLLXRXPmSAXU2EYey yVeSmFgdTVwVLuiFKWQ03TCV5ABgK0tcrkZGFheWwfdxzIx73CpU5O2tQqJ6qdlsu1/V Q0MQ== X-Gm-Message-State: AOAM533+aul5s0jH9oGKjnKwUsh7VC9p3f28A6GrsHYNxXQiyNfbPV6f NQaCir5pCc3kJjqkiLAHBnE= X-Google-Smtp-Source: ABdhPJzCb10g65yPLdaE2IursYLjv7UFT4NjoJI17QCOeE02Qz9AIdZl763Ts4XOikt+a/5mgdnyoA== X-Received: by 2002:a2e:9847:0:b0:244:bbdf:8f72 with SMTP id e7-20020a2e9847000000b00244bbdf8f72mr15053326ljj.69.1647857689741; Mon, 21 Mar 2022 03:14:49 -0700 (PDT) Received: from wse-c0155.labs.westermo.se (static-193-12-47-89.cust.tele2.se. [193.12.47.89]) by smtp.gmail.com with ESMTPSA id f11-20020a0565123b0b00b0044a2809c621sm361598lfv.29.2022.03.21.03.14.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Mar 2022 03:14:49 -0700 (PDT) From: Casper Andersson To: "David S. Miller" , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org Cc: Lars Povlsen , Steen Hegelund , UNGLinuxDriver@microchip.com Subject: [PATCH net-next 2/2] net: sparx5: Add mdb handlers Date: Mon, 21 Mar 2022 11:14:46 +0100 Message-Id: <20220321101446.2372093-3-casper.casan@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220321101446.2372093-1-casper.casan@gmail.com> References: <20220321101446.2372093-1-casper.casan@gmail.com> MIME-Version: 1.0 Organization: Westermo Network Technologies AB Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Adds mdb handlers. Uses the PGID arbiter to find a free entry in the PGID table for the multicast group port mask. Signed-off-by: Casper Andersson --- .../microchip/sparx5/sparx5_mactable.c | 33 ++++-- .../ethernet/microchip/sparx5/sparx5_main.h | 2 + .../microchip/sparx5/sparx5_switchdev.c | 111 ++++++++++++++++++ 3 files changed, 136 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c b/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c index 82b1b3c9a065..35abb3d0ce19 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c @@ -186,11 +186,11 @@ bool sparx5_mact_getnext(struct sparx5 *sparx5, return ret == 0; } -static int sparx5_mact_lookup(struct sparx5 *sparx5, - const unsigned char mac[ETH_ALEN], - u16 vid) +bool sparx5_mact_find(struct sparx5 *sparx5, + const unsigned char mac[ETH_ALEN], u16 vid, u32 *pcfg2) { int ret; + u32 cfg2; mutex_lock(&sparx5->lock); @@ -202,16 +202,29 @@ static int sparx5_mact_lookup(struct sparx5 *sparx5, sparx5, LRN_COMMON_ACCESS_CTRL); ret = sparx5_mact_wait_for_completion(sparx5); - if (ret) - goto out; - - ret = LRN_MAC_ACCESS_CFG_2_MAC_ENTRY_VLD_GET - (spx5_rd(sparx5, LRN_MAC_ACCESS_CFG_2)); + if (ret == 0) { + cfg2 = spx5_rd(sparx5, LRN_MAC_ACCESS_CFG_2); + if (LRN_MAC_ACCESS_CFG_2_MAC_ENTRY_VLD_GET(cfg2)) + *pcfg2 = cfg2; + else + ret = -ENOENT; + } -out: mutex_unlock(&sparx5->lock); - return ret; + return ret == 0; +} + +static int sparx5_mact_lookup(struct sparx5 *sparx5, + const unsigned char mac[ETH_ALEN], + u16 vid) +{ + u32 pcfg2; + + if (sparx5_mact_find(sparx5, mac, vid, &pcfg2)) + return 1; + + return 0; } int sparx5_mact_forget(struct sparx5 *sparx5, diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h index e97fa091c740..7a04b8f2a546 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h @@ -310,6 +310,8 @@ int sparx5_mact_learn(struct sparx5 *sparx5, int port, const unsigned char mac[ETH_ALEN], u16 vid); bool sparx5_mact_getnext(struct sparx5 *sparx5, unsigned char mac[ETH_ALEN], u16 *vid, u32 *pcfg2); +bool sparx5_mact_find(struct sparx5 *sparx5, + const unsigned char mac[ETH_ALEN], u16 vid, u32 *pcfg2); int sparx5_mact_forget(struct sparx5 *sparx5, const unsigned char mac[ETH_ALEN], u16 vid); int sparx5_add_mact_entry(struct sparx5 *sparx5, diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c b/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c index 2d5de1c06fab..9e1ea35d0c40 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c @@ -366,6 +366,109 @@ static int sparx5_handle_port_vlan_add(struct net_device *dev, v->flags & BRIDGE_VLAN_INFO_UNTAGGED); } +static int sparx5_handle_port_mdb_add(struct net_device *dev, + struct notifier_block *nb, + const struct switchdev_obj_port_mdb *v) +{ + struct sparx5_port *port = netdev_priv(dev); + struct sparx5 *spx5 = port->sparx5; + u16 pgid_idx, vid; + u32 mact_entry; + int res, err; + + /* When VLAN unaware the vlan value is not parsed and we receive vid 0. + * Fall back to bridge vid 1. + */ + if (!br_vlan_enabled(spx5->hw_bridge_dev)) + vid = 1; + else + vid = v->vid; + + res = sparx5_mact_find(spx5, v->addr, vid, &mact_entry); + + if (res) { + pgid_idx = LRN_MAC_ACCESS_CFG_2_MAC_ENTRY_ADDR_GET(mact_entry); + + /* MC_IDX has an offset of 65 in the PGID table. */ + pgid_idx += PGID_MCAST_START; + sparx5_pgid_update_mask(port, pgid_idx, true); + } else { + err = sparx5_pgid_alloc_mcast(spx5, &pgid_idx); + if (err) { + netdev_warn(dev, "multicast pgid table full\n"); + return err; + } + sparx5_pgid_update_mask(port, pgid_idx, true); + err = sparx5_mact_learn(spx5, pgid_idx, v->addr, vid); + if (err) { + netdev_warn(dev, "could not learn mac address %pM\n", v->addr); + sparx5_pgid_update_mask(port, pgid_idx, false); + return err; + } + } + + return 0; +} + +static int sparx5_mdb_del_entry(struct net_device *dev, + struct sparx5 *spx5, + const unsigned char mac[ETH_ALEN], + const u16 vid, + u16 pgid_idx) +{ + int err; + + err = sparx5_mact_forget(spx5, mac, vid); + if (err) { + netdev_warn(dev, "could not forget mac address %pM", mac); + return err; + } + err = sparx5_pgid_free(spx5, pgid_idx); + if (err) { + netdev_err(dev, "attempted to free already freed pgid\n"); + return err; + } + return 0; +} + +static int sparx5_handle_port_mdb_del(struct net_device *dev, + struct notifier_block *nb, + const struct switchdev_obj_port_mdb *v) +{ + struct sparx5_port *port = netdev_priv(dev); + struct sparx5 *spx5 = port->sparx5; + u16 pgid_idx, vid; + u32 mact_entry, res, pgid_entry[3]; + int err; + + if (!br_vlan_enabled(spx5->hw_bridge_dev)) + vid = 1; + else + vid = v->vid; + + res = sparx5_mact_find(spx5, v->addr, vid, &mact_entry); + + if (res) { + pgid_idx = LRN_MAC_ACCESS_CFG_2_MAC_ENTRY_ADDR_GET(mact_entry); + + /* MC_IDX has an offset of 65 in the PGID table. */ + pgid_idx += PGID_MCAST_START; + sparx5_pgid_update_mask(port, pgid_idx, false); + + pgid_entry[0] = spx5_rd(spx5, ANA_AC_PGID_CFG(pgid_idx)); + pgid_entry[1] = spx5_rd(spx5, ANA_AC_PGID_CFG1(pgid_idx)); + pgid_entry[2] = spx5_rd(spx5, ANA_AC_PGID_CFG2(pgid_idx)); + if (pgid_entry[0] == 0 && pgid_entry[1] == 0 && pgid_entry[2] == 0) { + /* No ports are in MC group. Remove entry */ + err = sparx5_mdb_del_entry(dev, spx5, v->addr, vid, pgid_idx); + if (err) + return err; + } + } + + return 0; +} + static int sparx5_handle_port_obj_add(struct net_device *dev, struct notifier_block *nb, struct switchdev_notifier_port_obj_info *info) @@ -378,6 +481,10 @@ static int sparx5_handle_port_obj_add(struct net_device *dev, err = sparx5_handle_port_vlan_add(dev, nb, SWITCHDEV_OBJ_PORT_VLAN(obj)); break; + case SWITCHDEV_OBJ_ID_PORT_MDB: + err = sparx5_handle_port_mdb_add(dev, nb, + SWITCHDEV_OBJ_PORT_MDB(obj)); + break; default: err = -EOPNOTSUPP; break; @@ -426,6 +533,10 @@ static int sparx5_handle_port_obj_del(struct net_device *dev, err = sparx5_handle_port_vlan_del(dev, nb, SWITCHDEV_OBJ_PORT_VLAN(obj)->vid); break; + case SWITCHDEV_OBJ_ID_PORT_MDB: + err = sparx5_handle_port_mdb_del(dev, nb, + SWITCHDEV_OBJ_PORT_MDB(obj)); + break; default: err = -EOPNOTSUPP; break;