// SPDX-License-Identifier: GPL-2.0
#define pr_fmt(fmt)			"bcmasp_intf: " fmt

#include <asm/byteorder.h>
#include <linux/brcmphy.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/of_net.h>
#include <linux/of_mdio.h>
#include <linux/phy.h>
#include <linux/phy_fixed.h>
#include <linux/ptp_classify.h>
#include <linux/platform_device.h>
#include <net/ip.h>
#include <net/ipv6.h>

#include "bcmasp.h"
#include "bcmasp_intf_defs.h"

static int incr_ring(int index, int ring_count)
{
	index++;
	if (index == ring_count)
		return 0;

	return index;
}

/* Points to last byte of descriptor */
static dma_addr_t incr_last_byte(dma_addr_t addr, dma_addr_t beg,
				 int ring_count)
{
	dma_addr_t end = beg + (ring_count * DESC_SIZE);

	addr += DESC_SIZE;
	if (addr > end)
		return beg + DESC_SIZE - 1;

	return addr;
}

/* Points to first byte of descriptor */
static dma_addr_t incr_first_byte(dma_addr_t addr, dma_addr_t beg,
				  int ring_count)
{
	dma_addr_t end = beg + (ring_count * DESC_SIZE);

	addr += DESC_SIZE;
	if (addr >= end)
		return beg;

	return addr;
}

static void bcmasp_enable_tx(struct bcmasp_intf *intf, int en)
{
	if (en) {
		tx_spb_ctrl_wl(intf, TX_SPB_CTRL_ENABLE_EN, TX_SPB_CTRL_ENABLE);
		tx_epkt_core_wl(intf, (TX_EPKT_C_CFG_MISC_EN |
				TX_EPKT_C_CFG_MISC_PT |
				(intf->port << TX_EPKT_C_CFG_MISC_PS_SHIFT)),
				TX_EPKT_C_CFG_MISC);
	} else {
		tx_spb_ctrl_wl(intf, 0x0, TX_SPB_CTRL_ENABLE);
		tx_epkt_core_wl(intf, 0x0, TX_EPKT_C_CFG_MISC);
	}
}

static void bcmasp_enable_rx(struct bcmasp_intf *intf, int en)
{
	if (en)
		rx_edpkt_cfg_wl(intf, RX_EDPKT_CFG_ENABLE_EN,
				RX_EDPKT_CFG_ENABLE);
	else
		rx_edpkt_cfg_wl(intf, 0x0, RX_EDPKT_CFG_ENABLE);
}

