// SPDX-License-Identifier: GPL-2.0
/*
 * Texas Instruments Ethernet Switch Driver
 *
 * Copyright (C) 2019 Texas Instruments
 */

#include <linux/io.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/timer.h>
#include <linux/module.h>
#include <linux/irqreturn.h>
#include <linux/interrupt.h>
#include <linux/if_ether.h>
#include <linux/etherdevice.h>
#include <linux/net_tstamp.h>
#include <linux/phy.h>
#include <linux/phy/phy.h>
#include <linux/delay.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/gpio/consumer.h>
#include <linux/of.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/of_platform.h>
#include <linux/if_vlan.h>
#include <linux/kmemleak.h>
#include <linux/sys_soc.h>

#include <net/switchdev.h>
#include <net/page_pool/helpers.h>
#include <net/pkt_cls.h>
#include <net/devlink.h>

#include "cpsw.h"
#include "cpsw_ale.h"
#include "cpsw_priv.h"
#include "cpsw_sl.h"
#include "cpsw_switchdev.h"
#include "cpts.h"
#include "davinci_cpdma.h"

#include <net/pkt_sched.h>

static int debug_level;
static int ale_ageout = CPSW_ALE_AGEOUT_DEFAULT;
static int rx_packet_max = CPSW_MAX_PACKET_SIZE;
static int descs_pool_size = CPSW_CPDMA_DESCS_POOL_SIZE_DEFAULT;

struct cpsw_devlink {
	struct cpsw_common *cpsw;
};

enum cpsw_devlink_param_id {
	CPSW_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
	CPSW_DL_PARAM_SWITCH_MODE,
	CPSW_DL_PARAM_ALE_BYPASS,
};

/* struct cpsw_common is not needed, kept here for compatibility
 * reasons witrh the old driver
 */
static int cpsw_slave_index_priv(struct cpsw_common *cpsw,
				 struct cpsw_priv *priv)
{
	if (priv->emac_port == HOST_PORT_NUM)
		return -1;

	return priv->emac_port - 1;
}

static bool cpsw_is_switch_en(struct cpsw_common *cpsw)
{
	return !cpsw->data.dual_emac;
}

static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
{
	struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
	bool enable_uni = false;
	int i;

	if (cpsw_is_switch_en(cpsw))
		return;

	/* Enabling promiscuous mode for one interface will be
	 * common for both the interface as the interface shares
	 * the same hardware resource.
	 */
	for (i = 0; i < cpsw->data.slaves; i++)
		if (cpsw->slaves[i].ndev &&
		    (cpsw->slaves[i].ndev->flags & IFF_PROMISC))
			enable_uni = true;

	if (!enable && enable_uni) {
		enable = enable_uni;
		dev_dbg(cpsw->dev, "promiscuity not disabled as the other interface is still in promiscuity mode\n");
	}

	if (enable) {
		/* Enable unknown unicast, reg/unreg mcast */
		cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM,
				     ALE_P0_UNI_FLOOD, 1);

		dev_dbg(cpsw->dev, "promiscuity enabled\n");
	} else {
		/* Disable unknown unicast */
		cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM,
				     ALE_P0_UNI_FLOOD, 0);
		dev_dbg(cpsw->dev, "promiscuity disabled\n");
	}
}

/**
 * cpsw_set_mc - adds multicast entry to the table if it's not added or deletes
 * if it's not deleted
 * @ndev: device to sync
 * @addr: address to be added or deleted
 * @vid: vlan id, if vid < 0 set/unset address for real device
 * @add: add address if the flag is set or remove otherwise
 */
static int cpsw_set_mc(struct net_device *ndev, const u8 *addr,
		       int vid, int add)
{
	struct cpsw_priv *priv = netdev_priv(ndev);
	struct cpsw_common *cpsw = priv->cpsw;
	int mask, flags, ret, slave_no;

	slave_no = cpsw_slave_index(cpsw, priv);
	if (vid < 0)
		vid = cpsw->slaves[slave_no].port_vlan;

	mask =  ALE_PORT_HOST;
	flags = vid ? ALE_VLAN : 0;

	if (add)
		ret = cpsw_ale_add_mcast(cpsw->ale, addr, mask, flags, vid, 0);
	else
		ret = cpsw_ale_del_mcast(cpsw->ale, addr, 0, flags, vid);

	return ret;
}

static int cpsw_update_vlan_mc(struct net_device *vdev, int vid, void *ctx)
{
	struct addr_sync_ctx *sync_ctx = ctx;
	struct netdev_hw_addr *ha;
	int found = 0, ret = 0;

	if (!vdev || !(vdev->flags & IFF_UP))
		return 0;

	/* vlan address is relevant if its sync_cnt != 0 */
	netdev_for_each_mc_addr(ha, vdev) {
		if (ether_addr_equal(ha->addr, sync_ctx->addr)) {
			found = ha->sync_cnt;
			break;
		}
	}

	if (found)
		sync_ctx->consumed++;

	if (sync_ctx->flush) {
		if (!found)
			cpsw_set_mc(sync_ctx->ndev, sync_ctx->addr, vid, 0);
		return 0;
	}

	if (found)
		ret = cpsw_set_mc(sync_ctx->ndev, sync_ctx->addr, vid, 1);

	return ret;
}

static int cpsw_add_mc_addr(struct net_device *ndev, const u8 *addr, int num)
{
	struct addr_sync_ctx sync_ctx;
	int ret;

	sync_ctx.consumed = 0;
	sync_ctx.addr = addr;
	sync_ctx.ndev = ndev;
	sync_ctx.flush = 0;

	ret = vlan_for_each(ndev, cpsw_update_vlan_mc, &sync_ctx);
	if (sync_ctx.consumed < num && !ret)
		ret = cpsw_set_mc(ndev, addr, -1, 1);

	return ret;
}

static int cpsw_del_mc_addr(struct net_device *ndev, const u8 *addr, int num)
{
	struct addr_sync_ctx sync_ctx;

	sync_ctx.consumed = 0;
	sync_ctx.addr = addr;
	sync_ctx.ndev = ndev;
	sync_ctx.flush = 1;

	vlan_for_each(ndev, cpsw_update_vlan_mc, &sync_ctx);
	if (sync_ctx.consumed == num)
		cpsw_set_mc(ndev, addr, -1, 0);

	return 0;
}

static int cpsw_purge_vlan_mc(struct net_device *vdev, int vid, void *ctx)
{
	struct addr_sync_ctx *sync_ctx = ctx;
	struct netdev_hw_addr *ha;
	int found = 0;

	if (!vdev || !(vdev->flags & IFF_UP))
		return 0;

	/* vlan address is relevant if its sync_cnt != 0 */
	netdev_for_each_mc_addr(ha, vdev) {
		if (ether_addr_equal(ha->addr, sync_ctx->addr)) {
			found = ha->sync_cnt;
			break;
		}
	}

	if (!found)
		return 0;

	sync_ctx->consumed++;
	cpsw_set_mc(sync_ctx->ndev, sync_ctx->addr, vid, 0);
	return 0;
}

static int cpsw_purge_all_mc(struct net_device *ndev, const u8 *addr, int num)
{
	struct addr_sync_ctx sync_ctx;

	sync_ctx.addr = addr;
	sync_ctx.ndev = ndev;
	sync_ctx.consumed = 0;

	vlan_for_each(ndev, cpsw_purge_vlan_mc, &sync_ctx);
	if (sync_ctx.consumed < num)
		cpsw_set_mc(ndev, addr, -1, 0);

	return 0;
}

static void cpsw_ndo_set_rx_mode_work(struct work_struct *work)
{
	struct cpsw_priv *priv = container_of(work, struct cpsw_priv, rx_mode_work);
	struct cpsw_common *cpsw = priv->cpsw;
	struct net_device *ndev = priv->ndev;

	rtnl_lock();
	if (!netif_running(ndev))
		goto unlock_rtnl;

	netif_addr_lock_bh(ndev);
	if (ndev->flags & IFF_PROMISC) {
		/* Enable promiscuous mode */
		cpsw_set_promiscious(ndev, true);
		cpsw_ale_set_allmulti(cpsw->ale, IFF_ALLMULTI, priv->emac_port);
		goto unlock_addr;
	}

	/* Disable promiscuous mode */
	cpsw_set_promiscious(ndev, false);

	/* Restore allmulti on vlans if necessary */
	cpsw_ale_set_allmulti(cpsw->ale,
			      ndev->flags & IFF_ALLMULTI, priv->emac_port);

	/* add/remove mcast address either for real netdev or for vlan */
	__hw_addr_ref_sync_dev(&ndev->mc, ndev, cpsw_add_mc_addr,
			       cpsw_del_mc_addr);

unlock_addr:
	netif_addr_unlock_bh(ndev);
unlock_rtnl:
	rtnl_unlock();
}

static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
{
	struct cpsw_priv *priv = netdev_priv(ndev);

	schedule_work(&priv->rx_mode_work);
}

static unsigned int cpsw_rxbuf_total_len(unsigned int len)
{
	len += CPSW_HEADROOM_NA;
	len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));

	return SKB_DATA_ALIGN(len);
}

