// SPDX-License-Identifier: GPL-2.0+
/* Microchip Sparx5 Switch driver
 *
 * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries.
 */

#include <linux/module.h>
#include <linux/phy/phy.h>

#include "sparx5_main_regs.h"
#include "sparx5_main.h"
#include "sparx5_port.h"

#define SPX5_ETYPE_TAG_C     0x8100
#define SPX5_ETYPE_TAG_S     0x88a8

#define SPX5_WAIT_US         1000
#define SPX5_WAIT_MAX_US     2000

enum port_error {
	SPX5_PERR_SPEED,
	SPX5_PERR_IFTYPE,
};

#define PAUSE_DISCARD        0xC
#define ETH_MAXLEN           (ETH_DATA_LEN + ETH_HLEN + ETH_FCS_LEN)

static void decode_sgmii_word(u16 lp_abil, struct sparx5_port_status *status)
{
	status->an_complete = true;
	if (!(lp_abil & LPA_SGMII_LINK)) {
		status->link = false;
		return;
	}

	switch (lp_abil & LPA_SGMII_SPD_MASK) {
	case LPA_SGMII_10:
		status->speed = SPEED_10;
		break;
	case LPA_SGMII_100:
		status->speed = SPEED_100;
		break;
	case LPA_SGMII_1000:
		status->speed = SPEED_1000;
		break;
	default:
		status->link = false;
		return;
	}
	if (lp_abil & LPA_SGMII_FULL_DUPLEX)
		status->duplex = DUPLEX_FULL;
	else
		status->duplex = DUPLEX_HALF;
}

static void decode_cl37_word(u16 lp_abil, uint16_t ld_abil, struct sparx5_port_status *status)
{
	status->link = !(lp_abil & ADVERTISE_RFAULT) && status->link;
	status->an_complete = true;
	status->duplex = (ADVERTISE_1000XFULL & lp_abil) ?
		DUPLEX_FULL : DUPLEX_UNKNOWN; // 1G HDX not supported

	if ((ld_abil & ADVERTISE_1000XPAUSE) &&
	    (lp_abil & ADVERTISE_1000XPAUSE)) {
		status->pause = MLO_PAUSE_RX | MLO_PAUSE_TX;
	} else if ((ld_abil & ADVERTISE_1000XPSE_ASYM) &&
		   (lp_abil & ADVERTISE_1000XPSE_ASYM)) {
		status->pause |= (lp_abil & ADVERTISE_1000XPAUSE) ?
			MLO_PAUSE_TX : 0;
		status->pause |= (ld_abil & ADVERTISE_1000XPAUSE) ?
			MLO_PAUSE_RX : 0;
	} else {
		status->pause = MLO_PAUSE_NONE;
	}
}

static int sparx5_get_dev2g5_status(struct sparx5 *sparx5,
				    struct sparx5_port *port,
				    struct sparx5_port_status *status)
{
	u32 portno = port->portno;
	u16 lp_adv, ld_adv;
	u32 value;

	/* Get PCS Link down sticky */
	value = spx5_rd(sparx5, DEV2G5_PCS1G_STICKY(portno));
	status->link_down = DEV2G5_PCS1G_STICKY_LINK_DOWN_STICKY_GET(value);
	if (status->link_down)	/* Clear the sticky */
		spx5_wr(value, sparx5, DEV2G5_PCS1G_STICKY(portno));

	/* Get both current Link and Sync status */
	value = spx5_rd(sparx5, DEV2G5_PCS1G_LINK_STATUS(portno));
	status->link = DEV2G5_PCS1G_LINK_STATUS_LINK_STATUS_GET(value) &&
		       DEV2G5_PCS1G_LINK_STATUS_SYNC_STATUS_GET(value);

	if (port->conf.portmode == PHY_INTERFACE_MODE_1000BASEX)
		status->speed = SPEED_1000;
	else if (port->conf.portmode == PHY_INTERFACE_MODE_2500BASEX)
		status->speed = SPEED_2500;

	status->duplex = DUPLEX_FULL;

	/* Get PCS ANEG status register */
	value = spx5_rd(sparx5, DEV2G5_PCS1G_ANEG_STATUS(portno));

	/* Aneg complete provides more information  */
	if (DEV2G5_PCS1G_ANEG_STATUS_ANEG_COMPLETE_GET(value)) {
		lp_adv = DEV2G5_PCS1G_ANEG_STATUS_LP_ADV_ABILITY_GET(value);
		if (port->conf.portmode == PHY_INTERFACE_MODE_SGMII) {
			decode_sgmii_word(lp_adv, status);
		} else {
			value = spx5_rd(sparx5, DEV2G5_PCS1G_ANEG_CFG(portno));
			ld_adv = DEV2G5_PCS1G_ANEG_CFG_ADV_ABILITY_GET(value);
			decode_cl37_word(lp_adv, ld_adv, status);
		}
	}
	return 0;
}

static int sparx5_get_sfi_status(struct sparx5 *sparx5,
				 struct sparx5_port *port,
				 struct sparx5_port_status *status)
{
	bool high_speed_dev = sparx5_is_baser(port->conf.portmode);
	u32 portno = port->portno;
	u32 value, dev, tinst;
	void __iomem *inst;

	if (!high_speed_dev) {
		netdev_err(port->ndev, "error: low speed and SFI mode\n");
		return -EINVAL;
	}

	dev = sparx5_to_high_dev(portno);
	tinst = sparx5_port_dev_index(portno);
	inst = spx5_inst_get(sparx5, dev, tinst);

	value = spx5_inst_rd(inst, DEV10G_MAC_TX_MONITOR_STICKY(0));
	if (value != DEV10G_MAC_TX_MONITOR_STICKY_IDLE_STATE_STICKY) {
		/* The link is or has been down. Clear the sticky bit */
		status->link_down = 1;
		spx5_inst_wr(0xffffffff, inst, DEV10G_MAC_TX_MONITOR_STICKY(0));
		value = spx5_inst_rd(inst, DEV10G_MAC_TX_MONITOR_STICKY(0));
	}
	status->link = (value == DEV10G_MAC_TX_MONITOR_STICKY_IDLE_STATE_STICKY);
	status->duplex = DUPLEX_FULL;
	if (port->conf.portmode == PHY_INTERFACE_MODE_5GBASER)
		status->speed = SPEED_5000;
	else if (port->conf.portmode == PHY_INTERFACE_MODE_10GBASER)
		status->speed = SPEED_10000;
	else
		status->speed = SPEED_25000;

