/*
 * Copyright 2015 Freescale Semiconductor, Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <netdev.h>
#include <asm/io.h>
#include <asm/arch/fsl_serdes.h>
#include <hwconfig.h>
#include <fsl_mdio.h>
#include <malloc.h>
#include <fm_eth.h>
#include <i2c.h>
#include <miiphy.h>
#include <fsl-mc/fsl_mc.h>
#include <fsl-mc/ldpaa_wriop.h>

#include "../common/qixis.h"

#include "ls2080aqds_qixis.h"

#define MC_BOOT_ENV_VAR "mcinitcmd"

#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
 /* - In LS2080A there are only 16 SERDES lanes, spread across 2 SERDES banks.
 *   Bank 1 -> Lanes A, B, C, D, E, F, G, H
 *   Bank 2 -> Lanes A,B, C, D, E, F, G, H
 */

 /* Mapping of 16 SERDES lanes to LS2080A QDS board slots. A value of '0' here
  * means that the mapping must be determined dynamically, or that the lane
  * maps to something other than a board slot.
  */

static u8 lane_to_slot_fsm1[] = {
	0, 0, 0, 0, 0, 0, 0, 0
};

static u8 lane_to_slot_fsm2[] = {
	0, 0, 0, 0, 0, 0, 0, 0
};

/* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs
 * housed.
 */

static int xqsgii_riser_phy_addr[] = {
	XQSGMII_CARD_PHY1_PORT0_ADDR,
	XQSGMII_CARD_PHY2_PORT0_ADDR,
	XQSGMII_CARD_PHY3_PORT0_ADDR,
	XQSGMII_CARD_PHY4_PORT0_ADDR,
	XQSGMII_CARD_PHY3_PORT2_ADDR,
	XQSGMII_CARD_PHY1_PORT2_ADDR,
	XQSGMII_CARD_PHY4_PORT2_ADDR,
	XQSGMII_CARD_PHY2_PORT2_ADDR,
};

static int sgmii_riser_phy_addr[] = {
	SGMII_CARD_PORT1_PHY_ADDR,
	SGMII_CARD_PORT2_PHY_ADDR,
	SGMII_CARD_PORT3_PHY_ADDR,
	SGMII_CARD_PORT4_PHY_ADDR,
};

/* Slot2 does not have EMI connections */
#define EMI_NONE	0xFF
#define EMI1_SLOT1	0
#define EMI1_SLOT2	1
#define EMI1_SLOT3	2
#define EMI1_SLOT4	3
#define EMI1_SLOT5	4
#define EMI1_SLOT6	5
#define EMI2		6
#define SFP_TX		0

static const char * const mdio_names[] = {
	"LS2080A_QDS_MDIO0",
	"LS2080A_QDS_MDIO1",
	"LS2080A_QDS_MDIO2",
	"LS2080A_QDS_MDIO3",
	"LS2080A_QDS_MDIO4",
	"LS2080A_QDS_MDIO5",
	DEFAULT_WRIOP_MDIO2_NAME,
};

struct ls2080a_qds_mdio {
	u8 muxval;
	struct mii_dev *realbus;
};

