ec10bdc2d98b52278a0e61df22be5c3242155ba6
[openwrt/openwrt.git] / package / kernel / qca-nss-dp / patches / 0009-nss-dp-switchdev-fix-FDB-roaming.patch
1 From 25ca3308edb67aa0c6c70b83edf0e22b8ae7533f Mon Sep 17 00:00:00 2001
2 From: Robert Marko <robimarko@gmail.com>
3 Date: Thu, 29 Jun 2023 13:52:58 +0200
4 Subject: [PATCH] nss-dp: switchdev: fix FDB roaming
5
6 Try and solve the roaming issue by trying to replicate what NSS bridge
7 module is doing, but by utilizing switchdev FDB notifiers instead of
8 adding new notifiers to the bridge code.
9
10 We register a new non-blocking switchdev notifier and simply wait for
11 notification, and then process the SWITCHDEV_FDB_DEL_TO_DEVICE
12 notifications.
13
14 Those tell us that a certain FDB entry should be removed, then a VSI ID
15 is fetched for the physical PPE port and using that VSI ID and the
16 notification provided MAC adress existing FDB entry gets removed.
17
18 Signed-off-by: Robert Marko <robimarko@gmail.com>
19 ---
20 nss_dp_switchdev.c | 73 +++++++++++++++++++++++++++++++++++++++++++++-
21 1 file changed, 72 insertions(+), 1 deletion(-)
22
23 --- a/nss_dp_switchdev.c
24 +++ b/nss_dp_switchdev.c
25 @@ -29,6 +29,8 @@
26 #include "nss_dp_dev.h"
27 #include "fal/fal_stp.h"
28 #include "fal/fal_ctrlpkt.h"
29 +#include "fal/fal_fdb.h"
30 +#include "ref/ref_vsi.h"
31
32 #define NSS_DP_SWITCH_ID 0
33 #define NSS_DP_SW_ETHTYPE_PID 0 /* PPE ethtype profile ID for slow protocols */
34 @@ -521,7 +523,76 @@ static struct notifier_block *nss_dp_sw_
35
36 #else
37
38 -static struct notifier_block *nss_dp_sw_ev_nb;
39 +/*
40 + * nss_dp_switchdev_fdb_del_event
41 + *
42 + * Used for EDMA v1 to remove old MAC in order to preventing having
43 + * duplicate MAC entries in FDB thus and avoid roaming issues.
44 + */
45 +
46 +static int nss_dp_switchdev_fdb_del_event(struct net_device *netdev,
47 + struct switchdev_notifier_fdb_info *fdb_info)
48 +{
49 + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev);
50 + fal_fdb_entry_t entry;
51 + a_uint32_t vsi_id;
52 + sw_error_t rv;
53 +
54 + netdev_dbg(netdev, "FDB DEL %pM port %d\n", fdb_info->addr, dp_priv->macid);
55 +
56 + rv = ppe_port_vsi_get(NSS_DP_SWITCH_ID, dp_priv->macid, &vsi_id);
57 + if (rv) {
58 + netdev_err(netdev, "cannot get VSI ID for port %d\n", dp_priv->macid);
59 + return notifier_from_errno(rv);
60 + }
61 +
62 + memset(&entry, 0, sizeof(entry));
63 + memcpy(&entry.addr, fdb_info->addr, ETH_ALEN);
64 + entry.fid = vsi_id;
65 +
66 + rv = fal_fdb_entry_del_bymac(NSS_DP_SWITCH_ID, &entry);
67 + if (rv) {
68 + netdev_err(netdev, "FDB entry delete failed with MAC %pM and fid %d\n",
69 + &entry.addr, entry.fid);
70 + return notifier_from_errno(rv);
71 + }
72 +
73 + return notifier_from_errno(rv);
74 +}
75 +
76 +/*
77 + * nss_dp_switchdev_event_nb
78 + *
79 + * Non blocking switchdev event for netdevice.
80 + * Used for EDMA v1 to remove old MAC and avoid roaming issues.
81 + */
82 +static int nss_dp_switchdev_event_nb(struct notifier_block *unused,
83 + unsigned long event, void *ptr)
84 +{
85 + struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
86 +
87 + /*
88 + * Handle switchdev event only for physical devices
89 + */
90 + if (!nss_dp_is_phy_dev(dev)) {
91 + return NOTIFY_DONE;
92 + }
93 +
94 + switch (event) {
95 + case SWITCHDEV_FDB_DEL_TO_DEVICE:
96 + return nss_dp_switchdev_fdb_del_event(dev, ptr);
97 + default:
98 + netdev_dbg(dev, "Switchdev event %lu is not supported\n", event);
99 + }
100 +
101 + return NOTIFY_DONE;
102 +}
103 +
104 +static struct notifier_block nss_dp_switchdev_notifier_nb = {
105 + .notifier_call = nss_dp_switchdev_event_nb,
106 +};
107 +
108 +static struct notifier_block *nss_dp_sw_ev_nb = &nss_dp_switchdev_notifier_nb;
109
110 /*
111 * nss_dp_bridge_attr_set()