	return 0;
}

/* Get link status of 1000Base-X/in-band and SFI ports.
 */
int sparx5_get_port_status(struct sparx5 *sparx5,
			   struct sparx5_port *port,
			   struct sparx5_port_status *status)
{
	memset(status, 0, sizeof(*status));
	status->speed = port->conf.speed;
	if (port->conf.power_down) {
		status->link = false;
		return 0;
	}
	switch (port->conf.portmode) {
	case PHY_INTERFACE_MODE_SGMII:
	case PHY_INTERFACE_MODE_QSGMII:
	case PHY_INTERFACE_MODE_1000BASEX:
	case PHY_INTERFACE_MODE_2500BASEX:
		return sparx5_get_dev2g5_status(sparx5, port, status);
	case PHY_INTERFACE_MODE_5GBASER:
	case PHY_INTERFACE_MODE_10GBASER:
	case PHY_INTERFACE_MODE_25GBASER:
		return sparx5_get_sfi_status(sparx5, port, status);
	case PHY_INTERFACE_MODE_NA:
		return 0;
	default:
		netdev_err(port->ndev, "Status not supported");
		return -ENODEV;
	}
	return 0;
}

static int sparx5_port_error(struct sparx5_port *port,
			     struct sparx5_port_config *conf,
			     enum port_error errtype)
{
	switch (errtype) {
	case SPX5_PERR_SPEED:
		netdev_err(port->ndev,
			   "Interface does not support speed: %u: for %s\n",
			   conf->speed, phy_modes(conf->portmode));
		break;
	case SPX5_PERR_IFTYPE:
		netdev_err(port->ndev,
			   "Switch port does not support interface type: %s\n",
			   phy_modes(conf->portmode));
		break;
	default:
		netdev_err(port->ndev,
			   "Interface configuration error\n");
	}

	return -EINVAL;
}

static int sparx5_port_verify_speed(struct sparx5 *sparx5,
				    struct sparx5_port *port,
				    struct sparx5_port_config *conf)
{
	if ((sparx5_port_is_2g5(port->portno) &&
	     conf->speed > SPEED_2500) ||
	    (sparx5_port_is_5g(port->portno)  &&
	     conf->speed > SPEED_5000) ||
	    (sparx5_port_is_10g(port->portno) &&
	     conf->speed > SPEED_10000))
		return sparx5_port_error(port, conf, SPX5_PERR_SPEED);

	switch (conf->portmode) {
	case PHY_INTERFACE_MODE_NA:
		return -EINVAL;
	case PHY_INTERFACE_MODE_1000BASEX:
		if (conf->speed != SPEED_1000 ||
		    sparx5_port_is_2g5(port->portno))
			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
		if (sparx5_port_is_2g5(port->portno))
			return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE);
		break;
	case PHY_INTERFACE_MODE_2500BASEX:
		if (conf->speed != SPEED_2500 ||
		    sparx5_port_is_2g5(port->portno))
			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
		break;
	case PHY_INTERFACE_MODE_QSGMII:
		if (port->portno > 47)
			return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE);
		fallthrough;
	case PHY_INTERFACE_MODE_SGMII:
		if (conf->speed != SPEED_1000 &&
		    conf->speed != SPEED_100 &&
		    conf->speed != SPEED_10 &&
		    conf->speed != SPEED_2500)
			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
		break;
	case PHY_INTERFACE_MODE_5GBASER:
	case PHY_INTERFACE_MODE_10GBASER:
	case PHY_INTERFACE_MODE_25GBASER:
		if ((conf->speed != SPEED_5000 &&
		     conf->speed != SPEED_10000 &&
		     conf->speed != SPEED_25000))
			return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
		break;
	default:
		return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE);
	}
	return 0;
}

static bool sparx5_dev_change(struct sparx5 *sparx5,
			      struct sparx5_port *port,
			      struct sparx5_port_config *conf)
{
	return sparx5_is_baser(port->conf.portmode) ^
		sparx5_is_baser(conf->portmode);
}

static int sparx5_port_flush_poll(struct sparx5 *sparx5, u32 portno)
{
	u32  value, resource, prio, delay_cnt = 0;
	bool poll_src = true;
	char *mem = "";

	/* Resource == 0: Memory tracked per source (SRC-MEM)
	 * Resource == 1: Frame references tracked per source (SRC-REF)
	 * Resource == 2: Memory tracked per destination (DST-MEM)
	 * Resource == 3: Frame references tracked per destination. (DST-REF)
	 */
	while (1) {
		bool empty = true;

		for (resource = 0; resource < (poll_src ? 2 : 1); resource++) {
			u32 base;

			base = (resource == 0 ? 2048 : 0) + SPX5_PRIOS * portno;
			for (prio = 0; prio < SPX5_PRIOS; prio++) {
				value = spx5_rd(sparx5,
						QRES_RES_STAT(base + prio));
				if (value) {
					mem = resource == 0 ?
						"DST-MEM" : "SRC-MEM";
					empty = false;
				}
			}
		}

		if (empty)
			break;

		if (delay_cnt++ == 2000) {
			dev_err(sparx5->dev,
				"Flush timeout port %u. %s queue not empty\n",
				portno, mem);
			return -EINVAL;
		}

		usleep_range(SPX5_WAIT_US, SPX5_WAIT_MAX_US);
	}
	return 0;
}

