Commit e9a5073a authored by Michael Dege's avatar Michael Dege Committed by Paolo Abeni
Browse files

net: renesas: rswitch: fix forwarding offload statemachine



A change of the port state of one port, caused the state of another
port to change. This behvior was unintended.

Fixes: b7502b10 ("net: renesas: rswitch: add offloading for L2 switching")
Signed-off-by: default avatarMichael Dege <michael.dege@renesas.com>
Link: https://patch.msgid.link/20260206-fix-offloading-statemachine-v3-1-07bfba07d03e@renesas.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent cdb1634d
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/* Renesas Ethernet Switch device driver
 *
 * Copyright (C) 2025 Renesas Electronics Corporation
 * Copyright (C) 2025 - 2026 Renesas Electronics Corporation
 */

#include <linux/err.h>
@@ -60,6 +60,7 @@ static void rswitch_update_l2_hw_learning(struct rswitch_private *priv)
static void rswitch_update_l2_hw_forwarding(struct rswitch_private *priv)
{
	struct rswitch_device *rdev;
	bool new_forwarding_offload;
	unsigned int fwd_mask;

	/* calculate fwd_mask with zeroes in bits corresponding to ports that
@@ -73,8 +74,9 @@ static void rswitch_update_l2_hw_forwarding(struct rswitch_private *priv)
	}

	rswitch_for_all_ports(priv, rdev) {
		if ((rdev_for_l2_offload(rdev) && rdev->forwarding_requested) ||
		    rdev->forwarding_offloaded) {
		new_forwarding_offload = (rdev_for_l2_offload(rdev) && rdev->forwarding_requested);

		if (new_forwarding_offload || rdev->forwarding_offloaded) {
			/* Update allowed offload destinations even for ports
			 * with L2 offload enabled earlier.
			 *
@@ -84,15 +86,12 @@ static void rswitch_update_l2_hw_forwarding(struct rswitch_private *priv)
				  priv->addr + FWPC2(rdev->port));
		}

		if (rdev_for_l2_offload(rdev) &&
		    rdev->forwarding_requested &&
		    !rdev->forwarding_offloaded) {
		if (new_forwarding_offload && !rdev->forwarding_offloaded)
			rswitch_change_l2_hw_offloading(rdev, true, false);
		} else if (rdev->forwarding_offloaded) {
		else if (!new_forwarding_offload && rdev->forwarding_offloaded)
			rswitch_change_l2_hw_offloading(rdev, false, false);
	}
}
}

void rswitch_update_l2_offload(struct rswitch_private *priv)
{