// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
 * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
 * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016 John Crispin <john@phrozen.org>
 */

#include <linux/module.h>
#include <linux/phy.h>
#include <linux/netdevice.h>
#include <linux/bitfield.h>
#include <linux/regmap.h>
#include <net/dsa.h>
#include <linux/of_net.h>
#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <linux/mdio.h>
#include <linux/phylink.h>
#include <linux/gpio/consumer.h>
#include <linux/etherdevice.h>
#include <linux/dsa/tag_qca.h>

#include "qca8k.h"
#include "qca8k_leds.h"

static void
qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
{
	regaddr >>= 1;
	*r1 = regaddr & 0x1e;

	regaddr >>= 5;
	*r2 = regaddr & 0x7;

	regaddr >>= 3;
	*page = regaddr & 0x3ff;
}

static int
qca8k_mii_write_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
{
	int ret;
	u16 lo;

	lo = val & 0xffff;
	ret = bus->write(bus, phy_id, regnum, lo);
	if (ret < 0)
		dev_err_ratelimited(&bus->dev,
				    "failed to write qca8k 32bit lo register\n");

	return ret;
}

static int
qca8k_mii_write_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
{
	int ret;
	u16 hi;

	hi = (u16)(val >> 16);
	ret = bus->write(bus, phy_id, regnum, hi);
	if (ret < 0)
		dev_err_ratelimited(&bus->dev,
				    "failed to write qca8k 32bit hi register\n");

	return ret;
}

static int
qca8k_mii_read_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
{
	int ret;

	ret = bus->read(bus, phy_id, regnum);
	if (ret < 0)
		goto err;

	*val = ret & 0xffff;
	return 0;

err:
	dev_err_ratelimited(&bus->dev,
			    "failed to read qca8k 32bit lo register\n");
	*val = 0;

	return ret;
}

static int
qca8k_mii_read_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
{
	int ret;

	ret = bus->read(bus, phy_id, regnum);
	if (ret < 0)
		goto err;

	*val = ret << 16;
	return 0;

err:
	dev_err_ratelimited(&bus->dev,
			    "failed to read qca8k 32bit hi register\n");
	*val = 0;

	return ret;
}

static int
qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
{
	u32 hi, lo;
	int ret;

	*val = 0;

	ret = qca8k_mii_read_lo(bus, phy_id, regnum, &lo);
	if (ret < 0)
		goto err;

	ret = qca8k_mii_read_hi(bus, phy_id, regnum + 1, &hi);
	if (ret < 0)
		goto err;

	*val = lo | hi;

err:
	return ret;
}

static void
qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
{
	if (qca8k_mii_write_lo(bus, phy_id, regnum, val) < 0)
		return;

	qca8k_mii_write_hi(bus, phy_id, regnum + 1, val);
}

static int
qca8k_set_page(struct qca8k_priv *priv, u16 page)
{
	u16 *cached_page = &priv->mdio_cache.page;
	struct mii_bus *bus = priv->bus;
	int ret;

	if (page == *cached_page)
		return 0;

	ret = bus->write(bus, 0x18, 0, page);
	if (ret < 0) {
		dev_err_ratelimited(&bus->dev,
				    "failed to set qca8k page\n");
		return ret;
	}

	*cached_page = page;
	usleep_range(1000, 2000);
	return 0;
}

static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
{
	struct qca8k_mgmt_eth_data *mgmt_eth_data;
	struct qca8k_priv *priv = ds->priv;
	struct qca_mgmt_ethhdr *mgmt_ethhdr;
	u32 command;
	u8 len, cmd;
	int i;

	mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb);
	mgmt_eth_data = &priv->mgmt_eth_data;

	command = get_unaligned_le32(&mgmt_ethhdr->command);
	cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command);

	len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command);
	/* Special case for len of 15 as this is the max value for len and needs to
	 * be increased before converting it from word to dword.
	 */
	if (len == 15)
		len++;

	/* We can ignore odd value, we always round up them in the alloc function. */
	len *= sizeof(u16);

	/* Make sure the seq match the requested packet */
	if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq)
		mgmt_eth_data->ack = true;

	if (cmd == MDIO_READ) {
		u32 *val = mgmt_eth_data->data;

		*val = get_unaligned_le32(&mgmt_ethhdr->mdio_data);

		/* Get the rest of the 12 byte of data.
		 * The read/write function will extract the requested data.
		 */
		if (len > QCA_HDR_MGMT_DATA1_LEN) {
			__le32 *data2 = (__le32 *)skb->data;
			int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN,
					     len - QCA_HDR_MGMT_DATA1_LEN);

			val++;

			for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) {
				*val = get_unaligned_le32(data2);
				val++;
				data2++;
			}
		}
	}

	complete(&mgmt_eth_data->rw_done);
}

static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val,
					       int priority, unsigned int len)
{
	struct qca_mgmt_ethhdr *mgmt_ethhdr;
	unsigned int real_len;
	struct sk_buff *skb;
	__le32 *data2;
	u32 command;
	u16 hdr;
	int i;

	skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN);
	if (!skb)
		return NULL;

	/* Hdr mgmt length value is in step of word size.
	 * As an example to process 4 byte of data the correct length to set is 2.
	 * To process 8 byte 4, 12 byte 6, 16 byte 8...
	 *
	 * Odd values will always return the next size on the ack packet.
	 * (length of 3 (6 byte) will always return 8 bytes of data)
	 *
	 * This means that a value of 15 (0xf) actually means reading/writing 32 bytes
	 * of data.
	 *
	 * To correctly calculate the length we devide the requested len by word and
	 * round up.
	 * On the ack function we can skip the odd check as we already handle the
	 * case here.
	 */
	real_len = DIV_ROUND_UP(len, sizeof(u16));

	/* We check if the result len is odd and we round up another time to
	 * the next size. (length of 3 will be increased to 4 as switch will always
	 * return 8 bytes)
	 */
	if (real_len % sizeof(u16) != 0)
		real_len++;

	/* Max reg value is 0xf(15) but switch will always return the next size (32 byte) */
	if (real_len == 16)
		real_len--;

	skb_reset_mac_header(skb);
	skb_set_network_header(skb, skb->len);

	mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN);

	hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION);
	hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority);
	hdr |= QCA_HDR_XMIT_FROM_CPU;
	hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0));
	hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG);

	command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
	command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len);
	command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
	command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
					   QCA_HDR_MGMT_CHECK_CODE_VAL);

	put_unaligned_le32(command, &mgmt_ethhdr->command);

	if (cmd == MDIO_WRITE)
		put_unaligned_le32(*val, &mgmt_ethhdr->mdio_data);

	mgmt_ethhdr->hdr = htons(hdr);

	data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN);
	if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) {
		int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN,
				     len - QCA_HDR_MGMT_DATA1_LEN);

		val++;

		for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) {
			put_unaligned_le32(*val, data2);
			data2++;
			val++;
		}
	}

	return skb;
}

static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num)
{
	struct qca_mgmt_ethhdr *mgmt_ethhdr;
	u32 seq;

	seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
	mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data;
	put_unaligned_le32(seq, &mgmt_ethhdr->seq);
}