static int sparx5_port_disable(struct sparx5 *sparx5, struct sparx5_port *port, bool high_spd_dev)
{
	u32 tinst = high_spd_dev ?
		    sparx5_port_dev_index(port->portno) : port->portno;
	u32 dev = high_spd_dev ?
		  sparx5_to_high_dev(port->portno) : TARGET_DEV2G5;
	void __iomem *devinst = spx5_inst_get(sparx5, dev, tinst);
	u32 spd = port->conf.speed;
	u32 spd_prm;
	int err;

	if (high_spd_dev) {
		/* 1: Reset the PCS Rx clock domain  */
		spx5_inst_rmw(DEV10G_DEV_RST_CTRL_PCS_RX_RST,
			      DEV10G_DEV_RST_CTRL_PCS_RX_RST,
			      devinst,
			      DEV10G_DEV_RST_CTRL(0));

		/* 2: Disable MAC frame reception */
		spx5_inst_rmw(0,
			      DEV10G_MAC_ENA_CFG_RX_ENA,
			      devinst,
			      DEV10G_MAC_ENA_CFG(0));
	} else {
		/* 1: Reset the PCS Rx clock domain  */
		spx5_inst_rmw(DEV2G5_DEV_RST_CTRL_PCS_RX_RST,
			      DEV2G5_DEV_RST_CTRL_PCS_RX_RST,
			      devinst,
			      DEV2G5_DEV_RST_CTRL(0));
		/* 2: Disable MAC frame reception */
		spx5_inst_rmw(0,
			      DEV2G5_MAC_ENA_CFG_RX_ENA,
			      devinst,
			      DEV2G5_MAC_ENA_CFG(0));
	}
	/* 3: Disable traffic being sent to or from switch port->portno */
	spx5_rmw(0,
		 QFWD_SWITCH_PORT_MODE_PORT_ENA,
		 sparx5,
		 QFWD_SWITCH_PORT_MODE(port->portno));

	/* 4: Disable dequeuing from the egress queues  */
	spx5_rmw(HSCH_PORT_MODE_DEQUEUE_DIS,
		 HSCH_PORT_MODE_DEQUEUE_DIS,
		 sparx5,
		 HSCH_PORT_MODE(port->portno));

	/* 5: Disable Flowcontrol */
	spx5_rmw(QSYS_PAUSE_CFG_PAUSE_STOP_SET(0xFFF - 1),
		 QSYS_PAUSE_CFG_PAUSE_STOP,
		 sparx5,
		 QSYS_PAUSE_CFG(port->portno));

	spd_prm = spd == SPEED_10 ? 1000 : spd == SPEED_100 ? 100 : 10;
	/* 6: Wait while the last frame is exiting the queues */
	usleep_range(8 * spd_prm, 10 * spd_prm);

	/* 7: Flush the queues accociated with the port->portno */
	spx5_rmw(HSCH_FLUSH_CTRL_FLUSH_PORT_SET(port->portno) |
		 HSCH_FLUSH_CTRL_FLUSH_DST_SET(1) |
		 HSCH_FLUSH_CTRL_FLUSH_SRC_SET(1) |
		 HSCH_FLUSH_CTRL_FLUSH_ENA_SET(1),
		 HSCH_FLUSH_CTRL_FLUSH_PORT |
		 HSCH_FLUSH_CTRL_FLUSH_DST |
		 HSCH_FLUSH_CTRL_FLUSH_SRC |
		 HSCH_FLUSH_CTRL_FLUSH_ENA,
		 sparx5,
		 HSCH_FLUSH_CTRL);

	/* 8: Enable dequeuing from the egress queues */
	spx5_rmw(0,
		 HSCH_PORT_MODE_DEQUEUE_DIS,
		 sparx5,
		 HSCH_PORT_MODE(port->portno));

	/* 9: Wait until flushing is complete */
	err = sparx5_port_flush_poll(sparx5, port->portno);
	if (err)
		return err;

	/* 10: Reset the  MAC clock domain */
	if (high_spd_dev) {
		spx5_inst_rmw(DEV10G_DEV_RST_CTRL_PCS_TX_RST_SET(1) |
			      DEV10G_DEV_RST_CTRL_MAC_RX_RST_SET(1) |
			      DEV10G_DEV_RST_CTRL_MAC_TX_RST_SET(1),
			      DEV10G_DEV_RST_CTRL_PCS_TX_RST |
			      DEV10G_DEV_RST_CTRL_MAC_RX_RST |
			      DEV10G_DEV_RST_CTRL_MAC_TX_RST,
			      devinst,
			      DEV10G_DEV_RST_CTRL(0));

	} else {
		spx5_inst_rmw(DEV2G5_DEV_RST_CTRL_SPEED_SEL_SET(3) |
			      DEV2G5_DEV_RST_CTRL_PCS_TX_RST_SET(1) |
			      DEV2G5_DEV_RST_CTRL_PCS_RX_RST_SET(1) |
			      DEV2G5_DEV_RST_CTRL_MAC_TX_RST_SET(1) |
			      DEV2G5_DEV_RST_CTRL_MAC_RX_RST_SET(1),
			      DEV2G5_DEV_RST_CTRL_SPEED_SEL |
			      DEV2G5_DEV_RST_CTRL_PCS_TX_RST |
			      DEV2G5_DEV_RST_CTRL_PCS_RX_RST |
			      DEV2G5_DEV_RST_CTRL_MAC_TX_RST |
			      DEV2G5_DEV_RST_CTRL_MAC_RX_RST,
			      devinst,
			      DEV2G5_DEV_RST_CTRL(0));
	}
	/* 11: Clear flushing */
	spx5_rmw(HSCH_FLUSH_CTRL_FLUSH_PORT_SET(port->portno) |
		 HSCH_FLUSH_CTRL_FLUSH_ENA_SET(0),
		 HSCH_FLUSH_CTRL_FLUSH_PORT |
		 HSCH_FLUSH_CTRL_FLUSH_ENA,
		 sparx5,
		 HSCH_FLUSH_CTRL);

	if (high_spd_dev) {
		u32 pcs = sparx5_to_pcs_dev(port->portno);
		void __iomem *pcsinst = spx5_inst_get(sparx5, pcs, tinst);

		/* 12: Disable 5G/10G/25 BaseR PCS */
		spx5_inst_rmw(PCS10G_BR_PCS_CFG_PCS_ENA_SET(0),
			      PCS10G_BR_PCS_CFG_PCS_ENA,
			      pcsinst,
			      PCS10G_BR_PCS_CFG(0));

		if (sparx5_port_is_25g(port->portno))
			/* Disable 25G PCS */
			spx5_rmw(DEV25G_PCS25G_CFG_PCS25G_ENA_SET(0),
				 DEV25G_PCS25G_CFG_PCS25G_ENA,
				 sparx5,
				 DEV25G_PCS25G_CFG(tinst));
	} else {
		/* 12: Disable 1G PCS */
		spx5_rmw(DEV2G5_PCS1G_CFG_PCS_ENA_SET(0),
			 DEV2G5_PCS1G_CFG_PCS_ENA,
			 sparx5,
			 DEV2G5_PCS1G_CFG(port->portno));
	}

	/* The port is now flushed and disabled  */
	return 0;
}

