Commit dfd222e2 authored by Justin Chen's avatar Justin Chen Committed by Paolo Abeni
Browse files

net: bcmasp: Bring up unimac after PHY link up



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: 490cb412 ("net: bcmasp: Add support for ASP2.0 Ethernet controller")
Signed-off-by: default avatarJustin Chen <justin.chen@broadcom.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 6a4aee27
Loading
Loading
Loading
Loading
+19 −9
Original line number Diff line number Diff line
@@ -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) {