static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
{
	struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data;
	struct sk_buff *skb;
	bool ack;
	int ret;

	skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL,
				      QCA8K_ETHERNET_MDIO_PRIORITY, len);
	if (!skb)
		return -ENOMEM;

	mutex_lock(&mgmt_eth_data->mutex);

	/* Check if the mgmt_conduit if is operational */
	if (!priv->mgmt_conduit) {
		kfree_skb(skb);
		mutex_unlock(&mgmt_eth_data->mutex);
		return -EINVAL;
	}

	skb->dev = priv->mgmt_conduit;

	reinit_completion(&mgmt_eth_data->rw_done);

	/* Increment seq_num and set it in the mdio pkt */
	mgmt_eth_data->seq++;
	qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
	mgmt_eth_data->ack = false;

	dev_queue_xmit(skb);

	ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
					  msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));

	*val = mgmt_eth_data->data[0];
	if (len > QCA_HDR_MGMT_DATA1_LEN)
		memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN);

	ack = mgmt_eth_data->ack;

	mutex_unlock(&mgmt_eth_data->mutex);

	if (ret <= 0)
		return -ETIMEDOUT;

	if (!ack)
		return -EINVAL;

	return 0;
}

static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
{
	struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data;
	struct sk_buff *skb;
	bool ack;
	int ret;

	skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val,
				      QCA8K_ETHERNET_MDIO_PRIORITY, len);
	if (!skb)
		return -ENOMEM;

	mutex_lock(&mgmt_eth_data->mutex);

	/* Check if the mgmt_conduit if is operational */
	if (!priv->mgmt_conduit) {
		kfree_skb(skb);
		mutex_unlock(&mgmt_eth_data->mutex);
		return -EINVAL;
	}

	skb->dev = priv->mgmt_conduit;

	reinit_completion(&mgmt_eth_data->rw_done);

	/* Increment seq_num and set it in the mdio pkt */
	mgmt_eth_data->seq++;
	qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
	mgmt_eth_data->ack = false;

	dev_queue_xmit(skb);

	ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
					  msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT));

	ack = mgmt_eth_data->ack;

	mutex_unlock(&mgmt_eth_data->mutex);

	if (ret <= 0)
		return -ETIMEDOUT;

	if (!ack)
		return -EINVAL;

	return 0;
}

static int
qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
{
	u32 val = 0;
	int ret;

	ret = qca8k_read_eth(priv, reg, &val, sizeof(val));
	if (ret)
		return ret;

	val &= ~mask;
	val |= write_val;

	return qca8k_write_eth(priv, reg, &val, sizeof(val));
}

static int
qca8k_read_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t *val)
{
	struct mii_bus *bus = priv->bus;
	u16 r1, r2, page;
	int ret;

	qca8k_split_addr(reg, &r1, &r2, &page);

	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);

	ret = qca8k_set_page(priv, page);
	if (ret < 0)
		goto exit;

	ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val);

exit:
	mutex_unlock(&bus->mdio_lock);
	return ret;
}

static int
qca8k_write_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t val)
{
	struct mii_bus *bus = priv->bus;
	u16 r1, r2, page;
	int ret;

	qca8k_split_addr(reg, &r1, &r2, &page);

	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);

	ret = qca8k_set_page(priv, page);
	if (ret < 0)
		goto exit;

	qca8k_mii_write32(bus, 0x10 | r2, r1, val);

exit:
	mutex_unlock(&bus->mdio_lock);
	return ret;
}

static int
qca8k_regmap_update_bits_mii(struct qca8k_priv *priv, uint32_t reg,
			     uint32_t mask, uint32_t write_val)
{
	struct mii_bus *bus = priv->bus;
	u16 r1, r2, page;
	u32 val;
	int ret;

	qca8k_split_addr(reg, &r1, &r2, &page);

	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);

	ret = qca8k_set_page(priv, page);
	if (ret < 0)
		goto exit;

	ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
	if (ret < 0)
		goto exit;

	val &= ~mask;
	val |= write_val;
	qca8k_mii_write32(bus, 0x10 | r2, r1, val);

exit:
	mutex_unlock(&bus->mdio_lock);

	return ret;
}

static int
qca8k_bulk_read(void *ctx, const void *reg_buf, size_t reg_len,
		void *val_buf, size_t val_len)
{
	int i, count = val_len / sizeof(u32), ret;
	struct qca8k_priv *priv = ctx;
	u32 reg = *(u16 *)reg_buf;

	if (priv->mgmt_conduit &&
	    !qca8k_read_eth(priv, reg, val_buf, val_len))
		return 0;

	/* loop count times and increment reg of 4 */
	for (i = 0; i < count; i++, reg += sizeof(u32)) {
		ret = qca8k_read_mii(priv, reg, val_buf + i);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int
qca8k_bulk_gather_write(void *ctx, const void *reg_buf, size_t reg_len,
			const void *val_buf, size_t val_len)
{
	int i, count = val_len / sizeof(u32), ret;
	struct qca8k_priv *priv = ctx;
	u32 reg = *(u16 *)reg_buf;
	u32 *val = (u32 *)val_buf;

	if (priv->mgmt_conduit &&
	    !qca8k_write_eth(priv, reg, val, val_len))
		return 0;

	/* loop count times, increment reg of 4 and increment val ptr to
	 * the next value
	 */
	for (i = 0; i < count; i++, reg += sizeof(u32), val++) {
		ret = qca8k_write_mii(priv, reg, *val);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int
qca8k_bulk_write(void *ctx, const void *data, size_t bytes)
{
	return qca8k_bulk_gather_write(ctx, data, sizeof(u16), data + sizeof(u16),
				       bytes - sizeof(u16));
}

static int
qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val)
{
	struct qca8k_priv *priv = ctx;

	if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val))
		return 0;

	return qca8k_regmap_update_bits_mii(priv, reg, mask, write_val);
}

static const struct regmap_config qca8k_regmap_config = {
	.reg_bits = 16,
	.val_bits = 32,
	.reg_stride = 4,
	.max_register = 0x16ac, /* end MIB - Port6 range */
	.read = qca8k_bulk_read,
	.write = qca8k_bulk_write,
	.reg_update_bits = qca8k_regmap_update_bits,
	.rd_table = &qca8k_readable_table,
	.disable_locking = true, /* Locking is handled by qca8k read/write */
	.cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */
	.max_raw_read = 32, /* mgmt eth can read up to 8 registers at time */
	/* ATU regs suffer from a bug where some data are not correctly
	 * written. Disable bulk write to correctly write ATU entry.
	 */
	.use_single_write = true,
};

static int
qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data,
			struct sk_buff *read_skb, u32 *val)
{
	struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL);
	bool ack;
	int ret;

	if (!skb)
		return -ENOMEM;

	reinit_completion(&mgmt_eth_data->rw_done);

	/* Increment seq_num and set it in the copy pkt */
	mgmt_eth_data->seq++;
	qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq);
	mgmt_eth_data->ack = false;

	dev_queue_xmit(skb);

	ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
					  QCA8K_ETHERNET_TIMEOUT);

	ack = mgmt_eth_data->ack;

	if (ret <= 0)
		return -ETIMEDOUT;

	if (!ack)
		return -EINVAL;

	*val = mgmt_eth_data->data[0];

	return 0;
}

