// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Marvell 88E6xxx Switch Global 2 Registers support
 *
 * Copyright (c) 2008 Marvell Semiconductor
 *
 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
 *	Vivien Didelot <vivien.didelot@savoirfairelinux.com>
 */

#include <linux/bitfield.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>

#include "chip.h"
#include "global1.h" /* for MV88E6XXX_G1_STS_IRQ_DEVICE */
#include "global2.h"

int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
{
	return mv88e6xxx_read(chip, chip->info->global2_addr, reg, val);
}

int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
{
	return mv88e6xxx_write(chip, chip->info->global2_addr, reg, val);
}

int mv88e6xxx_g2_wait_bit(struct mv88e6xxx_chip *chip, int reg, int
			  bit, int val)
{
	return mv88e6xxx_wait_bit(chip, chip->info->global2_addr, reg,
				  bit, val);
}

/* Offset 0x00: Interrupt Source Register */

static int mv88e6xxx_g2_int_source(struct mv88e6xxx_chip *chip, u16 *src)
{
	/* Read (and clear most of) the Interrupt Source bits */
	return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_INT_SRC, src);
}

/* Offset 0x01: Interrupt Mask Register */

static int mv88e6xxx_g2_int_mask(struct mv88e6xxx_chip *chip, u16 mask)
{
	return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_INT_MASK, mask);
}

/* Offset 0x02: Management Enable 2x */

static int mv88e6xxx_g2_mgmt_enable_2x(struct mv88e6xxx_chip *chip, u16 en2x)
{
	return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_2X, en2x);
}

/* Offset 0x03: Management Enable 0x */

static int mv88e6xxx_g2_mgmt_enable_0x(struct mv88e6xxx_chip *chip, u16 en0x)
{
	return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_0X, en0x);
}

/* Offset 0x05: Switch Management Register */

static int mv88e6xxx_g2_switch_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip,
					     bool enable)
{
	u16 val;
	int err;

	err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SWITCH_MGMT, &val);
	if (err)
		return err;

	if (enable)
		val |= MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU;
	else
		val &= ~MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU;

	return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MGMT, val);
}

int mv88e6185_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
{
	int err;

	/* Consider the frames with reserved multicast destination
	 * addresses matching 01:80:c2:00:00:0x as MGMT.
	 */
	err = mv88e6xxx_g2_mgmt_enable_0x(chip, 0xffff);
	if (err)
		return err;

	return mv88e6xxx_g2_switch_mgmt_rsvd2cpu(chip, true);
}

int mv88e6352_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
{
	int err;

	/* Consider the frames with reserved multicast destination
	 * addresses matching 01:80:c2:00:00:2x as MGMT.
	 */
	err = mv88e6xxx_g2_mgmt_enable_2x(chip, 0xffff);
	if (err)
		return err;

	return mv88e6185_g2_mgmt_rsvd2cpu(chip);
}

/* Offset 0x06: Device Mapping Table register */

int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target,
				      int port)
{
	u16 val = (target << 8) | (port & 0x1f);
	/* Modern chips use 5 bits to define a device mapping port,
	 * but bit 4 is reserved on older chips, so it is safe to use.
	 */

	return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_DEVICE_MAPPING,
				  MV88E6XXX_G2_DEVICE_MAPPING_UPDATE | val);
}

/* Offset 0x07: Trunk Mask Table register */

static int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num,
					 bool hash, u16 mask)
{
	u16 val = (num << 12) | (mask & mv88e6xxx_port_mask(chip));

	if (hash)
		val |= MV88E6XXX_G2_TRUNK_MASK_HASH;

	return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_TRUNK_MASK,
				  MV88E6XXX_G2_TRUNK_MASK_UPDATE | val);
}

/* Offset 0x08: Trunk Mapping Table register */

