net: stmmac: xgmac: fix a typo of register name in DPP safety handling
[platform/kernel/linux-starfive.git] / drivers / net / ethernet / stmicro / stmmac / dwxgmac2_core.c
index f352be2..b5509f2 100644 (file)
@@ -830,6 +830,44 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
        { false, "UNKNOWN", "Unknown Error" }, /* 31 */
 };
 
+#define DPP_RX_ERR "Read Rx Descriptor Parity checker Error"
+#define DPP_TX_ERR "Read Tx Descriptor Parity checker Error"
+
+static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
+       { true, "TDPES0", DPP_TX_ERR },
+       { true, "TDPES1", DPP_TX_ERR },
+       { true, "TDPES2", DPP_TX_ERR },
+       { true, "TDPES3", DPP_TX_ERR },
+       { true, "TDPES4", DPP_TX_ERR },
+       { true, "TDPES5", DPP_TX_ERR },
+       { true, "TDPES6", DPP_TX_ERR },
+       { true, "TDPES7", DPP_TX_ERR },
+       { true, "TDPES8", DPP_TX_ERR },
+       { true, "TDPES9", DPP_TX_ERR },
+       { true, "TDPES10", DPP_TX_ERR },
+       { true, "TDPES11", DPP_TX_ERR },
+       { true, "TDPES12", DPP_TX_ERR },
+       { true, "TDPES13", DPP_TX_ERR },
+       { true, "TDPES14", DPP_TX_ERR },
+       { true, "TDPES15", DPP_TX_ERR },
+       { true, "RDPES0", DPP_RX_ERR },
+       { true, "RDPES1", DPP_RX_ERR },
+       { true, "RDPES2", DPP_RX_ERR },
+       { true, "RDPES3", DPP_RX_ERR },
+       { true, "RDPES4", DPP_RX_ERR },
+       { true, "RDPES5", DPP_RX_ERR },
+       { true, "RDPES6", DPP_RX_ERR },
+       { true, "RDPES7", DPP_RX_ERR },
+       { true, "RDPES8", DPP_RX_ERR },
+       { true, "RDPES9", DPP_RX_ERR },
+       { true, "RDPES10", DPP_RX_ERR },
+       { true, "RDPES11", DPP_RX_ERR },
+       { true, "RDPES12", DPP_RX_ERR },
+       { true, "RDPES13", DPP_RX_ERR },
+       { true, "RDPES14", DPP_RX_ERR },
+       { true, "RDPES15", DPP_RX_ERR },
+};
+
 static void dwxgmac3_handle_dma_err(struct net_device *ndev,
                                    void __iomem *ioaddr, bool correctable,
                                    struct stmmac_safety_stats *stats)
@@ -841,6 +879,13 @@ static void dwxgmac3_handle_dma_err(struct net_device *ndev,
 
        dwxgmac3_log_error(ndev, value, correctable, "DMA",
                           dwxgmac3_dma_errors, STAT_OFF(dma_errors), stats);
+
+       value = readl(ioaddr + XGMAC_DMA_DPP_INT_STATUS);
+       writel(value, ioaddr + XGMAC_DMA_DPP_INT_STATUS);
+
+       dwxgmac3_log_error(ndev, value, false, "DMA_DPP",
+                          dwxgmac3_dma_dpp_errors,
+                          STAT_OFF(dma_dpp_errors), stats);
 }
 
 static int
@@ -881,6 +926,12 @@ dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp,
        value |= XGMAC_TMOUTEN; /* FSM Timeout Feature */
        writel(value, ioaddr + XGMAC_MAC_FSM_CONTROL);
 
+       /* 5. Enable Data Path Parity Protection */
+       value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL);
+       /* already enabled by default, explicit enable it again */
+       value &= ~XGMAC_DPP_DISABLE;
+       writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL);
+
        return 0;
 }
 
@@ -914,7 +965,11 @@ static int dwxgmac3_safety_feat_irq_status(struct net_device *ndev,
                ret |= !corr;
        }
 
-       err = dma & (XGMAC_DEUIS | XGMAC_DECIS);
+       /* DMA_DPP_Interrupt_Status is indicated by MCSIS bit in
+        * DMA_Safety_Interrupt_Status, so we handle DMA Data Path
+        * Parity Errors here
+        */
+       err = dma & (XGMAC_DEUIS | XGMAC_DECIS | XGMAC_MCSIS);
        corr = dma & XGMAC_DECIS;
        if (err) {
                dwxgmac3_handle_dma_err(ndev, ioaddr, corr, stats);
@@ -930,6 +985,7 @@ static const struct dwxgmac3_error {
        { dwxgmac3_mac_errors },
        { dwxgmac3_mtl_errors },
        { dwxgmac3_dma_errors },
+       { dwxgmac3_dma_dpp_errors },
 };
 
 static int dwxgmac3_safety_feat_dump(struct stmmac_safety_stats *stats,
@@ -1178,7 +1234,19 @@ static int dwxgmac2_flex_pps_config(void __iomem *ioaddr, int index,
 
        val |= XGMAC_PPSCMDx(index, XGMAC_PPSCMD_START);
        val |= XGMAC_TRGTMODSELx(index, XGMAC_PPSCMD_START);
-       val |= XGMAC_PPSEN0;
+
+       /* XGMAC Core has 4 PPS outputs at most.
+        *
+        * Prior XGMAC Core 3.20, Fixed mode or Flexible mode are selectable for
+        * PPS0 only via PPSEN0. PPS{1,2,3} are in Flexible mode by default,
+        * and can not be switched to Fixed mode, since PPSEN{1,2,3} are
+        * read-only reserved to 0.
+        * But we always set PPSEN{1,2,3} do not make things worse ;-)
+        *
+        * From XGMAC Core 3.20 and later, PPSEN{0,1,2,3} are writable and must
+        * be set, or the PPS outputs stay in Fixed PPS mode by default.
+        */
+       val |= XGMAC_PPSENx(index);
 
        writel(cfg->start.tv_sec, ioaddr + XGMAC_PPSx_TARGET_TIME_SEC(index));
 
@@ -1472,7 +1540,8 @@ static int dwxgmac3_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg,
        return 0;
 }
 
-static void dwxgmac3_fpe_configure(void __iomem *ioaddr, u32 num_txq,
+static void dwxgmac3_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,
+                                  u32 num_txq,
                                   u32 num_rxq, bool enable)
 {
        u32 value;