static int
qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy,
		      int regnum, u16 data)
{
	struct sk_buff *write_skb, *clear_skb, *read_skb;
	struct qca8k_mgmt_eth_data *mgmt_eth_data;
	u32 write_val, clear_val = 0, val;
	struct net_device *mgmt_conduit;
	int ret, ret1;
	bool ack;

	if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
		return -EINVAL;

	mgmt_eth_data = &priv->mgmt_eth_data;

	write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
		    QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
		    QCA8K_MDIO_MASTER_REG_ADDR(regnum);

	if (read) {
		write_val |= QCA8K_MDIO_MASTER_READ;
	} else {
		write_val |= QCA8K_MDIO_MASTER_WRITE;
		write_val |= QCA8K_MDIO_MASTER_DATA(data);
	}

	/* Prealloc all the needed skb before the lock */
	write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val,
					    QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val));
	if (!write_skb)
		return -ENOMEM;

	clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val,
					    QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));
	if (!clear_skb) {
		ret = -ENOMEM;
		goto err_clear_skb;
	}

	read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val,
					   QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));
	if (!read_skb) {
		ret = -ENOMEM;
		goto err_read_skb;
	}

	/* It seems that accessing the switch's internal PHYs via management
	 * packets still uses the MDIO bus within the switch internally, and
	 * these accesses can conflict with external MDIO accesses to other
	 * devices on the MDIO bus.
	 * We therefore need to lock the MDIO bus onto which the switch is
	 * connected.
	 */
	mutex_lock(&priv->bus->mdio_lock);

	/* Actually start the request:
	 * 1. Send mdio master packet
	 * 2. Busy Wait for mdio master command
	 * 3. Get the data if we are reading
	 * 4. Reset the mdio master (even with error)
	 */
	mutex_lock(&mgmt_eth_data->mutex);

	/* Check if mgmt_conduit is operational */
	mgmt_conduit = priv->mgmt_conduit;
	if (!mgmt_conduit) {
		mutex_unlock(&mgmt_eth_data->mutex);
		mutex_unlock(&priv->bus->mdio_lock);
		ret = -EINVAL;
		goto err_mgmt_conduit;
	}

	read_skb->dev = mgmt_conduit;
	clear_skb->dev = mgmt_conduit;
	write_skb->dev = mgmt_conduit;

	reinit_completion(&mgmt_eth_data->rw_done);

	/* Increment seq_num and set it in the write pkt */
	mgmt_eth_data->seq++;
	qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq);
	mgmt_eth_data->ack = false;

	dev_queue_xmit(write_skb);

	ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
					  QCA8K_ETHERNET_TIMEOUT);

	ack = mgmt_eth_data->ack;

	if (ret <= 0) {
		ret = -ETIMEDOUT;
		kfree_skb(read_skb);
		goto exit;
	}

	if (!ack) {
		ret = -EINVAL;
		kfree_skb(read_skb);
		goto exit;
	}

	ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1,
				!(val & QCA8K_MDIO_MASTER_BUSY), 0,
				QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
				mgmt_eth_data, read_skb, &val);

	if (ret < 0 && ret1 < 0) {
		ret = ret1;
		goto exit;
	}

	if (read) {
		reinit_completion(&mgmt_eth_data->rw_done);

		/* Increment seq_num and set it in the read pkt */
		mgmt_eth_data->seq++;
		qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq);
		mgmt_eth_data->ack = false;

		dev_queue_xmit(read_skb);

		ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done,
						  QCA8K_ETHERNET_TIMEOUT);

		ack = mgmt_eth_data->ack;

		if (ret <= 0) {
			ret = -ETIMEDOUT;
			goto exit;
		}

		if (!ack) {
			ret = -EINVAL;
			goto exit;
		}

		ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK;
	} else {
		kfree_skb(read_skb);
	}
exit:
	reinit_completion(&mgmt_eth_data->rw_done);

	/* Increment seq_num and set it in the clear pkt */
	mgmt_eth_data->seq++;
	qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq);
	mgmt_eth_data->ack = false;

	dev_queue_xmit(clear_skb);

	wait_for_completion_timeout(&mgmt_eth_data->rw_done,
				    QCA8K_ETHERNET_TIMEOUT);

	mutex_unlock(&mgmt_eth_data->mutex);
	mutex_unlock(&priv->bus->mdio_lock);

	return ret;

	/* Error handling before lock */
err_mgmt_conduit:
	kfree_skb(read_skb);
err_read_skb:
	kfree_skb(clear_skb);
err_clear_skb:
	kfree_skb(write_skb);

	return ret;
}

static int
qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask)
{
	u16 r1, r2, page;
	u32 val;
	int ret, ret1;

	qca8k_split_addr(reg, &r1, &r2, &page);

	ret = read_poll_timeout(qca8k_mii_read_hi, ret1, !(val & mask), 0,
				QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
				bus, 0x10 | r2, r1 + 1, &val);

	/* Check if qca8k_read has failed for a different reason
	 * before returnting -ETIMEDOUT
	 */
	if (ret < 0 && ret1 < 0)
		return ret1;

	return ret;
}

static int
qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data)
{
	struct mii_bus *bus = priv->bus;
	u16 r1, r2, page;
	u32 val;
	int ret;

	if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
		return -EINVAL;

	val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
	      QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
	      QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
	      QCA8K_MDIO_MASTER_DATA(data);

	qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);

	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);

	ret = qca8k_set_page(priv, page);
	if (ret)
		goto exit;

	qca8k_mii_write32(bus, 0x10 | r2, r1, val);

	ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
				   QCA8K_MDIO_MASTER_BUSY);

exit:
	/* even if the busy_wait timeouts try to clear the MASTER_EN */
	qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0);

	mutex_unlock(&bus->mdio_lock);

	return ret;
}

static int
qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum)
{
	struct mii_bus *bus = priv->bus;
	u16 r1, r2, page;
	u32 val;
	int ret;

	if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
		return -EINVAL;

	val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
	      QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
	      QCA8K_MDIO_MASTER_REG_ADDR(regnum);

	qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);

	mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);

	ret = qca8k_set_page(priv, page);
	if (ret)
		goto exit;

	qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, val);

	ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
				   QCA8K_MDIO_MASTER_BUSY);
	if (ret)
		goto exit;

	ret = qca8k_mii_read_lo(bus, 0x10 | r2, r1, &val);

exit:
	/* even if the busy_wait timeouts try to clear the MASTER_EN */
	qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0);

	mutex_unlock(&bus->mdio_lock);

	if (ret >= 0)
		ret = val & QCA8K_MDIO_MASTER_DATA_MASK;

	return ret;
}

static int
qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data)
{
	struct qca8k_priv *priv = slave_bus->priv;
	int ret;

	/* Use mdio Ethernet when available, fallback to legacy one on error */
	ret = qca8k_phy_eth_command(priv, false, phy, regnum, data);
	if (!ret)
		return 0;

	return qca8k_mdio_write(priv, phy, regnum, data);
}

static int
qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum)
{
	struct qca8k_priv *priv = slave_bus->priv;
	int ret;

	/* Use mdio Ethernet when available, fallback to legacy one on error */
	ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0);
	if (ret >= 0)
		return ret;

	ret = qca8k_mdio_read(priv, phy, regnum);

	if (ret < 0)
		return 0xffff;

	return ret;
}

static int
qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data)
{
	port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;

	return qca8k_internal_mdio_write(slave_bus, port, regnum, data);
}

static int
qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum)
{
	port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;

	return qca8k_internal_mdio_read(slave_bus, port, regnum);
}