static void bcmasp_set_rx_mode(struct net_device *dev)
{
	unsigned char mask[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
	struct bcmasp_intf *intf = netdev_priv(dev);
	struct netdev_hw_addr *ha;
	int ret;

	spin_lock_bh(&intf->parent->mda_lock);

	bcmasp_disable_all_filters(intf);

	if (dev->flags & IFF_PROMISC)
		goto set_promisc;

	bcmasp_set_promisc(intf, 0);

	bcmasp_set_broad(intf, 1);

	bcmasp_set_oaddr(intf, dev->dev_addr, 1);

	if (dev->flags & IFF_ALLMULTI) {
		bcmasp_set_allmulti(intf, 1);
	} else {
		bcmasp_set_allmulti(intf, 0);

		netdev_for_each_mc_addr(ha, dev) {
			ret = bcmasp_set_en_mda_filter(intf, ha->addr, mask);
			if (ret) {
				intf->mib.mc_filters_full_cnt++;
				goto set_promisc;
			}
		}
	}

	netdev_for_each_uc_addr(ha, dev) {
		ret = bcmasp_set_en_mda_filter(intf, ha->addr, mask);
		if (ret) {
			intf->mib.uc_filters_full_cnt++;
			goto set_promisc;
		}
	}

	spin_unlock_bh(&intf->parent->mda_lock);
	return;

set_promisc:
	bcmasp_set_promisc(intf, 1);
	intf->mib.promisc_filters_cnt++;

	/* disable all filters used by this port */
	bcmasp_disable_all_filters(intf);

	spin_unlock_bh(&intf->parent->mda_lock);
}

static void bcmasp_clean_txcb(struct bcmasp_intf *intf, int index)
{
	struct bcmasp_tx_cb *txcb = &intf->tx_cbs[index];

	txcb->skb = NULL;
	dma_unmap_addr_set(txcb, dma_addr, 0);
	dma_unmap_len_set(txcb, dma_len, 0);
	txcb->last = false;
}

static int tx_spb_ring_full(struct bcmasp_intf *intf, int cnt)
{
	int next_index, i;

	/* Check if we have enough room for cnt descriptors */
	for (i = 0; i < cnt; i++) {
		next_index = incr_ring(intf->tx_spb_index, DESC_RING_COUNT);
		if (next_index == intf->tx_spb_clean_index)
			return 1;
	}

	return 0;
}

static struct sk_buff *bcmasp_csum_offload(struct net_device *dev,
					   struct sk_buff *skb,
					   bool *csum_hw)
{
	struct bcmasp_intf *intf = netdev_priv(dev);
	u32 header = 0, header2 = 0, epkt = 0;
	struct bcmasp_pkt_offload *offload;
	unsigned int header_cnt = 0;
	u8 ip_proto;
	int ret;

	if (skb->ip_summed != CHECKSUM_PARTIAL)
		return skb;

	ret = skb_cow_head(skb, sizeof(*offload));
	if (ret < 0) {
		intf->mib.tx_realloc_offload_failed++;
		goto help;
	}

	switch (skb->protocol) {
	case htons(ETH_P_IP):
		header |= PKT_OFFLOAD_HDR_SIZE_2((ip_hdrlen(skb) >> 8) & 0xf);
		header2 |= PKT_OFFLOAD_HDR2_SIZE_2(ip_hdrlen(skb) & 0xff);
		epkt |= PKT_OFFLOAD_EPKT_IP(0) | PKT_OFFLOAD_EPKT_CSUM_L2;
		ip_proto = ip_hdr(skb)->protocol;
		header_cnt += 2;
		break;
	case htons(ETH_P_IPV6):
		header |= PKT_OFFLOAD_HDR_SIZE_2((IP6_HLEN >> 8) & 0xf);
		header2 |= PKT_OFFLOAD_HDR2_SIZE_2(IP6_HLEN & 0xff);
		epkt |= PKT_OFFLOAD_EPKT_IP(1) | PKT_OFFLOAD_EPKT_CSUM_L2;
		ip_proto = ipv6_hdr(skb)->nexthdr;
		header_cnt += 2;
		break;
	default:
		goto help;
	}

	switch (ip_proto) {
	case IPPROTO_TCP:
		header2 |= PKT_OFFLOAD_HDR2_SIZE_3(tcp_hdrlen(skb));
		epkt |= PKT_OFFLOAD_EPKT_TP(0) | PKT_OFFLOAD_EPKT_CSUM_L3;
		header_cnt++;
		break;
	case IPPROTO_UDP:
		header2 |= PKT_OFFLOAD_HDR2_SIZE_3(UDP_HLEN);
		epkt |= PKT_OFFLOAD_EPKT_TP(1) | PKT_OFFLOAD_EPKT_CSUM_L3;
		header_cnt++;
		break;
	default:
		goto help;
	}

	offload = (struct bcmasp_pkt_offload *)skb_push(skb, sizeof(*offload));

	header |= PKT_OFFLOAD_HDR_OP | PKT_OFFLOAD_HDR_COUNT(header_cnt) |
		  PKT_OFFLOAD_HDR_SIZE_1(ETH_HLEN);
	epkt |= PKT_OFFLOAD_EPKT_OP;

	offload->nop = htonl(PKT_OFFLOAD_NOP);
	offload->header = htonl(header);
	offload->header2 = htonl(header2);
	offload->epkt = htonl(epkt);
	offload->end = htonl(PKT_OFFLOAD_END_OP);
	*csum_hw = true;

	return skb;

help:
	skb_checksum_help(skb);

	return skb;
}

static unsigned long bcmasp_rx_edpkt_dma_rq(struct bcmasp_intf *intf)
{
	return rx_edpkt_dma_rq(intf, RX_EDPKT_DMA_VALID);
}

static void bcmasp_rx_edpkt_cfg_wq(struct bcmasp_intf *intf, dma_addr_t addr)
{
	rx_edpkt_cfg_wq(intf, addr, RX_EDPKT_RING_BUFFER_READ);
}

static void bcmasp_rx_edpkt_dma_wq(struct bcmasp_intf *intf, dma_addr_t addr)
{
	rx_edpkt_dma_wq(intf, addr, RX_EDPKT_DMA_READ);
}

static unsigned long bcmasp_tx_spb_dma_rq(struct bcmasp_intf *intf)
{
	return tx_spb_dma_rq(intf, TX_SPB_DMA_READ);
}

static void bcmasp_tx_spb_dma_wq(struct bcmasp_intf *intf, dma_addr_t addr)
{
	tx_spb_dma_wq(intf, addr, TX_SPB_DMA_VALID);
}

static const struct bcmasp_intf_ops bcmasp_intf_ops = {
	.rx_desc_read = bcmasp_rx_edpkt_dma_rq,
	.rx_buffer_write = bcmasp_rx_edpkt_cfg_wq,
	.rx_desc_write = bcmasp_rx_edpkt_dma_wq,
	.tx_read = bcmasp_tx_spb_dma_rq,
	.tx_write = bcmasp_tx_spb_dma_wq,
};

static netdev_tx_t bcmasp_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct bcmasp_intf *intf = netdev_priv(dev);
	unsigned int total_bytes, size;
	int spb_index, nr_frags, i, j;
	struct bcmasp_tx_cb *txcb;
	dma_addr_t mapping, valid;
	struct bcmasp_desc *desc;
	bool csum_hw = false;
	struct device *kdev;
	skb_frag_t *frag;

	kdev = &intf->parent->pdev->dev;

	nr_frags = skb_shinfo(skb)->nr_frags;

	if (tx_spb_ring_full(intf, nr_frags + 1)) {
		netif_stop_queue(dev);
		if (net_ratelimit())
			netdev_err(dev, "Tx Ring Full!\n");
		return NETDEV_TX_BUSY;
	}

	/* Save skb len before adding csum offload header */
	total_bytes = skb->len;
	skb = bcmasp_csum_offload(dev, skb, &csum_hw);
	if (!skb)
		return NETDEV_TX_OK;

	spb_index = intf->tx_spb_index;
	valid = intf->tx_spb_dma_valid;
	for (i = 0; i <= nr_frags; i++) {
		if (!i) {
			size = skb_headlen(skb);
			if (!nr_frags && size < (ETH_ZLEN + ETH_FCS_LEN)) {
				if (skb_put_padto(skb, ETH_ZLEN + ETH_FCS_LEN))
					return NETDEV_TX_OK;
				size = skb->len;
			}
			mapping = dma_map_single(kdev, skb->data, size,
						 DMA_TO_DEVICE);
		} else {
			frag = &skb_shinfo(skb)->frags[i - 1];
			size = skb_frag_size(frag);
			mapping = skb_frag_dma_map(kdev, frag, 0, size,
						   DMA_TO_DEVICE);
		}

		if (dma_mapping_error(kdev, mapping)) {
			intf->mib.tx_dma_failed++;
			spb_index = intf->tx_spb_index;
			for (j = 0; j < i; j++) {
				bcmasp_clean_txcb(intf, spb_index);
				spb_index = incr_ring(spb_index,
						      DESC_RING_COUNT);
			}
			/* Rewind so we do not have a hole */
			spb_index = intf->tx_spb_index;
			return NETDEV_TX_OK;
		}

		txcb = &intf->tx_cbs[spb_index];
		desc = &intf->tx_spb_cpu[spb_index];
		memset(desc, 0, sizeof(*desc));
		txcb->skb = skb;
		txcb->bytes_sent = total_bytes;
		dma_unmap_addr_set(txcb, dma_addr, mapping);
		dma_unmap_len_set(txcb, dma_len, size);
		if (!i) {
			desc->flags |= DESC_SOF;
			if (csum_hw)
				desc->flags |= DESC_EPKT_CMD;
		}

		if (i == nr_frags) {
			desc->flags |= DESC_EOF;
			txcb->last = true;
		}

		desc->buf = mapping;
		desc->size = size;
		desc->flags |= DESC_INT_EN;

		netif_dbg(intf, tx_queued, dev,
			  "%s dma_buf=%pad dma_len=0x%x flags=0x%x index=0x%x\n",
			  __func__, &mapping, desc->size, desc->flags,
			  spb_index);

		spb_index = incr_ring(spb_index, DESC_RING_COUNT);
		valid = incr_last_byte(valid, intf->tx_spb_dma_addr,
				       DESC_RING_COUNT);
	}

	/* Ensure all descriptors have been written to DRAM for the
	 * hardware to see up-to-date contents.
	 */
	wmb();

	intf->tx_spb_index = spb_index;
	intf->tx_spb_dma_valid = valid;
	bcmasp_intf_tx_write(intf, intf->tx_spb_dma_valid);

	if (tx_spb_ring_full(intf, MAX_SKB_FRAGS + 1))
		netif_stop_queue(dev);

	return NETDEV_TX_OK;
}