static int mv88e6xxx_g2_trunk_mapping_write(struct mv88e6xxx_chip *chip, int id,
					    u16 map)
{
	const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
	u16 val = (id << 11) | (map & port_mask);

	return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_TRUNK_MAPPING,
				  MV88E6XXX_G2_TRUNK_MAPPING_UPDATE | val);
}

int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip)
{
	const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
	int i, err;

	/* Clear all eight possible Trunk Mask vectors */
	for (i = 0; i < 8; ++i) {
		err = mv88e6xxx_g2_trunk_mask_write(chip, i, false, port_mask);
		if (err)
			return err;
	}

	/* Clear all sixteen possible Trunk ID routing vectors */
	for (i = 0; i < 16; ++i) {
		err = mv88e6xxx_g2_trunk_mapping_write(chip, i, 0);
		if (err)
			return err;
	}

	return 0;
}

/* Offset 0x09: Ingress Rate Command register
 * Offset 0x0A: Ingress Rate Data register
 */

static int mv88e6xxx_g2_irl_wait(struct mv88e6xxx_chip *chip)
{
	int bit = __bf_shf(MV88E6XXX_G2_IRL_CMD_BUSY);

	return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_IRL_CMD, bit, 0);
}

static int mv88e6xxx_g2_irl_op(struct mv88e6xxx_chip *chip, u16 op, int port,
			       int res, int reg)
{
	int err;

	err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_IRL_CMD,
				 MV88E6XXX_G2_IRL_CMD_BUSY | op | (port << 8) |
				 (res << 5) | reg);
	if (err)
		return err;

	return mv88e6xxx_g2_irl_wait(chip);
}

int mv88e6352_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port)
{
	return mv88e6xxx_g2_irl_op(chip, MV88E6352_G2_IRL_CMD_OP_INIT_ALL, port,
				   0, 0);
}

int mv88e6390_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port)
{
	return mv88e6xxx_g2_irl_op(chip, MV88E6390_G2_IRL_CMD_OP_INIT_ALL, port,
				   0, 0);
}

/* Offset 0x0B: Cross-chip Port VLAN (Addr) Register
 * Offset 0x0C: Cross-chip Port VLAN Data Register
 */

static int mv88e6xxx_g2_pvt_op_wait(struct mv88e6xxx_chip *chip)
{
	int bit = __bf_shf(MV88E6XXX_G2_PVT_ADDR_BUSY);

	return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_PVT_ADDR, bit, 0);
}

static int mv88e6xxx_g2_pvt_op(struct mv88e6xxx_chip *chip, int src_dev,
			       int src_port, u16 op)
{
	int err;

	/* 9-bit Cross-chip PVT pointer: with MV88E6XXX_G2_MISC_5_BIT_PORT
	 * cleared, source device is 5-bit, source port is 4-bit.
	 */
	op |= MV88E6XXX_G2_PVT_ADDR_BUSY;
	op |= (src_dev & 0x1f) << 4;
	op |= (src_port & 0xf);

	err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PVT_ADDR, op);
	if (err)
		return err;

	return mv88e6xxx_g2_pvt_op_wait(chip);
}

int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev,
			   int src_port, u16 data)
{
	int err;

	err = mv88e6xxx_g2_pvt_op_wait(chip);
	if (err)
		return err;

	err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PVT_DATA, data);
	if (err)
		return err;

	return mv88e6xxx_g2_pvt_op(chip, src_dev, src_port,
				   MV88E6XXX_G2_PVT_ADDR_OP_WRITE_PVLAN);
}

/* Offset 0x0D: Switch MAC/WoL/WoF register */

static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip,
					 unsigned int pointer, u8 data)
{
	u16 val = (pointer << 8) | data;

	return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MAC,
				  MV88E6XXX_G2_SWITCH_MAC_UPDATE | val);
}

int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
{
	int i, err;

	for (i = 0; i < 6; i++) {
		err = mv88e6xxx_g2_switch_mac_write(chip, i, addr[i]);
		if (err)
			break;
	}

	return err;
}