static void cpsw_rx_handler(void *token, int len, int status)
{
	struct page *new_page, *page = token;
	void *pa = page_address(page);
	int headroom = CPSW_HEADROOM_NA;
	struct cpsw_meta_xdp *xmeta;
	struct cpsw_common *cpsw;
	struct net_device *ndev;
	int port, ch, pkt_size;
	struct cpsw_priv *priv;
	struct page_pool *pool;
	struct sk_buff *skb;
	struct xdp_buff xdp;
	u32 metasize = 0;
	int ret = 0;
	dma_addr_t dma;

	xmeta = pa + CPSW_XMETA_OFFSET;
	cpsw = ndev_to_cpsw(xmeta->ndev);
	ndev = xmeta->ndev;
	pkt_size = cpsw->rx_packet_max;
	ch = xmeta->ch;

	if (status >= 0) {
		port = CPDMA_RX_SOURCE_PORT(status);
		if (port)
			ndev = cpsw->slaves[--port].ndev;
	}

	priv = netdev_priv(ndev);
	pool = cpsw->page_pool[ch];

	if (unlikely(status < 0) || unlikely(!netif_running(ndev))) {
		/* In dual emac mode check for all interfaces */
		if (cpsw->usage_count && status >= 0) {
			/* The packet received is for the interface which
			 * is already down and the other interface is up
			 * and running, instead of freeing which results
			 * in reducing of the number of rx descriptor in
			 * DMA engine, requeue page back to cpdma.
			 */
			new_page = page;
			goto requeue;
		}

		/* the interface is going down, pages are purged */
		page_pool_recycle_direct(pool, page);
		return;
	}

	new_page = page_pool_dev_alloc_pages(pool);
	if (unlikely(!new_page)) {
		new_page = page;
		ndev->stats.rx_dropped++;
		goto requeue;
	}

	if (priv->xdp_prog) {
		int size = len;

		xdp_init_buff(&xdp, PAGE_SIZE, &priv->xdp_rxq[ch]);
		if (status & CPDMA_RX_VLAN_ENCAP) {
			headroom += CPSW_RX_VLAN_ENCAP_HDR_SIZE;
			size -= CPSW_RX_VLAN_ENCAP_HDR_SIZE;
		}

		xdp_prepare_buff(&xdp, pa, headroom, size, true);

		ret = cpsw_run_xdp(priv, ch, &xdp, page, priv->emac_port, &len);
		if (ret != CPSW_XDP_PASS)
			goto requeue;

		headroom = xdp.data - xdp.data_hard_start;
		metasize = xdp.data - xdp.data_meta;

		/* XDP prog can modify vlan tag, so can't use encap header */
		status &= ~CPDMA_RX_VLAN_ENCAP;
	}

	/* pass skb to netstack if no XDP prog or returned XDP_PASS */
	skb = build_skb(pa, cpsw_rxbuf_total_len(pkt_size));
	if (!skb) {
		ndev->stats.rx_dropped++;
		page_pool_recycle_direct(pool, page);
		goto requeue;
	}

	skb->offload_fwd_mark = priv->offload_fwd_mark;
	skb_reserve(skb, headroom);
	skb_put(skb, len);
	if (metasize)
		skb_metadata_set(skb, metasize);
	skb->dev = ndev;
	if (status & CPDMA_RX_VLAN_ENCAP)
		cpsw_rx_vlan_encap(skb);
	if (priv->rx_ts_enabled)
		cpts_rx_timestamp(cpsw->cpts, skb);
	skb->protocol = eth_type_trans(skb, ndev);

	/* mark skb for recycling */
	skb_mark_for_recycle(skb);
	netif_receive_skb(skb);

	ndev->stats.rx_bytes += len;
	ndev->stats.rx_packets++;

requeue:
	xmeta = page_address(new_page) + CPSW_XMETA_OFFSET;
	xmeta->ndev = ndev;
	xmeta->ch = ch;

	dma = page_pool_get_dma_addr(new_page) + CPSW_HEADROOM_NA;
	ret = cpdma_chan_submit_mapped(cpsw->rxv[ch].ch, new_page, dma,
				       pkt_size, 0);
	if (ret < 0) {
		WARN_ON(ret == -ENOMEM);
		page_pool_recycle_direct(pool, new_page);
	}
}

static int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv,
				   unsigned short vid)
{
	struct cpsw_common *cpsw = priv->cpsw;
	int unreg_mcast_mask = 0;
	int mcast_mask;
	u32 port_mask;
	int ret;

	port_mask = (1 << priv->emac_port) | ALE_PORT_HOST;

	mcast_mask = ALE_PORT_HOST;
	if (priv->ndev->flags & IFF_ALLMULTI)
		unreg_mcast_mask = mcast_mask;

	ret = cpsw_ale_add_vlan(cpsw->ale, vid, port_mask, 0, port_mask,
				unreg_mcast_mask);
	if (ret != 0)
		return ret;

	ret = cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr,
				 HOST_PORT_NUM, ALE_VLAN, vid);
	if (ret != 0)
		goto clean_vid;

	ret = cpsw_ale_add_mcast(cpsw->ale, priv->ndev->broadcast,
				 mcast_mask, ALE_VLAN, vid, 0);
	if (ret != 0)
		goto clean_vlan_ucast;
	return 0;

clean_vlan_ucast:
	cpsw_ale_del_ucast(cpsw->ale, priv->mac_addr,
			   HOST_PORT_NUM, ALE_VLAN, vid);
clean_vid:
	cpsw_ale_del_vlan(cpsw->ale, vid, 0);
	return ret;
}

static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev,
				    __be16 proto, u16 vid)
{
	struct cpsw_priv *priv = netdev_priv(ndev);
	struct cpsw_common *cpsw = priv->cpsw;
	int ret, i;

	if (cpsw_is_switch_en(cpsw)) {
		dev_dbg(cpsw->dev, ".ndo_vlan_rx_add_vid called in switch mode\n");
		return 0;
	}

	if (vid == cpsw->data.default_vlan)
		return 0;

	ret = pm_runtime_resume_and_get(cpsw->dev);
	if (ret < 0)
		return ret;

	/* In dual EMAC, reserved VLAN id should not be used for
	 * creating VLAN interfaces as this can break the dual
	 * EMAC port separation
	 */
	for (i = 0; i < cpsw->data.slaves; i++) {
		if (cpsw->slaves[i].ndev &&
		    vid == cpsw->slaves[i].port_vlan) {
			ret = -EINVAL;
			goto err;
		}
	}

	dev_dbg(priv->dev, "Adding vlanid %d to vlan filter\n", vid);
	ret = cpsw_add_vlan_ale_entry(priv, vid);
err:
	pm_runtime_put(cpsw->dev);
	return ret;
}

static int cpsw_restore_vlans(struct net_device *vdev, int vid, void *arg)
{
	struct cpsw_priv *priv = arg;

	if (!vdev || !vid)
		return 0;

	cpsw_ndo_vlan_rx_add_vid(priv->ndev, 0, vid);
	return 0;
}

/* restore resources after port reset */
static void cpsw_restore(struct cpsw_priv *priv)
{
	struct cpsw_common *cpsw = priv->cpsw;

	/* restore vlan configurations */
	vlan_for_each(priv->ndev, cpsw_restore_vlans, priv);

	/* restore MQPRIO offload */
	cpsw_mqprio_resume(&cpsw->slaves[priv->emac_port - 1], priv);

	/* restore CBS offload */
	cpsw_cbs_resume(&cpsw->slaves[priv->emac_port - 1], priv);

	cpsw_qos_clsflower_resume(priv);
}

static void cpsw_init_stp_ale_entry(struct cpsw_common *cpsw)
{
	static const char stpa[] = {0x01, 0x80, 0xc2, 0x0, 0x0, 0x0};

	cpsw_ale_add_mcast(cpsw->ale, stpa,
			   ALE_PORT_HOST, ALE_SUPER, 0,
			   ALE_MCAST_BLOCK_LEARN_FWD);
}

static void cpsw_init_host_port_switch(struct cpsw_common *cpsw)
{
	int vlan = cpsw->data.default_vlan;

	writel(CPSW_FIFO_NORMAL_MODE, &cpsw->host_port_regs->tx_in_ctl);

	writel(vlan, &cpsw->host_port_regs->port_vlan);

	cpsw_ale_add_vlan(cpsw->ale, vlan, ALE_ALL_PORTS,
			  ALE_ALL_PORTS, ALE_ALL_PORTS,
			  ALE_PORT_1 | ALE_PORT_2);

	cpsw_init_stp_ale_entry(cpsw);

	cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_P0_UNI_FLOOD, 1);
	dev_dbg(cpsw->dev, "Set P0_UNI_FLOOD\n");
	cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_PORT_NOLEARN, 0);
}

static void cpsw_init_host_port_dual_mac(struct cpsw_common *cpsw)
{
	int vlan = cpsw->data.default_vlan;

	writel(CPSW_FIFO_DUAL_MAC_MODE, &cpsw->host_port_regs->tx_in_ctl);

	cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_P0_UNI_FLOOD, 0);
	dev_dbg(cpsw->dev, "unset P0_UNI_FLOOD\n");

	writel(vlan, &cpsw->host_port_regs->port_vlan);

	cpsw_ale_add_vlan(cpsw->ale, vlan, ALE_ALL_PORTS, ALE_ALL_PORTS, 0, 0);
	/* learning make no sense in dual_mac mode */
	cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_PORT_NOLEARN, 1);
}