static void sgmii_configure_repeater(int serdes_port)
{
	struct mii_dev *bus;
	uint8_t a = 0xf;
	int i, j, ret;
	int dpmac_id = 0, dpmac, mii_bus = 0;
	unsigned short value;
	char dev[2][20] = {"LS2080A_QDS_MDIO0", "LS2080A_QDS_MDIO3"};
	uint8_t i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5f, 0x60};

	uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
	uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
	uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
	uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};

	int *riser_phy_addr = &xqsgii_riser_phy_addr[0];

	/* Set I2c to Slot 1 */
	i2c_write(0x77, 0, 0, &a, 1);

	for (dpmac = 0; dpmac < 8; dpmac++) {
		/* Check the PHY status */
		switch (serdes_port) {
		case 1:
			mii_bus = 0;
			dpmac_id = dpmac + 1;
			break;
		case 2:
			mii_bus = 1;
			dpmac_id = dpmac + 9;
			a = 0xb;
			i2c_write(0x76, 0, 0, &a, 1);
			break;
		}

		ret = miiphy_set_current_dev(dev[mii_bus]);
		if (ret > 0)
			goto error;

		bus = mdio_get_current_dev();
		debug("Reading from bus %s\n", bus->name);

		ret = miiphy_write(dev[mii_bus], riser_phy_addr[dpmac], 0x1f,
				   3);
		if (ret > 0)
			goto error;

		mdelay(10);
		ret = miiphy_read(dev[mii_bus], riser_phy_addr[dpmac], 0x11,
				  &value);
		if (ret > 0)
			goto error;

		mdelay(10);

		if ((value & 0xfff) == 0x401) {
			printf("DPMAC %d:PHY is ..... Configured\n", dpmac_id);
			miiphy_write(dev[mii_bus], riser_phy_addr[dpmac],
				     0x1f, 0);
			continue;
		}

		for (i = 0; i < 4; i++) {
			for (j = 0; j < 4; j++) {
				a = 0x18;
				i2c_write(i2c_addr[dpmac], 6, 1, &a, 1);
				a = 0x38;
				i2c_write(i2c_addr[dpmac], 4, 1, &a, 1);
				a = 0x4;
				i2c_write(i2c_addr[dpmac], 8, 1, &a, 1);

				i2c_write(i2c_addr[dpmac], 0xf, 1,
					  &ch_a_eq[i], 1);
				i2c_write(i2c_addr[dpmac], 0x11, 1,
					  &ch_a_ctl2[j], 1);

				i2c_write(i2c_addr[dpmac], 0x16, 1,
					  &ch_b_eq[i], 1);
				i2c_write(i2c_addr[dpmac], 0x18, 1,
					  &ch_b_ctl2[j], 1);

				a = 0x14;
				i2c_write(i2c_addr[dpmac], 0x23, 1, &a, 1);
				a = 0xb5;
				i2c_write(i2c_addr[dpmac], 0x2d, 1, &a, 1);
				a = 0x20;
				i2c_write(i2c_addr[dpmac], 4, 1, &a, 1);
				mdelay(100);
				ret = miiphy_read(dev[mii_bus],
						  riser_phy_addr[dpmac],
						  0x11, &value);
				if (ret > 0)
					goto error;

				mdelay(100);
				ret = miiphy_read(dev[mii_bus],
						  riser_phy_addr[dpmac],
						  0x11, &value);
				if (ret > 0)
					goto error;

				if ((value & 0xfff) == 0x401) {
					printf("DPMAC %d :PHY is configured ",
					       dpmac_id);
					printf("after setting repeater 0x%x\n",
					       value);
					i = 5;
					j = 5;
				} else {
					printf("DPMAC %d :PHY is failed to ",
					       dpmac_id);
					printf("configure the repeater 0x%x\n",
					       value);
				}
			}
		}
		miiphy_write(dev[mii_bus], riser_phy_addr[dpmac], 0x1f, 0);
	}
error:
	if (ret)
		printf("DPMAC %d ..... FAILED to configure PHY\n", dpmac_id);
	return;
}