/* Offset 0x0E: ATU Statistics */

int mv88e6xxx_g2_atu_stats_set(struct mv88e6xxx_chip *chip, u16 kind, u16 bin)
{
	return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_ATU_STATS,
				  kind | bin);
}

int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip, u16 *stats)
{
	return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_ATU_STATS, stats);
}

/* Offset 0x0F: Priority Override Table */

static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer,
				  u8 data)
{
	u16 val = (pointer << 8) | (data & 0x7);

	return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PRIO_OVERRIDE,
				  MV88E6XXX_G2_PRIO_OVERRIDE_UPDATE | val);
}

int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
{
	int i, err;

	/* Clear all sixteen possible Priority Override entries */
	for (i = 0; i < 16; i++) {
		err = mv88e6xxx_g2_pot_write(chip, i, 0);
		if (err)
			break;
	}

	return err;
}

/* Offset 0x14: EEPROM Command
 * Offset 0x15: EEPROM Data (for 16-bit data access)
 * Offset 0x15: EEPROM Addr (for 8-bit data access)
 */

static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
{
	int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY);
	int err;

	err = mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_EEPROM_CMD, bit, 0);
	if (err)
		return err;

	bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_RUNNING);

	return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_EEPROM_CMD, bit, 0);
}

static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
{
	int err;

	err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_EEPROM_CMD,
				 MV88E6XXX_G2_EEPROM_CMD_BUSY | cmd);
	if (err)
		return err;

	return mv88e6xxx_g2_eeprom_wait(chip);
}

static int mv88e6xxx_g2_eeprom_read8(struct mv88e6xxx_chip *chip,
				     u16 addr, u8 *data)
{
	u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ;
	int err;

	err = mv88e6xxx_g2_eeprom_wait(chip);
	if (err)
		return err;

	err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
	if (err)
		return err;

	err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
	if (err)
		return err;

	err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &cmd);
	if (err)
		return err;

	*data = cmd & 0xff;

	return 0;
}

static int mv88e6xxx_g2_eeprom_write8(struct mv88e6xxx_chip *chip,
				      u16 addr, u8 data)
{
	u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE |
		MV88E6XXX_G2_EEPROM_CMD_WRITE_EN;
	int err;

	err = mv88e6xxx_g2_eeprom_wait(chip);
	if (err)
		return err;

	err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
	if (err)
		return err;

	return mv88e6xxx_g2_eeprom_cmd(chip, cmd | data);
}

static int mv88e6xxx_g2_eeprom_read16(struct mv88e6xxx_chip *chip,
				      u8 addr, u16 *data)
{
	u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ | addr;
	int err;

	err = mv88e6xxx_g2_eeprom_wait(chip);
	if (err)
		return err;

	err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
	if (err)
		return err;

	return mv88e6xxx_g2_read(chip, MV88E6352_G2_EEPROM_DATA, data);
}

static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip,
				       u8 addr, u16 data)
{
	u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE | addr;
	int err;

	err = mv88e6xxx_g2_eeprom_wait(chip);
	if (err)
		return err;

	err = mv88e6xxx_g2_write(chip, MV88E6352_G2_EEPROM_DATA, data);
	if (err)
		return err;

	return mv88e6xxx_g2_eeprom_cmd(chip, cmd);
}

int mv88e6xxx_g2_get_eeprom8(struct mv88e6xxx_chip *chip,
			     struct ethtool_eeprom *eeprom, u8 *data)
{
	unsigned int offset = eeprom->offset;
	unsigned int len = eeprom->len;
	int err;

	eeprom->len = 0;

	while (len) {
		err = mv88e6xxx_g2_eeprom_read8(chip, offset, data);
		if (err)
			return err;

		eeprom->len++;
		offset++;
		data++;
		len--;
	}

	return 0;
}