static void cpsw_init_host_port(struct cpsw_priv *priv)
{
	struct cpsw_common *cpsw = priv->cpsw;
	u32 control_reg;

	/* soft reset the controller and initialize ale */
	cpsw_soft_reset("cpsw", &cpsw->regs->soft_reset);
	cpsw_ale_start(cpsw->ale);

	/* switch to vlan aware mode */
	cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_VLAN_AWARE,
			     CPSW_ALE_VLAN_AWARE);
	control_reg = readl(&cpsw->regs->control);
	control_reg |= CPSW_VLAN_AWARE | CPSW_RX_VLAN_ENCAP;
	writel(control_reg, &cpsw->regs->control);

	/* setup host port priority mapping */
	writel_relaxed(CPDMA_TX_PRIORITY_MAP,
		       &cpsw->host_port_regs->cpdma_tx_pri_map);
	writel_relaxed(0, &cpsw->host_port_regs->cpdma_rx_chan_map);

	/* disable priority elevation */
	writel_relaxed(0, &cpsw->regs->ptype);

	/* enable statistics collection only on all ports */
	writel_relaxed(0x7, &cpsw->regs->stat_port_en);

	/* Enable internal fifo flow control */
	writel(0x7, &cpsw->regs->flow_control);

	if (cpsw_is_switch_en(cpsw))
		cpsw_init_host_port_switch(cpsw);
	else
		cpsw_init_host_port_dual_mac(cpsw);

	cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM,
			     ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
}

static void cpsw_port_add_dual_emac_def_ale_entries(struct cpsw_priv *priv,
						    struct cpsw_slave *slave)
{
	u32 port_mask = 1 << priv->emac_port | ALE_PORT_HOST;
	struct cpsw_common *cpsw = priv->cpsw;
	u32 reg;

	reg = (cpsw->version == CPSW_VERSION_1) ? CPSW1_PORT_VLAN :
	       CPSW2_PORT_VLAN;
	slave_write(slave, slave->port_vlan, reg);

	cpsw_ale_add_vlan(cpsw->ale, slave->port_vlan, port_mask,
			  port_mask, port_mask, 0);
	cpsw_ale_add_mcast(cpsw->ale, priv->ndev->broadcast,
			   ALE_PORT_HOST, ALE_VLAN, slave->port_vlan,
			   ALE_MCAST_FWD);
	cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr,
			   HOST_PORT_NUM, ALE_VLAN |
			   ALE_SECURE, slave->port_vlan);
	cpsw_ale_control_set(cpsw->ale, priv->emac_port,
			     ALE_PORT_DROP_UNKNOWN_VLAN, 1);
	/* learning make no sense in dual_mac mode */
	cpsw_ale_control_set(cpsw->ale, priv->emac_port,
			     ALE_PORT_NOLEARN, 1);
}

static void cpsw_port_add_switch_def_ale_entries(struct cpsw_priv *priv,
						 struct cpsw_slave *slave)
{
	u32 port_mask = 1 << priv->emac_port | ALE_PORT_HOST;
	struct cpsw_common *cpsw = priv->cpsw;
	u32 reg;

	cpsw_ale_control_set(cpsw->ale, priv->emac_port,
			     ALE_PORT_DROP_UNKNOWN_VLAN, 0);
	cpsw_ale_control_set(cpsw->ale, priv->emac_port,
			     ALE_PORT_NOLEARN, 0);
	/* disabling SA_UPDATE required to make stp work, without this setting
	 * Host MAC addresses will jump between ports.
	 * As per TRM MAC address can be defined as unicast supervisory (super)
	 * by setting both (ALE_BLOCKED | ALE_SECURE) which should prevent
	 * SA_UPDATE, but HW seems works incorrectly and setting ALE_SECURE
	 * causes STP packets to be dropped due to ingress filter
	 *	if (source address found) and (secure) and
	 *	   (receive port number != port_number))
	 *	   then discard the packet
	 */
	cpsw_ale_control_set(cpsw->ale, priv->emac_port,
			     ALE_PORT_NO_SA_UPDATE, 1);

	cpsw_ale_add_mcast(cpsw->ale, priv->ndev->broadcast,
			   port_mask, ALE_VLAN, slave->port_vlan,
			   ALE_MCAST_FWD_2);
	cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr,
			   HOST_PORT_NUM, ALE_VLAN, slave->port_vlan);

	reg = (cpsw->version == CPSW_VERSION_1) ? CPSW1_PORT_VLAN :
	       CPSW2_PORT_VLAN;
	slave_write(slave, slave->port_vlan, reg);
}

static void cpsw_adjust_link(struct net_device *ndev)
{
	struct cpsw_priv *priv = netdev_priv(ndev);
	struct cpsw_common *cpsw = priv->cpsw;
	struct cpsw_slave *slave;
	struct phy_device *phy;
	u32 mac_control = 0;

	slave = &cpsw->slaves[priv->emac_port - 1];
	phy = slave->phy;

	if (!phy)
		return;

	if (phy->link) {
		mac_control = CPSW_SL_CTL_GMII_EN;

		if (phy->speed == 1000)
			mac_control |= CPSW_SL_CTL_GIG;
		if (phy->duplex)
			mac_control |= CPSW_SL_CTL_FULLDUPLEX;

		/* set speed_in input in case RMII mode is used in 100Mbps */
		if (phy->speed == 100)
			mac_control |= CPSW_SL_CTL_IFCTL_A;
		/* in band mode only works in 10Mbps RGMII mode */
		else if ((phy->speed == 10) && phy_interface_is_rgmii(phy))
			mac_control |= CPSW_SL_CTL_EXT_EN; /* In Band mode */

		if (priv->rx_pause)
			mac_control |= CPSW_SL_CTL_RX_FLOW_EN;

		if (priv->tx_pause)
			mac_control |= CPSW_SL_CTL_TX_FLOW_EN;

		if (mac_control != slave->mac_control)
			cpsw_sl_ctl_set(slave->mac_sl, mac_control);

		/* enable forwarding */
		cpsw_ale_control_set(cpsw->ale, priv->emac_port,
				     ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);

		netif_tx_wake_all_queues(ndev);

		if (priv->shp_cfg_speed &&
		    priv->shp_cfg_speed != slave->phy->speed &&
		    !cpsw_shp_is_off(priv))
			dev_warn(priv->dev, "Speed was changed, CBS shaper speeds are changed!");
	} else {
		netif_tx_stop_all_queues(ndev);

		mac_control = 0;
		/* disable forwarding */
		cpsw_ale_control_set(cpsw->ale, priv->emac_port,
				     ALE_PORT_STATE, ALE_PORT_STATE_DISABLE);

		cpsw_sl_wait_for_idle(slave->mac_sl, 100);

		cpsw_sl_ctl_reset(slave->mac_sl);
	}

	if (mac_control != slave->mac_control)
		phy_print_status(phy);

	slave->mac_control = mac_control;

	if (phy->link && cpsw_need_resplit(cpsw))
		cpsw_split_res(cpsw);
}

static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
{
	struct cpsw_common *cpsw = priv->cpsw;
	struct phy_device *phy;

	cpsw_sl_reset(slave->mac_sl, 100);
	cpsw_sl_ctl_reset(slave->mac_sl);

	/* setup priority mapping */
	cpsw_sl_reg_write(slave->mac_sl, CPSW_SL_RX_PRI_MAP,
			  RX_PRIORITY_MAPPING);

	switch (cpsw->version) {
	case CPSW_VERSION_1:
		slave_write(slave, TX_PRIORITY_MAPPING, CPSW1_TX_PRI_MAP);
		/* Increase RX FIFO size to 5 for supporting fullduplex
		 * flow control mode
		 */
		slave_write(slave,
			    (CPSW_MAX_BLKS_TX << CPSW_MAX_BLKS_TX_SHIFT) |
			    CPSW_MAX_BLKS_RX, CPSW1_MAX_BLKS);
		break;
	case CPSW_VERSION_2:
	case CPSW_VERSION_3:
	case CPSW_VERSION_4:
		slave_write(slave, TX_PRIORITY_MAPPING, CPSW2_TX_PRI_MAP);
		/* Increase RX FIFO size to 5 for supporting fullduplex
		 * flow control mode
		 */
		slave_write(slave,
			    (CPSW_MAX_BLKS_TX << CPSW_MAX_BLKS_TX_SHIFT) |
			    CPSW_MAX_BLKS_RX, CPSW2_MAX_BLKS);
		break;
	}

	/* setup max packet size, and mac address */
	cpsw_sl_reg_write(slave->mac_sl, CPSW_SL_RX_MAXLEN,
			  cpsw->rx_packet_max);
	cpsw_set_slave_mac(slave, priv);

	slave->mac_control = 0;	/* no link yet */

	if (cpsw_is_switch_en(cpsw))
		cpsw_port_add_switch_def_ale_entries(priv, slave);
	else
		cpsw_port_add_dual_emac_def_ale_entries(priv, slave);

	if (!slave->data->phy_node)
		dev_err(priv->dev, "no phy found on slave %d\n",
			slave->slave_num);
	phy = of_phy_connect(priv->ndev, slave->data->phy_node,
			     &cpsw_adjust_link, 0, slave->data->phy_if);
	if (!phy) {
		dev_err(priv->dev, "phy \"%pOF\" not found on slave %d\n",
			slave->data->phy_node,
			slave->slave_num);
		return;
	}

	phy->mac_managed_pm = true;

	slave->phy = phy;

	phy_disable_eee(slave->phy);

	phy_attached_info(slave->phy);

	phy_start(slave->phy);

	/* Configure GMII_SEL register */
	phy_set_mode_ext(slave->data->ifphy, PHY_MODE_ETHERNET,
			 slave->data->phy_if);
}