static int
qca8k_mdio_register(struct qca8k_priv *priv)
{
	struct dsa_switch *ds = priv->ds;
	struct device *dev = ds->dev;
	struct device_node *mdio;
	struct mii_bus *bus;
	int ret = 0;

	mdio = of_get_child_by_name(dev->of_node, "mdio");
	if (mdio && !of_device_is_available(mdio))
		goto out_put_node;

	bus = devm_mdiobus_alloc(dev);
	if (!bus) {
		ret = -ENOMEM;
		goto out_put_node;
	}

	priv->internal_mdio_bus = bus;
	bus->priv = (void *)priv;
	snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d",
		 ds->dst->index, ds->index);
	bus->parent = dev;

	if (mdio) {
		/* Check if the device tree declares the port:phy mapping */
		bus->name = "qca8k user mii";
		bus->read = qca8k_internal_mdio_read;
		bus->write = qca8k_internal_mdio_write;
	} else {
		/* If a mapping can't be found, the legacy mapping is used,
		 * using qca8k_port_to_phy()
		 */
		ds->user_mii_bus = bus;
		bus->phy_mask = ~ds->phys_mii_mask;
		bus->name = "qca8k-legacy user mii";
		bus->read = qca8k_legacy_mdio_read;
		bus->write = qca8k_legacy_mdio_write;
	}

	ret = devm_of_mdiobus_register(dev, bus, mdio);

out_put_node:
	of_node_put(mdio);
	return ret;
}

static int
qca8k_setup_mdio_bus(struct qca8k_priv *priv)
{
	u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg;
	struct device_node *ports, *port;
	phy_interface_t mode;
	int ret;

	ports = of_get_child_by_name(priv->dev->of_node, "ports");
	if (!ports)
		ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports");

	if (!ports)
		return -EINVAL;

	for_each_available_child_of_node(ports, port) {
		ret = of_property_read_u32(port, "reg", &reg);
		if (ret) {
			of_node_put(port);
			of_node_put(ports);
			return ret;
		}

		if (!dsa_is_user_port(priv->ds, reg))
			continue;

		of_get_phy_mode(port, &mode);

		if (of_property_read_bool(port, "phy-handle") &&
		    mode != PHY_INTERFACE_MODE_INTERNAL)
			external_mdio_mask |= BIT(reg);
		else
			internal_mdio_mask |= BIT(reg);
	}

	of_node_put(ports);
	if (!external_mdio_mask && !internal_mdio_mask) {
		dev_err(priv->dev, "no PHYs are defined.\n");
		return -EINVAL;
	}

	/* The QCA8K_MDIO_MASTER_EN Bit, which grants access to PHYs through
	 * the MDIO_MASTER register also _disconnects_ the external MDC
	 * passthrough to the internal PHYs. It's not possible to use both
	 * configurations at the same time!
	 *
	 * Because this came up during the review process:
	 * If the external mdio-bus driver is capable magically disabling
	 * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's
	 * accessors for the time being, it would be possible to pull this
	 * off.
	 */
	if (!!external_mdio_mask && !!internal_mdio_mask) {
		dev_err(priv->dev, "either internal or external mdio bus configuration is supported.\n");
		return -EINVAL;
	}

	if (external_mdio_mask) {
		/* Make sure to disable the internal mdio bus in cases
		 * a dt-overlay and driver reload changed the configuration
		 */

		return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL,
					 QCA8K_MDIO_MASTER_EN);
	}

	return qca8k_mdio_register(priv);
}

static int
qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
{
	u32 mask = 0;
	int ret = 0;

	/* SoC specific settings for ipq8064.
	 * If more device require this consider adding
	 * a dedicated binding.
	 */
	if (of_machine_is_compatible("qcom,ipq8064"))
		mask |= QCA8K_MAC_PWR_RGMII0_1_8V;

	/* SoC specific settings for ipq8065 */
	if (of_machine_is_compatible("qcom,ipq8065"))
		mask |= QCA8K_MAC_PWR_RGMII1_1_8V;

	if (mask) {
		ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL,
				QCA8K_MAC_PWR_RGMII0_1_8V |
				QCA8K_MAC_PWR_RGMII1_1_8V,
				mask);
	}

	return ret;
}

static int qca8k_find_cpu_port(struct dsa_switch *ds)
{
	struct qca8k_priv *priv = ds->priv;

	/* Find the connected cpu port. Valid port are 0 or 6 */
	if (dsa_is_cpu_port(ds, 0))
		return 0;

	dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6");

	if (dsa_is_cpu_port(ds, 6))
		return 6;

	return -EINVAL;
}

static int
qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
{
	const struct qca8k_match_data *data = priv->info;
	struct device_node *node = priv->dev->of_node;
	u32 val = 0;
	int ret;

	/* QCA8327 require to set to the correct mode.
	 * His bigger brother QCA8328 have the 172 pin layout.
	 * Should be applied by default but we set this just to make sure.
	 */
	if (priv->switch_id == QCA8K_ID_QCA8327) {
		/* Set the correct package of 148 pin for QCA8327 */
		if (data->reduced_package)
			val |= QCA8327_PWS_PACKAGE148_EN;

		ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
				val);
		if (ret)
			return ret;
	}

	if (of_property_read_bool(node, "qca,ignore-power-on-sel"))
		val |= QCA8K_PWS_POWER_ON_SEL;

	if (of_property_read_bool(node, "qca,led-open-drain")) {
		if (!(val & QCA8K_PWS_POWER_ON_SEL)) {
			dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set.");
			return -EINVAL;
		}

		val |= QCA8K_PWS_LED_OPEN_EN_CSR;
	}

	return qca8k_rmw(priv, QCA8K_REG_PWS,
			QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL,
			val);
}

static int
qca8k_parse_port_config(struct qca8k_priv *priv)
{
	int port, cpu_port_index = -1, ret;
	struct device_node *port_dn;
	phy_interface_t mode;
	struct dsa_port *dp;
	u32 delay;

	/* We have 2 CPU port. Check them */
	for (port = 0; port < QCA8K_NUM_PORTS; port++) {
		/* Skip every other port */
		if (port != 0 && port != 6)
			continue;

		dp = dsa_to_port(priv->ds, port);
		port_dn = dp->dn;
		cpu_port_index++;

		if (!of_device_is_available(port_dn))
			continue;

		ret = of_get_phy_mode(port_dn, &mode);
		if (ret)
			continue;

		switch (mode) {
		case PHY_INTERFACE_MODE_RGMII:
		case PHY_INTERFACE_MODE_RGMII_ID:
		case PHY_INTERFACE_MODE_RGMII_TXID:
		case PHY_INTERFACE_MODE_RGMII_RXID:
		case PHY_INTERFACE_MODE_SGMII:
			delay = 0;

			if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
				/* Switch regs accept value in ns, convert ps to ns */
				delay = delay / 1000;
			else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
				 mode == PHY_INTERFACE_MODE_RGMII_TXID)
				delay = 1;

			if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) {
				dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
				delay = 3;
			}

			priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay;

			delay = 0;

			if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay))
				/* Switch regs accept value in ns, convert ps to ns */
				delay = delay / 1000;
			else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
				 mode == PHY_INTERFACE_MODE_RGMII_RXID)
				delay = 2;

			if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) {
				dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
				delay = 3;
			}

			priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay;

			/* Skip sgmii parsing for rgmii* mode */
			if (mode == PHY_INTERFACE_MODE_RGMII ||
			    mode == PHY_INTERFACE_MODE_RGMII_ID ||
			    mode == PHY_INTERFACE_MODE_RGMII_TXID ||
			    mode == PHY_INTERFACE_MODE_RGMII_RXID)
				break;

			if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
				priv->ports_config.sgmii_tx_clk_falling_edge = true;

			if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
				priv->ports_config.sgmii_rx_clk_falling_edge = true;

			if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
				priv->ports_config.sgmii_enable_pll = true;

				if (priv->switch_id == QCA8K_ID_QCA8327) {
					dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
					priv->ports_config.sgmii_enable_pll = false;
				}

				if (priv->switch_revision < 2)
					dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more.");
			}

			break;
		default:
			continue;
		}
	}

	return 0;
}