int mv88e6xxx_g2_set_eeprom8(struct mv88e6xxx_chip *chip,
			     struct ethtool_eeprom *eeprom, u8 *data)
{
	unsigned int offset = eeprom->offset;
	unsigned int len = eeprom->len;
	int err;

	eeprom->len = 0;

	while (len) {
		err = mv88e6xxx_g2_eeprom_write8(chip, offset, *data);
		if (err)
			return err;

		eeprom->len++;
		offset++;
		data++;
		len--;
	}

	return 0;
}

int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip,
			      struct ethtool_eeprom *eeprom, u8 *data)
{
	unsigned int offset = eeprom->offset;
	unsigned int len = eeprom->len;
	u16 val;
	int err;

	eeprom->len = 0;

	if (offset & 1) {
		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
		if (err)
			return err;

		*data++ = (val >> 8) & 0xff;

		offset++;
		len--;
		eeprom->len++;
	}

	while (len >= 2) {
		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
		if (err)
			return err;

		*data++ = val & 0xff;
		*data++ = (val >> 8) & 0xff;

		offset += 2;
		len -= 2;
		eeprom->len += 2;
	}

	if (len) {
		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
		if (err)
			return err;

		*data++ = val & 0xff;

		offset++;
		len--;
		eeprom->len++;
	}

	return 0;
}

int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
			      struct ethtool_eeprom *eeprom, u8 *data)
{
	unsigned int offset = eeprom->offset;
	unsigned int len = eeprom->len;
	u16 val;
	int err;

	/* Ensure the RO WriteEn bit is set */
	err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &val);
	if (err)
		return err;

	if (!(val & MV88E6XXX_G2_EEPROM_CMD_WRITE_EN))
		return -EROFS;

	eeprom->len = 0;

	if (offset & 1) {
		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
		if (err)
			return err;

		val = (*data++ << 8) | (val & 0xff);

		err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
		if (err)
			return err;

		offset++;
		len--;
		eeprom->len++;
	}

	while (len >= 2) {
		val = *data++;
		val |= *data++ << 8;

		err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
		if (err)
			return err;

		offset += 2;
		len -= 2;
		eeprom->len += 2;
	}

	if (len) {
		err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
		if (err)
			return err;

		val = (val & 0xff00) | *data++;

		err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
		if (err)
			return err;

		offset++;
		len--;
		eeprom->len++;
	}

	return 0;
}

/* Offset 0x18: SMI PHY Command Register
 * Offset 0x19: SMI PHY Data Register
 */

static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip)
{
	int bit = __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_BUSY);

	return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_SMI_PHY_CMD, bit, 0);
}

static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
{
	int err;

	err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_CMD,
				 MV88E6XXX_G2_SMI_PHY_CMD_BUSY | cmd);
	if (err)
		return err;

	return mv88e6xxx_g2_smi_phy_wait(chip);
}

static int mv88e6xxx_g2_smi_phy_access(struct mv88e6xxx_chip *chip,
				       bool external, bool c45, u16 op, int dev,
				       int reg)
{
	u16 cmd = op;

	if (external)
		cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_EXTERNAL;
	else
		cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_INTERNAL; /* empty mask */

	if (c45)
		cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_45; /* empty mask */
	else
		cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_22;

	dev <<= __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK);
	cmd |= dev & MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK;
	cmd |= reg & MV88E6XXX_G2_SMI_PHY_CMD_REG_ADDR_MASK;

	return mv88e6xxx_g2_smi_phy_cmd(chip, cmd);
}

static int mv88e6xxx_g2_smi_phy_access_c22(struct mv88e6xxx_chip *chip,
					   bool external, u16 op, int dev,
					   int reg)
{
	return mv88e6xxx_g2_smi_phy_access(chip, external, false, op, dev, reg);
}

