From: Joseph Huang <Joseph.Huang@garmin.com>
To: <netdev@vger.kernel.org>
Cc: "Joseph Huang" <Joseph.Huang@garmin.com>,
"Andrew Lunn" <andrew@lunn.ch>,
"Florian Fainelli" <f.fainelli@gmail.com>,
"Vladimir Oltean" <olteanv@gmail.com>,
"David S. Miller" <davem@davemloft.net>,
"Eric Dumazet" <edumazet@google.com>,
"Jakub Kicinski" <kuba@kernel.org>,
"Paolo Abeni" <pabeni@redhat.com>,
"Roopa Prabhu" <roopa@nvidia.com>,
"Nikolay Aleksandrov" <razor@blackwall.org>,
"Linus Lüssing" <linus.luessing@c0d3.blue>,
linux-kernel@vger.kernel.org, bridge@lists.linux.dev
Subject: [PATCH RFC net-next 07/10] net: dsa: mv88e6xxx: Track bridge mdb objects
Date: Mon, 1 Apr 2024 20:11:06 -0400 [thread overview]
Message-ID: <20240402001137.2980589-8-Joseph.Huang@garmin.com> (raw)
In-Reply-To: <20240402001137.2980589-1-Joseph.Huang@garmin.com>
Keep track of bridge mdb objects in the driver.
Similar to the previous patch, since the driver doesn't get explicit
notifications about mdb group creation or destruction, just create
the mdb group when the first port joins the group via
mv88e6xxx_port_mdb_add(), and destroys the group when the last port left
the group via mv88e6xxx_port_mdb_del().
Use the group's L2 address together with the VLAN ID as the key to the list.
Port membership is again stored in a bitmask.
Signed-off-by: Joseph Huang <Joseph.Huang@garmin.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 117 +++++++++++++++++++++++++++++++
1 file changed, 117 insertions(+)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index f66ddde484dc..32a613c965b1 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -47,6 +47,14 @@ struct mv88e6xxx_bridge {
struct list_head head;
struct net_device *br_dev;
u16 ports;
+ struct list_head br_mdb_list;
+};
+
+struct mv88e6xxx_br_mdb {
+ struct list_head head;
+ unsigned char addr[ETH_ALEN];
+ u16 vid;
+ u16 portvec;
};
static void assert_reg_lock(struct mv88e6xxx_chip *chip)
@@ -2974,6 +2982,7 @@ mv88e6xxx_bridge_create(struct mv88e6xxx_chip *chip, struct net_device *br_dev)
return ERR_PTR(-ENOMEM);
mv_bridge->br_dev = br_dev;
+ INIT_LIST_HEAD(&mv_bridge->br_mdb_list);
list_add(&mv_bridge->head, &chip->bridge_list);
return mv_bridge;
@@ -2984,6 +2993,7 @@ static void mv88e6xxx_bridge_destroy(struct mv88e6xxx_bridge *mv_bridge)
list_del(&mv_bridge->head);
WARN_ON(mv_bridge->ports);
+ WARN_ON(!list_empty(&mv_bridge->br_mdb_list));
kfree(mv_bridge);
}
@@ -6583,16 +6593,101 @@ static int mv88e6xxx_change_tag_protocol(struct dsa_switch *ds,
return err;
}
+static struct mv88e6xxx_br_mdb *
+mv88e6xxx_br_mdb_create(struct mv88e6xxx_bridge *mv_bridge,
+ const struct switchdev_obj_port_mdb *mdb)
+{
+ struct mv88e6xxx_br_mdb *mv_br_mdb;
+
+ mv_br_mdb = kzalloc(sizeof(*mv_br_mdb), GFP_KERNEL);
+ if (!mv_br_mdb)
+ return ERR_PTR(-ENOMEM);
+
+ ether_addr_copy(mv_br_mdb->addr, mdb->addr);
+ mv_br_mdb->vid = mdb->vid;
+ list_add(&mv_br_mdb->head, &mv_bridge->br_mdb_list);
+
+ return mv_br_mdb;
+}
+
+static void mv88e6xxx_br_mdb_destroy(struct mv88e6xxx_br_mdb *mv_br_mdb)
+{
+ list_del(&mv_br_mdb->head);
+
+ WARN_ON(mv_br_mdb->portvec);
+ kfree(mv_br_mdb);
+}
+
+static struct mv88e6xxx_br_mdb *
+mv88e6xxx_br_mdb_find(struct mv88e6xxx_bridge *mv_bridge,
+ const struct switchdev_obj_port_mdb *mdb)
+{
+ struct mv88e6xxx_br_mdb *mv_br_mdb;
+
+ list_for_each_entry(mv_br_mdb, &mv_bridge->br_mdb_list, head)
+ if (ether_addr_equal(mv_br_mdb->addr, mdb->addr) &&
+ mv_br_mdb->vid == mdb->vid)
+ return mv_br_mdb;
+
+ return NULL;
+}
+
+static struct mv88e6xxx_br_mdb *
+mv88e6xxx_br_mdb_get(struct mv88e6xxx_bridge *mv_bridge,
+ const struct switchdev_obj_port_mdb *mdb)
+{
+ struct mv88e6xxx_br_mdb *mv_br_mdb;
+
+ mv_br_mdb = mv88e6xxx_br_mdb_find(mv_bridge, mdb);
+ if (!mv_br_mdb)
+ mv_br_mdb = mv88e6xxx_br_mdb_create(mv_bridge, mdb);
+
+ return mv_br_mdb;
+}
+
+static void mv88e6xxx_br_mdb_put(struct mv88e6xxx_br_mdb *mv_br_mdb)
+{
+ if (!mv_br_mdb->portvec)
+ mv88e6xxx_br_mdb_destroy(mv_br_mdb);
+}
+
static int mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_mdb *mdb,
struct dsa_db db)
{
struct mv88e6xxx_chip *chip = ds->priv;
+ struct mv88e6xxx_bridge *mv_bridge;
+ struct mv88e6xxx_br_mdb *mv_br_mdb;
+ struct net_device *orig_dev;
+ struct net_device *br_dev;
int err;
+ orig_dev = mdb->obj.orig_dev;
+ br_dev = netdev_master_upper_dev_get(orig_dev);
+ if (!br_dev)
+ br_dev = orig_dev;
+
+ mv_bridge = mv88e6xxx_bridge_by_dev(chip, br_dev);
+ if (!mv_bridge)
+ return -EINVAL;
+
+ mv_br_mdb = mv88e6xxx_br_mdb_get(mv_bridge, mdb);
+ if (IS_ERR(mv_br_mdb))
+ return PTR_ERR(mv_br_mdb);
+
+ if (mv_br_mdb->portvec & BIT(port))
+ return -EEXIST;
+
mv88e6xxx_reg_lock(chip);
err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC);
+
+ if (err)
+ goto out;
+
+ mv_br_mdb->portvec |= BIT(port);
+
+out:
mv88e6xxx_reg_unlock(chip);
return err;
@@ -6603,10 +6698,32 @@ static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, int port,
struct dsa_db db)
{
struct mv88e6xxx_chip *chip = ds->priv;
+ struct mv88e6xxx_bridge *mv_bridge;
+ struct mv88e6xxx_br_mdb *mv_br_mdb;
+ struct net_device *orig_dev;
+ struct net_device *br_dev;
int err;
+ orig_dev = mdb->obj.orig_dev;
+ br_dev = netdev_master_upper_dev_get(orig_dev);
+ if (!br_dev)
+ br_dev = orig_dev;
+
+ mv_bridge = mv88e6xxx_bridge_by_dev(chip, br_dev);
+ if (!mv_bridge)
+ return -EINVAL;
+
+ mv_br_mdb = mv88e6xxx_br_mdb_find(mv_bridge, mdb);
+ if (!mv_br_mdb)
+ return -ENOENT;
+
+ if (!(mv_br_mdb->portvec & BIT(port)))
+ return -ENOENT;
+
mv88e6xxx_reg_lock(chip);
err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid, 0);
+ mv_br_mdb->portvec &= ~BIT(port);
+ mv88e6xxx_br_mdb_put(mv_br_mdb);
mv88e6xxx_reg_unlock(chip);
return err;
--
2.17.1
next prev parent reply other threads:[~2024-04-02 0:53 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-02 0:10 [PATCH RFC net-next 00/10] MC Flood disable and snooping Joseph Huang
2024-04-02 0:11 ` [PATCH RFC net-next 01/10] net: bridge: Flood Queries even when mc flood is disabled Joseph Huang
2024-04-02 0:11 ` [PATCH RFC net-next 02/10] net: bridge: Always multicast_flood Reports Joseph Huang
2024-04-03 15:52 ` Simon Horman
2024-04-02 0:11 ` [PATCH RFC net-next 03/10] net: bridge: Always flood local subnet mc packets Joseph Huang
2024-04-02 0:11 ` [PATCH RFC net-next 04/10] net: dsa: mv88e6xxx: Add all hosts mc addr to ATU Joseph Huang
2024-04-02 18:08 ` Vladimir Oltean
2024-04-02 0:11 ` [PATCH RFC net-next 05/10] net: dsa: Add support for PORT_MROUTER attribute Joseph Huang
2024-04-02 0:11 ` [PATCH RFC net-next 06/10] net: dsa: mv88e6xxx: Track soft bridge objects Joseph Huang
2024-04-02 0:11 ` Joseph Huang [this message]
2024-04-02 12:23 ` [PATCH RFC net-next 07/10] net: dsa: mv88e6xxx: Track bridge mdb objects Vladimir Oltean
2024-04-04 20:43 ` Joseph Huang
2024-04-05 11:07 ` Vladimir Oltean
2024-04-05 18:58 ` Joseph Huang
2024-04-29 22:07 ` Joseph Huang
2024-04-30 0:59 ` Vladimir Oltean
2024-04-30 16:27 ` Joseph Huang
2024-05-02 20:37 ` Joseph Huang
2024-04-02 0:11 ` [PATCH RFC net-next 08/10] net: dsa: mv88e6xxx: Convert MAB to use bit flags Joseph Huang
2024-04-02 0:11 ` [PATCH RFC net-next 09/10] net: dsa: mv88e6xxx: Enable mc flood for mrouter port Joseph Huang
2024-04-03 15:49 ` Simon Horman
2024-04-02 0:11 ` [PATCH RFC net-next 10/10] net: dsa: mv88e6xxx: Offload " Joseph Huang
2024-04-02 9:28 ` [PATCH RFC net-next 00/10] MC Flood disable and snooping Nikolay Aleksandrov
2024-04-02 17:43 ` Vladimir Oltean
2024-04-02 18:50 ` Nikolay Aleksandrov
2024-04-02 20:46 ` Vladimir Oltean
2024-04-02 21:59 ` Nikolay Aleksandrov
2024-04-04 22:16 ` Joseph Huang
2024-04-05 10:20 ` Vladimir Oltean
2024-04-05 11:00 ` Nikolay Aleksandrov
2024-04-05 20:22 ` Joseph Huang
2024-04-05 21:15 ` Vladimir Oltean
2024-04-29 20:14 ` Joseph Huang
2024-04-30 1:21 ` Vladimir Oltean
2024-04-30 17:01 ` Joseph Huang
2024-05-02 12:12 ` Nikolay Aleksandrov
2025-02-26 20:20 ` Linus Lüssing
2025-02-26 22:17 ` Linus Lüssing
2024-04-02 12:43 ` Andrew Lunn
2024-04-04 21:35 ` Joseph Huang
2024-04-04 22:11 ` Andrew Lunn
2024-04-04 22:40 ` Joseph Huang
2024-04-05 13:09 ` Andrew Lunn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240402001137.2980589-8-Joseph.Huang@garmin.com \
--to=joseph.huang@garmin.com \
--cc=andrew@lunn.ch \
--cc=bridge@lists.linux.dev \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=f.fainelli@gmail.com \
--cc=kuba@kernel.org \
--cc=linus.luessing@c0d3.blue \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=pabeni@redhat.com \
--cc=razor@blackwall.org \
--cc=roopa@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox