mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 15:32:33 +00:00
2558e7b443
Qualcomm NSS-DP is as its name says Qualcomms ethernet driver for the NSS subsystem (Networking subsystem) built-into various Qualcomm SoCs. It has 2 modes of operation: * Without NSS FW and rest of code required for offloading This is the one that we will use as the amount of kernel patching required for NSS offloading and the fact that its not upstreamable at all makes it unusable for us. Driver in this mode is rather basic, it currently only offers NAPI GRO (Added by us as part of the fixup) and basically relies on the powerfull CPU to get good throughput. * With NSS FW and rest of code required for offloading In this mode, driver just registers the interfaces and hooks them into NSS-ECM to allow offloading. This mode is not viable for use in OpenWrt due to reasons already described above. This driver is required for ipq807x to have wired networking until a better one is available, so lets add the fixed-up version for 5.15 for now. Signed-off-by: Robert Marko <robimarko@gmail.com>
111 lines
3.2 KiB
Diff
111 lines
3.2 KiB
Diff
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);
|