static int cpsw_ndo_stop(struct net_device *ndev)
{
	struct cpsw_priv *priv = netdev_priv(ndev);
	struct cpsw_common *cpsw = priv->cpsw;
	struct cpsw_slave *slave;

	cpsw_info(priv, ifdown, "shutting down ndev\n");
	slave = &cpsw->slaves[priv->emac_port - 1];
	if (slave->phy)
		phy_stop(slave->phy);

	netif_tx_stop_all_queues(priv->ndev);

	if (slave->phy) {
		phy_disconnect(slave->phy);
		slave->phy = NULL;
	}

	__hw_addr_ref_unsync_dev(&ndev->mc, ndev, cpsw_purge_all_mc);

	if (cpsw->usage_count <= 1) {
		napi_disable(&cpsw->napi_rx);
		napi_disable(&cpsw->napi_tx);
		cpts_unregister(cpsw->cpts);
		cpsw_intr_disable(cpsw);
		cpdma_ctlr_stop(cpsw->dma);
		cpsw_ale_stop(cpsw->ale);
		cpsw_destroy_xdp_rxqs(cpsw);
	}

	if (cpsw_need_resplit(cpsw))
		cpsw_split_res(cpsw);

	cpsw->usage_count--;
	pm_runtime_put_sync(cpsw->dev);
	return 0;
}

static int cpsw_ndo_open(struct net_device *ndev)
{
	struct cpsw_priv *priv = netdev_priv(ndev);
	struct cpsw_common *cpsw = priv->cpsw;
	int ret;

	dev_info(priv->dev, "starting ndev. mode: %s\n",
		 cpsw_is_switch_en(cpsw) ? "switch" : "dual_mac");
	ret = pm_runtime_resume_and_get(cpsw->dev);
	if (ret < 0)
		return ret;

	/* Notify the stack of the actual queue counts. */
	ret = netif_set_real_num_tx_queues(ndev, cpsw->tx_ch_num);
	if (ret) {
		dev_err(priv->dev, "cannot set real number of tx queues\n");
		goto pm_cleanup;
	}

	ret = netif_set_real_num_rx_queues(ndev, cpsw->rx_ch_num);
	if (ret) {
		dev_err(priv->dev, "cannot set real number of rx queues\n");
		goto pm_cleanup;
	}

	/* Initialize host and slave ports */
	if (!cpsw->usage_count)
		cpsw_init_host_port(priv);
	cpsw_slave_open(&cpsw->slaves[priv->emac_port - 1], priv);

	/* initialize shared resources for every ndev */
	if (!cpsw->usage_count) {
		/* create rxqs for both infs in dual mac as they use same pool
		 * and must be destroyed together when no users.
		 */
		ret = cpsw_create_xdp_rxqs(cpsw);
		if (ret < 0)
			goto err_cleanup;

		ret = cpsw_fill_rx_channels(priv);
		if (ret < 0)
			goto err_cleanup;

		if (cpsw->cpts) {
			if (cpts_register(cpsw->cpts))
				dev_err(priv->dev, "error registering cpts device\n");
			else
				writel(0x10, &cpsw->wr_regs->misc_en);
		}

		napi_enable(&cpsw->napi_rx);
		napi_enable(&cpsw->napi_tx);

		if (cpsw->tx_irq_disabled) {
			cpsw->tx_irq_disabled = false;
			enable_irq(cpsw->irqs_table[1]);
		}

		if (cpsw->rx_irq_disabled) {
			cpsw->rx_irq_disabled = false;
			enable_irq(cpsw->irqs_table[0]);
		}
	}

	cpsw_restore(priv);

	/* Enable Interrupt pacing if configured */
	if (cpsw->coal_intvl != 0) {
		struct ethtool_coalesce coal;

		coal.rx_coalesce_usecs = cpsw->coal_intvl;
		cpsw_set_coalesce(ndev, &coal, NULL, NULL);
	}

	cpdma_ctlr_start(cpsw->dma);
	cpsw_intr_enable(cpsw);
	cpsw->usage_count++;

	return 0;

err_cleanup:
	cpsw_ndo_stop(ndev);

pm_cleanup:
	pm_runtime_put_sync(cpsw->dev);
	return ret;
}

static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb,
				       struct net_device *ndev)
{
	struct cpsw_priv *priv = netdev_priv(ndev);
	struct cpsw_common *cpsw = priv->cpsw;
	struct cpts *cpts = cpsw->cpts;
	struct netdev_queue *txq;
	struct cpdma_chan *txch;
	int ret, q_idx;

	if (skb_put_padto(skb, READ_ONCE(priv->tx_packet_min))) {
		cpsw_err(priv, tx_err, "packet pad failed\n");
		ndev->stats.tx_dropped++;
		return NET_XMIT_DROP;
	}

	if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
	    priv->tx_ts_enabled && cpts_can_timestamp(cpts, skb))
		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;

	q_idx = skb_get_queue_mapping(skb);
	if (q_idx >= cpsw->tx_ch_num)
		q_idx = q_idx % cpsw->tx_ch_num;

	txch = cpsw->txv[q_idx].ch;
	txq = netdev_get_tx_queue(ndev, q_idx);
	skb_tx_timestamp(skb);
	ret = cpdma_chan_submit(txch, skb, skb->data, skb->len,
				priv->emac_port);
	if (unlikely(ret != 0)) {
		cpsw_err(priv, tx_err, "desc submit failed\n");
		goto fail;
	}

	/* If there is no more tx desc left free then we need to
	 * tell the kernel to stop sending us tx frames.
	 */
	if (unlikely(!cpdma_check_free_tx_desc(txch))) {
		netif_tx_stop_queue(txq);

		/* Barrier, so that stop_queue visible to other cpus */
		smp_mb__after_atomic();

		if (cpdma_check_free_tx_desc(txch))
			netif_tx_wake_queue(txq);
	}

	return NETDEV_TX_OK;
fail:
	ndev->stats.tx_dropped++;
	netif_tx_stop_queue(txq);

	/* Barrier, so that stop_queue visible to other cpus */
	smp_mb__after_atomic();

	if (cpdma_check_free_tx_desc(txch))
		netif_tx_wake_queue(txq);

	return NETDEV_TX_BUSY;
}

static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p)
{
	struct sockaddr *addr = (struct sockaddr *)p;
	struct cpsw_priv *priv = netdev_priv(ndev);
	struct cpsw_common *cpsw = priv->cpsw;
	int ret, slave_no;
	int flags = 0;
	u16 vid = 0;

	slave_no = cpsw_slave_index(cpsw, priv);
	if (!is_valid_ether_addr(addr->sa_data))
		return -EADDRNOTAVAIL;

	ret = pm_runtime_resume_and_get(cpsw->dev);
	if (ret < 0)
		return ret;

	vid = cpsw->slaves[slave_no].port_vlan;
	flags = ALE_VLAN | ALE_SECURE;

	cpsw_ale_del_ucast(cpsw->ale, priv->mac_addr, HOST_PORT_NUM,
			   flags, vid);
	cpsw_ale_add_ucast(cpsw->ale, addr->sa_data, HOST_PORT_NUM,
			   flags, vid);

	ether_addr_copy(priv->mac_addr, addr->sa_data);
	eth_hw_addr_set(ndev, priv->mac_addr);
	cpsw_set_slave_mac(&cpsw->slaves[slave_no], priv);

	pm_runtime_put(cpsw->dev);

	return 0;
}

static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev,
				     __be16 proto, u16 vid)
{
	struct cpsw_priv *priv = netdev_priv(ndev);
	struct cpsw_common *cpsw = priv->cpsw;
	int ret;
	int i;

	if (cpsw_is_switch_en(cpsw)) {
		dev_dbg(cpsw->dev, "ndo del vlan is called in switch mode\n");
		return 0;
	}

	if (vid == cpsw->data.default_vlan)
		return 0;

	ret = pm_runtime_resume_and_get(cpsw->dev);
	if (ret < 0)
		return ret;

	/* reset the return code as pm_runtime_get_sync() can return
	 * non zero values as well.
	 */
	ret = 0;
	for (i = 0; i < cpsw->data.slaves; i++) {
		if (cpsw->slaves[i].ndev &&
		    vid == cpsw->slaves[i].port_vlan) {
			ret = -EINVAL;
			goto err;
		}
	}

	dev_dbg(priv->dev, "removing vlanid %d from vlan filter\n", vid);
	ret = cpsw_ale_del_vlan(cpsw->ale, vid, 0);
	if (ret)
		dev_err(priv->dev, "cpsw_ale_del_vlan() failed: ret %d\n", ret);
	ret = cpsw_ale_del_ucast(cpsw->ale, priv->mac_addr,
				 HOST_PORT_NUM, ALE_VLAN, vid);
	if (ret)
		dev_err(priv->dev, "cpsw_ale_del_ucast() failed: ret %d\n",
			ret);
	ret = cpsw_ale_del_mcast(cpsw->ale, priv->ndev->broadcast,
				 0, ALE_VLAN, vid);
	if (ret)
		dev_err(priv->dev, "cpsw_ale_del_mcast failed. ret %d\n",
			ret);
	cpsw_ale_flush_multicast(cpsw->ale, ALE_PORT_HOST, vid);
	ret = 0;
err:
	pm_runtime_put(cpsw->dev);
	return ret;
}