static int sparx5_port_fifo_sz(struct sparx5 *sparx5,
			       u32 portno, u32 speed)
{
	u32 sys_clk = sparx5_clk_period(sparx5->coreclock);
	const u32 taxi_dist[SPX5_PORTS_ALL] = {
		6, 8, 10, 6, 8, 10, 6, 8, 10, 6, 8, 10,
		4, 4, 4, 4,
		11, 12, 13, 14, 15, 16, 17, 18,
		11, 12, 13, 14, 15, 16, 17, 18,
		11, 12, 13, 14, 15, 16, 17, 18,
		11, 12, 13, 14, 15, 16, 17, 18,
		4, 6, 8, 4, 6, 8, 6, 8,
		2, 2, 2, 2, 2, 2, 2, 4, 2
	};
	u32 mac_per    = 6400, tmp1, tmp2, tmp3;
	u32 fifo_width = 16;
	u32 mac_width  = 8;
	u32 addition   = 0;

	switch (speed) {
	case SPEED_25000:
		return 0;
	case SPEED_10000:
		mac_per = 6400;
		mac_width = 8;
		addition = 1;
		break;
	case SPEED_5000:
		mac_per = 12800;
		mac_width = 8;
		addition = 0;
		break;
	case SPEED_2500:
		mac_per = 3200;
		mac_width = 1;
		addition = 0;
		break;
	case SPEED_1000:
		mac_per =  8000;
		mac_width = 1;
		addition = 0;
		break;
	case SPEED_100:
	case SPEED_10:
		return 1;
	default:
		break;
	}

	tmp1 = 1000 * mac_width / fifo_width;
	tmp2 = 3000 + ((12000 + 2 * taxi_dist[portno] * 1000)
		       * sys_clk / mac_per);
	tmp3 = tmp1 * tmp2 / 1000;
	return  (tmp3 + 2000 + 999) / 1000 + addition;
}

/* Configure port muxing:
 * QSGMII:     4x2G5 devices
 */
static int sparx5_port_mux_set(struct sparx5 *sparx5,
			       struct sparx5_port *port,
			       struct sparx5_port_config *conf)
{
	u32 portno = port->portno;
	u32 inst;

	if (port->conf.portmode == conf->portmode)
		return 0; /* Nothing to do */

	switch (conf->portmode) {
	case PHY_INTERFACE_MODE_QSGMII: /* QSGMII: 4x2G5 devices. Mode Q'  */
		inst = (portno - portno % 4) / 4;
		spx5_rmw(BIT(inst),
			 BIT(inst),
			 sparx5,
			 PORT_CONF_QSGMII_ENA);

		if ((portno / 4 % 2) == 0) {
			/* Affects d0-d3,d8-d11..d40-d43 */
			spx5_rmw(PORT_CONF_USGMII_CFG_BYPASS_SCRAM_SET(1) |
				 PORT_CONF_USGMII_CFG_BYPASS_DESCRAM_SET(1) |
				 PORT_CONF_USGMII_CFG_QUAD_MODE_SET(1),
				 PORT_CONF_USGMII_CFG_BYPASS_SCRAM |
				 PORT_CONF_USGMII_CFG_BYPASS_DESCRAM |
				 PORT_CONF_USGMII_CFG_QUAD_MODE,
				 sparx5,
				 PORT_CONF_USGMII_CFG((portno / 8)));
		}
		break;
	default:
		break;
	}
	return 0;
}

static int sparx5_port_max_tags_set(struct sparx5 *sparx5,
				    struct sparx5_port *port)
{
	enum sparx5_port_max_tags max_tags    = port->max_vlan_tags;
	int tag_ct          = max_tags == SPX5_PORT_MAX_TAGS_ONE ? 1 :
			      max_tags == SPX5_PORT_MAX_TAGS_TWO ? 2 : 0;
	bool dtag           = max_tags == SPX5_PORT_MAX_TAGS_TWO;
	enum sparx5_vlan_port_type vlan_type  = port->vlan_type;
	bool dotag          = max_tags != SPX5_PORT_MAX_TAGS_NONE;
	u32 dev             = sparx5_to_high_dev(port->portno);
	u32 tinst           = sparx5_port_dev_index(port->portno);
	void __iomem *inst  = spx5_inst_get(sparx5, dev, tinst);
	u32 etype;

	etype = (vlan_type == SPX5_VLAN_PORT_TYPE_S_CUSTOM ?
		 port->custom_etype :
		 vlan_type == SPX5_VLAN_PORT_TYPE_C ?
		 SPX5_ETYPE_TAG_C : SPX5_ETYPE_TAG_S);

	spx5_wr(DEV2G5_MAC_TAGS_CFG_TAG_ID_SET(etype) |
		DEV2G5_MAC_TAGS_CFG_PB_ENA_SET(dtag) |
		DEV2G5_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(dotag) |
		DEV2G5_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_SET(dotag),
		sparx5,
		DEV2G5_MAC_TAGS_CFG(port->portno));

	if (sparx5_port_is_2g5(port->portno))
		return 0;

	spx5_inst_rmw(DEV10G_MAC_TAGS_CFG_TAG_ID_SET(etype) |
		      DEV10G_MAC_TAGS_CFG_TAG_ENA_SET(dotag),
		      DEV10G_MAC_TAGS_CFG_TAG_ID |
		      DEV10G_MAC_TAGS_CFG_TAG_ENA,
		      inst,
		      DEV10G_MAC_TAGS_CFG(0, 0));