static void qsgmii_configure_repeater(int dpmac)
{
	uint8_t a = 0xf;
	int i, j;
	int i2c_phy_addr = 0;
	int phy_addr = 0;
	int i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b};

	uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
	uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
	uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
	uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};

	const char *dev = "LS2080A_QDS_MDIO0";
	int ret = 0;
	unsigned short value;

	/* Set I2c to Slot 1 */
	i2c_write(0x77, 0, 0, &a, 1);

	switch (dpmac) {
	case 1:
	case 2:
	case 3:
	case 4:
		i2c_phy_addr = i2c_addr[0];
		phy_addr = 0;
		break;

	case 5:
	case 6:
	case 7:
	case 8:
		i2c_phy_addr = i2c_addr[1];
		phy_addr = 4;
		break;

	case 9:
	case 10:
	case 11:
	case 12:
		i2c_phy_addr = i2c_addr[2];
		phy_addr = 8;
		break;

	case 13:
	case 14:
	case 15:
	case 16:
		i2c_phy_addr = i2c_addr[3];
		phy_addr = 0xc;
		break;
	}

	/* Check the PHY status */
	ret = miiphy_set_current_dev(dev);
	ret = miiphy_write(dev, phy_addr, 0x1f, 3);
	mdelay(10);
	ret = miiphy_read(dev, phy_addr, 0x11, &value);
	mdelay(10);
	ret = miiphy_read(dev, phy_addr, 0x11, &value);
	mdelay(10);
	if ((value & 0xf) == 0xf) {
		printf("DPMAC %d :PHY is ..... Configured\n", dpmac);
		return;
	}

	for (i = 0; i < 4; i++) {
		for (j = 0; j < 4; j++) {
			a = 0x18;
			i2c_write(i2c_phy_addr, 6, 1, &a, 1);
			a = 0x38;
			i2c_write(i2c_phy_addr, 4, 1, &a, 1);
			a = 0x4;
			i2c_write(i2c_phy_addr, 8, 1, &a, 1);

			i2c_write(i2c_phy_addr, 0xf, 1, &ch_a_eq[i], 1);
			i2c_write(i2c_phy_addr, 0x11, 1, &ch_a_ctl2[j], 1);

			i2c_write(i2c_phy_addr, 0x16, 1, &ch_b_eq[i], 1);
			i2c_write(i2c_phy_addr, 0x18, 1, &ch_b_ctl2[j], 1);

			a = 0x14;
			i2c_write(i2c_phy_addr, 0x23, 1, &a, 1);
			a = 0xb5;
			i2c_write(i2c_phy_addr, 0x2d, 1, &a, 1);
			a = 0x20;
			i2c_write(i2c_phy_addr, 4, 1, &a, 1);
			mdelay(100);
			ret = miiphy_read(dev, phy_addr, 0x11, &value);
			if (ret > 0)
				goto error;
			mdelay(1);
			ret = miiphy_read(dev, phy_addr, 0x11, &value);
			if (ret > 0)
				goto error;
			mdelay(10);
			if ((value & 0xf) == 0xf) {
				printf("DPMAC %d :PHY is ..... Configured\n",
				       dpmac);
				return;
			}
		}
	}
error:
	printf("DPMAC %d :PHY ..... FAILED to configure PHY\n", dpmac);
	return;
}

static const char *ls2080a_qds_mdio_name_for_muxval(u8 muxval)
{
	return mdio_names[muxval];
}

struct mii_dev *mii_dev_for_muxval(u8 muxval)
{
	struct mii_dev *bus;
	const char *name = ls2080a_qds_mdio_name_for_muxval(muxval);

	if (!name) {
		printf("No bus for muxval %x\n", muxval);
		return NULL;
	}

	bus = miiphy_get_dev_by_name(name);

	if (!bus) {
		printf("No bus by name %s\n", name);
		return NULL;
	}

	return bus;
}

static void ls2080a_qds_enable_SFP_TX(u8 muxval)
{
	u8 brdcfg9;

	brdcfg9 = QIXIS_READ(brdcfg[9]);
	brdcfg9 &= ~BRDCFG9_SFPTX_MASK;
	brdcfg9 |= (muxval << BRDCFG9_SFPTX_SHIFT);
	QIXIS_WRITE(brdcfg[9], brdcfg9);
}

static void ls2080a_qds_mux_mdio(u8 muxval)
{
	u8 brdcfg4;

	if (muxval <= 5) {
		brdcfg4 = QIXIS_READ(brdcfg[4]);
		brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
		brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
		QIXIS_WRITE(brdcfg[4], brdcfg4);
	}
}

static int ls2080a_qds_mdio_read(struct mii_dev *bus, int addr,
				 int devad, int regnum)
{
	struct ls2080a_qds_mdio *priv = bus->priv;

	ls2080a_qds_mux_mdio(priv->muxval);

	return priv->realbus->read(priv->realbus, addr, devad, regnum);
}

static int ls2080a_qds_mdio_write(struct mii_dev *bus, int addr, int devad,
				  int regnum, u16 value)
{
	struct ls2080a_qds_mdio *priv = bus->priv;

	ls2080a_qds_mux_mdio(priv->muxval);

	return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
}

static int ls2080a_qds_mdio_reset(struct mii_dev *bus)
{
	struct ls2080a_qds_mdio *priv = bus->priv;

	return priv->realbus->reset(priv->realbus);
}

