]> git.droids-corp.org - dpdk.git/commitdiff
net/axgbe: reset PHY Rx when mailbox command timeout
authorSelwin Sebastian <selwin.sebastian@amd.com>
Tue, 25 Jan 2022 12:17:45 +0000 (17:47 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Thu, 27 Jan 2022 14:29:24 +0000 (15:29 +0100)
Sometimes mailbox commands timeout when the RX data path becomes
unresponsive. This prevents the submission of new mailbox commands
to DXIO. This patch identifies the timeout and resets the RX data
path so that the next message can be submitted properly.

Signed-off-by: Selwin Sebastian <selwin.sebastian@amd.com>
Acked-by: Chandubabu Namburu <chandu@amd.com>
drivers/net/axgbe/axgbe_common.h
drivers/net/axgbe/axgbe_phy_impl.c

index 5a7ac35b6a84010ca3f38021927bccac24c30df3..a5431dd9983c4ec8a28de84cd8e3ee9edde3b395 100644 (file)
 #define MDIO_PMA_10GBR_FECCTRL         0x00ab
 #endif
 
+#ifndef MDIO_PMA_RX_CTRL1
+#define MDIO_PMA_RX_CTRL1              0x8051
+#endif
+
 #ifndef MDIO_PCS_DIG_CTRL
 #define MDIO_PCS_DIG_CTRL              0x8000
 #endif
 
+#ifndef MDIO_PCS_DIGITAL_STAT
+#define MDIO_PCS_DIGITAL_STAT          0x8010
+#endif
+
 #ifndef MDIO_AN_XNP
 #define MDIO_AN_XNP                    0x0016
 #endif
 #define AXGBE_KR_TRAINING_ENABLE       BIT(1)
 
 #define AXGBE_PCS_CL37_BP              BIT(12)
+#define XGBE_PCS_PSEQ_STATE_MASK       0x1c
+#define XGBE_PCS_PSEQ_STATE_POWER_GOOD 0x10
 
 #define AXGBE_AN_CL37_INT_CMPLT                BIT(0)
 #define AXGBE_AN_CL37_INT_MASK         0x01
@@ -1401,6 +1411,10 @@ static inline uint32_t high32_value(uint64_t addr)
 #define XGBE_PMA_PLL_CTRL_SET          BIT(15)
 #define XGBE_PMA_PLL_CTRL_CLEAR                0x0000
 
+#define XGBE_PMA_RX_RST_0_MASK         BIT(4)
+#define XGBE_PMA_RX_RST_0_RESET_ON     0x10
+#define XGBE_PMA_RX_RST_0_RESET_OFF    0x00
+
 /*END*/
 
 /* Bit setting and getting macros
index 2ed94868b8ecce200c55db9aad3269f4ba91b4d6..eefb03e94e94a5c74997d3bcd1d4aa03be6a37b6 100644 (file)
@@ -1196,6 +1196,28 @@ static void axgbe_phy_set_redrv_mode(struct axgbe_port *pdata)
        axgbe_phy_put_comm_ownership(pdata);
 }
 
+static void axgbe_phy_rx_reset(struct axgbe_port *pdata)
+{
+       int reg;
+
+       reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PCS, MDIO_PCS_DIGITAL_STAT,
+                             XGBE_PCS_PSEQ_STATE_MASK);
+       if (reg == XGBE_PCS_PSEQ_STATE_POWER_GOOD) {
+               /* Mailbox command timed out, reset of RX block is required.
+                * This can be done by asseting the reset bit and wait for
+                * its compeletion.
+                */
+               XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1,
+                                XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_ON);
+               rte_delay_us(20);
+               XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1,
+                                XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_OFF);
+               rte_delay_us(45);
+               PMD_DRV_LOG(ERR, "firmware mailbox reset performed\n");
+       }
+}
+
+
 static void axgbe_phy_pll_ctrl(struct axgbe_port *pdata, bool enable)
 {
        XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_MISC_CTRL0,
@@ -1216,8 +1238,10 @@ static void axgbe_phy_perform_ratechange(struct axgbe_port *pdata,
        axgbe_phy_pll_ctrl(pdata, false);
 
        /* Log if a previous command did not complete */
-       if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS))
+       if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) {
                PMD_DRV_LOG(NOTICE, "firmware mailbox not ready for command\n");
+               axgbe_phy_rx_reset(pdata);
+       }
 
        /* Construct the command */
        XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, cmd);
@@ -1235,6 +1259,9 @@ static void axgbe_phy_perform_ratechange(struct axgbe_port *pdata,
                        goto reenable_pll;
                rte_delay_us(1500);
        }
+       PMD_DRV_LOG(NOTICE, "firmware mailbox command did not complete\n");
+       /* Reset on error */
+       axgbe_phy_rx_reset(pdata);
 
 reenable_pll:
         /* Re-enable the PLL control */