qualcommax: qca_ppe: trap slow-protocol frames to the CPU

ppe_ctrlpkt_init() redirects only the STP address 01:80:c2:00:00:00
(RFDB entry 31, APP_CTRL[0]) to the CPU port. The slow-protocols
address 01:80:c2:00:00:02 has no entry, so LACPDUs sent by a switch
never reach a Linux bond on the LAN ports: the bond keeps
"Partner Mac Address: 00:00:00:00:00:00" and every 802.3ad group stays
unformed, while the switch side reports the board's own LACPDUs.

Add RFDB entry 30 for 01:80:c2:00:00:02 and let APP_CTRL[0] match
entries 30 and 31 (bits 32 and 33 of the RFDB index bitmap; the
field layout follows the SSDK hppe_ctrlpkt_reg.h / hppe_fdb_reg.h).

Tested on a Xiaomi AX3600 against a switch running LACP: lan1+lan2 in
an 802.3ad bond converge (both slaves in one aggregator, partner MAC
set, port state 0x3f on both ends) and carry ~1.3 Gbit/s per direction
over the two 1 GbE links with 8 parallel flows. Before the change the
same setup never negotiated.

Signed-off-by: Max Grass <gh-owrt-1@maxgrass.eu>
Link: https://github.com/openwrt/openwrt/pull/25184
Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
Max Grass authored and Robert Marko committed 2026-09-14 20:42:45 +02:00
1 parent ad7179f9b9
commit 883ebad9ba
1 file changed
+11 -2
@@ -1789,9 +1789,18 @@ static void ppe_ctrlpkt_init(struct qca_ppe_priv *priv)
regmap_write(priv->regmap, PPE_RFDB_TBL(31), 0xc2000000);
regmap_write(priv->regmap, PPE_RFDB_TBL(31) + 4, 0x00010180);
/* APP_CTRL[0]: match RFDB profile 31, bypass STP, redirect to CPU */
/* RFDB_TBL[30]: Slow Protocols MAC 01:80:c2:00:00:02 (LACP, marker).
* Without this entry the PPE keeps LACPDUs away from the CPU port and a
* bond over these ports never sees its partner.
*/
regmap_write(priv->regmap, PPE_RFDB_TBL(30), 0xc2000002);
regmap_write(priv->regmap, PPE_RFDB_TBL(30) + 4, 0x00010180);
/* APP_CTRL[0]: match RFDB profiles 30 and 31 (bits 32 and 33 of the
* RFDB index bitmap), bypass STP, redirect to CPU
*/
regmap_write(priv->regmap, PPE_APP_CTRL(0), 0x00000003);
regmap_write(priv->regmap, PPE_APP_CTRL(0) + 4, 0x00000002);
regmap_write(priv->regmap, PPE_APP_CTRL(0) + 4, 0x00000003);
regmap_write(priv->regmap, PPE_APP_CTRL(0) + 8,
PPE_APP_CTRL_PORT_BITMAP_EN |
FIELD_PREP(PPE_APP_CTRL_PORT_BITMAP, ports) |