static void bcmasp_netif_start(struct net_device *dev)
{
	struct bcmasp_intf *intf = netdev_priv(dev);

	bcmasp_set_rx_mode(dev);
	napi_enable(&intf->tx_napi);
	napi_enable(&intf->rx_napi);

	bcmasp_enable_rx_irq(intf, 1);
	bcmasp_enable_tx_irq(intf, 1);
	bcmasp_enable_phy_irq(intf, 1);

	phy_start(dev->phydev);
}

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);
}

static void umac_set_hw_addr(struct bcmasp_intf *intf,
			     const unsigned char *addr)
{
	u32 mac0 = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) |
		    addr[3];
	u32 mac1 = (addr[4] << 8) | addr[5];

	umac_wl(intf, mac0, UMC_MAC0);
	umac_wl(intf, mac1, UMC_MAC1);
}

static void umac_enable_set(struct bcmasp_intf *intf, u32 mask,
			    unsigned int enable)
{
	u32 reg;

	reg = umac_rl(intf, UMC_CMD);
	if (enable)
		reg |= mask;
	else
		reg &= ~mask;
	umac_wl(intf, reg, UMC_CMD);

	/* UniMAC stops on a packet boundary, wait for a full-sized packet
	 * to be processed (1 msec).
	 */
	if (enable == 0)
		usleep_range(1000, 2000);
}

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)
{
	struct bcmasp_intf *intf =
		container_of(napi, struct bcmasp_intf, tx_napi);
	struct bcmasp_intf_stats64 *stats = &intf->stats64;
	struct device *kdev = &intf->parent->pdev->dev;
	unsigned long read, released = 0;
	struct bcmasp_tx_cb *txcb;
	struct bcmasp_desc *desc;
	dma_addr_t mapping;

	read = bcmasp_intf_tx_read(intf);
	while (intf->tx_spb_dma_read != read) {
		txcb = &intf->tx_cbs[intf->tx_spb_clean_index];
		mapping = dma_unmap_addr(txcb, dma_addr);

		dma_unmap_single(kdev, mapping,
				 dma_unmap_len(txcb, dma_len),
				 DMA_TO_DEVICE);

		if (txcb->last) {
			dev_consume_skb_any(txcb->skb);

			u64_stats_update_begin(&stats->syncp);
			u64_stats_inc(&stats->tx_packets);
			u64_stats_add(&stats->tx_bytes, txcb->bytes_sent);
			u64_stats_update_end(&stats->syncp);
		}

		desc = &intf->tx_spb_cpu[intf->tx_spb_clean_index];

		netif_dbg(intf, tx_done, intf->ndev,
			  "%s dma_buf=%pad dma_len=0x%x flags=0x%x c_index=0x%x\n",
			  __func__, &mapping, desc->size, desc->flags,
			  intf->tx_spb_clean_index);

		bcmasp_clean_txcb(intf, intf->tx_spb_clean_index);
		released++;

		intf->tx_spb_clean_index = incr_ring(intf->tx_spb_clean_index,
						     DESC_RING_COUNT);
		intf->tx_spb_dma_read = incr_first_byte(intf->tx_spb_dma_read,
							intf->tx_spb_dma_addr,
							DESC_RING_COUNT);
	}

	/* Ensure all descriptors have been written to DRAM for the hardware
	 * to see updated contents.
	 */
	wmb();

	napi_complete(&intf->tx_napi);

	bcmasp_enable_tx_irq(intf, 1);

	if (released)
		netif_wake_queue(intf->ndev);

	return 0;
}

static int bcmasp_rx_poll(struct napi_struct *napi, int budget)
{
	struct bcmasp_intf *intf =
		container_of(napi, struct bcmasp_intf, rx_napi);
	struct bcmasp_intf_stats64 *stats = &intf->stats64;
	struct device *kdev = &intf->parent->pdev->dev;
	unsigned long processed = 0;
	struct bcmasp_desc *desc;
	struct sk_buff *skb;
	dma_addr_t valid;
	void *data;
	u64 flags;
	u32 len;

	valid = bcmasp_intf_rx_desc_read(intf) + 1;
	if (valid == intf->rx_edpkt_dma_addr + DESC_RING_SIZE)
		valid = intf->rx_edpkt_dma_addr;

	while ((processed < budget) && (valid != intf->rx_edpkt_dma_read)) {
		desc = &intf->rx_edpkt_cpu[intf->rx_edpkt_index];

		/* Ensure that descriptor has been fully written to DRAM by
		 * hardware before reading by the CPU
		 */
		rmb();

		/* Calculate virt addr by offsetting from physical addr */
		data = intf->rx_ring_cpu +
			(DESC_ADDR(desc->buf) - intf->rx_ring_dma);

		flags = DESC_FLAGS(desc->buf);
		if (unlikely(flags & (DESC_CRC_ERR | DESC_RX_SYM_ERR))) {
			if (net_ratelimit()) {
				netif_err(intf, rx_status, intf->ndev,
					  "flags=0x%llx\n", flags);
			}

			u64_stats_update_begin(&stats->syncp);
			if (flags & DESC_CRC_ERR)
				u64_stats_inc(&stats->rx_crc_errs);
			if (flags & DESC_RX_SYM_ERR)
				u64_stats_inc(&stats->rx_sym_errs);
			u64_stats_update_end(&stats->syncp);

			goto next;
		}

		dma_sync_single_for_cpu(kdev, DESC_ADDR(desc->buf), desc->size,
					DMA_FROM_DEVICE);

		len = desc->size;

		skb = napi_alloc_skb(napi, len);
		if (!skb) {
			u64_stats_update_begin(&stats->syncp);
			u64_stats_inc(&stats->rx_dropped);
			u64_stats_update_end(&stats->syncp);
			intf->mib.alloc_rx_skb_failed++;

			goto next;
		}

		skb_put(skb, len);
		memcpy(skb->data, data, len);

		skb_pull(skb, 2);
		len -= 2;
		if (likely(intf->crc_fwd)) {
			skb_trim(skb, len - ETH_FCS_LEN);
			len -= ETH_FCS_LEN;
		}

		if ((intf->ndev->features & NETIF_F_RXCSUM) &&
		    (desc->buf & DESC_CHKSUM))
			skb->ip_summed = CHECKSUM_UNNECESSARY;

		skb->protocol = eth_type_trans(skb, intf->ndev);

		napi_gro_receive(napi, skb);

		u64_stats_update_begin(&stats->syncp);
		u64_stats_inc(&stats->rx_packets);
		u64_stats_add(&stats->rx_bytes, len);
		u64_stats_update_end(&stats->syncp);

next:
		bcmasp_intf_rx_buffer_write(intf, (DESC_ADDR(desc->buf) +
					    desc->size));

		processed++;
		intf->rx_edpkt_dma_read =
			incr_first_byte(intf->rx_edpkt_dma_read,
					intf->rx_edpkt_dma_addr,
					DESC_RING_COUNT);
		intf->rx_edpkt_index = incr_ring(intf->rx_edpkt_index,
						 DESC_RING_COUNT);
	}

	bcmasp_intf_rx_desc_write(intf, intf->rx_edpkt_dma_read);

	if (processed < budget) {
		napi_complete_done(&intf->rx_napi, processed);
		bcmasp_enable_rx_irq(intf, 1);
	}

	return processed;
}