	spx5_inst_rmw(DEV10G_MAC_NUM_TAGS_CFG_NUM_TAGS_SET(tag_ct),
		      DEV10G_MAC_NUM_TAGS_CFG_NUM_TAGS,
		      inst,
		      DEV10G_MAC_NUM_TAGS_CFG(0));

	spx5_inst_rmw(DEV10G_MAC_MAXLEN_CFG_MAX_LEN_TAG_CHK_SET(dotag),
		      DEV10G_MAC_MAXLEN_CFG_MAX_LEN_TAG_CHK,
		      inst,
		      DEV10G_MAC_MAXLEN_CFG(0));
	return 0;
}

static int sparx5_port_fwd_urg(struct sparx5 *sparx5, u32 speed)
{
	u32 clk_period_ps = 1600; /* 625Mhz for now */
	u32 urg = 672000;

	switch (speed) {
	case SPEED_10:
	case SPEED_100:
	case SPEED_1000:
		urg = 672000;
		break;
	case SPEED_2500:
		urg = 270000;
		break;
	case SPEED_5000:
		urg = 135000;
		break;
	case SPEED_10000:
		urg = 67200;
		break;
	case SPEED_25000:
		urg = 27000;
		break;
	}
	return urg / clk_period_ps - 1;
}

static u16 sparx5_wm_enc(u16 value)
{
	if (value >= 2048)
		return 2048 + value / 16;

	return value;
}

static int sparx5_port_fc_setup(struct sparx5 *sparx5,
				struct sparx5_port *port,
				struct sparx5_port_config *conf)
{
	bool fc_obey = conf->pause & MLO_PAUSE_RX ? 1 : 0;
	u32 pause_stop = 0xFFF - 1; /* FC gen disabled */

	if (conf->pause & MLO_PAUSE_TX)
		pause_stop = sparx5_wm_enc(4  * (ETH_MAXLEN /
						 SPX5_BUFFER_CELL_SZ));

	/* Set HDX flowcontrol */
	spx5_rmw(DSM_MAC_CFG_HDX_BACKPREASSURE_SET(conf->duplex == DUPLEX_HALF),
		 DSM_MAC_CFG_HDX_BACKPREASSURE,
		 sparx5,
		 DSM_MAC_CFG(port->portno));

	/* Obey flowcontrol  */
	spx5_rmw(DSM_RX_PAUSE_CFG_RX_PAUSE_EN_SET(fc_obey),
		 DSM_RX_PAUSE_CFG_RX_PAUSE_EN,
		 sparx5,
		 DSM_RX_PAUSE_CFG(port->portno));

	/* Disable forward pressure */
	spx5_rmw(QSYS_FWD_PRESSURE_FWD_PRESSURE_DIS_SET(fc_obey),
		 QSYS_FWD_PRESSURE_FWD_PRESSURE_DIS,
		 sparx5,
		 QSYS_FWD_PRESSURE(port->portno));

	/* Generate pause frames */
	spx5_rmw(QSYS_PAUSE_CFG_PAUSE_STOP_SET(pause_stop),
		 QSYS_PAUSE_CFG_PAUSE_STOP,
		 sparx5,
		 QSYS_PAUSE_CFG(port->portno));

	return 0;
}

static u16 sparx5_get_aneg_word(struct sparx5_port_config *conf)
{
	if (conf->portmode == PHY_INTERFACE_MODE_1000BASEX) /* cl-37 aneg */
		return (conf->pause_adv | ADVERTISE_LPACK | ADVERTISE_1000XFULL);
	else
		return 1; /* Enable SGMII Aneg */
}

int sparx5_serdes_set(struct sparx5 *sparx5,
		      struct sparx5_port *port,
		      struct sparx5_port_config *conf)
{
	int portmode, err, speed = conf->speed;

	if (conf->portmode == PHY_INTERFACE_MODE_QSGMII &&
	    ((port->portno % 4) != 0)) {
		return 0;
	}
	if (sparx5_is_baser(conf->portmode)) {
		if (conf->portmode == PHY_INTERFACE_MODE_25GBASER)
			speed = SPEED_25000;
		else if (conf->portmode == PHY_INTERFACE_MODE_10GBASER)
			speed = SPEED_10000;
		else
			speed = SPEED_5000;
	}

	err = phy_set_media(port->serdes, conf->media);
	if (err)
		return err;
	if (speed > 0) {
		err = phy_set_speed(port->serdes, speed);
		if (err)
			return err;
	}
	if (conf->serdes_reset) {
		err = phy_reset(port->serdes);
		if (err)
			return err;
	}

	/* Configure SerDes with port parameters
	 * For BaseR, the serdes driver supports 10GGBASE-R and speed 5G/10G/25G
	 */
	portmode = conf->portmode;
	if (sparx5_is_baser(conf->portmode))
		portmode = PHY_INTERFACE_MODE_10GBASER;
	err = phy_set_mode_ext(port->serdes, PHY_MODE_ETHERNET, portmode);
	if (err)
		return err;
	conf->serdes_reset = false;
	return err;
}

static int sparx5_port_pcs_low_set(struct sparx5 *sparx5,
				   struct sparx5_port *port,
				   struct sparx5_port_config *conf)
{
	bool sgmii = false, inband_aneg = false;
	int err;

	if (port->conf.inband) {
		if (conf->portmode == PHY_INTERFACE_MODE_SGMII ||
		    conf->portmode == PHY_INTERFACE_MODE_QSGMII)
			inband_aneg = true; /* Cisco-SGMII in-band-aneg */
		else if (conf->portmode == PHY_INTERFACE_MODE_1000BASEX &&
			 conf->autoneg)
			inband_aneg = true; /* Clause-37 in-band-aneg */

		err = sparx5_serdes_set(sparx5, port, conf);
		if (err)
			return -EINVAL;
	} else {
		sgmii = true; /* Phy is connnected to the MAC */
	}

	/* Choose SGMII or 1000BaseX/2500BaseX PCS mode */
	spx5_rmw(DEV2G5_PCS1G_MODE_CFG_SGMII_MODE_ENA_SET(sgmii),
		 DEV2G5_PCS1G_MODE_CFG_SGMII_MODE_ENA,
		 sparx5,
		 DEV2G5_PCS1G_MODE_CFG(port->portno));

