diff --git a/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe.h b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe.h index bc31b61486c..5e526f5dc5e 100644 --- a/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe.h +++ b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe.h @@ -276,6 +276,12 @@ #define PPE_RFDB_TBL(idx) (PPE_L2_BASE + 0x1000 + (idx) * 0x8) #define PPE_APP_CTRL(idx) (PPE_L2_BASE + 0x1400 + (idx) * 0x10) +/* Fields in the third 32-bit word of APP_CTRL. */ +#define PPE_APP_CTRL_PORT_BITMAP_EN BIT(2) +#define PPE_APP_CTRL_PORT_BITMAP GENMASK(10, 3) +#define PPE_APP_CTRL_STP_BYPASS BIT(12) +#define PPE_APP_CTRL_CMD GENMASK(16, 15) +#define PPE_APP_CTRL_REDIRECT_CPU 3 #define PPE_VSI_TBL(vsi) (PPE_L2_BASE + 0x1800 + (vsi) * 0x10) #define PPE_VSI_TBL_MEMBER GENMASK(7, 0) diff --git a/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_main.c b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_main.c index e6d546762ed..61709630892 100644 --- a/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_main.c +++ b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_main.c @@ -1683,6 +1683,12 @@ static void ppe_mac_hw_init(struct qca_ppe_priv *priv) static void ppe_ctrlpkt_init(struct qca_ppe_priv *priv) { + u32 ports; + + /* Trap external BPDUs, but let CPU-originated BPDUs reach the wire. */ + ports = GENMASK(priv->data->num_ports - 1, 0) & + ~(BIT(QCA_PPE_CPU_PORT) | BIT(priv->data->loopback_port)); + /* RFDB_TBL[31]: STP multicast MAC 01:80:c2:00:00:00 */ regmap_write(priv->regmap, PPE_RFDB_TBL(31), 0xc2000000); regmap_write(priv->regmap, PPE_RFDB_TBL(31) + 4, 0x00010180); @@ -1690,7 +1696,11 @@ static void ppe_ctrlpkt_init(struct qca_ppe_priv *priv) /* APP_CTRL[0]: match RFDB profile 31, 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) + 8, 0x000093fc); + regmap_write(priv->regmap, PPE_APP_CTRL(0) + 8, + PPE_APP_CTRL_PORT_BITMAP_EN | + FIELD_PREP(PPE_APP_CTRL_PORT_BITMAP, ports) | + PPE_APP_CTRL_STP_BYPASS | + FIELD_PREP(PPE_APP_CTRL_CMD, PPE_APP_CTRL_REDIRECT_CPU)); } static int ppe_ipq6018_mux_setup(struct qca_ppe_priv *priv)