static void bcmasp_adj_link(struct net_device *dev)
{
	struct bcmasp_intf *intf = netdev_priv(dev);
	struct phy_device *phydev = dev->phydev;
	u32 cmd_bits = 0, reg;
	int changed = 0;
	bool active;

	if (intf->old_link != phydev->link) {
		changed = 1;
		intf->old_link = phydev->link;
	}

	if (intf->old_duplex != phydev->duplex) {
		changed = 1;
		intf->old_duplex = phydev->duplex;
	}

	switch (phydev->speed) {
	case SPEED_2500:
		cmd_bits = UMC_CMD_SPEED_2500;
		break;
	case SPEED_1000:
		cmd_bits = UMC_CMD_SPEED_1000;
		break;
	case SPEED_100:
		cmd_bits = UMC_CMD_SPEED_100;
		break;
	case SPEED_10:
		cmd_bits = UMC_CMD_SPEED_10;
		break;
	default:
		break;
	}
	cmd_bits <<= UMC_CMD_SPEED_SHIFT;

	if (phydev->duplex == DUPLEX_HALF)
		cmd_bits |= UMC_CMD_HD_EN;

	if (intf->old_pause != phydev->pause) {
		changed = 1;
		intf->old_pause = phydev->pause;
	}

	if (!phydev->pause)
		cmd_bits |= UMC_CMD_RX_PAUSE_IGNORE | UMC_CMD_TX_PAUSE_IGNORE;

	if (!changed)
		return;

	if (phydev->link) {
		reg = umac_rl(intf, UMC_CMD);
		reg &= ~((UMC_CMD_SPEED_MASK << UMC_CMD_SPEED_SHIFT) |
			UMC_CMD_HD_EN | UMC_CMD_RX_PAUSE_IGNORE |
			UMC_CMD_TX_PAUSE_IGNORE);
		reg |= cmd_bits;
		umac_wl(intf, reg, UMC_CMD);

		active = phy_init_eee(phydev, 0) >= 0;
		bcmasp_eee_enable_set(intf, active);
	}

	reg = rgmii_rl(intf, RGMII_OOB_CNTRL);
	if (phydev->link)
		reg |= RGMII_LINK;
	else
		reg &= ~RGMII_LINK;
	rgmii_wl(intf, reg, RGMII_OOB_CNTRL);

	if (changed)
		phy_print_status(phydev);
}

static int bcmasp_alloc_buffers(struct bcmasp_intf *intf)
{
	struct device *kdev = &intf->parent->pdev->dev;
	struct page *buffer_pg;

	/* Alloc RX */
	intf->rx_buf_order = get_order(RING_BUFFER_SIZE);
	buffer_pg = alloc_pages(GFP_KERNEL, intf->rx_buf_order);
	if (!buffer_pg)
		return -ENOMEM;

	intf->rx_ring_cpu = page_to_virt(buffer_pg);
	intf->rx_ring_dma = dma_map_page(kdev, buffer_pg, 0, RING_BUFFER_SIZE,
					 DMA_FROM_DEVICE);
	if (dma_mapping_error(kdev, intf->rx_ring_dma))
		goto free_rx_buffer;

	intf->rx_edpkt_cpu = dma_alloc_coherent(kdev, DESC_RING_SIZE,
						&intf->rx_edpkt_dma_addr, GFP_KERNEL);
	if (!intf->rx_edpkt_cpu)
		goto free_rx_buffer_dma;

	/* Alloc TX */
	intf->tx_spb_cpu = dma_alloc_coherent(kdev, DESC_RING_SIZE,
					      &intf->tx_spb_dma_addr, GFP_KERNEL);
	if (!intf->tx_spb_cpu)
		goto free_rx_edpkt_dma;

	intf->tx_cbs = kcalloc(DESC_RING_COUNT, sizeof(struct bcmasp_tx_cb),
			       GFP_KERNEL);
	if (!intf->tx_cbs)
		goto free_tx_spb_dma;

	return 0;

free_tx_spb_dma:
	dma_free_coherent(kdev, DESC_RING_SIZE, intf->tx_spb_cpu,
			  intf->tx_spb_dma_addr);
free_rx_edpkt_dma:
	dma_free_coherent(kdev, DESC_RING_SIZE, intf->rx_edpkt_cpu,
			  intf->rx_edpkt_dma_addr);
free_rx_buffer_dma:
	dma_unmap_page(kdev, intf->rx_ring_dma, RING_BUFFER_SIZE,
		       DMA_FROM_DEVICE);
free_rx_buffer:
	__free_pages(buffer_pg, intf->rx_buf_order);

	return -ENOMEM;
}

static void bcmasp_reclaim_free_buffers(struct bcmasp_intf *intf)
{
	struct device *kdev = &intf->parent->pdev->dev;

	/* RX buffers */
	dma_free_coherent(kdev, DESC_RING_SIZE, intf->rx_edpkt_cpu,
			  intf->rx_edpkt_dma_addr);
	dma_unmap_page(kdev, intf->rx_ring_dma, RING_BUFFER_SIZE,
		       DMA_FROM_DEVICE);
	__free_pages(virt_to_page(intf->rx_ring_cpu), intf->rx_buf_order);

	/* TX buffers */
	dma_free_coherent(kdev, DESC_RING_SIZE, intf->tx_spb_cpu,
			  intf->tx_spb_dma_addr);
	kfree(intf->tx_cbs);
}