	/* Enable PCS */
	spx5_wr(DEV2G5_PCS1G_CFG_PCS_ENA_SET(1),
		sparx5,
		DEV2G5_PCS1G_CFG(port->portno));

	if (inband_aneg) {
		u16 abil = sparx5_get_aneg_word(conf);

		/* Enable in-band aneg */
		spx5_wr(DEV2G5_PCS1G_ANEG_CFG_ADV_ABILITY_SET(abil) |
			DEV2G5_PCS1G_ANEG_CFG_SW_RESOLVE_ENA_SET(1) |
			DEV2G5_PCS1G_ANEG_CFG_ANEG_ENA_SET(1) |
			DEV2G5_PCS1G_ANEG_CFG_ANEG_RESTART_ONE_SHOT_SET(1),
			sparx5,
			DEV2G5_PCS1G_ANEG_CFG(port->portno));
	} else {
		spx5_wr(0, sparx5, DEV2G5_PCS1G_ANEG_CFG(port->portno));
	}

	/* Take PCS out of reset */
	spx5_rmw(DEV2G5_DEV_RST_CTRL_SPEED_SEL_SET(2) |
		 DEV2G5_DEV_RST_CTRL_PCS_TX_RST_SET(0) |
		 DEV2G5_DEV_RST_CTRL_PCS_RX_RST_SET(0),
		 DEV2G5_DEV_RST_CTRL_SPEED_SEL |
		 DEV2G5_DEV_RST_CTRL_PCS_TX_RST |
		 DEV2G5_DEV_RST_CTRL_PCS_RX_RST,
		 sparx5,
		 DEV2G5_DEV_RST_CTRL(port->portno));

	return 0;
}

static int sparx5_port_pcs_high_set(struct sparx5 *sparx5,
				    struct sparx5_port *port,
				    struct sparx5_port_config *conf)
{
	u32 clk_spd = conf->portmode == PHY_INTERFACE_MODE_5GBASER ? 1 : 0;
	u32 pix = sparx5_port_dev_index(port->portno);
	u32 dev = sparx5_to_high_dev(port->portno);
	u32 pcs = sparx5_to_pcs_dev(port->portno);
	void __iomem *devinst;
	void __iomem *pcsinst;
	int err;

	devinst = spx5_inst_get(sparx5, dev, pix);
	pcsinst = spx5_inst_get(sparx5, pcs, pix);

	/*  SFI : No in-band-aneg. Speeds 5G/10G/25G */
	err = sparx5_serdes_set(sparx5, port, conf);
	if (err)
		return -EINVAL;
	if (conf->portmode == PHY_INTERFACE_MODE_25GBASER) {
		/* Enable PCS for 25G device, speed 25G */
		spx5_rmw(DEV25G_PCS25G_CFG_PCS25G_ENA_SET(1),
			 DEV25G_PCS25G_CFG_PCS25G_ENA,
			 sparx5,
			 DEV25G_PCS25G_CFG(pix));
	} else {
		/* Enable PCS for 5G/10G/25G devices, speed 5G/10G */
		spx5_inst_rmw(PCS10G_BR_PCS_CFG_PCS_ENA_SET(1),
			      PCS10G_BR_PCS_CFG_PCS_ENA,
			      pcsinst,
			      PCS10G_BR_PCS_CFG(0));
	}

	/* Enable 5G/10G/25G MAC module */
	spx5_inst_wr(DEV10G_MAC_ENA_CFG_RX_ENA_SET(1) |
		     DEV10G_MAC_ENA_CFG_TX_ENA_SET(1),
		     devinst,
		     DEV10G_MAC_ENA_CFG(0));

	/* Take the device out of reset */
	spx5_inst_rmw(DEV10G_DEV_RST_CTRL_PCS_RX_RST_SET(0) |
		      DEV10G_DEV_RST_CTRL_PCS_TX_RST_SET(0) |
		      DEV10G_DEV_RST_CTRL_MAC_RX_RST_SET(0) |
		      DEV10G_DEV_RST_CTRL_MAC_TX_RST_SET(0) |
		      DEV10G_DEV_RST_CTRL_SPEED_SEL_SET(clk_spd),
		      DEV10G_DEV_RST_CTRL_PCS_RX_RST |
		      DEV10G_DEV_RST_CTRL_PCS_TX_RST |
		      DEV10G_DEV_RST_CTRL_MAC_RX_RST |
		      DEV10G_DEV_RST_CTRL_MAC_TX_RST |
		      DEV10G_DEV_RST_CTRL_SPEED_SEL,
		      devinst,
		      DEV10G_DEV_RST_CTRL(0));

	return 0;
}

/* Switch between 1G/2500 and 5G/10G/25G devices */
static void sparx5_dev_switch(struct sparx5 *sparx5, int port, bool hsd)
{
	int bt_indx = BIT(sparx5_port_dev_index(port));

	if (sparx5_port_is_5g(port)) {
		spx5_rmw(hsd ? 0 : bt_indx,
			 bt_indx,
			 sparx5,
			 PORT_CONF_DEV5G_MODES);
	} else if (sparx5_port_is_10g(port)) {
		spx5_rmw(hsd ? 0 : bt_indx,
			 bt_indx,
			 sparx5,
			 PORT_CONF_DEV10G_MODES);
	} else if (sparx5_port_is_25g(port)) {
		spx5_rmw(hsd ? 0 : bt_indx,
			 bt_indx,
			 sparx5,
			 PORT_CONF_DEV25G_MODES);
	}
}

/* Configure speed/duplex dependent registers */
static int sparx5_port_config_low_set(struct sparx5 *sparx5,
				      struct sparx5_port *port,
				      struct sparx5_port_config *conf)
{
	u32 clk_spd, gig_mode, tx_gap, hdx_gap_1, hdx_gap_2;
	bool fdx = conf->duplex == DUPLEX_FULL;
	int spd = conf->speed;