static int ls2080a_qds_mdio_init(char *realbusname, u8 muxval)
{
	struct ls2080a_qds_mdio *pmdio;
	struct mii_dev *bus = mdio_alloc();

	if (!bus) {
		printf("Failed to allocate ls2080a_qds MDIO bus\n");
		return -1;
	}

	pmdio = malloc(sizeof(*pmdio));
	if (!pmdio) {
		printf("Failed to allocate ls2080a_qds private data\n");
		free(bus);
		return -1;
	}

	bus->read = ls2080a_qds_mdio_read;
	bus->write = ls2080a_qds_mdio_write;
	bus->reset = ls2080a_qds_mdio_reset;
	strcpy(bus->name, ls2080a_qds_mdio_name_for_muxval(muxval));

	pmdio->realbus = miiphy_get_dev_by_name(realbusname);

	if (!pmdio->realbus) {
		printf("No bus with name %s\n", realbusname);
		free(bus);
		free(pmdio);
		return -1;
	}

	pmdio->muxval = muxval;
	bus->priv = pmdio;

	return mdio_register(bus);
}

/*
 * Initialize the dpmac_info array.
 *
 */
static void initialize_dpmac_to_slot(void)
{
	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
	int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
				FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
		>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;

	char *env_hwconfig;
	env_hwconfig = getenv("hwconfig");

	switch (serdes1_prtcl) {
	case 0x07:
	case 0x09:
	case 0x33:
		printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
		       serdes1_prtcl);
		lane_to_slot_fsm1[0] = EMI1_SLOT1;
		lane_to_slot_fsm1[1] = EMI1_SLOT1;
		lane_to_slot_fsm1[2] = EMI1_SLOT1;
		lane_to_slot_fsm1[3] = EMI1_SLOT1;
		if (hwconfig_f("xqsgmii", env_hwconfig)) {
			lane_to_slot_fsm1[4] = EMI1_SLOT1;
			lane_to_slot_fsm1[5] = EMI1_SLOT1;
			lane_to_slot_fsm1[6] = EMI1_SLOT1;
			lane_to_slot_fsm1[7] = EMI1_SLOT1;
		} else {
			lane_to_slot_fsm1[4] = EMI1_SLOT2;
			lane_to_slot_fsm1[5] = EMI1_SLOT2;
			lane_to_slot_fsm1[6] = EMI1_SLOT2;
			lane_to_slot_fsm1[7] = EMI1_SLOT2;
		}
		break;

	case 0x39:
		printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
		       serdes1_prtcl);
		if (hwconfig_f("xqsgmii", env_hwconfig)) {
			lane_to_slot_fsm1[0] = EMI1_SLOT3;
			lane_to_slot_fsm1[1] = EMI1_SLOT3;
			lane_to_slot_fsm1[2] = EMI1_SLOT3;
			lane_to_slot_fsm1[3] = EMI_NONE;
		} else {
			lane_to_slot_fsm1[0] = EMI_NONE;
			lane_to_slot_fsm1[1] = EMI_NONE;
			lane_to_slot_fsm1[2] = EMI_NONE;
			lane_to_slot_fsm1[3] = EMI_NONE;
		}
		lane_to_slot_fsm1[4] = EMI1_SLOT3;
		lane_to_slot_fsm1[5] = EMI1_SLOT3;
		lane_to_slot_fsm1[6] = EMI1_SLOT3;
		lane_to_slot_fsm1[7] = EMI_NONE;
		break;

	case 0x4D:
		printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
		       serdes1_prtcl);
		if (hwconfig_f("xqsgmii", env_hwconfig)) {
			lane_to_slot_fsm1[0] = EMI1_SLOT3;
			lane_to_slot_fsm1[1] = EMI1_SLOT3;
			lane_to_slot_fsm1[2] = EMI_NONE;
			lane_to_slot_fsm1[3] = EMI_NONE;
		} else {
			lane_to_slot_fsm1[0] = EMI_NONE;
			lane_to_slot_fsm1[1] = EMI_NONE;
			lane_to_slot_fsm1[2] = EMI_NONE;
			lane_to_slot_fsm1[3] = EMI_NONE;
		}
		lane_to_slot_fsm1[4] = EMI1_SLOT3;
		lane_to_slot_fsm1[5] = EMI1_SLOT3;
		lane_to_slot_fsm1[6] = EMI_NONE;
		lane_to_slot_fsm1[7] = EMI_NONE;
		break;

	case 0x2A:
	case 0x4B:
	case 0x4C:
		printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
		       serdes1_prtcl);
		break;
	default:
		printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
		       __func__, serdes1_prtcl);
		break;
	}

	switch (serdes2_prtcl) {
	case 0x07:
	case 0x08:
	case 0x09:
	case 0x49:
		printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
		       serdes2_prtcl);
		lane_to_slot_fsm2[0] = EMI1_SLOT4;
		lane_to_slot_fsm2[1] = EMI1_SLOT4;
		lane_to_slot_fsm2[2] = EMI1_SLOT4;
		lane_to_slot_fsm2[3] = EMI1_SLOT4;

		if (hwconfig_f("xqsgmii", env_hwconfig)) {
			lane_to_slot_fsm2[4] = EMI1_SLOT4;
			lane_to_slot_fsm2[5] = EMI1_SLOT4;
			lane_to_slot_fsm2[6] = EMI1_SLOT4;
			lane_to_slot_fsm2[7] = EMI1_SLOT4;
		} else {
			/* No MDIO physical connection */
			lane_to_slot_fsm2[4] = EMI1_SLOT6;
			lane_to_slot_fsm2[5] = EMI1_SLOT6;
			lane_to_slot_fsm2[6] = EMI1_SLOT6;
			lane_to_slot_fsm2[7] = EMI1_SLOT6;
		}
		break;

	case 0x47:
		printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
		       serdes2_prtcl);
		lane_to_slot_fsm2[0] = EMI_NONE;
		lane_to_slot_fsm2[1] = EMI1_SLOT5;
		lane_to_slot_fsm2[2] = EMI1_SLOT5;
		lane_to_slot_fsm2[3] = EMI1_SLOT5;

		if (hwconfig_f("xqsgmii", env_hwconfig)) {
			lane_to_slot_fsm2[4] = EMI_NONE;
			lane_to_slot_fsm2[5] = EMI1_SLOT5;
			lane_to_slot_fsm2[6] = EMI1_SLOT5;
			lane_to_slot_fsm2[7] = EMI1_SLOT5;
		}
		break;

	case 0x57:
		printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
		       serdes2_prtcl);
		if (hwconfig_f("xqsgmii", env_hwconfig)) {
			lane_to_slot_fsm2[0] = EMI_NONE;
			lane_to_slot_fsm2[1] = EMI_NONE;
			lane_to_slot_fsm2[2] = EMI_NONE;
			lane_to_slot_fsm2[3] = EMI_NONE;
		}
		lane_to_slot_fsm2[4] = EMI_NONE;
		lane_to_slot_fsm2[5] = EMI_NONE;
		lane_to_slot_fsm2[6] = EMI1_SLOT5;
		lane_to_slot_fsm2[7] = EMI1_SLOT5;
		break;

	default:
		printf(" %s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
		       __func__ , serdes2_prtcl);
		break;
	}
}