static int cpsw_ndo_get_phys_port_name(struct net_device *ndev, char *name,
				       size_t len)
{
	struct cpsw_priv *priv = netdev_priv(ndev);
	int err;

	err = snprintf(name, len, "p%d", priv->emac_port);

	if (err >= len)
		return -EINVAL;

	return 0;
}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void cpsw_ndo_poll_controller(struct net_device *ndev)
{
	struct cpsw_common *cpsw = ndev_to_cpsw(ndev);

	cpsw_intr_disable(cpsw);
	cpsw_rx_interrupt(cpsw->irqs_table[0], cpsw);
	cpsw_tx_interrupt(cpsw->irqs_table[1], cpsw);
	cpsw_intr_enable(cpsw);
}
#endif

static int cpsw_ndo_xdp_xmit(struct net_device *ndev, int n,
			     struct xdp_frame **frames, u32 flags)
{
	struct cpsw_priv *priv = netdev_priv(ndev);
	struct xdp_frame *xdpf;
	int i, nxmit = 0;

	if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
		return -EINVAL;

	for (i = 0; i < n; i++) {
		xdpf = frames[i];
		if (xdpf->len < READ_ONCE(priv->tx_packet_min))
			break;

		if (cpsw_xdp_tx_frame(priv, xdpf, NULL, priv->emac_port))
			break;
		nxmit++;
	}

	return nxmit;
}

static int cpsw_get_port_parent_id(struct net_device *ndev,
				   struct netdev_phys_item_id *ppid)
{
	struct cpsw_common *cpsw = ndev_to_cpsw(ndev);

	ppid->id_len = sizeof(cpsw->base_mac);
	memcpy(&ppid->id, &cpsw->base_mac, ppid->id_len);

	return 0;
}

static const struct net_device_ops cpsw_netdev_ops = {
	.ndo_open		= cpsw_ndo_open,
	.ndo_stop		= cpsw_ndo_stop,
	.ndo_start_xmit		= cpsw_ndo_start_xmit,
	.ndo_set_mac_address	= cpsw_ndo_set_mac_address,
	.ndo_eth_ioctl		= phy_do_ioctl_running,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_tx_timeout		= cpsw_ndo_tx_timeout,
	.ndo_set_rx_mode	= cpsw_ndo_set_rx_mode,
	.ndo_set_tx_maxrate	= cpsw_ndo_set_tx_maxrate,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= cpsw_ndo_poll_controller,
#endif
	.ndo_vlan_rx_add_vid	= cpsw_ndo_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid	= cpsw_ndo_vlan_rx_kill_vid,
	.ndo_setup_tc           = cpsw_ndo_setup_tc,
	.ndo_get_phys_port_name = cpsw_ndo_get_phys_port_name,
	.ndo_bpf		= cpsw_ndo_bpf,
	.ndo_xdp_xmit		= cpsw_ndo_xdp_xmit,
	.ndo_get_port_parent_id	= cpsw_get_port_parent_id,
	.ndo_hwtstamp_get	= cpsw_hwtstamp_get,
	.ndo_hwtstamp_set	= cpsw_hwtstamp_set,
};

static void cpsw_get_drvinfo(struct net_device *ndev,
			     struct ethtool_drvinfo *info)
{
	struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
	struct platform_device *pdev;

	pdev = to_platform_device(cpsw->dev);
	strscpy(info->driver, "cpsw-switch", sizeof(info->driver));
	strscpy(info->version, "2.0", sizeof(info->version));
	strscpy(info->bus_info, pdev->name, sizeof(info->bus_info));
}

static int cpsw_set_pauseparam(struct net_device *ndev,
			       struct ethtool_pauseparam *pause)
{
	struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
	struct cpsw_priv *priv = netdev_priv(ndev);
	int slave_no;

	slave_no = cpsw_slave_index(cpsw, priv);
	if (!cpsw->slaves[slave_no].phy)
		return -EINVAL;

	if (!phy_validate_pause(cpsw->slaves[slave_no].phy, pause))
		return -EINVAL;

	priv->rx_pause = pause->rx_pause ? true : false;
	priv->tx_pause = pause->tx_pause ? true : false;

	phy_set_asym_pause(cpsw->slaves[slave_no].phy,
			   priv->rx_pause, priv->tx_pause);

	return 0;
}

static int cpsw_set_channels(struct net_device *ndev,
			     struct ethtool_channels *chs)
{
	return cpsw_set_channels_common(ndev, chs, cpsw_rx_handler);
}

static const struct ethtool_ops cpsw_ethtool_ops = {
	.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS,
	.get_drvinfo		= cpsw_get_drvinfo,
	.get_msglevel		= cpsw_get_msglevel,
	.set_msglevel		= cpsw_set_msglevel,
	.get_link		= ethtool_op_get_link,
	.get_ts_info		= cpsw_get_ts_info,
	.get_coalesce		= cpsw_get_coalesce,
	.set_coalesce		= cpsw_set_coalesce,
	.get_sset_count		= cpsw_get_sset_count,
	.get_strings		= cpsw_get_strings,
	.get_ethtool_stats	= cpsw_get_ethtool_stats,
	.get_pauseparam		= cpsw_get_pauseparam,
	.set_pauseparam		= cpsw_set_pauseparam,
	.get_wol		= cpsw_get_wol,
	.set_wol		= cpsw_set_wol,
	.get_regs_len		= cpsw_get_regs_len,
	.get_regs		= cpsw_get_regs,
	.begin			= cpsw_ethtool_op_begin,
	.complete		= cpsw_ethtool_op_complete,
	.get_channels		= cpsw_get_channels,
	.set_channels		= cpsw_set_channels,
	.get_link_ksettings	= cpsw_get_link_ksettings,
	.set_link_ksettings	= cpsw_set_link_ksettings,
	.get_eee		= cpsw_get_eee,
	.nway_reset		= cpsw_nway_reset,
	.get_ringparam		= cpsw_get_ringparam,
	.set_ringparam		= cpsw_set_ringparam,
};

static int cpsw_probe_dt(struct cpsw_common *cpsw)
{
	struct device_node *node = cpsw->dev->of_node, *tmp_node, *port_np;
	struct cpsw_platform_data *data = &cpsw->data;
	struct device *dev = cpsw->dev;
	int ret;
	u32 prop;

	if (!node)
		return -EINVAL;

	tmp_node = of_get_child_by_name(node, "ethernet-ports");
	if (!tmp_node)
		return -ENOENT;
	data->slaves = of_get_child_count(tmp_node);
	if (data->slaves != CPSW_SLAVE_PORTS_NUM) {
		of_node_put(tmp_node);
		return -ENOENT;
	}

	data->active_slave = 0;
	data->channels = CPSW_MAX_QUEUES;
	data->dual_emac = true;
	data->bd_ram_size = CPSW_BD_RAM_SIZE;
	data->mac_control = 0;

	data->slave_data = devm_kcalloc(dev, CPSW_SLAVE_PORTS_NUM,
					sizeof(struct cpsw_slave_data),
					GFP_KERNEL);
	if (!data->slave_data) {
		of_node_put(tmp_node);
		return -ENOMEM;
	}

	/* Populate all the child nodes here...
	 */
	ret = devm_of_platform_populate(dev);
	/* We do not want to force this, as in some cases may not have child */
	if (ret)
		dev_warn(dev, "Doesn't have any child node\n");

	for_each_child_of_node(tmp_node, port_np) {
		struct cpsw_slave_data *slave_data;
		u32 port_id;

		ret = of_property_read_u32(port_np, "reg", &port_id);
		if (ret < 0) {
			dev_err(dev, "%pOF error reading port_id %d\n",
				port_np, ret);
			goto err_node_put;
		}

		if (!port_id || port_id > CPSW_SLAVE_PORTS_NUM) {
			dev_err(dev, "%pOF has invalid port_id %u\n",
				port_np, port_id);
			ret = -EINVAL;
			goto err_node_put;
		}

		slave_data = &data->slave_data[port_id - 1];

		slave_data->disabled = !of_device_is_available(port_np);
		if (slave_data->disabled)
			continue;

		slave_data->slave_node = port_np;
		slave_data->ifphy = devm_of_phy_get(dev, port_np, NULL);
		if (IS_ERR(slave_data->ifphy)) {
			ret = PTR_ERR(slave_data->ifphy);
			dev_err(dev, "%pOF: Error retrieving port phy: %d\n",
				port_np, ret);
			goto err_node_put;
		}

		if (of_phy_is_fixed_link(port_np)) {
			ret = of_phy_register_fixed_link(port_np);
			if (ret) {
				dev_err_probe(dev, ret, "%pOF failed to register fixed-link phy\n",
					      port_np);
				goto err_node_put;
			}
			slave_data->phy_node = of_node_get(port_np);
		} else {
			slave_data->phy_node =
				of_parse_phandle(port_np, "phy-handle", 0);
		}

		if (!slave_data->phy_node) {
			dev_err(dev, "%pOF no phy found\n", port_np);
			ret = -ENODEV;
			goto err_node_put;
		}

		ret = of_get_phy_mode(port_np, &slave_data->phy_if);
		if (ret) {
			dev_err(dev, "%pOF read phy-mode err %d\n",
				port_np, ret);
			goto err_node_put;
		}

		ret = of_get_mac_address(port_np, slave_data->mac_addr);
		if (ret) {
			ret = ti_cm_get_macid(dev, port_id - 1,
					      slave_data->mac_addr);
			if (ret)
				goto err_node_put;
		}

		if (of_property_read_u32(port_np, "ti,dual-emac-pvid",
					 &prop)) {
			dev_err(dev, "%pOF Missing dual_emac_res_vlan in DT.\n",
				port_np);
			slave_data->dual_emac_res_vlan = port_id;
			dev_err(dev, "%pOF Using %d as Reserved VLAN\n",
				port_np, slave_data->dual_emac_res_vlan);
		} else {
			slave_data->dual_emac_res_vlan = prop;
		}
	}

	of_node_put(tmp_node);
	return 0;

err_node_put:
	of_node_put(port_np);
	of_node_put(tmp_node);
	return ret;
}