/* IEEE 802.3 Clause 22 Read Data Register */
static int mv88e6xxx_g2_smi_phy_read_data_c22(struct mv88e6xxx_chip *chip,
					      bool external, int dev, int reg,
					      u16 *data)
{
	u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_READ_DATA;
	int err;

	err = mv88e6xxx_g2_smi_phy_wait(chip);
	if (err)
		return err;

	err = mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
	if (err)
		return err;

	return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
}

/* IEEE 802.3 Clause 22 Write Data Register */
static int mv88e6xxx_g2_smi_phy_write_data_c22(struct mv88e6xxx_chip *chip,
					       bool external, int dev, int reg,
					       u16 data)
{
	u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_WRITE_DATA;
	int err;

	err = mv88e6xxx_g2_smi_phy_wait(chip);
	if (err)
		return err;

	err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
	if (err)
		return err;

	return mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
}

static int mv88e6xxx_g2_smi_phy_access_c45(struct mv88e6xxx_chip *chip,
					   bool external, u16 op, int port,
					   int dev)
{
	return mv88e6xxx_g2_smi_phy_access(chip, external, true, op, port, dev);
}

/* IEEE 802.3 Clause 45 Write Address Register */
static int mv88e6xxx_g2_smi_phy_write_addr_c45(struct mv88e6xxx_chip *chip,
					       bool external, int port, int dev,
					       int addr)
{
	u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_ADDR;
	int err;

	err = mv88e6xxx_g2_smi_phy_wait(chip);
	if (err)
		return err;

	err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, addr);
	if (err)
		return err;

	return mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
}

/* IEEE 802.3 Clause 45 Read Data Register */
static int mv88e6xxx_g2_smi_phy_read_data_c45(struct mv88e6xxx_chip *chip,
					      bool external, int port, int dev,
					      u16 *data)
{
	u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_READ_DATA;
	int err;

	err = mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
	if (err)
		return err;

	return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
}

static int mv88e6xxx_g2_smi_phy_read_c45(struct mv88e6xxx_chip *chip,
					 bool external, int port, int reg,
					 u16 *data)
{
	int dev = (reg >> 16) & 0x1f;
	int addr = reg & 0xffff;
	int err;

	err = mv88e6xxx_g2_smi_phy_write_addr_c45(chip, external, port, dev,
						  addr);
	if (err)
		return err;

	return mv88e6xxx_g2_smi_phy_read_data_c45(chip, external, port, dev,
						  data);
}

/* IEEE 802.3 Clause 45 Write Data Register */
static int mv88e6xxx_g2_smi_phy_write_data_c45(struct mv88e6xxx_chip *chip,
					       bool external, int port, int dev,
					       u16 data)
{
	u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_DATA;
	int err;

	err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
	if (err)
		return err;

	return mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
}

static int mv88e6xxx_g2_smi_phy_write_c45(struct mv88e6xxx_chip *chip,
					  bool external, int port, int reg,
					  u16 data)
{
	int dev = (reg >> 16) & 0x1f;
	int addr = reg & 0xffff;
	int err;

	err = mv88e6xxx_g2_smi_phy_write_addr_c45(chip, external, port, dev,
						  addr);
	if (err)
		return err;

	return mv88e6xxx_g2_smi_phy_write_data_c45(chip, external, port, dev,
						   data);
}

int mv88e6xxx_g2_smi_phy_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
			      int addr, int reg, u16 *val)
{
	struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
	bool external = mdio_bus->external;

	if (reg & MII_ADDR_C45)
		return mv88e6xxx_g2_smi_phy_read_c45(chip, external, addr, reg,
						     val);

	return mv88e6xxx_g2_smi_phy_read_data_c22(chip, external, addr, reg,
						  val);
}

int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
			       int addr, int reg, u16 val)
{
	struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
	bool external = mdio_bus->external;

	if (reg & MII_ADDR_C45)
		return mv88e6xxx_g2_smi_phy_write_c45(chip, external, addr, reg,
						      val);

	return mv88e6xxx_g2_smi_phy_write_data_c22(chip, external, addr, reg,
						   val);
}