void ls2080a_handle_phy_interface_sgmii(int dpmac_id)
{
	int lane, slot;
	struct mii_dev *bus;
	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
	int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
				FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
		>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;

	int *riser_phy_addr;
	char *env_hwconfig = getenv("hwconfig");

	if (hwconfig_f("xqsgmii", env_hwconfig))
		riser_phy_addr = &xqsgii_riser_phy_addr[0];
	else
		riser_phy_addr = &sgmii_riser_phy_addr[0];

	if (dpmac_id > WRIOP1_DPMAC9)
		goto serdes2;

	switch (serdes1_prtcl) {
	case 0x07:
	case 0x39:
	case 0x4D:
		lane = serdes_get_first_lane(FSL_SRDS_1, SGMII1 + dpmac_id - 1);

		slot = lane_to_slot_fsm1[lane];

		switch (++slot) {
		case 1:
			/* Slot housing a SGMII riser card? */
			wriop_set_phy_address(dpmac_id,
					      riser_phy_addr[dpmac_id - 1]);
			dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
			bus = mii_dev_for_muxval(EMI1_SLOT1);
			wriop_set_mdio(dpmac_id, bus);
			break;
		case 2:
			/* Slot housing a SGMII riser card? */
			wriop_set_phy_address(dpmac_id,
					      riser_phy_addr[dpmac_id - 1]);
			dpmac_info[dpmac_id].board_mux = EMI1_SLOT2;
			bus = mii_dev_for_muxval(EMI1_SLOT2);
			wriop_set_mdio(dpmac_id, bus);
			break;
		case 3:
			if (slot == EMI_NONE)
				return;
			if (serdes1_prtcl == 0x39) {
				wriop_set_phy_address(dpmac_id,
					riser_phy_addr[dpmac_id - 2]);
				if (dpmac_id >= 6 && hwconfig_f("xqsgmii",
								env_hwconfig))
					wriop_set_phy_address(dpmac_id,
						riser_phy_addr[dpmac_id - 3]);
			} else {
				wriop_set_phy_address(dpmac_id,
					riser_phy_addr[dpmac_id - 2]);
				if (dpmac_id >= 7 && hwconfig_f("xqsgmii",
								env_hwconfig))
					wriop_set_phy_address(dpmac_id,
						riser_phy_addr[dpmac_id - 3]);
			}
			dpmac_info[dpmac_id].board_mux = EMI1_SLOT3;
			bus = mii_dev_for_muxval(EMI1_SLOT3);
			wriop_set_mdio(dpmac_id, bus);
			break;
		case 4:
			break;
		case 5:
			break;
		case 6:
			break;
		}
	break;
	default:
		printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
		       __func__ , serdes1_prtcl);
	break;
	}

