Update driver to be ready for the upcoming firmware release. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
135 lines
5.4 KiB
Diff
135 lines
5.4 KiB
Diff
From 8120b9b88ec47ee41b8350e3e4341839f5fdc28e Mon Sep 17 00:00:00 2001
|
|
From: Daniel Golle <daniel@makrotopia.org>
|
|
Date: Tue, 24 Mar 2026 18:17:49 +0000
|
|
Subject: [PATCH 17/19] DO NOT SUBMIT: net: dsa: mxl862xx: re-introduce PCE
|
|
workaround for old firmware
|
|
|
|
Re-introduce the legacy PCE rule paths needed for firmware versions
|
|
older than 1.0.83.
|
|
|
|
Firmware >= 1.0.83 exposes the new GSW_TFLOW_PCERULELOGICWRITE API
|
|
which selects the per-CTP block via @region/@logicalportid and grows
|
|
the hardware block on demand. Older firmware lacks that command and
|
|
exposes only the legacy GSW_TFLOW_PCERULEWRITE call, where the rule
|
|
index is a direct offset into a fixed-size pre-allocated CTP block.
|
|
Add MXL862XX_TFLOW_PCERULEWRITE back to mxl862xx-cmd.h and make
|
|
mxl862xx_pce_rule_write() pick the right command at runtime based on
|
|
the cached firmware version.
|
|
|
|
In addition, firmware older than 1.0.80 still installs global PCE
|
|
rules at boot that redirect link-local frames (BPDUs, LLDP, LACP) to
|
|
port 0 (the on-chip microcontroller) instead of the DSA CPU port.
|
|
With port 0 disabled under DSA these rules silently drop matching
|
|
traffic. Re-introduce mxl862xx_disable_fw_global_rules() to clear
|
|
them out during setup. The upstream submission replaced that call
|
|
with a dev_warn() since firmware >= 1.0.80 no longer installs the
|
|
problematic rules.
|
|
|
|
This commit is for downstream use only and must not be submitted
|
|
upstream.
|
|
|
|
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|
---
|
|
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 1 +
|
|
drivers/net/dsa/mxl862xx/mxl862xx.c | 61 +++++++++++++++++++++----
|
|
2 files changed, 53 insertions(+), 9 deletions(-)
|
|
|
|
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
|
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
|
@@ -32,6 +32,7 @@
|
|
#define MXL862XX_COMMON_MONITORPORTCFGSET (MXL862XX_COMMON_MAGIC + 0xe)
|
|
#define MXL862XX_COMMON_REGISTERMOD (MXL862XX_COMMON_MAGIC + 0x11)
|
|
|
|
+#define MXL862XX_TFLOW_PCERULEWRITE (MXL862XX_TFLOW_MAGIC + 0x2)
|
|
#define MXL862XX_TFLOW_PCERULEALLOC (MXL862XX_TFLOW_MAGIC + 0x4)
|
|
#define MXL862XX_TFLOW_PCERULEFREE (MXL862XX_TFLOW_MAGIC + 0x5)
|
|
#define MXL862XX_TFLOW_PCERULELOGICWRITE \
|
|
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
|
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
|
@@ -449,6 +449,43 @@ static int mxl862xx_setup_drop_meter(str
|
|
return MXL862XX_API_WRITE(priv, MXL862XX_COMMON_REGISTERMOD, reg);
|
|
}
|
|
|
|
+/* Disable firmware global PCE rules that trap various protocols to the
|
|
+ * on-die microcontroller (port 0) via PORTMAP_CPU. Under DSA, these
|
|
+ * frames must either reach the host CPU via per-port rules (link-local)
|
|
+ * or through the normal bridge forwarding path (ARP broadcast), so the
|
|
+ * global firmware rules are not needed. With the microcontroller port
|
|
+ * disabled they would silently drop matching traffic.
|
|
+ *
|
|
+ * Global rules have lower indices than CTP rules, hence higher priority
|
|
+ * in the PCE pipeline -- they must be explicitly disabled or they will
|
|
+ * shadow the per-CTP traps.
|
|
+ *
|
|
+ * Indices from gsw_flow_index.h:
|
|
+ * 1 -- BPDU (STP/RSTP, dst 01:80:c2:00:00:00)
|
|
+ * 3 -- LLDP (EtherType 0x88cc)
|
|
+ * 4 -- OAM/LACP (EtherType 0x8809)
|
|
+ * 6 -- System MAC (dst 02:e0:92:00:00:01, vendor management MAC)
|
|
+ * 7 -- ARP Request (broadcast + EtherType 0x0806 + TPA 192.0.2.1)
|
|
+ */
|
|
+static int mxl862xx_disable_fw_global_rules(struct dsa_switch *ds)
|
|
+{
|
|
+ static const u16 indices[] = { 1, 3, 4, 6, 7 };
|
|
+ struct mxl862xx_pce_rule rule;
|
|
+ int i, ret;
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(indices); i++) {
|
|
+ memset(&rule, 0, sizeof(rule));
|
|
+ rule.pattern.index = cpu_to_le16(indices[i]);
|
|
+ /* pattern.enable == 0 -> rule is disabled */
|
|
+
|
|
+ ret = MXL862XX_API_WRITE(ds->priv,
|
|
+ MXL862XX_TFLOW_PCERULEWRITE, rule);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
|
|
/* Per-CTP logical indices for protocol trap rules.
|
|
*
|
|
@@ -463,16 +500,20 @@ static int mxl862xx_setup_drop_meter(str
|
|
#define MXL862XX_MLDV1_CTP_INDEX 3
|
|
#define MXL862XX_MLDV2_CTP_INDEX 4
|
|
|
|
-/* Install (or overwrite) a PCE rule via the firmware's logical-index
|
|
- * API. The firmware translates the logical index in @rule->pattern.index
|
|
- * to a physical position within the block selected by @rule->region and
|
|
- * @rule->logicalportid, and expands the hardware block size as needed.
|
|
+/* Install (or overwrite) a PCE rule. On firmware >= 1.0.83 use the
|
|
+ * logical-index API (PCERULELOGICWRITE), which grows the per-CTP block
|
|
+ * on demand. On older firmware that API does not exist, so fall back
|
|
+ * to the legacy PCERULEWRITE call which uses the rule index as a
|
|
+ * direct offset into a fixed-size pre-allocated CTP block.
|
|
*/
|
|
static int mxl862xx_pce_rule_write(struct mxl862xx_priv *priv,
|
|
struct mxl862xx_pce_rule *rule)
|
|
{
|
|
- return MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULELOGICWRITE,
|
|
- *rule);
|
|
+ u16 cmd = MXL862XX_FW_VER_MIN(priv, 1, 0, 83) ?
|
|
+ MXL862XX_TFLOW_PCERULELOGICWRITE :
|
|
+ MXL862XX_TFLOW_PCERULEWRITE;
|
|
+
|
|
+ return MXL862XX_API_WRITE(priv, cmd, *rule);
|
|
}
|
|
|
|
/**
|
|
@@ -1130,9 +1171,11 @@ static int mxl862xx_setup(struct dsa_swi
|
|
if (ret)
|
|
return ret;
|
|
|
|
- if (!MXL862XX_FW_VER_MIN(priv, 1, 0, 80))
|
|
- dev_warn(ds->dev, "firmware < 1.0.80 installs global PCE rules "
|
|
- "that interfere with DSA operation, please update\n");
|
|
+ if (!MXL862XX_FW_VER_MIN(priv, 1, 0, 80)) {
|
|
+ ret = mxl862xx_disable_fw_global_rules(ds);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
|
|
/* Pre-allocate firmware resources for all ports. The DSA core
|
|
* calls change_tag_protocol() between setup() and port_setup(),
|