/* Offset 0x1B: Watchdog Control */
static int mv88e6097_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
{
	u16 reg;

	mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, &reg);

	dev_info(chip->dev, "Watchdog event: 0x%04x", reg);

	return IRQ_HANDLED;
}

static void mv88e6097_watchdog_free(struct mv88e6xxx_chip *chip)
{
	u16 reg;

	mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, &reg);

	reg &= ~(MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
		 MV88E6352_G2_WDOG_CTL_QC_ENABLE);

	mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL, reg);
}

static int mv88e6097_watchdog_setup(struct mv88e6xxx_chip *chip)
{
	return mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL,
				  MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
				  MV88E6352_G2_WDOG_CTL_QC_ENABLE |
				  MV88E6352_G2_WDOG_CTL_SWRESET);
}

const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops = {
	.irq_action = mv88e6097_watchdog_action,
	.irq_setup = mv88e6097_watchdog_setup,
	.irq_free = mv88e6097_watchdog_free,
};

static void mv88e6250_watchdog_free(struct mv88e6xxx_chip *chip)
{
	u16 reg;

	mv88e6xxx_g2_read(chip, MV88E6250_G2_WDOG_CTL, &reg);

	reg &= ~(MV88E6250_G2_WDOG_CTL_EGRESS_ENABLE |
		 MV88E6250_G2_WDOG_CTL_QC_ENABLE);

	mv88e6xxx_g2_write(chip, MV88E6250_G2_WDOG_CTL, reg);
}

static int mv88e6250_watchdog_setup(struct mv88e6xxx_chip *chip)
{
	return mv88e6xxx_g2_write(chip, MV88E6250_G2_WDOG_CTL,
				  MV88E6250_G2_WDOG_CTL_EGRESS_ENABLE |
				  MV88E6250_G2_WDOG_CTL_QC_ENABLE |
				  MV88E6250_G2_WDOG_CTL_SWRESET);
}

const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops = {
	.irq_action = mv88e6097_watchdog_action,
	.irq_setup = mv88e6250_watchdog_setup,
	.irq_free = mv88e6250_watchdog_free,
};

static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip *chip)
{
	return mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
				  MV88E6390_G2_WDOG_CTL_UPDATE |
				  MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE |
				  MV88E6390_G2_WDOG_CTL_CUT_THROUGH |
				  MV88E6390_G2_WDOG_CTL_QUEUE_CONTROLLER |
				  MV88E6390_G2_WDOG_CTL_EGRESS |
				  MV88E6390_G2_WDOG_CTL_FORCE_IRQ);
}

static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
{
	int err;
	u16 reg;

	mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
			   MV88E6390_G2_WDOG_CTL_PTR_EVENT);
	err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);

	dev_info(chip->dev, "Watchdog event: 0x%04x",
		 reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);

	mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
			   MV88E6390_G2_WDOG_CTL_PTR_HISTORY);
	err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);

	dev_info(chip->dev, "Watchdog history: 0x%04x",
		 reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);

	/* Trigger a software reset to try to recover the switch */
	if (chip->info->ops->reset)
		chip->info->ops->reset(chip);

	mv88e6390_watchdog_setup(chip);

	return IRQ_HANDLED;
}

static void mv88e6390_watchdog_free(struct mv88e6xxx_chip *chip)
{
	mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
			   MV88E6390_G2_WDOG_CTL_UPDATE |
			   MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE);
}

const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {
	.irq_action = mv88e6390_watchdog_action,
	.irq_setup = mv88e6390_watchdog_setup,
	.irq_free = mv88e6390_watchdog_free,
};

