diff options
Diffstat (limited to 'package/kernel/qca-nss-dp/patches/0010-switchdev-fix-FDB-roaming.patch')
-rw-r--r-- | package/kernel/qca-nss-dp/patches/0010-switchdev-fix-FDB-roaming.patch | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/package/kernel/qca-nss-dp/patches/0010-switchdev-fix-FDB-roaming.patch b/package/kernel/qca-nss-dp/patches/0010-switchdev-fix-FDB-roaming.patch new file mode 100644 index 0000000000..19395ac42c --- /dev/null +++ b/package/kernel/qca-nss-dp/patches/0010-switchdev-fix-FDB-roaming.patch @@ -0,0 +1,110 @@ +From d16102cad769f430144ca8094d928762b445e9b0 Mon Sep 17 00:00:00 2001 +From: Robert Marko <robimarko@gmail.com> +Date: Fri, 18 Mar 2022 22:02:01 +0100 +Subject: [PATCH] switchdev: fix FDB roaming + +Try and solve the roaming issue by trying to replicate what NSS bridge +module is doing, but by utilizing switchdev FDB notifiers instead of +adding new notifiers to the bridge code. + +We register a new non-blocking switchdev notifier and simply wait for +notification, and then process the SWITCHDEV_FDB_DEL_TO_DEVICE +notifications. + +Those tell us that a certain FDB entry should be removed, then a VSI ID +is fetched for the physical PPE port and using that VSI ID and the +notification provided MAC adress existing FDB entry gets removed. + +Signed-off-by: Robert Marko <robimarko@gmail.com> +--- + nss_dp_switchdev.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 61 insertions(+) + +--- a/nss_dp_switchdev.c ++++ b/nss_dp_switchdev.c +@@ -24,6 +24,8 @@ + #include "nss_dp_dev.h" + #include "fal/fal_stp.h" + #include "fal/fal_ctrlpkt.h" ++#include "fal/fal_fdb.h" ++#include "ref/ref_vsi.h" + + #define NSS_DP_SWITCH_ID 0 + #define NSS_DP_SW_ETHTYPE_PID 0 /* PPE ethtype profile ID for slow protocols */ +@@ -348,10 +350,64 @@ static int nss_dp_switchdev_event(struct + return NOTIFY_DONE; + } + ++static int nss_dp_switchdev_fdb_del_event(struct net_device *netdev, ++ struct switchdev_notifier_fdb_info *fdb_info) ++{ ++ struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); ++ fal_fdb_entry_t entry; ++ a_uint32_t vsi_id; ++ sw_error_t rv; ++ ++ netdev_dbg(netdev, "FDB DEL %pM port %d\n", fdb_info->addr, dp_priv->macid); ++ ++ rv = ppe_port_vsi_get(NSS_DP_SWITCH_ID, dp_priv->macid, &vsi_id); ++ if (rv) { ++ netdev_err(netdev, "cannot get VSI ID for port %d\n", dp_priv->macid); ++ return notifier_from_errno(rv); ++ } ++ ++ memset(&entry, 0, sizeof(entry)); ++ memcpy(&entry.addr, fdb_info->addr, ETH_ALEN); ++ entry.fid = vsi_id; ++ ++ rv = fal_fdb_entry_del_bymac(NSS_DP_SWITCH_ID, &entry); ++ if (rv) { ++ netdev_err(netdev, "FDB entry delete failed with MAC %pM and fid %d\n", ++ &entry.addr, entry.fid); ++ return notifier_from_errno(rv); ++ } ++ ++ return notifier_from_errno(rv); ++} ++ ++static int nss_dp_fdb_switchdev_event(struct notifier_block *nb, ++ unsigned long event, void *ptr) ++{ ++ struct net_device *dev = switchdev_notifier_info_to_dev(ptr); ++ ++ /* ++ * Handle switchdev event only for physical devices ++ */ ++ if (!nss_dp_is_phy_dev(dev)) { ++ return NOTIFY_DONE; ++ } ++ ++ switch (event) { ++ case SWITCHDEV_FDB_DEL_TO_DEVICE: ++ return nss_dp_switchdev_fdb_del_event(dev, ptr); ++ } ++ ++ return NOTIFY_DONE; ++} ++ + static struct notifier_block nss_dp_switchdev_notifier = { + .notifier_call = nss_dp_switchdev_event, + }; + ++static struct notifier_block nss_dp_switchdev_fdb_notifier = { ++ .notifier_call = nss_dp_fdb_switchdev_event, ++}; ++ + static bool switch_init_done; + + /* +@@ -366,6 +422,11 @@ void nss_dp_switchdev_setup(struct net_d + return; + } + ++ err = register_switchdev_notifier(&nss_dp_switchdev_fdb_notifier); ++ if (err) { ++ netdev_dbg(dev, "%px:Failed to register switchdev FDB notifier\n", dev); ++ } ++ + err = register_switchdev_blocking_notifier(&nss_dp_switchdev_notifier); + if (err) { + netdev_dbg(dev, "%px:Failed to register switchdev notifier\n", dev); |