static void cpsw_remove_dt(struct cpsw_common *cpsw)
{
	struct cpsw_platform_data *data = &cpsw->data;
	int i = 0;

	for (i = 0; i < cpsw->data.slaves; i++) {
		struct cpsw_slave_data *slave_data = &data->slave_data[i];
		struct device_node *port_np = slave_data->phy_node;

		if (port_np) {
			if (of_phy_is_fixed_link(port_np))
				of_phy_deregister_fixed_link(port_np);

			of_node_put(port_np);
		}
	}
}

static int cpsw_create_ports(struct cpsw_common *cpsw)
{
	struct cpsw_platform_data *data = &cpsw->data;
	struct net_device *ndev, *napi_ndev = NULL;
	struct device *dev = cpsw->dev;
	struct cpsw_priv *priv;
	int ret = 0, i = 0;

	for (i = 0; i < cpsw->data.slaves; i++) {
		struct cpsw_slave_data *slave_data = &data->slave_data[i];

		if (slave_data->disabled)
			continue;

		ndev = devm_alloc_etherdev_mqs(dev, sizeof(struct cpsw_priv),
					       CPSW_MAX_QUEUES,
					       CPSW_MAX_QUEUES);
		if (!ndev) {
			dev_err(dev, "error allocating net_device\n");
			return -ENOMEM;
		}

		priv = netdev_priv(ndev);
		priv->cpsw = cpsw;
		priv->ndev = ndev;
		priv->dev  = dev;
		priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
		priv->emac_port = i + 1;
		priv->tx_packet_min = CPSW_MIN_PACKET_SIZE;
		INIT_WORK(&priv->rx_mode_work, cpsw_ndo_set_rx_mode_work);

		if (is_valid_ether_addr(slave_data->mac_addr)) {
			ether_addr_copy(priv->mac_addr, slave_data->mac_addr);
			dev_info(cpsw->dev, "Detected MACID = %pM\n",
				 priv->mac_addr);
		} else {
			eth_random_addr(slave_data->mac_addr);
			dev_info(cpsw->dev, "Random MACID = %pM\n",
				 priv->mac_addr);
		}
		eth_hw_addr_set(ndev, slave_data->mac_addr);
		ether_addr_copy(priv->mac_addr, slave_data->mac_addr);

		cpsw->slaves[i].ndev = ndev;

		ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER |
				  NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_TC;
		ndev->netns_immutable = true;

		ndev->xdp_features = NETDEV_XDP_ACT_BASIC |
				     NETDEV_XDP_ACT_REDIRECT |
				     NETDEV_XDP_ACT_NDO_XMIT;

		ndev->netdev_ops = &cpsw_netdev_ops;
		ndev->ethtool_ops = &cpsw_ethtool_ops;
		SET_NETDEV_DEV(ndev, dev);
		ndev->dev.of_node = slave_data->slave_node;

		if (!napi_ndev) {
			/* CPSW Host port CPDMA interface is shared between
			 * ports and there is only one TX and one RX IRQs
			 * available for all possible TX and RX channels
			 * accordingly.
			 */
			netif_napi_add(ndev, &cpsw->napi_rx,
				       cpsw->quirk_irq ? cpsw_rx_poll : cpsw_rx_mq_poll);
			netif_napi_add_tx(ndev, &cpsw->napi_tx,
					  cpsw->quirk_irq ?
					  cpsw_tx_poll : cpsw_tx_mq_poll);
		}

		napi_ndev = ndev;
	}

	return ret;
}

static void cpsw_unregister_ports(struct cpsw_common *cpsw)
{
	struct net_device *ndev;
	struct cpsw_priv *priv;
	int i = 0;

	for (i = 0; i < cpsw->data.slaves; i++) {
		ndev = cpsw->slaves[i].ndev;
		if (!ndev || ndev->reg_state != NETREG_REGISTERED)
			continue;

		priv = netdev_priv(ndev);
		unregister_netdev(ndev);
		disable_work_sync(&priv->rx_mode_work);
	}
}

static int cpsw_register_ports(struct cpsw_common *cpsw)
{
	int ret = 0, i = 0;

	for (i = 0; i < cpsw->data.slaves; i++) {
		if (!cpsw->slaves[i].ndev)
			continue;

		/* register the network device */
		ret = register_netdev(cpsw->slaves[i].ndev);
		if (ret) {
			dev_err(cpsw->dev,
				"cpsw: err registering net device%d\n", i);
			break;
		}
	}

	if (ret)
		cpsw_unregister_ports(cpsw);
	return ret;
}

bool cpsw_port_dev_check(const struct net_device *ndev)
{
	if (ndev->netdev_ops == &cpsw_netdev_ops) {
		struct cpsw_common *cpsw = ndev_to_cpsw(ndev);

		return !cpsw->data.dual_emac;
	}

	return false;
}

static void cpsw_port_offload_fwd_mark_update(struct cpsw_common *cpsw)
{
	int set_val = 0;
	int i;

	if (!cpsw->ale_bypass &&
	    (cpsw->br_members == (ALE_PORT_1 | ALE_PORT_2)))
		set_val = 1;

	dev_dbg(cpsw->dev, "set offload_fwd_mark %d\n", set_val);

	for (i = 0; i < cpsw->data.slaves; i++) {
		struct net_device *sl_ndev = cpsw->slaves[i].ndev;
		struct cpsw_priv *priv = netdev_priv(sl_ndev);

		priv->offload_fwd_mark = set_val;
	}
}

static int cpsw_netdevice_port_link(struct net_device *ndev,
				    struct net_device *br_ndev,
				    struct netlink_ext_ack *extack)
{
	struct cpsw_priv *priv = netdev_priv(ndev);
	struct cpsw_common *cpsw = priv->cpsw;
	int err;

	if (!cpsw->br_members) {
		cpsw->hw_bridge_dev = br_ndev;
	} else {
		/* This is adding the port to a second bridge, this is
		 * unsupported
		 */
		if (cpsw->hw_bridge_dev != br_ndev)
			return -EOPNOTSUPP;
	}

	err = switchdev_bridge_port_offload(ndev, ndev, NULL, NULL, NULL,
					    false, extack);
	if (err)
		return err;

	cpsw->br_members |= BIT(priv->emac_port);

	cpsw_port_offload_fwd_mark_update(cpsw);

	return NOTIFY_DONE;
}

static void cpsw_netdevice_port_unlink(struct net_device *ndev)
{
	struct cpsw_priv *priv = netdev_priv(ndev);
	struct cpsw_common *cpsw = priv->cpsw;

	switchdev_bridge_port_unoffload(ndev, NULL, NULL, NULL);

	cpsw->br_members &= ~BIT(priv->emac_port);

	cpsw_port_offload_fwd_mark_update(cpsw);

	if (!cpsw->br_members)
		cpsw->hw_bridge_dev = NULL;
}

/* netdev notifier */
static int cpsw_netdevice_event(struct notifier_block *unused,
				unsigned long event, void *ptr)
{
	struct netlink_ext_ack *extack = netdev_notifier_info_to_extack(ptr);
	struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
	struct netdev_notifier_changeupper_info *info;
	int ret = NOTIFY_DONE;

	if (!cpsw_port_dev_check(ndev))
		return NOTIFY_DONE;

	switch (event) {
	case NETDEV_CHANGEUPPER:
		info = ptr;

		if (netif_is_bridge_master(info->upper_dev)) {
			if (info->linking)
				ret = cpsw_netdevice_port_link(ndev,
							       info->upper_dev,
							       extack);
			else
				cpsw_netdevice_port_unlink(ndev);
		}
		break;
	default:
		return NOTIFY_DONE;
	}

	return notifier_from_errno(ret);
}