static irqreturn_t mv88e6xxx_g2_watchdog_thread_fn(int irq, void *dev_id)
{
	struct mv88e6xxx_chip *chip = dev_id;
	irqreturn_t ret = IRQ_NONE;

	mv88e6xxx_reg_lock(chip);
	if (chip->info->ops->watchdog_ops->irq_action)
		ret = chip->info->ops->watchdog_ops->irq_action(chip, irq);
	mv88e6xxx_reg_unlock(chip);

	return ret;
}

static void mv88e6xxx_g2_watchdog_free(struct mv88e6xxx_chip *chip)
{
	mv88e6xxx_reg_lock(chip);
	if (chip->info->ops->watchdog_ops->irq_free)
		chip->info->ops->watchdog_ops->irq_free(chip);
	mv88e6xxx_reg_unlock(chip);

	free_irq(chip->watchdog_irq, chip);
	irq_dispose_mapping(chip->watchdog_irq);
}

static int mv88e6xxx_g2_watchdog_setup(struct mv88e6xxx_chip *chip)
{
	int err;

	chip->watchdog_irq = irq_find_mapping(chip->g2_irq.domain,
					      MV88E6XXX_G2_INT_SOURCE_WATCHDOG);
	if (chip->watchdog_irq < 0)
		return chip->watchdog_irq;

	snprintf(chip->watchdog_irq_name, sizeof(chip->watchdog_irq_name),
		 "mv88e6xxx-%s-watchdog", dev_name(chip->dev));

	err = request_threaded_irq(chip->watchdog_irq, NULL,
				   mv88e6xxx_g2_watchdog_thread_fn,
				   IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
				   chip->watchdog_irq_name, chip);
	if (err)
		return err;

	mv88e6xxx_reg_lock(chip);
	if (chip->info->ops->watchdog_ops->irq_setup)
		err = chip->info->ops->watchdog_ops->irq_setup(chip);
	mv88e6xxx_reg_unlock(chip);

	return err;
}

/* Offset 0x1D: Misc Register */

static int mv88e6xxx_g2_misc_5_bit_port(struct mv88e6xxx_chip *chip,
					bool port_5_bit)
{
	u16 val;
	int err;

	err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_MISC, &val);
	if (err)
		return err;

	if (port_5_bit)
		val |= MV88E6XXX_G2_MISC_5_BIT_PORT;
	else
		val &= ~MV88E6XXX_G2_MISC_5_BIT_PORT;

	return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MISC, val);
}

int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
{
	return mv88e6xxx_g2_misc_5_bit_port(chip, false);
}

static void mv88e6xxx_g2_irq_mask(struct irq_data *d)
{
	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
	unsigned int n = d->hwirq;

	chip->g2_irq.masked |= (1 << n);
}

static void mv88e6xxx_g2_irq_unmask(struct irq_data *d)
{
	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
	unsigned int n = d->hwirq;

	chip->g2_irq.masked &= ~(1 << n);
}

static irqreturn_t mv88e6xxx_g2_irq_thread_fn(int irq, void *dev_id)
{
	struct mv88e6xxx_chip *chip = dev_id;
	unsigned int nhandled = 0;
	unsigned int sub_irq;
	unsigned int n;
	int err;
	u16 reg;

	mv88e6xxx_reg_lock(chip);
	err = mv88e6xxx_g2_int_source(chip, &reg);
	mv88e6xxx_reg_unlock(chip);
	if (err)
		goto out;

	for (n = 0; n < 16; ++n) {
		if (reg & (1 << n)) {
			sub_irq = irq_find_mapping(chip->g2_irq.domain, n);
			handle_nested_irq(sub_irq);
			++nhandled;
		}
	}
out:
	return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
}

static void mv88e6xxx_g2_irq_bus_lock(struct irq_data *d)
{
	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);

	mv88e6xxx_reg_lock(chip);
}

static void mv88e6xxx_g2_irq_bus_sync_unlock(struct irq_data *d)
{
	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
	int err;

	err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked);
	if (err)
		dev_err(chip->dev, "failed to mask interrupts\n");

	mv88e6xxx_reg_unlock(chip);
}

