[][[openwrt][mt7986][config][free pse buffer or drop the packets that forward to pse port when the pse port link down]]
[Description]
Fix pse buffer don't release which cause qdma can't tx packet
[Release-log]
-unplugging the network cable when
there are lots of packets may cause
buffer can't to be released
-the packets forwarding to the port
that is link down may occupy the PSE buff.
-setting GMAC force link down
can trigger PSE buffer release
-setting port link down to drop packets
forwarding to the link down eth port
Change-Id: Ifb467a768fa53c81e6409538a2c95db2db0fe39f
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7823574
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 6272f11..29630a8 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -875,6 +875,82 @@
return 1;
}
+static int mtk_gdm_fsm_get(struct mtk_mac *mac, u32 gdm)
+{
+ u32 fsm = mtk_r32(mac->hw, gdm);
+ u32 ret = 0;
+
+ if (mac->type == MTK_GDM_TYPE)
+ ret = fsm == 0;
+ else if (mac->type == MTK_XGDM_TYPE) {
+ if (mac->id == MTK_GMAC1_ID) {
+ if (((fsm & 0x7ffffff) == 0) &&
+ (mtk_r32(mac->hw, MTK_MAC_FSM(mac->id)) == 0x1010000))
+ ret = 1;
+ } else
+ ret = ((mac->interface == PHY_INTERFACE_MODE_XGMII) ?
+ ((fsm & 0xfffffff) == 0) : ((fsm & 0x0ffffff) == 0));
+ }
+
+ return ret;
+}
+
+static void mtk_gdm_fsm_poll(struct mtk_mac *mac)
+{
+ u32 gdm = 0, i = 0;
+
+ switch (mac->id) {
+ case MTK_GMAC1_ID:
+ gdm = MTK_FE_GDM1_FSM;
+ break;
+ case MTK_GMAC2_ID:
+ gdm = MTK_FE_GDM2_FSM;
+ break;
+ case MTK_GMAC3_ID:
+ gdm = MTK_FE_GDM3_FSM;
+ break;
+ default:
+ pr_info("%s mac id invalid", __func__);
+ break;
+ }
+ msleep(500);
+ while (i < 3) {
+ if (mtk_gdm_fsm_get(mac, gdm))
+ break;
+ msleep(500);
+ i++;
+ }
+
+ if (i == 3)
+ pr_info("%s fsm invalid", __func__);
+}
+
+static void mtk_pse_port_link_set(struct mtk_mac *mac, bool up)
+{
+ u32 fe_glo_cfg, val;
+
+ fe_glo_cfg = mtk_r32(mac->hw, MTK_FE_GLO_CFG(mac->id));
+ switch (mac->id) {
+ case MTK_GMAC1_ID:
+ val = MTK_FE_LINK_DOWN_P1;
+ break;
+ case MTK_GMAC2_ID:
+ val = MTK_FE_LINK_DOWN_P2;
+ break;
+ case MTK_GMAC3_ID:
+ val = MTK_FE_LINK_DOWN_P15;
+ break;
+ }
+
+ if (!up)
+ fe_glo_cfg |= val;
+ else
+ fe_glo_cfg &= ~val;
+
+ mtk_w32(mac->hw, fe_glo_cfg, MTK_FE_GLO_CFG(mac->id));
+ mtk_gdm_fsm_poll(mac);
+}
+
static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
phy_interface_t interface)
{
@@ -882,9 +958,10 @@
phylink_config);
u32 mcr, sts;
+ mtk_pse_port_link_set(mac, false);
if (mac->type == MTK_GDM_TYPE) {
mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
- mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN);
+ mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK);
mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
} else if (mac->type == MTK_XGDM_TYPE && mac->id != MTK_GMAC1_ID) {
mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
@@ -986,6 +1063,7 @@
mcr &= ~(XMAC_MCR_TRX_DISABLE);
mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
}
+ mtk_pse_port_link_set(mac, true);
}
static void mtk_validate(struct phylink_config *config,
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 57bf7b1..f87635c 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -69,9 +69,12 @@
#define MTK_RSS_MAX_INDIRECTION_TABLE 128
/* Frame Engine Global Configuration */
-#define MTK_FE_GLO_CFG 0x00
+#define MTK_FE_GLO_CFG(x) ((x == MTK_GMAC3_ID) ? 0x24 : 0x00)
+#define MTK_FE_LINK_DOWN_P1 BIT(9)
+#define MTK_FE_LINK_DOWN_P2 BIT(10)
#define MTK_FE_LINK_DOWN_P3 BIT(11)
#define MTK_FE_LINK_DOWN_P4 BIT(12)
+#define MTK_FE_LINK_DOWN_P15 BIT(7)
/* Frame Engine Global Reset Register */
#define MTK_RST_GL 0x04