--- /dev/null
+From 4bf24ad09bc0b05e97fb48b962b2c9246fc76727 Mon Sep 17 00:00:00 2001
+From: "Hans J. Schultz" <netdev@kapio-technology.com>
+Date: Fri, 9 Dec 2022 19:28:15 +0200
+Subject: net: dsa: mv88e6xxx: read FID when handling ATU violations
+
+From: Hans J. Schultz <netdev@kapio-technology.com>
+
+commit 4bf24ad09bc0b05e97fb48b962b2c9246fc76727 upstream.
+
+When an ATU violation occurs, the switch uses the ATU FID register to
+report the FID of the MAC address that incurred the violation. It would
+be good for the driver to know the FID value for purposes such as
+logging and CPU-based authentication.
+
+Up until now, the driver has been calling the mv88e6xxx_g1_atu_op()
+function to read ATU violations, but that doesn't do exactly what we
+want, namely it calls mv88e6xxx_g1_atu_fid_write() with FID 0.
+(side note, the documentation for the ATU Get/Clear Violation command
+says that writes to the ATU FID register have no effect before the
+operation starts, it's only that we disregard the value that this
+register provides once the operation completes)
+
+So mv88e6xxx_g1_atu_fid_write() is not what we want, but rather
+mv88e6xxx_g1_atu_fid_read(). However, the latter doesn't exist, we need
+to write it.
+
+The remainder of mv88e6xxx_g1_atu_op() except for
+mv88e6xxx_g1_atu_fid_write() is still needed, namely to send a
+GET_CLR_VIOLATION command to the ATU. In principle we could have still
+kept calling mv88e6xxx_g1_atu_op(), but the MDIO writes to the ATU FID
+register are pointless, but in the interest of doing less CPU work per
+interrupt, write a new function called mv88e6xxx_g1_read_atu_violation()
+and call it.
+
+The FID will be the port default FID as set by mv88e6xxx_port_set_fid()
+if the VID from the packet cannot be found in the VTU. Otherwise it is
+the FID derived from the VTU entry associated with that VID.
+
+Signed-off-by: Hans J. Schultz <netdev@kapio-technology.com>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Cc: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/dsa/mv88e6xxx/global1_atu.c | 72 +++++++++++++++++++++++++++-----
+ 1 file changed, 61 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/dsa/mv88e6xxx/global1_atu.c
++++ b/drivers/net/dsa/mv88e6xxx/global1_atu.c
+@@ -114,6 +114,19 @@ static int mv88e6xxx_g1_atu_op_wait(stru
+ return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_ATU_OP, bit, 0);
+ }
+
++static int mv88e6xxx_g1_read_atu_violation(struct mv88e6xxx_chip *chip)
++{
++ int err;
++
++ err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_ATU_OP,
++ MV88E6XXX_G1_ATU_OP_BUSY |
++ MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION);
++ if (err)
++ return err;
++
++ return mv88e6xxx_g1_atu_op_wait(chip);
++}
++
+ static int mv88e6xxx_g1_atu_op(struct mv88e6xxx_chip *chip, u16 fid, u16 op)
+ {
+ u16 val;
+@@ -159,6 +172,41 @@ int mv88e6xxx_g1_atu_get_next(struct mv8
+ return mv88e6xxx_g1_atu_op(chip, fid, MV88E6XXX_G1_ATU_OP_GET_NEXT_DB);
+ }
+
++static int mv88e6xxx_g1_atu_fid_read(struct mv88e6xxx_chip *chip, u16 *fid)
++{
++ u16 val = 0, upper = 0, op = 0;
++ int err = -EOPNOTSUPP;
++
++ if (mv88e6xxx_num_databases(chip) > 256) {
++ err = mv88e6xxx_g1_read(chip, MV88E6352_G1_ATU_FID, &val);
++ val &= 0xfff;
++ if (err)
++ return err;
++ } else {
++ err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_OP, &op);
++ if (err)
++ return err;
++ if (mv88e6xxx_num_databases(chip) > 64) {
++ /* ATU DBNum[7:4] are located in ATU Control 15:12 */
++ err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_CTL,
++ &upper);
++ if (err)
++ return err;
++
++ upper = (upper >> 8) & 0x00f0;
++ } else if (mv88e6xxx_num_databases(chip) > 16) {
++ /* ATU DBNum[5:4] are located in ATU Operation 9:8 */
++ upper = (op >> 4) & 0x30;
++ }
++
++ /* ATU DBNum[3:0] are located in ATU Operation 3:0 */
++ val = (op & 0xf) | upper;
++ }
++ *fid = val;
++
++ return err;
++}
++
+ /* Offset 0x0C: ATU Data Register */
+
+ static int mv88e6xxx_g1_atu_data_read(struct mv88e6xxx_chip *chip,
+@@ -353,14 +401,12 @@ static irqreturn_t mv88e6xxx_g1_atu_prob
+ {
+ struct mv88e6xxx_chip *chip = dev_id;
+ struct mv88e6xxx_atu_entry entry;
+- int spid;
+- int err;
+- u16 val;
++ int err, spid;
++ u16 val, fid;
+
+ mv88e6xxx_reg_lock(chip);
+
+- err = mv88e6xxx_g1_atu_op(chip, 0,
+- MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION);
++ err = mv88e6xxx_g1_read_atu_violation(chip);
+ if (err)
+ goto out;
+
+@@ -368,6 +414,10 @@ static irqreturn_t mv88e6xxx_g1_atu_prob
+ if (err)
+ goto out;
+
++ err = mv88e6xxx_g1_atu_fid_read(chip, &fid);
++ if (err)
++ goto out;
++
+ err = mv88e6xxx_g1_atu_data_read(chip, &entry);
+ if (err)
+ goto out;
+@@ -386,22 +436,22 @@ static irqreturn_t mv88e6xxx_g1_atu_prob
+
+ if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) {
+ dev_err_ratelimited(chip->dev,
+- "ATU member violation for %pM portvec %x spid %d\n",
+- entry.mac, entry.portvec, spid);
++ "ATU member violation for %pM fid %u portvec %x spid %d\n",
++ entry.mac, fid, entry.portvec, spid);
+ chip->ports[spid].atu_member_violation++;
+ }
+
+ if (val & MV88E6XXX_G1_ATU_OP_MISS_VIOLATION) {
+ dev_err_ratelimited(chip->dev,
+- "ATU miss violation for %pM portvec %x spid %d\n",
+- entry.mac, entry.portvec, spid);
++ "ATU miss violation for %pM fid %u portvec %x spid %d\n",
++ entry.mac, fid, entry.portvec, spid);
+ chip->ports[spid].atu_miss_violation++;
+ }
+
+ if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION) {
+ dev_err_ratelimited(chip->dev,
+- "ATU full violation for %pM portvec %x spid %d\n",
+- entry.mac, entry.portvec, spid);
++ "ATU full violation for %pM fid %u portvec %x spid %d\n",
++ entry.mac, fid, entry.portvec, spid);
+ chip->ports[spid].atu_full_violation++;
+ }
+ mv88e6xxx_reg_unlock(chip);
--- /dev/null
+From 8646384d80f3d3b4a66b3284dbbd8232d1b8799e Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Fri, 9 Dec 2022 19:28:16 +0200
+Subject: net: dsa: mv88e6xxx: replace ATU violation prints with trace points
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+commit 8646384d80f3d3b4a66b3284dbbd8232d1b8799e upstream.
+
+In applications where the switch ports must perform 802.1X based
+authentication and are therefore locked, ATU violation interrupts are
+quite to be expected as part of normal operation. The problem is that
+they currently spam the kernel log, even if rate limited.
+
+Create a series of trace points, all derived from the same event class,
+which log these violations to the kernel's trace buffer, which is both
+much faster and much easier to ignore than printing to a serial console.
+
+New usage model:
+
+$ trace-cmd list | grep mv88e6xxx
+mv88e6xxx
+mv88e6xxx:mv88e6xxx_atu_full_violation
+mv88e6xxx:mv88e6xxx_atu_miss_violation
+mv88e6xxx:mv88e6xxx_atu_member_violation
+$ trace-cmd record -e mv88e6xxx sleep 10
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Saeed Mahameed <saeed@kernel.org>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Cc: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/dsa/mv88e6xxx/Makefile | 4 +
+ drivers/net/dsa/mv88e6xxx/global1_atu.c | 19 ++++-----
+ drivers/net/dsa/mv88e6xxx/trace.c | 6 ++
+ drivers/net/dsa/mv88e6xxx/trace.h | 66 ++++++++++++++++++++++++++++++++
+ 4 files changed, 86 insertions(+), 9 deletions(-)
+ create mode 100644 drivers/net/dsa/mv88e6xxx/trace.c
+ create mode 100644 drivers/net/dsa/mv88e6xxx/trace.h
+
+--- a/drivers/net/dsa/mv88e6xxx/Makefile
++++ b/drivers/net/dsa/mv88e6xxx/Makefile
+@@ -15,3 +15,7 @@ mv88e6xxx-objs += port_hidden.o
+ mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += ptp.o
+ mv88e6xxx-objs += serdes.o
+ mv88e6xxx-objs += smi.o
++mv88e6xxx-objs += trace.o
++
++# for tracing framework to find trace.h
++CFLAGS_trace.o := -I$(src)
+--- a/drivers/net/dsa/mv88e6xxx/global1_atu.c
++++ b/drivers/net/dsa/mv88e6xxx/global1_atu.c
+@@ -12,6 +12,7 @@
+
+ #include "chip.h"
+ #include "global1.h"
++#include "trace.h"
+
+ /* Offset 0x01: ATU FID Register */
+
+@@ -435,23 +436,23 @@ static irqreturn_t mv88e6xxx_g1_atu_prob
+ }
+
+ if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) {
+- dev_err_ratelimited(chip->dev,
+- "ATU member violation for %pM fid %u portvec %x spid %d\n",
+- entry.mac, fid, entry.portvec, spid);
++ trace_mv88e6xxx_atu_member_violation(chip->dev, spid,
++ entry.portvec, entry.mac,
++ fid);
+ chip->ports[spid].atu_member_violation++;
+ }
+
+ if (val & MV88E6XXX_G1_ATU_OP_MISS_VIOLATION) {
+- dev_err_ratelimited(chip->dev,
+- "ATU miss violation for %pM fid %u portvec %x spid %d\n",
+- entry.mac, fid, entry.portvec, spid);
++ trace_mv88e6xxx_atu_miss_violation(chip->dev, spid,
++ entry.portvec, entry.mac,
++ fid);
+ chip->ports[spid].atu_miss_violation++;
+ }
+
+ if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION) {
+- dev_err_ratelimited(chip->dev,
+- "ATU full violation for %pM fid %u portvec %x spid %d\n",
+- entry.mac, fid, entry.portvec, spid);
++ trace_mv88e6xxx_atu_full_violation(chip->dev, spid,
++ entry.portvec, entry.mac,
++ fid);
+ chip->ports[spid].atu_full_violation++;
+ }
+ mv88e6xxx_reg_unlock(chip);
+--- /dev/null
++++ b/drivers/net/dsa/mv88e6xxx/trace.c
+@@ -0,0 +1,6 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/* Copyright 2022 NXP
++ */
++
++#define CREATE_TRACE_POINTS
++#include "trace.h"
+--- /dev/null
++++ b/drivers/net/dsa/mv88e6xxx/trace.h
+@@ -0,0 +1,66 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later */
++/* Copyright 2022 NXP
++ */
++
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM mv88e6xxx
++
++#if !defined(_MV88E6XXX_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
++#define _MV88E6XXX_TRACE_H
++
++#include <linux/device.h>
++#include <linux/if_ether.h>
++#include <linux/tracepoint.h>
++
++DECLARE_EVENT_CLASS(mv88e6xxx_atu_violation,
++
++ TP_PROTO(const struct device *dev, int spid, u16 portvec,
++ const unsigned char *addr, u16 fid),
++
++ TP_ARGS(dev, spid, portvec, addr, fid),
++
++ TP_STRUCT__entry(
++ __string(name, dev_name(dev))
++ __field(int, spid)
++ __field(u16, portvec)
++ __array(unsigned char, addr, ETH_ALEN)
++ __field(u16, fid)
++ ),
++
++ TP_fast_assign(
++ __assign_str(name, dev_name(dev));
++ __entry->spid = spid;
++ __entry->portvec = portvec;
++ memcpy(__entry->addr, addr, ETH_ALEN);
++ __entry->fid = fid;
++ ),
++
++ TP_printk("dev %s spid %d portvec 0x%x addr %pM fid %u",
++ __get_str(name), __entry->spid, __entry->portvec,
++ __entry->addr, __entry->fid)
++);
++
++DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_member_violation,
++ TP_PROTO(const struct device *dev, int spid, u16 portvec,
++ const unsigned char *addr, u16 fid),
++ TP_ARGS(dev, spid, portvec, addr, fid));
++
++DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_miss_violation,
++ TP_PROTO(const struct device *dev, int spid, u16 portvec,
++ const unsigned char *addr, u16 fid),
++ TP_ARGS(dev, spid, portvec, addr, fid));
++
++DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_full_violation,
++ TP_PROTO(const struct device *dev, int spid, u16 portvec,
++ const unsigned char *addr, u16 fid),
++ TP_ARGS(dev, spid, portvec, addr, fid));
++
++#endif /* _MV88E6XXX_TRACE_H */
++
++/* We don't want to use include/trace/events */
++#undef TRACE_INCLUDE_PATH
++#define TRACE_INCLUDE_PATH .
++#undef TRACE_INCLUDE_FILE
++#define TRACE_INCLUDE_FILE trace
++/* This part must be outside protection */
++#include <trace/define_trace.h>
--- /dev/null
+From 9e3d9ae52b5657399a7b61258cc7482434a911bb Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Fri, 9 Dec 2022 19:28:17 +0200
+Subject: net: dsa: mv88e6xxx: replace VTU violation prints with trace points
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+commit 9e3d9ae52b5657399a7b61258cc7482434a911bb upstream.
+
+It is possible to trigger these VTU violation messages very easily,
+it's only necessary to send packets with an unknown VLAN ID to a port
+that belongs to a VLAN-aware bridge.
+
+Do a similar thing as for ATU violation messages, and hide them in the
+kernel's trace buffer.
+
+New usage model:
+
+$ trace-cmd list | grep mv88e6xxx
+mv88e6xxx
+mv88e6xxx:mv88e6xxx_vtu_miss_violation
+mv88e6xxx:mv88e6xxx_vtu_member_violation
+$ trace-cmd report
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Saeed Mahameed <saeed@kernel.org>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Cc: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/dsa/mv88e6xxx/global1_vtu.c | 7 +++----
+ drivers/net/dsa/mv88e6xxx/trace.h | 30 ++++++++++++++++++++++++++++++
+ 2 files changed, 33 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/mv88e6xxx/global1_vtu.c
++++ b/drivers/net/dsa/mv88e6xxx/global1_vtu.c
+@@ -13,6 +13,7 @@
+
+ #include "chip.h"
+ #include "global1.h"
++#include "trace.h"
+
+ /* Offset 0x02: VTU FID Register */
+
+@@ -628,14 +629,12 @@ static irqreturn_t mv88e6xxx_g1_vtu_prob
+ spid = val & MV88E6XXX_G1_VTU_OP_SPID_MASK;
+
+ if (val & MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION) {
+- dev_err_ratelimited(chip->dev, "VTU member violation for vid %d, source port %d\n",
+- vid, spid);
++ trace_mv88e6xxx_vtu_member_violation(chip->dev, spid, vid);
+ chip->ports[spid].vtu_member_violation++;
+ }
+
+ if (val & MV88E6XXX_G1_VTU_OP_MISS_VIOLATION) {
+- dev_dbg_ratelimited(chip->dev, "VTU miss violation for vid %d, source port %d\n",
+- vid, spid);
++ trace_mv88e6xxx_vtu_miss_violation(chip->dev, spid, vid);
+ chip->ports[spid].vtu_miss_violation++;
+ }
+
+--- a/drivers/net/dsa/mv88e6xxx/trace.h
++++ b/drivers/net/dsa/mv88e6xxx/trace.h
+@@ -55,6 +55,36 @@ DEFINE_EVENT(mv88e6xxx_atu_violation, mv
+ const unsigned char *addr, u16 fid),
+ TP_ARGS(dev, spid, portvec, addr, fid));
+
++DECLARE_EVENT_CLASS(mv88e6xxx_vtu_violation,
++
++ TP_PROTO(const struct device *dev, int spid, u16 vid),
++
++ TP_ARGS(dev, spid, vid),
++
++ TP_STRUCT__entry(
++ __string(name, dev_name(dev))
++ __field(int, spid)
++ __field(u16, vid)
++ ),
++
++ TP_fast_assign(
++ __assign_str(name, dev_name(dev));
++ __entry->spid = spid;
++ __entry->vid = vid;
++ ),
++
++ TP_printk("dev %s spid %d vid %u",
++ __get_str(name), __entry->spid, __entry->vid)
++);
++
++DEFINE_EVENT(mv88e6xxx_vtu_violation, mv88e6xxx_vtu_member_violation,
++ TP_PROTO(const struct device *dev, int spid, u16 vid),
++ TP_ARGS(dev, spid, vid));
++
++DEFINE_EVENT(mv88e6xxx_vtu_violation, mv88e6xxx_vtu_miss_violation,
++ TP_PROTO(const struct device *dev, int spid, u16 vid),
++ TP_ARGS(dev, spid, vid));
++
+ #endif /* _MV88E6XXX_TRACE_H */
+
+ /* We don't want to use include/trace/events */
drm-i915-move-csc-load-back-into-.color_commit_arm-when-psr-is-enabled-on-skl-glk.patch
kvm-arm64-pmu-fix-get_one_reg-for-vpmc-regs-to-return-the-current-value.patch
kvm-arm64-disable-interrupts-while-walking-userspace-pts.patch
+net-dsa-mv88e6xxx-read-fid-when-handling-atu-violations.patch
+net-dsa-mv88e6xxx-replace-atu-violation-prints-with-trace-points.patch
+net-dsa-mv88e6xxx-replace-vtu-violation-prints-with-trace-points.patch