static const struct irq_chip mv88e6xxx_g2_irq_chip = {
	.name			= "mv88e6xxx-g2",
	.irq_mask		= mv88e6xxx_g2_irq_mask,
	.irq_unmask		= mv88e6xxx_g2_irq_unmask,
	.irq_bus_lock		= mv88e6xxx_g2_irq_bus_lock,
	.irq_bus_sync_unlock	= mv88e6xxx_g2_irq_bus_sync_unlock,
};

static int mv88e6xxx_g2_irq_domain_map(struct irq_domain *d,
				       unsigned int irq,
				       irq_hw_number_t hwirq)
{
	struct mv88e6xxx_chip *chip = d->host_data;

	irq_set_chip_data(irq, d->host_data);
	irq_set_chip_and_handler(irq, &chip->g2_irq.chip, handle_level_irq);
	irq_set_noprobe(irq);

	return 0;
}

static const struct irq_domain_ops mv88e6xxx_g2_irq_domain_ops = {
	.map	= mv88e6xxx_g2_irq_domain_map,
	.xlate	= irq_domain_xlate_twocell,
};

void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip)
{
	int irq, virq;

	mv88e6xxx_g2_watchdog_free(chip);

	free_irq(chip->device_irq, chip);
	irq_dispose_mapping(chip->device_irq);

	for (irq = 0; irq < 16; irq++) {
		virq = irq_find_mapping(chip->g2_irq.domain, irq);
		irq_dispose_mapping(virq);
	}

	irq_domain_remove(chip->g2_irq.domain);
}

int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
{
	int err, irq, virq;

	chip->g2_irq.domain = irq_domain_add_simple(
		chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip);
	if (!chip->g2_irq.domain)
		return -ENOMEM;

	for (irq = 0; irq < 16; irq++)
		irq_create_mapping(chip->g2_irq.domain, irq);

	chip->g2_irq.chip = mv88e6xxx_g2_irq_chip;
	chip->g2_irq.masked = ~0;

	chip->device_irq = irq_find_mapping(chip->g1_irq.domain,
					    MV88E6XXX_G1_STS_IRQ_DEVICE);
	if (chip->device_irq < 0) {
		err = chip->device_irq;
		goto out;
	}

	snprintf(chip->device_irq_name, sizeof(chip->device_irq_name),
		 "mv88e6xxx-%s-g2", dev_name(chip->dev));

	err = request_threaded_irq(chip->device_irq, NULL,
				   mv88e6xxx_g2_irq_thread_fn,
				   IRQF_ONESHOT, chip->device_irq_name, chip);
	if (err)
		goto out;

	return mv88e6xxx_g2_watchdog_setup(chip);

out:
	for (irq = 0; irq < 16; irq++) {
		virq = irq_find_mapping(chip->g2_irq.domain, irq);
		irq_dispose_mapping(virq);
	}

	irq_domain_remove(chip->g2_irq.domain);

	return err;
}

int mv88e6xxx_g2_irq_mdio_setup(struct mv88e6xxx_chip *chip,
				struct mii_bus *bus)
{
	int phy, irq, err, err_phy;

	for (phy = 0; phy < chip->info->num_internal_phys; phy++) {
		irq = irq_find_mapping(chip->g2_irq.domain, phy);
		if (irq < 0) {
			err = irq;
			goto out;
		}
		bus->irq[chip->info->phy_base_addr + phy] = irq;
	}
	return 0;
out:
	err_phy = phy;

	for (phy = 0; phy < err_phy; phy++)
		irq_dispose_mapping(bus->irq[phy]);

	return err;
}

void mv88e6xxx_g2_irq_mdio_free(struct mv88e6xxx_chip *chip,
				struct mii_bus *bus)
{
	int phy;

	for (phy = 0; phy < chip->info->num_internal_phys; phy++)
		irq_dispose_mapping(bus->irq[phy]);
}