static void bcmasp_init_rx(struct bcmasp_intf *intf)
{
	/* Restart from index 0 */
	intf->rx_ring_dma_valid = intf->rx_ring_dma + RING_BUFFER_SIZE - 1;
	intf->rx_edpkt_dma_valid = intf->rx_edpkt_dma_addr + (DESC_RING_SIZE - 1);
	intf->rx_edpkt_dma_read = intf->rx_edpkt_dma_addr;
	intf->rx_edpkt_index = 0;

	/* Make sure channels are disabled */
	rx_edpkt_cfg_wl(intf, 0x0, RX_EDPKT_CFG_ENABLE);

	/* Rx SPB */
	rx_edpkt_cfg_wq(intf, intf->rx_ring_dma, RX_EDPKT_RING_BUFFER_READ);
	rx_edpkt_cfg_wq(intf, intf->rx_ring_dma, RX_EDPKT_RING_BUFFER_WRITE);
	rx_edpkt_cfg_wq(intf, intf->rx_ring_dma, RX_EDPKT_RING_BUFFER_BASE);
	rx_edpkt_cfg_wq(intf, intf->rx_ring_dma_valid,
			RX_EDPKT_RING_BUFFER_END);
	rx_edpkt_cfg_wq(intf, intf->rx_ring_dma_valid,
			RX_EDPKT_RING_BUFFER_VALID);

	/* EDPKT */
	rx_edpkt_cfg_wl(intf, (RX_EDPKT_CFG_CFG0_RBUF_4K <<
			RX_EDPKT_CFG_CFG0_DBUF_SHIFT) |
		       (RX_EDPKT_CFG_CFG0_64_ALN <<
			RX_EDPKT_CFG_CFG0_BALN_SHIFT) |
		       (RX_EDPKT_CFG_CFG0_EFRM_STUF),
			RX_EDPKT_CFG_CFG0);
	rx_edpkt_dma_wq(intf, intf->rx_edpkt_dma_addr, RX_EDPKT_DMA_WRITE);
	rx_edpkt_dma_wq(intf, intf->rx_edpkt_dma_addr, RX_EDPKT_DMA_READ);
	rx_edpkt_dma_wq(intf, intf->rx_edpkt_dma_addr, RX_EDPKT_DMA_BASE);
	rx_edpkt_dma_wq(intf, intf->rx_edpkt_dma_valid, RX_EDPKT_DMA_END);
	rx_edpkt_dma_wq(intf, intf->rx_edpkt_dma_valid, RX_EDPKT_DMA_VALID);

	umac2fb_wl(intf, UMAC2FB_CFG_DEFAULT_EN | ((intf->channel + 11) <<
		   UMAC2FB_CFG_CHID_SHIFT) | (0xd << UMAC2FB_CFG_OK_SEND_SHIFT),
		   UMAC2FB_CFG);
}


static void bcmasp_init_tx(struct bcmasp_intf *intf)
{
	/* Restart from index 0 */
	intf->tx_spb_dma_valid = intf->tx_spb_dma_addr + DESC_RING_SIZE - 1;
	intf->tx_spb_dma_read = intf->tx_spb_dma_addr;
	intf->tx_spb_index = 0;
	intf->tx_spb_clean_index = 0;

	/* Make sure channels are disabled */
	tx_spb_ctrl_wl(intf, 0x0, TX_SPB_CTRL_ENABLE);
	tx_epkt_core_wl(intf, 0x0, TX_EPKT_C_CFG_MISC);

	/* Tx SPB */
	tx_spb_ctrl_wl(intf, ((intf->channel + 8) << TX_SPB_CTRL_XF_BID_SHIFT),
		       TX_SPB_CTRL_XF_CTRL2);
	tx_pause_ctrl_wl(intf, (1 << (intf->channel + 8)), TX_PAUSE_MAP_VECTOR);
	tx_spb_top_wl(intf, 0x1e, TX_SPB_TOP_BLKOUT);
	tx_spb_top_wl(intf, 0x0, TX_SPB_TOP_SPRE_BW_CTRL);

	tx_spb_dma_wq(intf, intf->tx_spb_dma_addr, TX_SPB_DMA_READ);
	tx_spb_dma_wq(intf, intf->tx_spb_dma_addr, TX_SPB_DMA_BASE);
	tx_spb_dma_wq(intf, intf->tx_spb_dma_valid, TX_SPB_DMA_END);
	tx_spb_dma_wq(intf, intf->tx_spb_dma_valid, TX_SPB_DMA_VALID);
}

static void bcmasp_ephy_enable_set(struct bcmasp_intf *intf, bool enable)
{
	u32 mask = RGMII_EPHY_CFG_IDDQ_BIAS | RGMII_EPHY_CFG_EXT_PWRDOWN |
		   RGMII_EPHY_CFG_IDDQ_GLOBAL;
	u32 reg;

	reg = rgmii_rl(intf, RGMII_EPHY_CNTRL);
	if (enable) {
		reg &= ~RGMII_EPHY_CK25_DIS;
		rgmii_wl(intf, reg, RGMII_EPHY_CNTRL);
		mdelay(1);

		reg &= ~mask;
		reg |= RGMII_EPHY_RESET;
		rgmii_wl(intf, reg, RGMII_EPHY_CNTRL);
		mdelay(1);

		reg &= ~RGMII_EPHY_RESET;
	} else {
		reg |= mask | RGMII_EPHY_RESET;
		rgmii_wl(intf, reg, RGMII_EPHY_CNTRL);
		mdelay(1);
		reg |= RGMII_EPHY_CK25_DIS;
	}
	rgmii_wl(intf, reg, RGMII_EPHY_CNTRL);
	mdelay(1);

	/* Set or clear the LED control override to avoid lighting up LEDs
	 * while the EPHY is powered off and drawing unnecessary current.
	 */
	reg = rgmii_rl(intf, RGMII_SYS_LED_CNTRL);
	if (enable)
		reg &= ~RGMII_SYS_LED_CNTRL_LINK_OVRD;
	else
		reg |= RGMII_SYS_LED_CNTRL_LINK_OVRD;
	rgmii_wl(intf, reg, RGMII_SYS_LED_CNTRL);
}