	clk_spd = spd == SPEED_10 ? 0 : spd == SPEED_100 ? 1 : 2;
	gig_mode = spd == SPEED_1000 || spd == SPEED_2500;
	tx_gap = spd == SPEED_1000 ? 4 : fdx ? 6 : 5;
	hdx_gap_1 = spd == SPEED_1000 ? 0 : spd == SPEED_100 ? 1 : 2;
	hdx_gap_2 = spd == SPEED_1000 ? 0 : spd == SPEED_100 ? 4 : 1;

	/* GIG/FDX mode */
	spx5_rmw(DEV2G5_MAC_MODE_CFG_GIGA_MODE_ENA_SET(gig_mode) |
		 DEV2G5_MAC_MODE_CFG_FDX_ENA_SET(fdx),
		 DEV2G5_MAC_MODE_CFG_GIGA_MODE_ENA |
		 DEV2G5_MAC_MODE_CFG_FDX_ENA,
		 sparx5,
		 DEV2G5_MAC_MODE_CFG(port->portno));

	/* Set MAC IFG Gaps */
	spx5_wr(DEV2G5_MAC_IFG_CFG_TX_IFG_SET(tx_gap) |
		DEV2G5_MAC_IFG_CFG_RX_IFG1_SET(hdx_gap_1) |
		DEV2G5_MAC_IFG_CFG_RX_IFG2_SET(hdx_gap_2),
		sparx5,
		DEV2G5_MAC_IFG_CFG(port->portno));

	/* Disabling frame aging when in HDX (due to HDX issue) */
	spx5_rmw(HSCH_PORT_MODE_AGE_DIS_SET(fdx == 0),
		 HSCH_PORT_MODE_AGE_DIS,
		 sparx5,
		 HSCH_PORT_MODE(port->portno));

	/* Enable MAC module */
	spx5_wr(DEV2G5_MAC_ENA_CFG_RX_ENA |
		DEV2G5_MAC_ENA_CFG_TX_ENA,
		sparx5,
		DEV2G5_MAC_ENA_CFG(port->portno));

	/* Select speed and take MAC out of reset */
	spx5_rmw(DEV2G5_DEV_RST_CTRL_SPEED_SEL_SET(clk_spd) |
		 DEV2G5_DEV_RST_CTRL_MAC_TX_RST_SET(0) |
		 DEV2G5_DEV_RST_CTRL_MAC_RX_RST_SET(0),
		 DEV2G5_DEV_RST_CTRL_SPEED_SEL |
		 DEV2G5_DEV_RST_CTRL_MAC_TX_RST |
		 DEV2G5_DEV_RST_CTRL_MAC_RX_RST,
		 sparx5,
		 DEV2G5_DEV_RST_CTRL(port->portno));

	return 0;
}

int sparx5_port_pcs_set(struct sparx5 *sparx5,
			struct sparx5_port *port,
			struct sparx5_port_config *conf)

{
	bool high_speed_dev = sparx5_is_baser(conf->portmode);
	int err;

	if (sparx5_dev_change(sparx5, port, conf)) {
		/* switch device */
		sparx5_dev_switch(sparx5, port->portno, high_speed_dev);

		/* Disable the not-in-use device */
		err = sparx5_port_disable(sparx5, port, !high_speed_dev);
		if (err)
			return err;
	}
	/* Disable the port before re-configuring */
	err = sparx5_port_disable(sparx5, port, high_speed_dev);
	if (err)
		return -EINVAL;

	if (high_speed_dev)
		err = sparx5_port_pcs_high_set(sparx5, port, conf);
	else
		err = sparx5_port_pcs_low_set(sparx5, port, conf);

	if (err)
		return -EINVAL;

	if (port->conf.inband) {
		/* Enable/disable 1G counters in ASM */
		spx5_rmw(ASM_PORT_CFG_CSC_STAT_DIS_SET(high_speed_dev),
			 ASM_PORT_CFG_CSC_STAT_DIS,
			 sparx5,
			 ASM_PORT_CFG(port->portno));

		/* Enable/disable 1G counters in DSM */
		spx5_rmw(DSM_BUF_CFG_CSC_STAT_DIS_SET(high_speed_dev),
			 DSM_BUF_CFG_CSC_STAT_DIS,
			 sparx5,
			 DSM_BUF_CFG(port->portno));
	}

	port->conf = *conf;

	return 0;
}

int sparx5_port_config(struct sparx5 *sparx5,
		       struct sparx5_port *port,
		       struct sparx5_port_config *conf)
{
	bool high_speed_dev = sparx5_is_baser(conf->portmode);
	int err, urgency, stop_wm;

	err = sparx5_port_verify_speed(sparx5, port, conf);
	if (err)
		return err;

	/* high speed device is already configured */
	if (!high_speed_dev)
		sparx5_port_config_low_set(sparx5, port, conf);

	/* Configure flow control */
	err = sparx5_port_fc_setup(sparx5, port, conf);
	if (err)
		return err;

	/* Set the DSM stop watermark */
	stop_wm = sparx5_port_fifo_sz(sparx5, port->portno, conf->speed);
	spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV_TX_STOP_WM_SET(stop_wm),
		 DSM_DEV_TX_STOP_WM_CFG_DEV_TX_STOP_WM,
		 sparx5,
		 DSM_DEV_TX_STOP_WM_CFG(port->portno));

	/* Enable port in queue system */
	urgency = sparx5_port_fwd_urg(sparx5, conf->speed);
	spx5_rmw(QFWD_SWITCH_PORT_MODE_PORT_ENA_SET(1) |
		 QFWD_SWITCH_PORT_MODE_FWD_URGENCY_SET(urgency),
		 QFWD_SWITCH_PORT_MODE_PORT_ENA |
		 QFWD_SWITCH_PORT_MODE_FWD_URGENCY,
		 sparx5,
		 QFWD_SWITCH_PORT_MODE(port->portno));

	/* Save the new values */
	port->conf = *conf;

	return 0;
}