static struct notifier_block cpsw_netdevice_nb __read_mostly = {
	.notifier_call = cpsw_netdevice_event,
};

static int cpsw_register_notifiers(struct cpsw_common *cpsw)
{
	int ret = 0;

	ret = register_netdevice_notifier(&cpsw_netdevice_nb);
	if (ret) {
		dev_err(cpsw->dev, "can't register netdevice notifier\n");
		return ret;
	}

	ret = cpsw_switchdev_register_notifiers(cpsw);
	if (ret)
		unregister_netdevice_notifier(&cpsw_netdevice_nb);

	return ret;
}

static void cpsw_unregister_notifiers(struct cpsw_common *cpsw)
{
	cpsw_switchdev_unregister_notifiers(cpsw);
	unregister_netdevice_notifier(&cpsw_netdevice_nb);
}

static const struct devlink_ops cpsw_devlink_ops = {
};

static int cpsw_dl_switch_mode_get(struct devlink *dl, u32 id,
				   struct devlink_param_gset_ctx *ctx)
{
	struct cpsw_devlink *dl_priv = devlink_priv(dl);
	struct cpsw_common *cpsw = dl_priv->cpsw;

	dev_dbg(cpsw->dev, "%s id:%u\n", __func__, id);

	if (id != CPSW_DL_PARAM_SWITCH_MODE)
		return  -EOPNOTSUPP;

	ctx->val.vbool = !cpsw->data.dual_emac;

	return 0;
}

static int cpsw_dl_switch_mode_set(struct devlink *dl, u32 id,
				   struct devlink_param_gset_ctx *ctx,
				   struct netlink_ext_ack *extack)
{
	struct cpsw_devlink *dl_priv = devlink_priv(dl);
	struct cpsw_common *cpsw = dl_priv->cpsw;
	int vlan = cpsw->data.default_vlan;
	bool switch_en = ctx->val.vbool;
	bool if_running = false;
	int i;

	dev_dbg(cpsw->dev, "%s id:%u\n", __func__, id);

	if (id != CPSW_DL_PARAM_SWITCH_MODE)
		return  -EOPNOTSUPP;

	if (switch_en == !cpsw->data.dual_emac)
		return 0;

	if (!switch_en && cpsw->br_members) {
		dev_err(cpsw->dev, "Remove ports from BR before disabling switch mode\n");
		return -EINVAL;
	}

	rtnl_lock();

	for (i = 0; i < cpsw->data.slaves; i++) {
		struct cpsw_slave *slave = &cpsw->slaves[i];
		struct net_device *sl_ndev = slave->ndev;

		if (!sl_ndev || !netif_running(sl_ndev))
			continue;

		if_running = true;
	}

	if (!if_running) {
		/* all ndevs are down */
		cpsw->data.dual_emac = !switch_en;
		for (i = 0; i < cpsw->data.slaves; i++) {
			struct cpsw_slave *slave = &cpsw->slaves[i];
			struct net_device *sl_ndev = slave->ndev;

			if (!sl_ndev)
				continue;

			if (switch_en)
				vlan = cpsw->data.default_vlan;
			else
				vlan = slave->data->dual_emac_res_vlan;
			slave->port_vlan = vlan;
		}
		goto exit;
	}

	if (switch_en) {
		dev_info(cpsw->dev, "Enable switch mode\n");

		/* enable bypass - no forwarding; all traffic goes to Host */
		cpsw_ale_control_set(cpsw->ale, 0, ALE_BYPASS, 1);

		/* clean up ALE table */
		cpsw_ale_control_set(cpsw->ale, 0, ALE_CLEAR, 1);
		cpsw_ale_control_get(cpsw->ale, 0, ALE_AGEOUT);

		cpsw_init_host_port_switch(cpsw);

		for (i = 0; i < cpsw->data.slaves; i++) {
			struct cpsw_slave *slave = &cpsw->slaves[i];
			struct net_device *sl_ndev = slave->ndev;
			struct cpsw_priv *priv;

			if (!sl_ndev)
				continue;

			priv = netdev_priv(sl_ndev);
			slave->port_vlan = vlan;
			WRITE_ONCE(priv->tx_packet_min, CPSW_MIN_PACKET_SIZE_VLAN);
			if (netif_running(sl_ndev))
				cpsw_port_add_switch_def_ale_entries(priv,
								     slave);
		}

		cpsw_ale_control_set(cpsw->ale, 0, ALE_BYPASS, 0);
		cpsw->data.dual_emac = false;
	} else {
		dev_info(cpsw->dev, "Disable switch mode\n");

		/* enable bypass - no forwarding; all traffic goes to Host */
		cpsw_ale_control_set(cpsw->ale, 0, ALE_BYPASS, 1);

		cpsw_ale_control_set(cpsw->ale, 0, ALE_CLEAR, 1);
		cpsw_ale_control_get(cpsw->ale, 0, ALE_AGEOUT);

		cpsw_init_host_port_dual_mac(cpsw);

		for (i = 0; i < cpsw->data.slaves; i++) {
			struct cpsw_slave *slave = &cpsw->slaves[i];
			struct net_device *sl_ndev = slave->ndev;
			struct cpsw_priv *priv;

			if (!sl_ndev)
				continue;

			priv = netdev_priv(slave->ndev);
			slave->port_vlan = slave->data->dual_emac_res_vlan;
			WRITE_ONCE(priv->tx_packet_min, CPSW_MIN_PACKET_SIZE);
			cpsw_port_add_dual_emac_def_ale_entries(priv, slave);
		}

		cpsw_ale_control_set(cpsw->ale, 0, ALE_BYPASS, 0);
		cpsw->data.dual_emac = true;
	}
exit:
	rtnl_unlock();

	return 0;
}

static int cpsw_dl_ale_ctrl_get(struct devlink *dl, u32 id,
				struct devlink_param_gset_ctx *ctx)
{
	struct cpsw_devlink *dl_priv = devlink_priv(dl);
	struct cpsw_common *cpsw = dl_priv->cpsw;

	dev_dbg(cpsw->dev, "%s id:%u\n", __func__, id);