static void bcmasp_rgmii_mode_en_set(struct bcmasp_intf *intf, bool enable)
{
	u32 reg;

	reg = rgmii_rl(intf, RGMII_OOB_CNTRL);
	reg &= ~RGMII_OOB_DIS;
	if (enable)
		reg |= RGMII_MODE_EN;
	else
		reg &= ~RGMII_MODE_EN;
	rgmii_wl(intf, reg, RGMII_OOB_CNTRL);
}

static void bcmasp_netif_deinit(struct net_device *dev)
{
	struct bcmasp_intf *intf = netdev_priv(dev);
	u32 reg, timeout = 1000;

	napi_disable(&intf->tx_napi);

	bcmasp_enable_tx(intf, 0);

	/* Flush any TX packets in the pipe */
	tx_spb_dma_wl(intf, TX_SPB_DMA_FIFO_FLUSH, TX_SPB_DMA_FIFO_CTRL);
	do {
		reg = tx_spb_dma_rl(intf, TX_SPB_DMA_FIFO_STATUS);
		if (!(reg & TX_SPB_DMA_FIFO_FLUSH))
			break;
		usleep_range(1000, 2000);
	} while (timeout-- > 0);
	tx_spb_dma_wl(intf, 0x0, TX_SPB_DMA_FIFO_CTRL);

	umac_enable_set(intf, UMC_CMD_TX_EN, 0);

	phy_stop(dev->phydev);

	umac_enable_set(intf, UMC_CMD_RX_EN, 0);

	bcmasp_flush_rx_port(intf);
	usleep_range(1000, 2000);
	bcmasp_enable_rx(intf, 0);

	napi_disable(&intf->rx_napi);

	/* Disable interrupts */
	bcmasp_enable_tx_irq(intf, 0);
	bcmasp_enable_rx_irq(intf, 0);
	bcmasp_enable_phy_irq(intf, 0);

	netif_napi_del(&intf->tx_napi);
	netif_napi_del(&intf->rx_napi);
}

static int bcmasp_stop(struct net_device *dev)
{
	struct bcmasp_intf *intf = netdev_priv(dev);

	netif_dbg(intf, ifdown, dev, "bcmasp stop\n");

	/* Stop tx from updating HW */
	netif_tx_disable(dev);

	bcmasp_netif_deinit(dev);

	bcmasp_reclaim_free_buffers(intf);

	phy_disconnect(dev->phydev);

	/* Disable internal EPHY or external PHY */
	if (intf->internal_phy)
		bcmasp_ephy_enable_set(intf, false);
	else
		bcmasp_rgmii_mode_en_set(intf, false);

	/* Disable the interface clocks */
	bcmasp_core_clock_set_intf(intf, false);

	clk_disable_unprepare(intf->parent->clk);

	return 0;
}

static void bcmasp_configure_port(struct bcmasp_intf *intf)
{
	u32 reg, id_mode_dis = 0;

	reg = rgmii_rl(intf, RGMII_PORT_CNTRL);
	reg &= ~RGMII_PORT_MODE_MASK;

	switch (intf->phy_interface) {
	case PHY_INTERFACE_MODE_RGMII:
		/* RGMII_NO_ID: TXC transitions at the same time as TXD
		 *		(requires PCB or receiver-side delay)
		 * RGMII:	Add 2ns delay on TXC (90 degree shift)
		 *
		 * ID is implicitly disabled for 100Mbps (RG)MII operation.
		 */
		id_mode_dis = RGMII_ID_MODE_DIS;
		fallthrough;
	case PHY_INTERFACE_MODE_RGMII_TXID:
		reg |= RGMII_PORT_MODE_EXT_GPHY;
		break;
	case PHY_INTERFACE_MODE_MII:
		reg |= RGMII_PORT_MODE_EXT_EPHY;
		break;
	default:
		break;
	}

	if (intf->internal_phy)
		reg |= RGMII_PORT_MODE_EPHY;

	rgmii_wl(intf, reg, RGMII_PORT_CNTRL);

	reg = rgmii_rl(intf, RGMII_OOB_CNTRL);
	reg &= ~RGMII_ID_MODE_DIS;
	reg |= id_mode_dis;
	rgmii_wl(intf, reg, RGMII_OOB_CNTRL);
}

static int bcmasp_netif_init(struct net_device *dev, bool phy_connect)
{
	struct bcmasp_intf *intf = netdev_priv(dev);
	phy_interface_t phy_iface = intf->phy_interface;
	u32 phy_flags = PHY_BRCM_AUTO_PWRDWN_ENABLE |
			PHY_BRCM_DIS_TXCRXC_NOENRGY |
			PHY_BRCM_IDDQ_SUSPEND;
	struct phy_device *phydev = NULL;
	int ret;

	/* Always enable interface clocks */
	bcmasp_core_clock_set_intf(intf, true);

	/* Enable internal PHY or external PHY before any MAC activity */
	if (intf->internal_phy)
		bcmasp_ephy_enable_set(intf, true);
	else
		bcmasp_rgmii_mode_en_set(intf, true);
	bcmasp_configure_port(intf);

	/* This is an ugly quirk but we have not been correctly
	 * interpreting the phy_interface values and we have done that
	 * across different drivers, so at least we are consistent in
	 * our mistakes.
	 *
	 * When the Generic PHY driver is in use either the PHY has
	 * been strapped or programmed correctly by the boot loader so
	 * we should stick to our incorrect interpretation since we
	 * have validated it.
	 *
	 * Now when a dedicated PHY driver is in use, we need to
	 * reverse the meaning of the phy_interface_mode values to
	 * something that the PHY driver will interpret and act on such
	 * that we have two mistakes canceling themselves so to speak.
	 * We only do this for the two modes that GENET driver
	 * officially supports on Broadcom STB chips:
	 * PHY_INTERFACE_MODE_RGMII and PHY_INTERFACE_MODE_RGMII_TXID.
	 * Other modes are not *officially* supported with the boot
	 * loader and the scripted environment generating Device Tree
	 * blobs for those platforms.
	 *
	 * Note that internal PHY and fixed-link configurations are not
	 * affected because they use different phy_interface_t values
	 * or the Generic PHY driver.
	 */
	switch (phy_iface) {
	case PHY_INTERFACE_MODE_RGMII:
		phy_iface = PHY_INTERFACE_MODE_RGMII_ID;
		break;
	case PHY_INTERFACE_MODE_RGMII_TXID:
		phy_iface = PHY_INTERFACE_MODE_RGMII_RXID;
		break;
	default:
		break;
	}

	if (phy_connect) {
		phydev = of_phy_connect(dev, intf->phy_dn,
					bcmasp_adj_link, phy_flags,
					phy_iface);
		if (!phydev) {
			ret = -ENODEV;
			netdev_err(dev, "could not attach to PHY\n");
			goto err_phy_disable;
		}

		if (intf->internal_phy)
			dev->phydev->irq = PHY_MAC_INTERRUPT;

		/* Indicate that the MAC is responsible for PHY PM */
		phydev->mac_managed_pm = true;
	} else if (!intf->wolopts) {
		ret = phy_resume(dev->phydev);
		if (ret)
			goto err_phy_disable;
	}

	umac_reset(intf);

	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;
	intf->old_link = -1;
	intf->old_pause = -1;

	bcmasp_init_tx(intf);
	netif_napi_add_tx(intf->ndev, &intf->tx_napi, bcmasp_tx_poll);
	bcmasp_enable_tx(intf, 1);

	bcmasp_init_rx(intf);
	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);

	netif_start_queue(dev);

	return 0;