static void
qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index,
				      u32 reg)
{
	u32 delay, val = 0;
	int ret;

	/* Delay can be declared in 3 different way.
	 * Mode to rgmii and internal-delay standard binding defined
	 * rgmii-id or rgmii-tx/rx phy mode set.
	 * The parse logic set a delay different than 0 only when one
	 * of the 3 different way is used. In all other case delay is
	 * not enabled. With ID or TX/RXID delay is enabled and set
	 * to the default and recommended value.
	 */
	if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) {
		delay = priv->ports_config.rgmii_tx_delay[cpu_port_index];

		val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
			QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
	}

	if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) {
		delay = priv->ports_config.rgmii_rx_delay[cpu_port_index];

		val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
			QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
	}

	/* Set RGMII delay based on the selected values */
	ret = qca8k_rmw(priv, reg,
			QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK |
			QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK |
			QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
			QCA8K_PORT_PAD_RGMII_RX_DELAY_EN,
			val);
	if (ret)
		dev_err(priv->dev, "Failed to set internal delay for CPU port%d",
			cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6);
}

static struct phylink_pcs *
qca8k_phylink_mac_select_pcs(struct phylink_config *config,
			     phy_interface_t interface)
{
	struct dsa_port *dp = dsa_phylink_to_port(config);
	struct qca8k_priv *priv = dp->ds->priv;
	struct phylink_pcs *pcs = NULL;
	int port = dp->index;

	switch (interface) {
	case PHY_INTERFACE_MODE_SGMII:
	case PHY_INTERFACE_MODE_1000BASEX:
		switch (port) {
		case 0:
			pcs = &priv->pcs_port_0.pcs;
			break;

		case 6:
			pcs = &priv->pcs_port_6.pcs;
			break;
		}
		break;

	default:
		break;
	}

	return pcs;
}

static void
qca8k_phylink_mac_config(struct phylink_config *config, unsigned int mode,
			 const struct phylink_link_state *state)
{
	struct dsa_port *dp = dsa_phylink_to_port(config);
	struct dsa_switch *ds = dp->ds;
	struct qca8k_priv *priv;
	int port = dp->index;
	int cpu_port_index;
	u32 reg;

	priv = ds->priv;

	switch (port) {
	case 0: /* 1st CPU port */
		if (state->interface != PHY_INTERFACE_MODE_RGMII &&
		    state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
		    state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
		    state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
		    state->interface != PHY_INTERFACE_MODE_SGMII)
			return;

		reg = QCA8K_REG_PORT0_PAD_CTRL;
		cpu_port_index = QCA8K_CPU_PORT0;
		break;
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		/* Internal PHY, nothing to do */
		return;
	case 6: /* 2nd CPU port / external PHY */
		if (state->interface != PHY_INTERFACE_MODE_RGMII &&
		    state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
		    state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
		    state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
		    state->interface != PHY_INTERFACE_MODE_SGMII &&
		    state->interface != PHY_INTERFACE_MODE_1000BASEX)
			return;

		reg = QCA8K_REG_PORT6_PAD_CTRL;
		cpu_port_index = QCA8K_CPU_PORT6;
		break;
	default:
		dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
		return;
	}

	if (port != 6 && phylink_autoneg_inband(mode)) {
		dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
			__func__);
		return;
	}

	switch (state->interface) {
	case PHY_INTERFACE_MODE_RGMII:
	case PHY_INTERFACE_MODE_RGMII_ID:
	case PHY_INTERFACE_MODE_RGMII_TXID:
	case PHY_INTERFACE_MODE_RGMII_RXID:
		qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);

		/* Configure rgmii delay */
		qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);

		/* QCA8337 requires to set rgmii rx delay for all ports.
		 * This is enabled through PORT5_PAD_CTRL for all ports,
		 * rather than individual port registers.
		 */
		if (priv->switch_id == QCA8K_ID_QCA8337)
			qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
				    QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
		break;
	case PHY_INTERFACE_MODE_SGMII:
	case PHY_INTERFACE_MODE_1000BASEX:
		/* Enable SGMII on the port */
		qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
		break;
	default:
		dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
			phy_modes(state->interface), port);
		return;
	}
}

static void qca8k_phylink_get_caps(struct dsa_switch *ds, int port,
				   struct phylink_config *config)
{
	switch (port) {
	case 0: /* 1st CPU port */
		phy_interface_set_rgmii(config->supported_interfaces);
		__set_bit(PHY_INTERFACE_MODE_SGMII,
			  config->supported_interfaces);
		break;

	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		/* Internal PHY */
		__set_bit(PHY_INTERFACE_MODE_GMII,
			  config->supported_interfaces);
		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
			  config->supported_interfaces);
		break;

	case 6: /* 2nd CPU port / external PHY */
		phy_interface_set_rgmii(config->supported_interfaces);
		__set_bit(PHY_INTERFACE_MODE_SGMII,
			  config->supported_interfaces);
		__set_bit(PHY_INTERFACE_MODE_1000BASEX,
			  config->supported_interfaces);
		break;
	}

	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
		MAC_10 | MAC_100 | MAC_1000FD;
}

static void
qca8k_phylink_mac_link_down(struct phylink_config *config, unsigned int mode,
			    phy_interface_t interface)
{
	struct dsa_port *dp = dsa_phylink_to_port(config);
	struct qca8k_priv *priv = dp->ds->priv;

	qca8k_port_set_status(priv, dp->index, 0);
}

static void
qca8k_phylink_mac_link_up(struct phylink_config *config,
			  struct phy_device *phydev, unsigned int mode,
			  phy_interface_t interface, int speed, int duplex,
			  bool tx_pause, bool rx_pause)
{
	struct dsa_port *dp = dsa_phylink_to_port(config);
	struct qca8k_priv *priv = dp->ds->priv;
	int port = dp->index;
	u32 reg;

	if (phylink_autoneg_inband(mode)) {
		reg = QCA8K_PORT_STATUS_LINK_AUTO;
	} else {
		switch (speed) {
		case SPEED_10:
			reg = QCA8K_PORT_STATUS_SPEED_10;
			break;
		case SPEED_100:
			reg = QCA8K_PORT_STATUS_SPEED_100;
			break;
		case SPEED_1000:
			reg = QCA8K_PORT_STATUS_SPEED_1000;
			break;
		default:
			reg = QCA8K_PORT_STATUS_LINK_AUTO;
			break;
		}

		if (duplex == DUPLEX_FULL)
			reg |= QCA8K_PORT_STATUS_DUPLEX;

		if (rx_pause || dsa_port_is_cpu(dp))
			reg |= QCA8K_PORT_STATUS_RXFLOW;

		if (tx_pause || dsa_port_is_cpu(dp))
			reg |= QCA8K_PORT_STATUS_TXFLOW;
	}

	reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;

	qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg);
}

