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

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