Files
infix/patches/linux/6.18.39/0048-net-dsa-mv88e6xxx-Trap-PTP-frames-on-timestamping-po.patch
T

184 lines
7.2 KiB
Diff

From 6831be7e8887363f2b6e1f1cf8c684afc2e065a1 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Fri, 17 Apr 2026 09:13:04 +0000
Subject: [PATCH 48/50] net: dsa: mv88e6xxx: Trap PTP frames on timestamping
ports, on 6393X
Similar to the Peridot (6390), the designation of PTP frames as
management (and the destination port) must be explicitly
configured. In contrast to the Peridot, the configuration is now done
on a per-port basis, rather than a chip-global setting.
Therefore, make sure to classify PTP frames as management, and route
them towards the CPU port whenever hardware timestamping is enabled on
a port.
---
drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
drivers/net/dsa/mv88e6xxx/hwtstamp.c | 26 ++++++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/hwtstamp.h | 2 ++
drivers/net/dsa/mv88e6xxx/port.c | 10 ++++++++++
drivers/net/dsa/mv88e6xxx/port.h | 4 ++++
drivers/net/dsa/mv88e6xxx/ptp.c | 23 +++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/ptp.h | 1 +
7 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 7bc3169839d3..1d1edf84b224 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -5689,7 +5689,7 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
/* TODO: serdes stats */
.gpio_ops = &mv88e6352_gpio_ops,
.avb_ops = &mv88e6390_avb_ops,
- .ptp_ops = &mv88e6352_ptp_ops,
+ .ptp_ops = &mv88e6393x_ptp_ops,
.phylink_get_caps = mv88e6393x_phylink_get_caps,
.pcs_ops = &mv88e6393x_pcs_ops,
};
diff --git a/drivers/net/dsa/mv88e6xxx/hwtstamp.c b/drivers/net/dsa/mv88e6xxx/hwtstamp.c
index 6e6472a3b75a..446e1c616752 100644
--- a/drivers/net/dsa/mv88e6xxx/hwtstamp.c
+++ b/drivers/net/dsa/mv88e6xxx/hwtstamp.c
@@ -13,6 +13,7 @@
#include "chip.h"
#include "global2.h"
#include "hwtstamp.h"
+#include "port.h"
#include "ptp.h"
#include <linux/ptp_classify.h>
@@ -533,6 +534,31 @@ int mv88e6352_hwtstamp_port_enable(struct mv88e6xxx_chip *chip, int port)
MV88E6XXX_PORT_PTP_CFG0_DISABLE_TSPEC_MATCH);
}
+int mv88e6393x_hwtstamp_port_disable(struct mv88e6xxx_chip *chip, int port)
+{
+ int upstream = MV88E6393X_PORT_POLICY_MGMT_CTL_CPU_DEST_DISABLED;
+ int err;
+
+
+ err = mv88e6352_hwtstamp_port_disable(chip, port);
+ if (err)
+ return err;
+
+ return mv88e6393x_port_set_ptp_port(chip, port, upstream);
+}
+
+int mv88e6393x_hwtstamp_port_enable(struct mv88e6xxx_chip *chip, int port)
+{
+ int upstream = dsa_upstream_port(chip->ds, port);
+ int err;
+
+ err = mv88e6393x_port_set_ptp_port(chip, port, upstream);
+ if (err)
+ return err;
+
+ return mv88e6352_hwtstamp_port_enable(chip, port);
+}
+
static int mv88e6xxx_hwtstamp_port_setup(struct mv88e6xxx_chip *chip, int port)
{
const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
diff --git a/drivers/net/dsa/mv88e6xxx/hwtstamp.h b/drivers/net/dsa/mv88e6xxx/hwtstamp.h
index c359821d5a6e..c51cd1ab2978 100644
--- a/drivers/net/dsa/mv88e6xxx/hwtstamp.h
+++ b/drivers/net/dsa/mv88e6xxx/hwtstamp.h
@@ -129,6 +129,8 @@ int mv88e6xxx_hwtstamp_setup(struct mv88e6xxx_chip *chip);
void mv88e6xxx_hwtstamp_free(struct mv88e6xxx_chip *chip);
int mv88e6352_hwtstamp_port_enable(struct mv88e6xxx_chip *chip, int port);
int mv88e6352_hwtstamp_port_disable(struct mv88e6xxx_chip *chip, int port);
+int mv88e6393x_hwtstamp_port_enable(struct mv88e6xxx_chip *chip, int port);
+int mv88e6393x_hwtstamp_port_disable(struct mv88e6xxx_chip *chip, int port);
int mv88e6165_global_enable(struct mv88e6xxx_chip *chip);
int mv88e6165_global_disable(struct mv88e6xxx_chip *chip);
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 1985b8553611..843972077576 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -1484,6 +1484,16 @@ int mv88e6393x_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
return mv88e6393x_port_policy_write(chip, port, ptr, data);
}
+int mv88e6393x_port_set_ptp_port(struct mv88e6xxx_chip *chip, int port,
+ int upstream_port)
+{
+ u16 ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_PTP_DEST;
+ u8 data = MV88E6393X_PORT_POLICY_MGMT_CTL_CPU_DEST_MGMTPRI |
+ upstream_port;
+
+ return mv88e6393x_port_policy_write(chip, port, ptr, data);
+}
+
int mv88e6393x_port_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
{
u16 ptr;
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index f4a56671fc4c..5f733f84b348 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -283,6 +283,8 @@
#define MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_INGRESS_DEST 0x3000
#define MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_CPU_DEST 0x3800
#define MV88E6393X_PORT_POLICY_MGMT_CTL_CPU_DEST_MGMTPRI 0x00e0
+#define MV88E6393X_PORT_POLICY_MGMT_CTL_CPU_DEST_DISABLED 0x001f
+#define MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_PTP_DEST 0x3f00
/* Offset 0x0F: Port Special Ether Type */
#define MV88E6XXX_PORT_ETH_TYPE 0x0f
@@ -577,6 +579,8 @@ int mv88e6393x_set_egress_port(struct mv88e6xxx_chip *chip,
int port);
int mv88e6393x_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
int upstream_port);
+int mv88e6393x_port_set_ptp_port(struct mv88e6xxx_chip *chip, int port,
+ int upstream_port);
int mv88e6393x_port_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
bool message_port);
diff --git a/drivers/net/dsa/mv88e6xxx/ptp.c b/drivers/net/dsa/mv88e6xxx/ptp.c
index f7603573d3a9..327a9f786437 100644
--- a/drivers/net/dsa/mv88e6xxx/ptp.c
+++ b/drivers/net/dsa/mv88e6xxx/ptp.c
@@ -444,6 +444,29 @@ const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = {
(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
};
+const struct mv88e6xxx_ptp_ops mv88e6393x_ptp_ops = {
+ .clock_read = mv88e6352_ptp_clock_read,
+ .ptp_enable = mv88e6352_ptp_enable,
+ .ptp_verify = mv88e6352_ptp_verify,
+ .event_work = mv88e6352_tai_event_work,
+ .port_enable = mv88e6393x_hwtstamp_port_enable,
+ .port_disable = mv88e6393x_hwtstamp_port_disable,
+ .n_ext_ts = 1,
+ .arr0_sts_reg = MV88E6XXX_PORT_PTP_ARR0_STS,
+ .arr1_sts_reg = MV88E6XXX_PORT_PTP_ARR1_STS,
+ .dep_sts_reg = MV88E6XXX_PORT_PTP_DEP_STS,
+ .rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
+};
+
static u64 mv88e6xxx_ptp_clock_read(struct cyclecounter *cc)
{
struct mv88e6xxx_chip *chip = cc_to_chip(cc);
diff --git a/drivers/net/dsa/mv88e6xxx/ptp.h b/drivers/net/dsa/mv88e6xxx/ptp.h
index 95bdddb0bf39..54dce1fbf1aa 100644
--- a/drivers/net/dsa/mv88e6xxx/ptp.h
+++ b/drivers/net/dsa/mv88e6xxx/ptp.h
@@ -75,6 +75,7 @@ void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip);
extern const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops;
extern const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops;
extern const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops;
+extern const struct mv88e6xxx_ptp_ops mv88e6393x_ptp_ops;
#else /* !CONFIG_NET_DSA_MV88E6XXX_PTP */