static struct qca8k_pcs *pcs_to_qca8k_pcs(struct phylink_pcs *pcs)
{
	return container_of(pcs, struct qca8k_pcs, pcs);
}

static void qca8k_pcs_get_state(struct phylink_pcs *pcs,
				struct phylink_link_state *state)
{
	struct qca8k_priv *priv = pcs_to_qca8k_pcs(pcs)->priv;
	int port = pcs_to_qca8k_pcs(pcs)->port;
	u32 reg;
	int ret;

	ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), &reg);
	if (ret < 0) {
		state->link = false;
		return;
	}

	state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP);
	state->an_complete = state->link;
	state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL :
							   DUPLEX_HALF;

	switch (reg & QCA8K_PORT_STATUS_SPEED) {
	case QCA8K_PORT_STATUS_SPEED_10:
		state->speed = SPEED_10;
		break;
	case QCA8K_PORT_STATUS_SPEED_100:
		state->speed = SPEED_100;
		break;
	case QCA8K_PORT_STATUS_SPEED_1000:
		state->speed = SPEED_1000;
		break;
	default:
		state->speed = SPEED_UNKNOWN;
		break;
	}

	if (reg & QCA8K_PORT_STATUS_RXFLOW)
		state->pause |= MLO_PAUSE_RX;
	if (reg & QCA8K_PORT_STATUS_TXFLOW)
		state->pause |= MLO_PAUSE_TX;
}

static int qca8k_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
			    phy_interface_t interface,
			    const unsigned long *advertising,
			    bool permit_pause_to_mac)
{
	struct qca8k_priv *priv = pcs_to_qca8k_pcs(pcs)->priv;
	int cpu_port_index, ret, port;
	u32 reg, val;

	port = pcs_to_qca8k_pcs(pcs)->port;
	switch (port) {
	case 0:
		reg = QCA8K_REG_PORT0_PAD_CTRL;
		cpu_port_index = QCA8K_CPU_PORT0;
		break;

	case 6:
		reg = QCA8K_REG_PORT6_PAD_CTRL;
		cpu_port_index = QCA8K_CPU_PORT6;
		break;

	default:
		WARN_ON(1);
		return -EINVAL;
	}

	/* Enable/disable SerDes auto-negotiation as necessary */
	val = neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ?
		0 : QCA8K_PWS_SERDES_AEN_DIS;

	ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8K_PWS_SERDES_AEN_DIS, val);
	if (ret)
		return ret;

	/* Configure the SGMII parameters */
	ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val);
	if (ret)
		return ret;

	val |= QCA8K_SGMII_EN_SD;

	if (priv->ports_config.sgmii_enable_pll)
		val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
		       QCA8K_SGMII_EN_TX;

	if (dsa_is_cpu_port(priv->ds, port)) {
		/* CPU port, we're talking to the CPU MAC, be a PHY */
		val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
		val |= QCA8K_SGMII_MODE_CTRL_PHY;
	} else if (interface == PHY_INTERFACE_MODE_SGMII) {
		val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
		val |= QCA8K_SGMII_MODE_CTRL_MAC;
	} else if (interface == PHY_INTERFACE_MODE_1000BASEX) {
		val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
		val |= QCA8K_SGMII_MODE_CTRL_BASEX;
	}

	qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);

	/* From original code is reported port instability as SGMII also
	 * require delay set. Apply advised values here or take them from DT.
	 */
	if (interface == PHY_INTERFACE_MODE_SGMII)
		qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
	/* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and
	 * falling edge is set writing in the PORT0 PAD reg
	 */
	if (priv->switch_id == QCA8K_ID_QCA8327 ||
	    priv->switch_id == QCA8K_ID_QCA8337)
		reg = QCA8K_REG_PORT0_PAD_CTRL;

	val = 0;

	/* SGMII Clock phase configuration */
	if (priv->ports_config.sgmii_rx_clk_falling_edge)
		val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;

	if (priv->ports_config.sgmii_tx_clk_falling_edge)
		val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;

	if (val)
		ret = qca8k_rmw(priv, reg,
				QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
				QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
				val);

	return 0;
}

static void qca8k_pcs_an_restart(struct phylink_pcs *pcs)
{
}

static const struct phylink_pcs_ops qca8k_pcs_ops = {
	.pcs_get_state = qca8k_pcs_get_state,
	.pcs_config = qca8k_pcs_config,
	.pcs_an_restart = qca8k_pcs_an_restart,
};

static void qca8k_setup_pcs(struct qca8k_priv *priv, struct qca8k_pcs *qpcs,
			    int port)
{
	qpcs->pcs.ops = &qca8k_pcs_ops;
	qpcs->pcs.neg_mode = true;

	/* We don't have interrupts for link changes, so we need to poll */
	qpcs->pcs.poll = true;
	qpcs->priv = priv;
	qpcs->port = port;
}

static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb)
{
	struct qca8k_mib_eth_data *mib_eth_data;
	struct qca8k_priv *priv = ds->priv;
	const struct qca8k_mib_desc *mib;
	struct mib_ethhdr *mib_ethhdr;
	__le32 *data2;
	u8 port;
	int i;

	mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb);
	mib_eth_data = &priv->mib_eth_data;

	/* The switch autocast every port. Ignore other packet and
	 * parse only the requested one.
	 */
	port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr));
	if (port != mib_eth_data->req_port)
		goto exit;

	data2 = (__le32 *)skb->data;

	for (i = 0; i < priv->info->mib_count; i++) {
		mib = &ar8327_mib[i];

		/* First 3 mib are present in the skb head */
		if (i < 3) {
			mib_eth_data->data[i] = get_unaligned_le32(mib_ethhdr->data + i);
			continue;
		}

		/* Some mib are 64 bit wide */
		if (mib->size == 2)
			mib_eth_data->data[i] = get_unaligned_le64((__le64 *)data2);
		else
			mib_eth_data->data[i] = get_unaligned_le32(data2);

		data2 += mib->size;
	}

exit:
	/* Complete on receiving all the mib packet */
	if (refcount_dec_and_test(&mib_eth_data->port_parsed))
		complete(&mib_eth_data->rw_done);
}

static int
qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data)
{
	struct dsa_port *dp = dsa_to_port(ds, port);
	struct qca8k_mib_eth_data *mib_eth_data;
	struct qca8k_priv *priv = ds->priv;
	int ret;

	mib_eth_data = &priv->mib_eth_data;

	mutex_lock(&mib_eth_data->mutex);

	reinit_completion(&mib_eth_data->rw_done);

	mib_eth_data->req_port = dp->index;
	mib_eth_data->data = data;
	refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS);

	mutex_lock(&priv->reg_mutex);

	/* Send mib autocast request */
	ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB,
				 QCA8K_MIB_FUNC | QCA8K_MIB_BUSY,
				 FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) |
				 QCA8K_MIB_BUSY);

	mutex_unlock(&priv->reg_mutex);

	if (ret)
		goto exit;

	ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT);

exit:
	mutex_unlock(&mib_eth_data->mutex);

	return ret;
}

static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port)
{
	struct qca8k_priv *priv = ds->priv;

	/* Communicate to the phy internal driver the switch revision.
	 * Based on the switch revision different values needs to be
	 * set to the dbg and mmd reg on the phy.
	 * The first 2 bit are used to communicate the switch revision
	 * to the phy driver.
	 */
	if (port > 0 && port < 6)
		return priv->switch_revision;

	return 0;
}