/* Initialize port config to default */
int sparx5_port_init(struct sparx5 *sparx5,
		     struct sparx5_port *port,
		     struct sparx5_port_config *conf)
{
	u32 pause_start = sparx5_wm_enc(6  * (ETH_MAXLEN / SPX5_BUFFER_CELL_SZ));
	u32 atop = sparx5_wm_enc(20 * (ETH_MAXLEN / SPX5_BUFFER_CELL_SZ));
	u32 devhigh = sparx5_to_high_dev(port->portno);
	u32 pix = sparx5_port_dev_index(port->portno);
	u32 pcs = sparx5_to_pcs_dev(port->portno);
	bool sd_pol = port->signd_active_high;
	bool sd_sel = !port->signd_internal;
	bool sd_ena = port->signd_enable;
	u32 pause_stop = 0xFFF - 1; /* FC generate disabled */
	void __iomem *devinst;
	void __iomem *pcsinst;
	int err;

	devinst = spx5_inst_get(sparx5, devhigh, pix);
	pcsinst = spx5_inst_get(sparx5, pcs, pix);

	/* Set the mux port mode  */
	err = sparx5_port_mux_set(sparx5, port, conf);
	if (err)
		return err;

	/* Configure MAC vlan awareness */
	err = sparx5_port_max_tags_set(sparx5, port);
	if (err)
		return err;

	/* Set Max Length */
	spx5_rmw(DEV2G5_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
		 DEV2G5_MAC_MAXLEN_CFG_MAX_LEN,
		 sparx5,
		 DEV2G5_MAC_MAXLEN_CFG(port->portno));

	/* 1G/2G5: Signal Detect configuration */
	spx5_wr(DEV2G5_PCS1G_SD_CFG_SD_POL_SET(sd_pol) |
		DEV2G5_PCS1G_SD_CFG_SD_SEL_SET(sd_sel) |
		DEV2G5_PCS1G_SD_CFG_SD_ENA_SET(sd_ena),
		sparx5,
		DEV2G5_PCS1G_SD_CFG(port->portno));

	/* Set Pause WM hysteresis */
	spx5_rmw(QSYS_PAUSE_CFG_PAUSE_START_SET(pause_start) |
		 QSYS_PAUSE_CFG_PAUSE_STOP_SET(pause_stop) |
		 QSYS_PAUSE_CFG_PAUSE_ENA_SET(1),
		 QSYS_PAUSE_CFG_PAUSE_START |
		 QSYS_PAUSE_CFG_PAUSE_STOP |
		 QSYS_PAUSE_CFG_PAUSE_ENA,
		 sparx5,
		 QSYS_PAUSE_CFG(port->portno));

	/* Port ATOP. Frames are tail dropped when this WM is hit */
	spx5_wr(QSYS_ATOP_ATOP_SET(atop),
		sparx5,
		QSYS_ATOP(port->portno));

	/* Discard pause frame 01-80-C2-00-00-01 */
	spx5_wr(PAUSE_DISCARD, sparx5, ANA_CL_CAPTURE_BPDU_CFG(port->portno));

	if (conf->portmode == PHY_INTERFACE_MODE_QSGMII ||
	    conf->portmode == PHY_INTERFACE_MODE_SGMII) {
		err = sparx5_serdes_set(sparx5, port, conf);
		if (err)
			return err;

		if (!sparx5_port_is_2g5(port->portno))
			/* Enable shadow device */
			spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA_SET(1),
				 DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA,
				 sparx5,
				 DSM_DEV_TX_STOP_WM_CFG(port->portno));

		sparx5_dev_switch(sparx5, port->portno, false);
	}
	if (conf->portmode == PHY_INTERFACE_MODE_QSGMII) {
		// All ports must be PCS enabled in QSGMII mode
		spx5_rmw(DEV2G5_DEV_RST_CTRL_PCS_TX_RST_SET(0),
			 DEV2G5_DEV_RST_CTRL_PCS_TX_RST,
			 sparx5,
			 DEV2G5_DEV_RST_CTRL(port->portno));
	}
	/* Default IFGs for 1G */
	spx5_wr(DEV2G5_MAC_IFG_CFG_TX_IFG_SET(6) |
		DEV2G5_MAC_IFG_CFG_RX_IFG1_SET(0) |
		DEV2G5_MAC_IFG_CFG_RX_IFG2_SET(0),
		sparx5,
		DEV2G5_MAC_IFG_CFG(port->portno));

	if (sparx5_port_is_2g5(port->portno))
		return 0; /* Low speed device only - return */

	/* Now setup the high speed device */
	if (conf->portmode == PHY_INTERFACE_MODE_NA)
		conf->portmode = PHY_INTERFACE_MODE_10GBASER;

	if (sparx5_is_baser(conf->portmode))
		sparx5_dev_switch(sparx5, port->portno, true);

	/* Set Max Length */
	spx5_inst_rmw(DEV10G_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
		      DEV10G_MAC_MAXLEN_CFG_MAX_LEN,
		      devinst,
		      DEV10G_MAC_ENA_CFG(0));

	/* Handle Signal Detect in 10G PCS */
	spx5_inst_wr(PCS10G_BR_PCS_SD_CFG_SD_POL_SET(sd_pol) |
		     PCS10G_BR_PCS_SD_CFG_SD_SEL_SET(sd_sel) |
		     PCS10G_BR_PCS_SD_CFG_SD_ENA_SET(sd_ena),
		     pcsinst,
		     PCS10G_BR_PCS_SD_CFG(0));

	if (sparx5_port_is_25g(port->portno)) {
		/* Handle Signal Detect in 25G PCS */
		spx5_wr(DEV25G_PCS25G_SD_CFG_SD_POL_SET(sd_pol) |
			DEV25G_PCS25G_SD_CFG_SD_SEL_SET(sd_sel) |
			DEV25G_PCS25G_SD_CFG_SD_ENA_SET(sd_ena),
			sparx5,
			DEV25G_PCS25G_SD_CFG(pix));
	}

	return 0;
}

void sparx5_port_enable(struct sparx5_port *port, bool enable)
{
	struct sparx5 *sparx5 = port->sparx5;

	/* Enable port for frame transfer? */
	spx5_rmw(QFWD_SWITCH_PORT_MODE_PORT_ENA_SET(enable),
		 QFWD_SWITCH_PORT_MODE_PORT_ENA,
		 sparx5,
		 QFWD_SWITCH_PORT_MODE(port->portno));
}