serdes2:
	switch (serdes2_prtcl) {
	case 0x07:
	case 0x08:
	case 0x49:
	case 0x47:
	case 0x57:
		lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 +
							(dpmac_id - 9));
		slot = lane_to_slot_fsm2[lane];

		switch (++slot) {
		case 1:
			break;
		case 3:
			break;
		case 4:
			/* Slot housing a SGMII riser card? */
			wriop_set_phy_address(dpmac_id,
					      riser_phy_addr[dpmac_id - 9]);
			dpmac_info[dpmac_id].board_mux = EMI1_SLOT4;
			bus = mii_dev_for_muxval(EMI1_SLOT4);
			wriop_set_mdio(dpmac_id, bus);
		break;
		case 5:
			if (slot == EMI_NONE)
				return;
			if (serdes2_prtcl == 0x47) {
				wriop_set_phy_address(dpmac_id,
					      riser_phy_addr[dpmac_id - 10]);
				if (dpmac_id >= 14 && hwconfig_f("xqsgmii",
								 env_hwconfig))
					wriop_set_phy_address(dpmac_id,
						riser_phy_addr[dpmac_id - 11]);
			} else {
				wriop_set_phy_address(dpmac_id,
					riser_phy_addr[dpmac_id - 11]);
			}
			dpmac_info[dpmac_id].board_mux = EMI1_SLOT5;
			bus = mii_dev_for_muxval(EMI1_SLOT5);
			wriop_set_mdio(dpmac_id, bus);
			break;
		case 6:
			/* Slot housing a SGMII riser card? */
			wriop_set_phy_address(dpmac_id,
					      riser_phy_addr[dpmac_id - 13]);
			dpmac_info[dpmac_id].board_mux = EMI1_SLOT6;
			bus = mii_dev_for_muxval(EMI1_SLOT6);
			wriop_set_mdio(dpmac_id, bus);
		break;
	}
	break;
	default:
		printf("%s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
		       __func__, serdes2_prtcl);
	break;
	}
}