static enum dsa_tag_protocol
qca8k_get_tag_protocol(struct dsa_switch *ds, int port,
		       enum dsa_tag_protocol mp)
{
	return DSA_TAG_PROTO_QCA;
}

static void
qca8k_conduit_change(struct dsa_switch *ds, const struct net_device *conduit,
		     bool operational)
{
	struct dsa_port *dp = conduit->dsa_ptr;
	struct qca8k_priv *priv = ds->priv;

	/* Ethernet MIB/MDIO is only supported for CPU port 0 */
	if (dp->index != 0)
		return;

	mutex_lock(&priv->mgmt_eth_data.mutex);
	mutex_lock(&priv->mib_eth_data.mutex);

	priv->mgmt_conduit = operational ? (struct net_device *)conduit : NULL;

	mutex_unlock(&priv->mib_eth_data.mutex);
	mutex_unlock(&priv->mgmt_eth_data.mutex);
}

static int qca8k_connect_tag_protocol(struct dsa_switch *ds,
				      enum dsa_tag_protocol proto)
{
	struct qca_tagger_data *tagger_data;

	switch (proto) {
	case DSA_TAG_PROTO_QCA:
		tagger_data = ds->tagger_data;

		tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler;
		tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler;

		break;
	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

static void qca8k_setup_hol_fixup(struct qca8k_priv *priv, int port)
{
	u32 mask;

	switch (port) {
	/* The 2 CPU port and port 5 requires some different
	 * priority than any other ports.
	 */
	case 0:
	case 5:
	case 6:
		mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
			QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
			QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) |
			QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) |
			QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) |
			QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) |
			QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e);
		break;
	default:
		mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
			QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
			QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) |
			QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) |
			QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19);
	}
	regmap_write(priv->regmap, QCA8K_REG_PORT_HOL_CTRL0(port), mask);

	mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) |
	       QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
	       QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
	       QCA8K_PORT_HOL_CTRL1_WRED_EN;
	regmap_update_bits(priv->regmap, QCA8K_REG_PORT_HOL_CTRL1(port),
			   QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK |
			   QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
			   QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
			   QCA8K_PORT_HOL_CTRL1_WRED_EN,
			   mask);
}

static int
qca8k_setup(struct dsa_switch *ds)
{
	struct qca8k_priv *priv = ds->priv;
	struct dsa_port *dp;
	int cpu_port, ret;
	u32 mask;

	cpu_port = qca8k_find_cpu_port(ds);
	if (cpu_port < 0) {
		dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6");
		return cpu_port;
	}

	/* Parse CPU port config to be later used in phy_link mac_config */
	ret = qca8k_parse_port_config(priv);
	if (ret)
		return ret;

	ret = qca8k_setup_mdio_bus(priv);
	if (ret)
		return ret;

	ret = qca8k_setup_of_pws_reg(priv);
	if (ret)
		return ret;

	ret = qca8k_setup_mac_pwr_sel(priv);
	if (ret)
		return ret;

	ret = qca8k_setup_led_ctrl(priv);
	if (ret)
		return ret;

	qca8k_setup_pcs(priv, &priv->pcs_port_0, 0);
	qca8k_setup_pcs(priv, &priv->pcs_port_6, 6);

	/* Make sure MAC06 is disabled */
	ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL,
				QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN);
	if (ret) {
		dev_err(priv->dev, "failed disabling MAC06 exchange");
		return ret;
	}

	/* Enable CPU Port */
	ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
			      QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
	if (ret) {
		dev_err(priv->dev, "failed enabling CPU port");
		return ret;
	}

	/* Enable MIB counters */
	ret = qca8k_mib_init(priv);
	if (ret)
		dev_warn(priv->dev, "mib init failed");

	/* Initial setup of all ports */
	dsa_switch_for_each_port(dp, ds) {
		/* Disable forwarding by default on all ports */
		ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(dp->index),
				QCA8K_PORT_LOOKUP_MEMBER, 0);
		if (ret)
			return ret;
	}

	/* Disable MAC by default on all user ports */
	dsa_switch_for_each_user_port(dp, ds)
		qca8k_port_set_status(priv, dp->index, 0);

	/* Enable QCA header mode on all cpu ports */
	dsa_switch_for_each_cpu_port(dp, ds) {
		ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(dp->index),
				  FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) |
				  FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL));
		if (ret) {
			dev_err(priv->dev, "failed enabling QCA header mode on port %d", dp->index);
			return ret;
		}
	}

	/* Forward all unknown frames to CPU port for Linux processing
	 * Notice that in multi-cpu config only one port should be set
	 * for igmp, unknown, multicast and broadcast packet
	 */
	ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
			  FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) |
			  FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) |
			  FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) |
			  FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port)));
	if (ret)
		return ret;

	/* CPU port gets connected to all user ports of the switch */
	ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),
			QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
	if (ret)
		return ret;

	/* Setup connection between CPU port & user ports
	 * Individual user ports get connected to CPU port only
	 */
	dsa_switch_for_each_user_port(dp, ds) {
		u8 port = dp->index;

		ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
				QCA8K_PORT_LOOKUP_MEMBER,
				BIT(cpu_port));
		if (ret)
			return ret;

		ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port),
					QCA8K_PORT_LOOKUP_LEARN);
		if (ret)
			return ret;

		/* For port based vlans to work we need to set the
		 * default egress vid
		 */
		ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
				QCA8K_EGREES_VLAN_PORT_MASK(port),
				QCA8K_EGREES_VLAN_PORT(port, QCA8K_PORT_VID_DEF));
		if (ret)
			return ret;

		ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
				  QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
				  QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
		if (ret)
			return ret;
	}

	/* The port 5 of the qca8337 have some problem in flood condition. The
	 * original legacy driver had some specific buffer and priority settings
	 * for the different port suggested by the QCA switch team. Add this
	 * missing settings to improve switch stability under load condition.
	 * This problem is limited to qca8337 and other qca8k switch are not affected.
	 */
	if (priv->switch_id == QCA8K_ID_QCA8337)
		dsa_switch_for_each_available_port(dp, ds)
			qca8k_setup_hol_fixup(priv, dp->index);

	/* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
	if (priv->switch_id == QCA8K_ID_QCA8327) {
		mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) |
		       QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496);
		qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH,
			  QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK |
			  QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK,
			  mask);
	}

	/* Setup our port MTUs to match power on defaults */
	ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
	if (ret)
		dev_warn(priv->dev, "failed setting MTU settings");

	/* Flush the FDB table */
	qca8k_fdb_flush(priv);

	/* Set min a max ageing value supported */
	ds->ageing_time_min = 7000;
	ds->ageing_time_max = 458745000;

	/* Set max number of LAGs supported */
	ds->num_lag_ids = QCA8K_NUM_LAGS;

	return 0;
}

static const struct phylink_mac_ops qca8k_phylink_mac_ops = {
	.mac_select_pcs	= qca8k_phylink_mac_select_pcs,
	.mac_config	= qca8k_phylink_mac_config,
	.mac_link_down	= qca8k_phylink_mac_link_down,
	.mac_link_up	= qca8k_phylink_mac_link_up,
};

