From: Ioana Ciornei <ioana.ciornei@nxp.com>
To: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH net-next 04/13] dpaa2-switch: extend dpaa2_switch_port_set_fdb() to cover bond scenarios
Date: Wed, 6 May 2026 18:15:31 +0300 [thread overview]
Message-ID: <20260506151540.1242997-5-ioana.ciornei@nxp.com> (raw)
In-Reply-To: <20260506151540.1242997-1-ioana.ciornei@nxp.com>
The dpaa2_switch_port_set_fdb() function is responsible with determining
what FDB should be used by a port as a consequence of changing its upper
device. This patch extends the function to also cover the circumstances
in which a DPAA2 switch port offloads a bond device.
This will allow us, for example, to setup the same FDB on all DPAA2
switch ports which are under the same bridge, even though not directly
but rather through an upper bond device which is bridged. How the
function does this is by first determining a DPAA2 port is already under
the same bridge and if so, choosing its FDB. To cover the entire
hierarchy in depth, we add an extra walk through all the lowers of a
bridged bond device.
When leaving an upper device, the DPAA2 switch port must find a new FDB
to use. If before it just searched for an unused FDB to go along with
its new standalone status, now it first checks if the port is still part
of a LAG and then uses the FDB of any port that already left the same
bridge.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
.../ethernet/freescale/dpaa2/dpaa2-switch.c | 102 +++++++++++++-----
1 file changed, 78 insertions(+), 24 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
index f1b4c24b8a47..9d3a0aef1568 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
@@ -66,28 +66,59 @@ static void dpaa2_switch_port_set_fdb(struct ethsw_port_priv *port_priv,
struct net_device *upper_dev,
bool linking)
{
+ struct ethsw_core *ethsw = port_priv->ethsw_data;
struct ethsw_port_priv *other_port_priv = NULL;
- struct dpaa2_switch_fdb *fdb;
- struct net_device *other_dev;
- struct list_head *iter;
+ struct net_device *other_dev, *other_dev2;
+ u16 fdb_id_old = port_priv->fdb->fdb_id;
+ struct dpaa2_switch_fdb *fdb = NULL;
+ struct list_head *iter, *iter2;
+ int i;
- /* If we leave a bridge, find an unused FDB and use that. */
+ /* If we leave a an upper device, be it a bond or a bridge, find an
+ * unused FDB and use that.
+ */
if (!linking) {
- fdb = dpaa2_switch_fdb_get_unused(port_priv->ethsw_data);
-
- /* If there is no unused FDB, we must be the last port that
- * leaves the last bridge, all the others are standalone. We
- * can just keep the FDB that we already have.
+ /* This port leaves a bridge, but it's still under a bond.
+ * Search for the first port under the same bond which already
+ * left the bridge.
*/
+ if (netif_is_bridge_master(upper_dev) && port_priv->lag) {
+ for (i = 0; i < ethsw->sw_attr.num_ifs; i++) {
+ other_port_priv = ethsw->ports[i];
+ if (!other_port_priv)
+ continue;
+
+ if (other_port_priv == port_priv)
+ continue;
+
+ /* Found a port which is under the same bond
+ * device but already left the bridge. Use
+ * this port's FDB.
+ */
+ if (other_port_priv->lag == port_priv->lag &&
+ other_port_priv->fdb->fdb_id != fdb_id_old) {
+ fdb = other_port_priv->fdb;
+ break;
+ }
+ }
+ }
- if (!fdb) {
- port_priv->fdb->bridge_dev = NULL;
- return;
+ /* Try to get hold of an unused FDB to use */
+ if (!fdb)
+ fdb = dpaa2_switch_fdb_get_unused(port_priv->ethsw_data);
+
+ if (fdb) {
+ port_priv->fdb = fdb;
+ port_priv->fdb->in_use = true;
}
- port_priv->fdb = fdb;
- port_priv->fdb->in_use = true;
- port_priv->fdb->bridge_dev = NULL;
+ if (netif_is_bridge_master(upper_dev))
+ port_priv->fdb->bridge_dev = NULL;
+
+ /* In case all FDBs are already in use, we must be the last
+ * port that becomes standalone. We can just keep the FDB that
+ * we already have. Nothing more to do in this case.
+ */
return;
}
@@ -97,18 +128,40 @@ static void dpaa2_switch_port_set_fdb(struct ethsw_port_priv *port_priv,
*/
ASSERT_RTNL();
- /* If part of a bridge, use the FDB of the first dpaa2 switch interface
- * to be present in that bridge
+ /* In case we are joining an upper device, be it a bridge device or a
+ * bond device, we will use the FDB of the first DPAA2 switch interface
+ * that is already present under the same upper device. For this to
+ * happen we have to extend our search so that we can find any DPAA2
+ * interface that is a lower of a bond bridged port
*/
+ other_port_priv = NULL;
netdev_for_each_lower_dev(upper_dev, other_dev, iter) {
- if (!dpaa2_switch_port_dev_check(other_dev))
- continue;
+ if (netif_is_lag_master(other_dev)) {
+ /* Search through all the lowers of the bridged lag */
+ netdev_for_each_lower_dev(other_dev, other_dev2, iter2) {
+ if (!dpaa2_switch_port_dev_check(other_dev2))
+ continue;
+ if (other_dev2 == port_priv->netdev)
+ continue;
+
+ /* Skip the port if it's the same upper */
+ other_port_priv = netdev_priv(other_dev2);
+ if (other_port_priv->lag == port_priv->lag) {
+ other_port_priv = NULL;
+ continue;
+ }
+ break;
+ }
- if (other_dev == port_priv->netdev)
- continue;
+ if (other_port_priv)
+ break;
+ } else if (dpaa2_switch_port_dev_check(other_dev)) {
+ if (other_dev == port_priv->netdev)
+ continue;
- other_port_priv = netdev_priv(other_dev);
- break;
+ other_port_priv = netdev_priv(other_dev);
+ break;
+ }
}
/* The current port is about to change its FDB to the one used by the
@@ -126,7 +179,8 @@ static void dpaa2_switch_port_set_fdb(struct ethsw_port_priv *port_priv,
}
/* Keep track of the new upper bridge device */
- port_priv->fdb->bridge_dev = upper_dev;
+ if (netif_is_bridge_master(upper_dev))
+ port_priv->fdb->bridge_dev = upper_dev;
}
static void dpaa2_switch_fdb_get_flood_cfg(struct ethsw_core *ethsw, u16 fdb_id,
--
2.25.1
next prev parent reply other threads:[~2026-05-06 15:16 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-06 15:15 [PATCH net-next 00/13] dpaa2-switch: add support for LAG offload Ioana Ciornei
2026-05-06 15:15 ` [PATCH net-next 01/13] dpaa2-switch: add LAG configuration API Ioana Ciornei
2026-05-06 15:15 ` [PATCH net-next 02/13] dpaa2-switch: add support for LAG offload Ioana Ciornei
2026-05-08 12:39 ` Ioana Ciornei
2026-05-06 15:15 ` [PATCH net-next 03/13] dpaa2-switch: change dpaa2_switch_port_set_fdb() function prototype Ioana Ciornei
2026-05-08 11:00 ` Ioana Ciornei
2026-05-06 15:15 ` Ioana Ciornei [this message]
2026-05-08 13:50 ` [PATCH net-next 04/13] dpaa2-switch: extend dpaa2_switch_port_set_fdb() to cover bond scenarios Ioana Ciornei
2026-05-06 15:15 ` [PATCH net-next 05/13] dpaa2-switch: add dpaa2_switch_port_to_bridge_port() helper Ioana Ciornei
2026-05-08 14:10 ` [PATCH net-next 05/13] dpaa2-switch: add dpaa2_switch_port_to_bridge_port() helpe Ioana Ciornei
2026-05-06 15:15 ` [PATCH net-next 06/13] dpaa2-switch: create a separate dpaa2_switch_port_fdb_event() function Ioana Ciornei
2026-05-06 15:15 ` [PATCH net-next 07/13] dpaa2-switch: check early if an FDB entry should be added Ioana Ciornei
2026-05-08 14:34 ` Ioana Ciornei
2026-05-06 15:15 ` [PATCH net-next 08/13] dpaa2-switch: consolidate unicast and multicast management Ioana Ciornei
2026-05-08 14:46 ` Ioana Ciornei
2026-05-06 15:15 ` [PATCH net-next 09/13] dpaa2-switch: offload FDBs added on an upper bond device Ioana Ciornei
2026-05-08 15:20 ` Ioana Ciornei
2026-05-06 15:15 ` [PATCH net-next 10/13] dpaa2-switch: offload port objects " Ioana Ciornei
2026-05-11 9:07 ` Ioana Ciornei
2026-05-06 15:15 ` [PATCH net-next 11/13] dpaa2-switch: trap all link local reserved addresses to the CPU Ioana Ciornei
2026-05-06 15:15 ` [PATCH net-next 12/13] dpaa2-switch: add support for imprecise source port Ioana Ciornei
2026-05-07 11:42 ` Ioana Ciornei
2026-05-11 11:32 ` Ioana Ciornei
2026-05-06 15:15 ` [PATCH net-next 13/13] dpaa2-switch: do not error out when the same VLAN is installed multiple times Ioana Ciornei
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=20260506151540.1242997-5-ioana.ciornei@nxp.com \
--to=ioana.ciornei@nxp.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.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