err_phy_disable:
	if (intf->internal_phy)
		bcmasp_ephy_enable_set(intf, false);
	else
		bcmasp_rgmii_mode_en_set(intf, false);
	return ret;
}

static int bcmasp_open(struct net_device *dev)
{
	struct bcmasp_intf *intf = netdev_priv(dev);
	int ret;

	netif_dbg(intf, ifup, dev, "bcmasp open\n");

	ret = bcmasp_alloc_buffers(intf);
	if (ret)
		return ret;

	ret = clk_prepare_enable(intf->parent->clk);
	if (ret)
		goto err_free_mem;

	ret = bcmasp_netif_init(dev, true);
	if (ret) {
		clk_disable_unprepare(intf->parent->clk);
		goto err_free_mem;
	}

	return ret;

err_free_mem:
	bcmasp_reclaim_free_buffers(intf);

	return ret;
}

static void bcmasp_tx_timeout(struct net_device *dev, unsigned int txqueue)
{
	struct bcmasp_intf *intf = netdev_priv(dev);

	netif_dbg(intf, tx_err, dev, "transmit timeout!\n");
	intf->mib.tx_timeout_cnt++;
}

static int bcmasp_get_phys_port_name(struct net_device *dev,
				     char *name, size_t len)
{
	struct bcmasp_intf *intf = netdev_priv(dev);

	if (snprintf(name, len, "p%d", intf->port) >= len)
		return -EINVAL;

	return 0;
}

static void bcmasp_get_stats64(struct net_device *dev,
			       struct rtnl_link_stats64 *stats)
{
	struct bcmasp_intf *intf = netdev_priv(dev);
	struct bcmasp_intf_stats64 *lstats;
	unsigned int start;

	lstats = &intf->stats64;

	do {
		start = u64_stats_fetch_begin(&lstats->syncp);
		stats->rx_packets = u64_stats_read(&lstats->rx_packets);
		stats->rx_bytes = u64_stats_read(&lstats->rx_bytes);
		stats->rx_dropped = u64_stats_read(&lstats->rx_dropped);
		stats->rx_crc_errors = u64_stats_read(&lstats->rx_crc_errs);
		stats->rx_frame_errors = u64_stats_read(&lstats->rx_sym_errs);
		stats->rx_errors = stats->rx_crc_errors + stats->rx_frame_errors;

		stats->tx_packets = u64_stats_read(&lstats->tx_packets);
		stats->tx_bytes = u64_stats_read(&lstats->tx_bytes);
	} while (u64_stats_fetch_retry(&lstats->syncp, start));
}

static const struct net_device_ops bcmasp_netdev_ops = {
	.ndo_open		= bcmasp_open,
	.ndo_stop		= bcmasp_stop,
	.ndo_start_xmit		= bcmasp_xmit,
	.ndo_tx_timeout		= bcmasp_tx_timeout,
	.ndo_set_rx_mode	= bcmasp_set_rx_mode,
	.ndo_get_phys_port_name	= bcmasp_get_phys_port_name,
	.ndo_eth_ioctl		= phy_do_ioctl_running,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_get_stats64	= bcmasp_get_stats64,
};

static void bcmasp_map_res(struct bcmasp_priv *priv, struct bcmasp_intf *intf)
{
	/* Per port */
	intf->res.umac = priv->base + UMC_OFFSET(intf);
	intf->res.umac2fb = priv->base + (priv->hw_info->umac2fb +
					  (intf->port * 0x4));
	intf->res.rgmii = priv->base + RGMII_OFFSET(intf);

	/* Per ch */
	intf->tx_spb_dma = priv->base + TX_SPB_DMA_OFFSET(intf);
	intf->res.tx_spb_ctrl = priv->base + TX_SPB_CTRL_OFFSET(intf);
	intf->res.tx_spb_top = priv->base + TX_SPB_TOP_OFFSET(intf);
	intf->res.tx_epkt_core = priv->base + TX_EPKT_C_OFFSET(intf);
	intf->res.tx_pause_ctrl = priv->base + TX_PAUSE_CTRL_OFFSET(intf);

	intf->rx_edpkt_dma = priv->base + RX_EDPKT_DMA_OFFSET(intf);
	intf->rx_edpkt_cfg = priv->base + RX_EDPKT_CFG_OFFSET(intf);
}

#define MAX_IRQ_STR_LEN		64
struct bcmasp_intf *bcmasp_interface_create(struct bcmasp_priv *priv,
					    struct device_node *ndev_dn, int i)
{
	struct device *dev = &priv->pdev->dev;
	struct bcmasp_intf *intf;
	struct net_device *ndev;
	int ch, port, ret;

	if (of_property_read_u32(ndev_dn, "reg", &port)) {
		dev_warn(dev, "%s: invalid port number\n", ndev_dn->name);
		goto err;
	}

	if (of_property_read_u32(ndev_dn, "brcm,channel", &ch)) {
		dev_warn(dev, "%s: invalid ch number\n", ndev_dn->name);
		goto err;
	}

	ndev = alloc_etherdev(sizeof(struct bcmasp_intf));
	if (!ndev) {
		dev_warn(dev, "%s: unable to alloc ndev\n", ndev_dn->name);
		goto err;
	}
	intf = netdev_priv(ndev);

	intf->parent = priv;
	intf->ndev = ndev;
	intf->channel = ch;
	intf->port = port;
	intf->ndev_dn = ndev_dn;
	intf->index = i;