static const struct dsa_switch_ops qca8k_switch_ops = {
	.get_tag_protocol	= qca8k_get_tag_protocol,
	.setup			= qca8k_setup,
	.get_strings		= qca8k_get_strings,
	.get_ethtool_stats	= qca8k_get_ethtool_stats,
	.get_sset_count		= qca8k_get_sset_count,
	.set_ageing_time	= qca8k_set_ageing_time,
	.get_mac_eee		= qca8k_get_mac_eee,
	.set_mac_eee		= qca8k_set_mac_eee,
	.port_enable		= qca8k_port_enable,
	.port_disable		= qca8k_port_disable,
	.port_change_mtu	= qca8k_port_change_mtu,
	.port_max_mtu		= qca8k_port_max_mtu,
	.port_stp_state_set	= qca8k_port_stp_state_set,
	.port_pre_bridge_flags	= qca8k_port_pre_bridge_flags,
	.port_bridge_flags	= qca8k_port_bridge_flags,
	.port_bridge_join	= qca8k_port_bridge_join,
	.port_bridge_leave	= qca8k_port_bridge_leave,
	.port_fast_age		= qca8k_port_fast_age,
	.port_fdb_add		= qca8k_port_fdb_add,
	.port_fdb_del		= qca8k_port_fdb_del,
	.port_fdb_dump		= qca8k_port_fdb_dump,
	.port_mdb_add		= qca8k_port_mdb_add,
	.port_mdb_del		= qca8k_port_mdb_del,
	.port_mirror_add	= qca8k_port_mirror_add,
	.port_mirror_del	= qca8k_port_mirror_del,
	.port_vlan_filtering	= qca8k_port_vlan_filtering,
	.port_vlan_add		= qca8k_port_vlan_add,
	.port_vlan_del		= qca8k_port_vlan_del,
	.phylink_get_caps	= qca8k_phylink_get_caps,
	.get_phy_flags		= qca8k_get_phy_flags,
	.port_lag_join		= qca8k_port_lag_join,
	.port_lag_leave		= qca8k_port_lag_leave,
	.conduit_state_change	= qca8k_conduit_change,
	.connect_tag_protocol	= qca8k_connect_tag_protocol,
};

static int
qca8k_sw_probe(struct mdio_device *mdiodev)
{
	struct qca8k_priv *priv;
	int ret;

	/* allocate the private data struct so that we can probe the switches
	 * ID register
	 */
	priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->bus = mdiodev->bus;
	priv->dev = &mdiodev->dev;
	priv->info = of_device_get_match_data(priv->dev);

	priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
						   GPIOD_OUT_HIGH);
	if (IS_ERR(priv->reset_gpio))
		return PTR_ERR(priv->reset_gpio);

	if (priv->reset_gpio) {
		/* The active low duration must be greater than 10 ms
		 * and checkpatch.pl wants 20 ms.
		 */
		msleep(20);
		gpiod_set_value_cansleep(priv->reset_gpio, 0);
	}

	/* Start by setting up the register mapping */
	priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv,
					&qca8k_regmap_config);
	if (IS_ERR(priv->regmap)) {
		dev_err(priv->dev, "regmap initialization failed");
		return PTR_ERR(priv->regmap);
	}

	priv->mdio_cache.page = 0xffff;

	/* Check the detected switch id */
	ret = qca8k_read_switch_id(priv);
	if (ret)
		return ret;

	priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
	if (!priv->ds)
		return -ENOMEM;

	mutex_init(&priv->mgmt_eth_data.mutex);
	init_completion(&priv->mgmt_eth_data.rw_done);

	mutex_init(&priv->mib_eth_data.mutex);
	init_completion(&priv->mib_eth_data.rw_done);

	priv->ds->dev = &mdiodev->dev;
	priv->ds->num_ports = QCA8K_NUM_PORTS;
	priv->ds->priv = priv;
	priv->ds->ops = &qca8k_switch_ops;
	priv->ds->phylink_mac_ops = &qca8k_phylink_mac_ops;
	mutex_init(&priv->reg_mutex);
	dev_set_drvdata(&mdiodev->dev, priv);

	return dsa_register_switch(priv->ds);
}

static void
qca8k_sw_remove(struct mdio_device *mdiodev)
{
	struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev);
	int i;

	if (!priv)
		return;

	for (i = 0; i < QCA8K_NUM_PORTS; i++)
		qca8k_port_set_status(priv, i, 0);

	dsa_unregister_switch(priv->ds);
}

static void qca8k_sw_shutdown(struct mdio_device *mdiodev)
{
	struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev);

	if (!priv)
		return;

	dsa_switch_shutdown(priv->ds);

	dev_set_drvdata(&mdiodev->dev, NULL);
}

#ifdef CONFIG_PM_SLEEP
static void
qca8k_set_pm(struct qca8k_priv *priv, int enable)
{
	int port;

	for (port = 0; port < QCA8K_NUM_PORTS; port++) {
		/* Do not enable on resume if the port was
		 * disabled before.
		 */
		if (!(priv->port_enabled_map & BIT(port)))
			continue;

		qca8k_port_set_status(priv, port, enable);
	}
}

static int qca8k_suspend(struct device *dev)
{
	struct qca8k_priv *priv = dev_get_drvdata(dev);

	qca8k_set_pm(priv, 0);

	return dsa_switch_suspend(priv->ds);
}

static int qca8k_resume(struct device *dev)
{
	struct qca8k_priv *priv = dev_get_drvdata(dev);

	qca8k_set_pm(priv, 1);

	return dsa_switch_resume(priv->ds);
}
#endif /* CONFIG_PM_SLEEP */

static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
			 qca8k_suspend, qca8k_resume);

static const struct qca8k_info_ops qca8xxx_ops = {
	.autocast_mib = qca8k_get_ethtool_stats_eth,
};

static const struct qca8k_match_data qca8327 = {
	.id = QCA8K_ID_QCA8327,
	.reduced_package = true,
	.mib_count = QCA8K_QCA832X_MIB_COUNT,
	.ops = &qca8xxx_ops,
};

static const struct qca8k_match_data qca8328 = {
	.id = QCA8K_ID_QCA8327,
	.mib_count = QCA8K_QCA832X_MIB_COUNT,
	.ops = &qca8xxx_ops,
};

static const struct qca8k_match_data qca833x = {
	.id = QCA8K_ID_QCA8337,
	.mib_count = QCA8K_QCA833X_MIB_COUNT,
	.ops = &qca8xxx_ops,
};

static const struct of_device_id qca8k_of_match[] = {
	{ .compatible = "qca,qca8327", .data = &qca8327 },
	{ .compatible = "qca,qca8328", .data = &qca8328 },
	{ .compatible = "qca,qca8334", .data = &qca833x },
	{ .compatible = "qca,qca8337", .data = &qca833x },
	{ /* sentinel */ },
};

static struct mdio_driver qca8kmdio_driver = {
	.probe  = qca8k_sw_probe,
	.remove = qca8k_sw_remove,
	.shutdown = qca8k_sw_shutdown,
	.mdiodrv.driver = {
		.name = "qca8k",
		.of_match_table = qca8k_of_match,
		.pm = &qca8k_pm_ops,
	},
};

mdio_module_driver(qca8kmdio_driver);

MODULE_AUTHOR("Mathieu Olivari, John Crispin <john@phrozen.org>");
MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:qca8k");
