]> Git Repo - linux.git/commitdiff
net: bcmasp: Bring up unimac after PHY link up
authorJustin Chen <[email protected]>
Mon, 25 Mar 2024 19:30:24 +0000 (12:30 -0700)
committerPaolo Abeni <[email protected]>
Thu, 28 Mar 2024 09:46:38 +0000 (10:46 +0100)
The unimac requires the PHY RX clk during reset or it may be put
into a bad state. Bring up the unimac after link up to ensure the
PHY RX clk exists.

Fixes: 490cb412007d ("net: bcmasp: Add support for ASP2.0 Ethernet controller")
Signed-off-by: Justin Chen <[email protected]>
Signed-off-by: Paolo Abeni <[email protected]>
drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c

index dd06b68b33ed617a8de969078b02ce59591b585c..34e5156762a86ec71fe972d34ec374f6a25727d7 100644 (file)
@@ -392,7 +392,9 @@ static void umac_reset(struct bcmasp_intf *intf)
        umac_wl(intf, 0x0, UMC_CMD);
        umac_wl(intf, UMC_CMD_SW_RESET, UMC_CMD);
        usleep_range(10, 100);
-       umac_wl(intf, 0x0, UMC_CMD);
+       /* We hold the umac in reset and bring it out of
+        * reset when phy link is up.
+        */
 }
 
 static void umac_set_hw_addr(struct bcmasp_intf *intf,
@@ -412,6 +414,8 @@ static void umac_enable_set(struct bcmasp_intf *intf, u32 mask,
        u32 reg;
 
        reg = umac_rl(intf, UMC_CMD);
+       if (reg & UMC_CMD_SW_RESET)
+               return;
        if (enable)
                reg |= mask;
        else
@@ -430,7 +434,6 @@ static void umac_init(struct bcmasp_intf *intf)
        umac_wl(intf, 0x800, UMC_FRM_LEN);
        umac_wl(intf, 0xffff, UMC_PAUSE_CNTRL);
        umac_wl(intf, 0x800, UMC_RX_MAX_PKT_SZ);
-       umac_enable_set(intf, UMC_CMD_PROMISC, 1);
 }
 
 static int bcmasp_tx_poll(struct napi_struct *napi, int budget)
@@ -658,6 +661,12 @@ static void bcmasp_adj_link(struct net_device *dev)
                        UMC_CMD_HD_EN | UMC_CMD_RX_PAUSE_IGNORE |
                        UMC_CMD_TX_PAUSE_IGNORE);
                reg |= cmd_bits;
+               if (reg & UMC_CMD_SW_RESET) {
+                       reg &= ~UMC_CMD_SW_RESET;
+                       umac_wl(intf, reg, UMC_CMD);
+                       udelay(2);
+                       reg |= UMC_CMD_TX_EN | UMC_CMD_RX_EN | UMC_CMD_PROMISC;
+               }
                umac_wl(intf, reg, UMC_CMD);
 
                active = phy_init_eee(phydev, 0) >= 0;
@@ -1045,9 +1054,6 @@ static int bcmasp_netif_init(struct net_device *dev, bool phy_connect)
 
        umac_init(intf);
 
-       /* Disable the UniMAC RX/TX */
-       umac_enable_set(intf, (UMC_CMD_RX_EN | UMC_CMD_TX_EN), 0);
-
        umac_set_hw_addr(intf, dev->dev_addr);
 
        intf->old_duplex = -1;
@@ -1062,9 +1068,6 @@ static int bcmasp_netif_init(struct net_device *dev, bool phy_connect)
        netif_napi_add(intf->ndev, &intf->rx_napi, bcmasp_rx_poll);
        bcmasp_enable_rx(intf, 1);
 
-       /* Turn on UniMAC TX/RX */
-       umac_enable_set(intf, (UMC_CMD_RX_EN | UMC_CMD_TX_EN), 1);
-
        intf->crc_fwd = !!(umac_rl(intf, UMC_CMD) & UMC_CMD_CRC_FWD);
 
        bcmasp_netif_start(dev);
@@ -1306,7 +1309,14 @@ static void bcmasp_suspend_to_wol(struct bcmasp_intf *intf)
        if (intf->wolopts & WAKE_FILTER)
                bcmasp_netfilt_suspend(intf);
 
-       /* UniMAC receive needs to be turned on */
+       /* Bring UniMAC out of reset if needed and enable RX */
+       reg = umac_rl(intf, UMC_CMD);
+       if (reg & UMC_CMD_SW_RESET)
+               reg &= ~UMC_CMD_SW_RESET;
+
+       reg |= UMC_CMD_RX_EN | UMC_CMD_PROMISC;
+       umac_wl(intf, reg, UMC_CMD);
+
        umac_enable_set(intf, UMC_CMD_RX_EN, 1);
 
        if (intf->parent->wol_irq > 0) {
This page took 0.055643 seconds and 4 git commands to generate.