	ret = of_get_phy_mode(ndev_dn, &intf->phy_interface);
	if (ret < 0) {
		dev_err(dev, "invalid PHY mode property\n");
		goto err_free_netdev;
	}

	if (intf->phy_interface == PHY_INTERFACE_MODE_INTERNAL)
		intf->internal_phy = true;

	intf->phy_dn = of_parse_phandle(ndev_dn, "phy-handle", 0);
	if (!intf->phy_dn && of_phy_is_fixed_link(ndev_dn)) {
		ret = of_phy_register_fixed_link(ndev_dn);
		if (ret) {
			dev_warn(dev, "%s: failed to register fixed PHY\n",
				 ndev_dn->name);
			goto err_free_netdev;
		}
		intf->phy_dn = ndev_dn;
	}

	/* Map resource */
	bcmasp_map_res(priv, intf);

	if ((!phy_interface_mode_is_rgmii(intf->phy_interface) &&
	     intf->phy_interface != PHY_INTERFACE_MODE_MII &&
	     intf->phy_interface != PHY_INTERFACE_MODE_INTERNAL) ||
	    (intf->port != 1 && intf->internal_phy)) {
		netdev_err(intf->ndev, "invalid PHY mode: %s for port %d\n",
			   phy_modes(intf->phy_interface), intf->port);
		ret = -EINVAL;
		goto err_free_netdev;
	}

	ret = of_get_ethdev_address(ndev_dn, ndev);
	if (ret) {
		netdev_warn(ndev, "using random Ethernet MAC\n");
		eth_hw_addr_random(ndev);
	}

	SET_NETDEV_DEV(ndev, dev);
	intf->ops = &bcmasp_intf_ops;
	ndev->netdev_ops = &bcmasp_netdev_ops;
	ndev->ethtool_ops = &bcmasp_ethtool_ops;
	intf->msg_enable = netif_msg_init(-1, NETIF_MSG_DRV |
					  NETIF_MSG_PROBE |
					  NETIF_MSG_LINK);
	ndev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
			  NETIF_F_RXCSUM;
	ndev->hw_features |= ndev->features;
	ndev->needed_headroom += sizeof(struct bcmasp_pkt_offload);

	return intf;

err_free_netdev:
	free_netdev(ndev);
err:
	return NULL;
}

void bcmasp_interface_destroy(struct bcmasp_intf *intf)
{
	if (intf->ndev->reg_state == NETREG_REGISTERED)
		unregister_netdev(intf->ndev);
	if (of_phy_is_fixed_link(intf->ndev_dn))
		of_phy_deregister_fixed_link(intf->ndev_dn);
	free_netdev(intf->ndev);
}

static void bcmasp_suspend_to_wol(struct bcmasp_intf *intf)
{
	struct net_device *ndev = intf->ndev;
	u32 reg;

	reg = umac_rl(intf, UMC_MPD_CTRL);
	if (intf->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE))
		reg |= UMC_MPD_CTRL_MPD_EN;
	reg &= ~UMC_MPD_CTRL_PSW_EN;
	if (intf->wolopts & WAKE_MAGICSECURE) {
		/* Program the SecureOn password */
		umac_wl(intf, get_unaligned_be16(&intf->sopass[0]),
			UMC_PSW_MS);
		umac_wl(intf, get_unaligned_be32(&intf->sopass[2]),
			UMC_PSW_LS);
		reg |= UMC_MPD_CTRL_PSW_EN;
	}
	umac_wl(intf, reg, UMC_MPD_CTRL);

	if (intf->wolopts & WAKE_FILTER)
		bcmasp_netfilt_suspend(intf);

	/* UniMAC receive needs to be turned on */
	umac_enable_set(intf, UMC_CMD_RX_EN, 1);

	if (intf->parent->wol_irq > 0) {
		wakeup_intr2_core_wl(intf->parent, 0xffffffff,
				     ASP_WAKEUP_INTR2_MASK_CLEAR);
	}

	if (intf->eee.eee_enabled && intf->parent->eee_fixup)
		intf->parent->eee_fixup(intf, true);

	netif_dbg(intf, wol, ndev, "entered WOL mode\n");
}

int bcmasp_interface_suspend(struct bcmasp_intf *intf)
{
	struct device *kdev = &intf->parent->pdev->dev;
	struct net_device *dev = intf->ndev;
	int ret = 0;

	if (!netif_running(dev))
		return 0;

	netif_device_detach(dev);

	bcmasp_netif_deinit(dev);

	if (!intf->wolopts) {
		ret = phy_suspend(dev->phydev);
		if (ret)
			goto out;

		if (intf->internal_phy)
			bcmasp_ephy_enable_set(intf, false);
		else
			bcmasp_rgmii_mode_en_set(intf, false);

		/* If Wake-on-LAN is disabled, we can safely
		 * disable the network interface clocks.
		 */
		bcmasp_core_clock_set_intf(intf, false);
	}

	if (device_may_wakeup(kdev) && intf->wolopts)
		bcmasp_suspend_to_wol(intf);

	clk_disable_unprepare(intf->parent->clk);

	return ret;

out:
	bcmasp_netif_init(dev, false);
	return ret;
}

static void bcmasp_resume_from_wol(struct bcmasp_intf *intf)
{
	u32 reg;

	if (intf->eee.eee_enabled && intf->parent->eee_fixup)
		intf->parent->eee_fixup(intf, false);

	reg = umac_rl(intf, UMC_MPD_CTRL);
	reg &= ~UMC_MPD_CTRL_MPD_EN;
	umac_wl(intf, reg, UMC_MPD_CTRL);

	if (intf->parent->wol_irq > 0) {
		wakeup_intr2_core_wl(intf->parent, 0xffffffff,
				     ASP_WAKEUP_INTR2_MASK_SET);
	}
}

int bcmasp_interface_resume(struct bcmasp_intf *intf)
{
	struct net_device *dev = intf->ndev;
	int ret;

	if (!netif_running(dev))
		return 0;

	ret = clk_prepare_enable(intf->parent->clk);
	if (ret)
		return ret;

	ret = bcmasp_netif_init(dev, false);
	if (ret)
		goto out;

	bcmasp_resume_from_wol(intf);

	if (intf->eee.eee_enabled)
		bcmasp_eee_enable_set(intf, true);

	netif_device_attach(dev);

	return 0;

out:
	clk_disable_unprepare(intf->parent->clk);
	return ret;
}