void ls2080a_handle_phy_interface_qsgmii(int dpmac_id)
{
	int lane = 0, slot;
	struct mii_dev *bus;
	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;

	switch (serdes1_prtcl) {
	case 0x33:
		switch (dpmac_id) {
		case 1:
		case 2:
		case 3:
		case 4:
			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_A);
		break;
		case 5:
		case 6:
		case 7:
		case 8:
			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_B);
		break;
		case 9:
		case 10:
		case 11:
		case 12:
			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_C);
		break;
		case 13:
		case 14:
		case 15:
		case 16:
			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_D);
		break;
	}

		slot = lane_to_slot_fsm1[lane];

		switch (++slot) {
		case 1:
			/* Slot housing a QSGMII riser card? */
			wriop_set_phy_address(dpmac_id, dpmac_id - 1);
			dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
			bus = mii_dev_for_muxval(EMI1_SLOT1);
			wriop_set_mdio(dpmac_id, bus);
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:
		break;
		case 6:
			break;
	}
	break;
	default:
		printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
		       serdes1_prtcl);
	break;
	}

	qsgmii_configure_repeater(dpmac_id);
}

void ls2080a_handle_phy_interface_xsgmii(int i)
{
	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;

	switch (serdes1_prtcl) {
	case 0x2A:
	case 0x4B:
	case 0x4C:
		/*
		 * XFI does not need a PHY to work, but to avoid U-Boot use
		 * default PHY address which is zero to a MAC when it found
		 * a MAC has no PHY address, we give a PHY address to XFI
		 * MAC, and should not use a real XAUI PHY address, since
		 * MDIO can access it successfully, and then MDIO thinks
		 * the XAUI card is used for the XFI MAC, which will cause
		 * error.
		 */
		wriop_set_phy_address(i, i + 4);
		ls2080a_qds_enable_SFP_TX(SFP_TX);

		break;
	default:
		printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
		       serdes1_prtcl);
		break;
	}
}
#endif

int board_eth_init(bd_t *bis)
{
	int error;
#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
	int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
				FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
		>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;

	struct memac_mdio_info *memac_mdio0_info;
	struct memac_mdio_info *memac_mdio1_info;
	unsigned int i;
	char *env_hwconfig;

	env_hwconfig = getenv("hwconfig");

	initialize_dpmac_to_slot();

	memac_mdio0_info = (struct memac_mdio_info *)malloc(
					sizeof(struct memac_mdio_info));
	memac_mdio0_info->regs =
		(struct memac_mdio_controller *)
					CONFIG_SYS_FSL_WRIOP1_MDIO1;
	memac_mdio0_info->name = DEFAULT_WRIOP_MDIO1_NAME;

	/* Register the real MDIO1 bus */
	fm_memac_mdio_init(bis, memac_mdio0_info);

	memac_mdio1_info = (struct memac_mdio_info *)malloc(
					sizeof(struct memac_mdio_info));
	memac_mdio1_info->regs =
		(struct memac_mdio_controller *)
					CONFIG_SYS_FSL_WRIOP1_MDIO2;
	memac_mdio1_info->name = DEFAULT_WRIOP_MDIO2_NAME;

	/* Register the real MDIO2 bus */
	fm_memac_mdio_init(bis, memac_mdio1_info);

	/* Register the muxing front-ends to the MDIO buses */
	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT1);
	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT2);
	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT3);
	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT4);
	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT5);
	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT6);

	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO2_NAME, EMI2);

	for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
		switch (wriop_get_enet_if(i)) {
		case PHY_INTERFACE_MODE_QSGMII:
			ls2080a_handle_phy_interface_qsgmii(i);
			break;
		case PHY_INTERFACE_MODE_SGMII:
			ls2080a_handle_phy_interface_sgmii(i);
			break;
		case PHY_INTERFACE_MODE_XGMII:
			ls2080a_handle_phy_interface_xsgmii(i);
			break;
		default:
			break;

		if (i == 16)
			i = NUM_WRIOP_PORTS;
		}
	}

	error = cpu_eth_init(bis);

	if (hwconfig_f("xqsgmii", env_hwconfig)) {
		if (serdes1_prtcl == 0x7)
			sgmii_configure_repeater(1);
		if (serdes2_prtcl == 0x7 || serdes2_prtcl == 0x8 ||
		    serdes2_prtcl == 0x49)
			sgmii_configure_repeater(2);
	}
#endif
	error = pci_eth_init(bis);
	return error;
}

#if defined(CONFIG_RESET_PHY_R)
void reset_phy(void)
{
	mc_env_boot();
}
#endif /* CONFIG_RESET_PHY_R */