	switch (id) {
	case CPSW_DL_PARAM_ALE_BYPASS:
		ctx->val.vbool = cpsw_ale_control_get(cpsw->ale, 0, ALE_BYPASS);
		break;
	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

static int cpsw_dl_ale_ctrl_set(struct devlink *dl, u32 id,
				struct devlink_param_gset_ctx *ctx,
				struct netlink_ext_ack *extack)
{
	struct cpsw_devlink *dl_priv = devlink_priv(dl);
	struct cpsw_common *cpsw = dl_priv->cpsw;
	int ret = -EOPNOTSUPP;

	dev_dbg(cpsw->dev, "%s id:%u\n", __func__, id);

	switch (id) {
	case CPSW_DL_PARAM_ALE_BYPASS:
		ret = cpsw_ale_control_set(cpsw->ale, 0, ALE_BYPASS,
					   ctx->val.vbool);
		if (!ret) {
			cpsw->ale_bypass = ctx->val.vbool;
			cpsw_port_offload_fwd_mark_update(cpsw);
		}
		break;
	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

static const struct devlink_param cpsw_devlink_params[] = {
	DEVLINK_PARAM_DRIVER(CPSW_DL_PARAM_SWITCH_MODE,
			     "switch_mode", DEVLINK_PARAM_TYPE_BOOL,
			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
			     cpsw_dl_switch_mode_get, cpsw_dl_switch_mode_set,
			     NULL),
	DEVLINK_PARAM_DRIVER(CPSW_DL_PARAM_ALE_BYPASS,
			     "ale_bypass", DEVLINK_PARAM_TYPE_BOOL,
			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
			     cpsw_dl_ale_ctrl_get, cpsw_dl_ale_ctrl_set, NULL),
};

static int cpsw_register_devlink(struct cpsw_common *cpsw)
{
	struct device *dev = cpsw->dev;
	struct cpsw_devlink *dl_priv;
	int ret = 0;

	cpsw->devlink = devlink_alloc(&cpsw_devlink_ops, sizeof(*dl_priv), dev);
	if (!cpsw->devlink)
		return -ENOMEM;

	dl_priv = devlink_priv(cpsw->devlink);
	dl_priv->cpsw = cpsw;

	ret = devlink_params_register(cpsw->devlink, cpsw_devlink_params,
				      ARRAY_SIZE(cpsw_devlink_params));
	if (ret) {
		dev_err(dev, "DL params reg fail ret:%d\n", ret);
		goto dl_unreg;
	}

	devlink_register(cpsw->devlink);
	return ret;

dl_unreg:
	devlink_free(cpsw->devlink);
	return ret;
}

static void cpsw_unregister_devlink(struct cpsw_common *cpsw)
{
	devlink_unregister(cpsw->devlink);
	devlink_params_unregister(cpsw->devlink, cpsw_devlink_params,
				  ARRAY_SIZE(cpsw_devlink_params));
	devlink_free(cpsw->devlink);
}

static const struct of_device_id cpsw_of_mtable[] = {
	{ .compatible = "ti,cpsw-switch"},
	{ .compatible = "ti,am335x-cpsw-switch"},
	{ .compatible = "ti,am4372-cpsw-switch"},
	{ .compatible = "ti,dra7-cpsw-switch"},
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, cpsw_of_mtable);

static const struct soc_device_attribute cpsw_soc_devices[] = {
	{ .family = "AM33xx", .revision = "ES1.0"},
	{ /* sentinel */ }
};

static int cpsw_probe(struct platform_device *pdev)
{
	const struct soc_device_attribute *soc;
	struct device *dev = &pdev->dev;
	struct cpsw_common *cpsw;
	struct resource *ss_res;
	struct gpio_descs *mode;
	void __iomem *ss_regs;
	int ret = 0, ch;
	struct clk *clk;
	int irq;

	cpsw = devm_kzalloc(dev, sizeof(struct cpsw_common), GFP_KERNEL);
	if (!cpsw)
		return -ENOMEM;

	cpsw_slave_index = cpsw_slave_index_priv;

	cpsw->dev = dev;

	cpsw->slaves = devm_kcalloc(dev,
				    CPSW_SLAVE_PORTS_NUM,
				    sizeof(struct cpsw_slave),
				    GFP_KERNEL);
	if (!cpsw->slaves)
		return -ENOMEM;

	mode = devm_gpiod_get_array_optional(dev, "mode", GPIOD_OUT_LOW);
	if (IS_ERR(mode)) {
		ret = PTR_ERR(mode);
		dev_err(dev, "gpio request failed, ret %d\n", ret);
		return ret;
	}

	clk = devm_clk_get(dev, "fck");
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		dev_err(dev, "fck is not found %d\n", ret);
		return ret;
	}
	cpsw->bus_freq_mhz = clk_get_rate(clk) / 1000000;

	ss_regs = devm_platform_get_and_ioremap_resource(pdev, 0, &ss_res);
	if (IS_ERR(ss_regs)) {
		ret = PTR_ERR(ss_regs);
		return ret;
	}
	cpsw->regs = ss_regs;

	irq = platform_get_irq_byname(pdev, "rx");
	if (irq < 0)
		return irq;
	cpsw->irqs_table[0] = irq;

	irq = platform_get_irq_byname(pdev, "tx");
	if (irq < 0)
		return irq;
	cpsw->irqs_table[1] = irq;

	irq = platform_get_irq_byname(pdev, "misc");
	if (irq <= 0)
		return irq;
	cpsw->misc_irq = irq;

	platform_set_drvdata(pdev, cpsw);
	/* This may be required here for child devices. */
	pm_runtime_enable(dev);

	/* Need to enable clocks with runtime PM api to access module
	 * registers
	 */
	ret = pm_runtime_resume_and_get(dev);
	if (ret < 0) {
		pm_runtime_disable(dev);
		return ret;
	}

	ret = cpsw_probe_dt(cpsw);
	if (ret)
		goto clean_dt_ret;

	soc = soc_device_match(cpsw_soc_devices);
	if (soc)
		cpsw->quirk_irq = true;

	cpsw->rx_packet_max = rx_packet_max;
	cpsw->descs_pool_size = descs_pool_size;
	eth_random_addr(cpsw->base_mac);

	ret = cpsw_init_common(cpsw, ss_regs, ale_ageout,
			       (u32 __force)ss_res->start + CPSW2_BD_OFFSET,
			       descs_pool_size);
	if (ret)
		goto clean_dt_ret;

	cpsw->wr_regs = cpsw->version == CPSW_VERSION_1 ?
			ss_regs + CPSW1_WR_OFFSET :
			ss_regs + CPSW2_WR_OFFSET;

	ch = cpsw->quirk_irq ? 0 : 7;
	cpsw->txv[0].ch = cpdma_chan_create(cpsw->dma, ch, cpsw_tx_handler, 0);
	if (IS_ERR(cpsw->txv[0].ch)) {
		dev_err(dev, "error initializing tx dma channel\n");
		ret = PTR_ERR(cpsw->txv[0].ch);
		goto clean_cpts;
	}

	cpsw->rxv[0].ch = cpdma_chan_create(cpsw->dma, 0, cpsw_rx_handler, 1);
	if (IS_ERR(cpsw->rxv[0].ch)) {
		dev_err(dev, "error initializing rx dma channel\n");
		ret = PTR_ERR(cpsw->rxv[0].ch);
		goto clean_cpts;
	}
	cpsw_split_res(cpsw);

	/* setup netdevs */
	ret = cpsw_create_ports(cpsw);
	if (ret)
		goto clean_cpts;

	/* Grab RX and TX IRQs. Note that we also have RX_THRESHOLD and
	 * MISC IRQs which are always kept disabled with this driver so
	 * we will not request them.
	 *
	 * If anyone wants to implement support for those, make sure to
	 * first request and append them to irqs_table array.
	 */

	ret = devm_request_irq(dev, cpsw->irqs_table[0], cpsw_rx_interrupt,
			       0, dev_name(dev), cpsw);
	if (ret < 0) {
		dev_err(dev, "error attaching irq (%d)\n", ret);
		goto clean_cpts;
	}

	ret = devm_request_irq(dev, cpsw->irqs_table[1], cpsw_tx_interrupt,
			       0, dev_name(dev), cpsw);
	if (ret < 0) {
		dev_err(dev, "error attaching irq (%d)\n", ret);
		goto clean_cpts;
	}

	if (!cpsw->cpts)
		goto skip_cpts;

	ret = devm_request_irq(dev, cpsw->misc_irq, cpsw_misc_interrupt,
			       0, dev_name(&pdev->dev), cpsw);
	if (ret < 0) {
		dev_err(dev, "error attaching misc irq (%d)\n", ret);
		goto clean_cpts;
	}

	/* Enable misc CPTS evnt_pend IRQ */
	cpts_set_irqpoll(cpsw->cpts, false);

skip_cpts:
	ret = cpsw_register_notifiers(cpsw);
	if (ret)
		goto clean_cpts;

	ret = cpsw_register_devlink(cpsw);
	if (ret)
		goto clean_unregister_notifiers;

	ret = cpsw_register_ports(cpsw);
	if (ret)
		goto clean_unregister_notifiers;

	dev_notice(dev, "initialized (regs %pa, pool size %d) hw_ver:%08X %d.%d (%d)\n",
		   &ss_res->start, descs_pool_size,
		   cpsw->version, CPSW_MAJOR_VERSION(cpsw->version),
		   CPSW_MINOR_VERSION(cpsw->version),
		   CPSW_RTL_VERSION(cpsw->version));

	pm_runtime_put(dev);

	return 0;

clean_unregister_notifiers:
	cpsw_unregister_notifiers(cpsw);
clean_cpts:
	cpts_release(cpsw->cpts);
	cpdma_ctlr_destroy(cpsw->dma);
clean_dt_ret:
	cpsw_remove_dt(cpsw);
	pm_runtime_put_sync(dev);
	pm_runtime_disable(dev);
	return ret;
}

static void cpsw_remove(struct platform_device *pdev)
{
	struct cpsw_common *cpsw = platform_get_drvdata(pdev);
	int ret;

	ret = pm_runtime_resume_and_get(&pdev->dev);
	if (ret < 0) {
		/* Note, if this error path is taken, we're leaking some
		 * resources.
		 */
		dev_err(&pdev->dev, "Failed to resume device (%pe)\n",
			ERR_PTR(ret));
		return;
	}

	cpsw_unregister_notifiers(cpsw);
	cpsw_unregister_devlink(cpsw);
	cpsw_unregister_ports(cpsw);

	cpts_release(cpsw->cpts);
	cpdma_ctlr_destroy(cpsw->dma);
	cpsw_remove_dt(cpsw);
	pm_runtime_put_sync(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
}

static int __maybe_unused cpsw_suspend(struct device *dev)
{
	struct cpsw_common *cpsw = dev_get_drvdata(dev);
	int i;

	rtnl_lock();

	for (i = 0; i < cpsw->data.slaves; i++) {
		struct net_device *ndev = cpsw->slaves[i].ndev;

		if (!(ndev && netif_running(ndev)))
			continue;

		cpsw_ndo_stop(ndev);
	}

	rtnl_unlock();

	/* Select sleep pin state */
	pinctrl_pm_select_sleep_state(dev);

	return 0;
}

static int __maybe_unused cpsw_resume(struct device *dev)
{
	struct cpsw_common *cpsw = dev_get_drvdata(dev);
	int i;

	/* Select default pin state */
	pinctrl_pm_select_default_state(dev);

	/* shut up ASSERT_RTNL() warning in netif_set_real_num_tx/rx_queues */
	rtnl_lock();

	for (i = 0; i < cpsw->data.slaves; i++) {
		struct net_device *ndev = cpsw->slaves[i].ndev;

		if (!(ndev && netif_running(ndev)))
			continue;

		cpsw_ndo_open(ndev);
	}

	rtnl_unlock();

	return 0;
}

static SIMPLE_DEV_PM_OPS(cpsw_pm_ops, cpsw_suspend, cpsw_resume);

static struct platform_driver cpsw_driver = {
	.driver = {
		.name	 = "cpsw-switch",
		.pm	 = &cpsw_pm_ops,
		.of_match_table = cpsw_of_mtable,
	},
	.probe = cpsw_probe,
	.remove = cpsw_remove,
};

module_platform_driver(cpsw_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("TI CPSW switchdev Ethernet driver");
