// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2013 Freescale Semiconductor, Inc.
 * Copyright 2020 NXP
 *
 * Shengzhou Liu <Shengzhou.Liu@freescale.com>
 */

#include <common.h>
#include <command.h>
#include <fdt_support.h>
#include <log.h>
#include <net.h>
#include <netdev.h>
#include <asm/mmu.h>
#include <asm/processor.h>
#include <asm/immap_85xx.h>
#include <asm/fsl_law.h>
#include <asm/fsl_serdes.h>
#include <asm/fsl_portals.h>
#include <asm/fsl_liodn.h>
#include <malloc.h>
#include <fm_eth.h>
#include <fsl_mdio.h>
#include <miiphy.h>
#include <phy.h>
#include <fsl_dtsec.h>
#include <asm/fsl_serdes.h>
#include <hwconfig.h>
#include "../common/qixis.h"
#include "../common/fman.h"
#include "t208xqds_qixis.h"
#include <linux/libfdt.h>

#define EMI_NONE	0xFFFFFFFF
#define EMI1_RGMII1	0
#define EMI1_RGMII2     1
#define EMI1_SLOT1	2
#if defined(CONFIG_TARGET_T2080QDS)
#define EMI1_SLOT2	6
#define EMI1_SLOT3	3
#define EMI1_SLOT4	4
#define EMI1_SLOT5	5
#define EMI2            7
#endif

#define PCCR1_SGMIIA_KX_MASK		0x00008000
#define PCCR1_SGMIIB_KX_MASK		0x00004000
#define PCCR1_SGMIIC_KX_MASK		0x00002000
#define PCCR1_SGMIID_KX_MASK		0x00001000
#define PCCR1_SGMIIE_KX_MASK		0x00000800
#define PCCR1_SGMIIF_KX_MASK		0x00000400
#define PCCR1_SGMIIG_KX_MASK		0x00000200
#define PCCR1_SGMIIH_KX_MASK		0x00000100

static int mdio_mux[NUM_FM_PORTS];

static const char * const mdio_names[] = {
#if defined(CONFIG_TARGET_T2080QDS)
	"T2080QDS_MDIO_RGMII1",
	"T2080QDS_MDIO_RGMII2",
	"T2080QDS_MDIO_SLOT1",
	"T2080QDS_MDIO_SLOT3",
	"T2080QDS_MDIO_SLOT4",
	"T2080QDS_MDIO_SLOT5",
	"T2080QDS_MDIO_SLOT2",
	"T2080QDS_MDIO_10GC",
#endif
};

/* Map SerDes1 8 lanes to default slot, will be initialized dynamically */
#if defined(CONFIG_TARGET_T2080QDS)
static u8 lane_to_slot[] = {3, 3, 3, 3, 1, 1, 1, 1};
#endif

static const char *t208xqds_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 = t208xqds_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;
}

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

static void t208xqds_mux_mdio(u8 muxval)
{
	u8 brdcfg4;
	if (muxval < 8) {
		brdcfg4 = QIXIS_READ(brdcfg[4]);
		brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
		brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
		QIXIS_WRITE(brdcfg[4], brdcfg4);
	}
}

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

	t208xqds_mux_mdio(priv->muxval);

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

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

	t208xqds_mux_mdio(priv->muxval);

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

static int t208xqds_mdio_reset(struct mii_dev *bus)
{
	struct t208xqds_mdio *priv = bus->priv;

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

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

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

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

	bus->read = t208xqds_mdio_read;
	bus->write = t208xqds_mdio_write;
	bus->reset = t208xqds_mdio_reset;
	strcpy(bus->name, t208xqds_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);
}

void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
				enum fm_port port, int offset)
{
	int phy;
	char alias[20];
	char lane_mode[2][20] = {"1000BASE-KX", "10GBASE-KR"};
	char buf[32] = "serdes-1,";
	struct fixed_link f_link;
	int media_type = 0;
	const char *phyconn;
	int off;

	ccsr_gur_t *gur = (void *)(CFG_SYS_MPC85xx_GUTS_ADDR);
#ifdef CONFIG_TARGET_T2080QDS
	serdes_corenet_t *srds_regs =
		(void *)CFG_SYS_FSL_CORENET_SERDES_ADDR;
	u32 srds1_pccr1 = in_be32(&srds_regs->srdspccr1);
#endif
	u32 srds_s1 = in_be32(&gur->rcwsr[4]) &
				FSL_CORENET2_RCWSR4_SRDS1_PRTCL;

	srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;

	if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) {
		phy = fm_info_get_phy_address(port);
		switch (port) {
#if defined(CONFIG_TARGET_T2080QDS)
		case FM1_DTSEC1:
			if (hwconfig_sub("fsl_1gkx", "fm1_1g1")) {
				media_type = 1;
				fdt_set_phy_handle(fdt, compat, addr,
						   "phy_1gkx1");
				fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio1");
				sprintf(buf, "%s%s%s", buf, "lane-c,",
						(char *)lane_mode[0]);
				out_be32(&srds_regs->srdspccr1, srds1_pccr1 |
					 PCCR1_SGMIIH_KX_MASK);
				break;
			}
		case FM1_DTSEC2:
			if (hwconfig_sub("fsl_1gkx", "fm1_1g2")) {
				media_type = 1;
				fdt_set_phy_handle(fdt, compat, addr,
						   "phy_1gkx2");
				fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio2");
				sprintf(buf, "%s%s%s", buf, "lane-d,",
						(char *)lane_mode[0]);
				out_be32(&srds_regs->srdspccr1, srds1_pccr1 |
					 PCCR1_SGMIIG_KX_MASK);
				break;
			}
		case FM1_DTSEC9:
			if (hwconfig_sub("fsl_1gkx", "fm1_1g9")) {
				media_type = 1;
				fdt_set_phy_handle(fdt, compat, addr,
						   "phy_1gkx9");
				fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio9");
				sprintf(buf, "%s%s%s", buf, "lane-a,",
						(char *)lane_mode[0]);
				out_be32(&srds_regs->srdspccr1, srds1_pccr1 |
					 PCCR1_SGMIIE_KX_MASK);
				break;
			}
		case FM1_DTSEC10:
			if (hwconfig_sub("fsl_1gkx", "fm1_1g10")) {
				media_type = 1;
				fdt_set_phy_handle(fdt, compat, addr,
						   "phy_1gkx10");
				fdt_status_okay_by_alias(fdt,
							 "1gkx_pcs_mdio10");
				sprintf(buf, "%s%s%s", buf, "lane-b,",
						(char *)lane_mode[0]);
				out_be32(&srds_regs->srdspccr1, srds1_pccr1 |
					 PCCR1_SGMIIF_KX_MASK);
				break;
			}
			if (mdio_mux[port] == EMI1_SLOT2) {
				sprintf(alias, "phy_sgmii_s2_%x", phy);
				fdt_set_phy_handle(fdt, compat, addr, alias);
				fdt_status_okay_by_alias(fdt, "emi1_slot2");
			} else if (mdio_mux[port] == EMI1_SLOT3) {
				sprintf(alias, "phy_sgmii_s3_%x", phy);
				fdt_set_phy_handle(fdt, compat, addr, alias);
				fdt_status_okay_by_alias(fdt, "emi1_slot3");
			}
			break;
		case FM1_DTSEC5:
			if (hwconfig_sub("fsl_1gkx", "fm1_1g5")) {
				media_type = 1;
				fdt_set_phy_handle(fdt, compat, addr,
						   "phy_1gkx5");
				fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio5");
				sprintf(buf, "%s%s%s", buf, "lane-g,",
						(char *)lane_mode[0]);
				out_be32(&srds_regs->srdspccr1, srds1_pccr1 |
					 PCCR1_SGMIIC_KX_MASK);
				break;
			}
		case FM1_DTSEC6:
			if (hwconfig_sub("fsl_1gkx", "fm1_1g6")) {
				media_type = 1;
				fdt_set_phy_handle(fdt, compat, addr,
						   "phy_1gkx6");
				fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio6");
				sprintf(buf, "%s%s%s", buf, "lane-h,",
						(char *)lane_mode[0]);
				out_be32(&srds_regs->srdspccr1, srds1_pccr1 |
					 PCCR1_SGMIID_KX_MASK);
				break;
			}
			if (mdio_mux[port] == EMI1_SLOT1) {
				sprintf(alias, "phy_sgmii_s1_%x", phy);
				fdt_set_phy_handle(fdt, compat, addr, alias);
				fdt_status_okay_by_alias(fdt, "emi1_slot1");
			} else if (mdio_mux[port] == EMI1_SLOT2) {
				sprintf(alias, "phy_sgmii_s2_%x", phy);
				fdt_set_phy_handle(fdt, compat, addr, alias);
				fdt_status_okay_by_alias(fdt, "emi1_slot2");
			}
			break;
#endif
		default:
			break;
		}
		if (media_type) {
			/* set property for 1000BASE-KX in dtb */
			off = fdt_node_offset_by_compat_reg(fdt,
					"fsl,fman-memac-mdio", addr + 0x1000);
			fdt_setprop_string(fdt, off, "lane-instance", buf);
		}

	} else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII) {
		switch (srds_s1) {
		case 0x66: /* 10GBase-R interface */
		case 0x6b:
		case 0x6c:
		case 0x6d:
		case 0x71:
			/*
			 * Check hwconfig to see what is the media type, there
			 * are two types, fiber or copper, fix the dtb
			 * accordingly.
			 */
			switch (port) {
			case FM1_10GEC1:
			if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g1")) {
				/* it's MAC9 */
				media_type = 1;
				fdt_set_phy_handle(fdt, compat, addr,
						"phy_xfi9");
				fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio9");
				sprintf(buf, "%s%s%s", buf, "lane-a,",
						(char *)lane_mode[1]);
			}
				break;
			case FM1_10GEC2:
			if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g2")) {
				/* it's MAC10 */
				media_type = 1;
				fdt_set_phy_handle(fdt, compat, addr,
						"phy_xfi10");
				fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio10");
				sprintf(buf, "%s%s%s", buf, "lane-b,",
						(char *)lane_mode[1]);
			}
				break;
			case FM1_10GEC3:
			if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g3")) {
				/* it's MAC1 */
				media_type = 1;
				fdt_set_phy_handle(fdt, compat, addr,
						"phy_xfi1");
				fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio1");
				sprintf(buf, "%s%s%s", buf, "lane-c,",
						(char *)lane_mode[1]);
			}
				break;
			case FM1_10GEC4:
			if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g4")) {
				/* it's MAC2 */
				media_type = 1;
				fdt_set_phy_handle(fdt, compat, addr,
						"phy_xfi2");
				fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio2");
				sprintf(buf, "%s%s%s", buf, "lane-d,",
						(char *)lane_mode[1]);
			}
				break;
			default:
				return;
			}

			if (!media_type) {
				phyconn = fdt_getprop(fdt, offset,
						      "phy-connection-type",
						      NULL);
				if (is_backplane_mode(phyconn)) {
					/* Backplane KR mode: skip fixups */
					printf("Interface %d in backplane KR mode\n",
					       port);
				} else {
					/* fixed-link for 10GBase-R fiber cable */
					f_link.phy_id = port;
					f_link.duplex = 1;
					f_link.link_speed = 10000;
					f_link.pause = 0;
					f_link.asym_pause = 0;
					fdt_delprop(fdt, offset, "phy-handle");
					fdt_setprop(fdt, offset, "fixed-link",
						    &f_link, sizeof(f_link));
				}
			} else {
				/* set property for copper cable */
				off = fdt_node_offset_by_compat_reg(fdt,
					"fsl,fman-memac-mdio", addr + 0x1000);
				fdt_setprop_string(fdt, off,
					"lane-instance", buf);
			}
			break;
		default:
			break;
		}
	}
}

void fdt_fixup_board_enet(void *fdt)
{
	return;
}

/*
 * This function reads RCW to check if Serdes1{A:H} is configured
 * to slot 1/2/3/4/5/6/7 and update the lane_to_slot[] array accordingly
 */
static void initialize_lane_to_slot(void)
{
	ccsr_gur_t *gur = (void *)(CFG_SYS_MPC85xx_GUTS_ADDR);
	u32 srds_s1 = in_be32(&gur->rcwsr[4]) &
				FSL_CORENET2_RCWSR4_SRDS1_PRTCL;

	srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;

	switch (srds_s1) {
#if defined(CONFIG_TARGET_T2080QDS)
	case 0x51:
	case 0x5f:
	case 0x65:
	case 0x6b:
	case 0x71:
		lane_to_slot[5] = 2;
		lane_to_slot[6] = 2;
		lane_to_slot[7] = 2;
		break;
	case 0xa6:
	case 0x8e:
	case 0x8f:
	case 0x82:
	case 0x83:
	case 0xd3:
	case 0xd9:
	case 0xcb:
		lane_to_slot[6] = 2;
		lane_to_slot[7] = 2;
		break;
	case 0xda:
		lane_to_slot[4] = 3;
		lane_to_slot[5] = 3;
		lane_to_slot[6] = 3;
		lane_to_slot[7] = 3;
		break;
#endif
	default:
		break;
	}
}

int board_eth_init(struct bd_info *bis)
{
#if defined(CONFIG_FMAN_ENET)
	int i, idx, lane, slot, interface;
	struct memac_mdio_info dtsec_mdio_info;
	struct memac_mdio_info tgec_mdio_info;
	ccsr_gur_t *gur = (void *)(CFG_SYS_MPC85xx_GUTS_ADDR);
	u32 rcwsr13 = in_be32(&gur->rcwsr[13]);
	u32 srds_s1;

	srds_s1 = in_be32(&gur->rcwsr[4]) &
					FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
	srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;

	initialize_lane_to_slot();

	/* Initialize the mdio_mux array so we can recognize empty elements */
	for (i = 0; i < NUM_FM_PORTS; i++)
		mdio_mux[i] = EMI_NONE;

	dtsec_mdio_info.regs =
		(struct memac_mdio_controller *)CFG_SYS_FM1_DTSEC_MDIO_ADDR;

	dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;

	/* Register the 1G MDIO bus */
	fm_memac_mdio_init(bis, &dtsec_mdio_info);

	tgec_mdio_info.regs =
		(struct memac_mdio_controller *)CFG_SYS_FM1_TGEC_MDIO_ADDR;
	tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;

	/* Register the 10G MDIO bus */
	fm_memac_mdio_init(bis, &tgec_mdio_info);

	/* Register the muxing front-ends to the MDIO buses */
	t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1);
	t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII2);
	t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1);
	t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT2);
	t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
#if defined(CONFIG_TARGET_T2080QDS)
	t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4);
#endif
	t208xqds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5);
	t208xqds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2);

	/* Set the two on-board RGMII PHY address */
	fm_info_set_phy_address(FM1_DTSEC3, RGMII_PHY1_ADDR);
	if ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) ==
			FSL_CORENET_RCWSR13_EC2_DTSEC4_RGMII)
		fm_info_set_phy_address(FM1_DTSEC4, RGMII_PHY2_ADDR);
	else
		fm_info_set_phy_address(FM1_DTSEC10, RGMII_PHY2_ADDR);

	switch (srds_s1) {
	case 0x1b:
	case 0x1c:
	case 0x95:
	case 0xa2:
	case 0x94:
		/* T2080QDS: SGMII in Slot3;  T2081QDS: SGMII in Slot2 */
		fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
		/* T2080QDS: SGMII in Slot2;  T2081QDS: SGMII in Slot1 */
		fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT4_PHY_ADDR);
		break;
	case 0x50:
	case 0x51:
	case 0x5e:
	case 0x5f:
	case 0x64:
	case 0x65:
		/* T2080QDS: XAUI/HiGig in Slot3;  T2081QDS: in Slot2 */
		fm_info_set_phy_address(FM1_10GEC1, FM1_10GEC1_PHY_ADDR);
		/* T2080QDS: SGMII in Slot2;  T2081QDS: in Slot3 */
		fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT4_PHY_ADDR);
		break;
	case 0x66:
	case 0x67:
		/*
		 * 10GBase-R 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 10GBase-R
		 * 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 10GBase-R MAC, which will cause
		 * error.
		 */
		fm_info_set_phy_address(FM1_10GEC1, 4);
		fm_info_set_phy_address(FM1_10GEC2, 5);
		fm_info_set_phy_address(FM1_10GEC3, 6);
		fm_info_set_phy_address(FM1_10GEC4, 7);
		break;
	case 0x6a:
	case 0x6b:
		fm_info_set_phy_address(FM1_10GEC1, 4);
		fm_info_set_phy_address(FM1_10GEC2, 5);
		fm_info_set_phy_address(FM1_10GEC3, 6);
		fm_info_set_phy_address(FM1_10GEC4, 7);
		/* T2080QDS: SGMII in Slot2;  T2081QDS: in Slot3 */
		fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR);
		break;
	case 0x6c:
	case 0x6d:
		fm_info_set_phy_address(FM1_10GEC1, 4);
		fm_info_set_phy_address(FM1_10GEC2, 5);
		/* T2080QDS: SGMII in Slot3;  T2081QDS: in Slot2 */
		fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
		break;
	case 0x70:
	case 0x71:
		/* SGMII in Slot3 */
		fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
		/* SGMII in Slot2 */
		fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR);
		break;
	case 0xa6:
	case 0x8e:
	case 0x8f:
	case 0x82:
	case 0x83:
		/* SGMII in Slot3 */
		fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
		/* SGMII in Slot2 */
		fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR);
		break;
	case 0xa4:
	case 0x96:
	case 0x8a:
		/* SGMII in Slot3 */
		fm_info_set_phy_address(FM1_DTSEC9, SGMII_CARD_PORT1_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
		break;
#if defined(CONFIG_TARGET_T2080QDS)
	case 0xd9:
	case 0xd3:
	case 0xcb:
		/* SGMII in Slot3 */
		fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT2_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT3_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR);
		/* SGMII in Slot2 */
		fm_info_set_phy_address(FM1_DTSEC5, SGMII_CARD_PORT3_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT2_PHY_ADDR);
		break;
#endif
	case 0xf2:
		/* T2080QDS: SGMII in Slot3; T2081QDS: SGMII in Slot7 */
		fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT2_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC10, SGMII_CARD_PORT3_PHY_ADDR);
		fm_info_set_phy_address(FM1_DTSEC6, SGMII_CARD_PORT4_PHY_ADDR);
		break;
	default:
		break;
	}

	for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CFG_SYS_NUM_FM1_DTSEC; i++) {
		idx = i - FM1_DTSEC1;
		interface = fm_info_get_enet_if(i);
		switch (interface) {
		case PHY_INTERFACE_MODE_SGMII:
			lane = serdes_get_first_lane(FSL_SRDS_1,
					SGMII_FM1_DTSEC1 + idx);
			if (lane < 0)
				break;
			slot = lane_to_slot[lane];
			debug("FM1@DTSEC%u expects SGMII in slot %u\n",
			      idx + 1, slot);
			if (QIXIS_READ(present2) & (1 << (slot - 1)))
				fm_disable_port(i);

			switch (slot) {
			case 1:
				mdio_mux[i] = EMI1_SLOT1;
				fm_info_set_mdio(i, mii_dev_for_muxval(
						 mdio_mux[i]));
				break;
			case 2:
				mdio_mux[i] = EMI1_SLOT2;
				fm_info_set_mdio(i, mii_dev_for_muxval(
						 mdio_mux[i]));
				break;
			case 3:
				mdio_mux[i] = EMI1_SLOT3;
				fm_info_set_mdio(i, mii_dev_for_muxval(
						 mdio_mux[i]));
				break;
			}
			break;
		case PHY_INTERFACE_MODE_RGMII:
		case PHY_INTERFACE_MODE_RGMII_TXID:
		case PHY_INTERFACE_MODE_RGMII_RXID:
		case PHY_INTERFACE_MODE_RGMII_ID:
			if (i == FM1_DTSEC3)
				mdio_mux[i] = EMI1_RGMII1;
			else if (i == FM1_DTSEC4 || FM1_DTSEC10)
				mdio_mux[i] = EMI1_RGMII2;
			fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
			break;
		default:
			break;
		}
	}

	for (i = FM1_10GEC1; i < FM1_10GEC1 + CFG_SYS_NUM_FM1_10GEC; i++) {
		idx = i - FM1_10GEC1;
		switch (fm_info_get_enet_if(i)) {
		case PHY_INTERFACE_MODE_XGMII:
			if (srds_s1 == 0x51) {
				lane = serdes_get_first_lane(FSL_SRDS_1,
						XAUI_FM1_MAC9 + idx);
			} else if ((srds_s1 == 0x5f) || (srds_s1 == 0x65)) {
				lane = serdes_get_first_lane(FSL_SRDS_1,
						HIGIG_FM1_MAC9 + idx);
			} else {
				if (i == FM1_10GEC1 || i == FM1_10GEC2)
					lane = serdes_get_first_lane(FSL_SRDS_1,
						XFI_FM1_MAC9 + idx);
				else
					lane = serdes_get_first_lane(FSL_SRDS_1,
						XFI_FM1_MAC1 + idx);
			}

			if (lane < 0)
				break;
			mdio_mux[i] = EMI2;
			fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));

			if ((srds_s1 == 0x66) || (srds_s1 == 0x6b) ||
			    (srds_s1 == 0x6a) || (srds_s1 == 0x70) ||
			    (srds_s1 == 0x6c) || (srds_s1 == 0x6d) ||
			    (srds_s1 == 0x71)) {
				/* As 10GBase-R is in cage intead of a slot, so
				 * ensure doesn't disable the corresponding port
				 */
				break;
			}

			slot = lane_to_slot[lane];
			if (QIXIS_READ(present2) & (1 << (slot - 1)))
				fm_disable_port(i);
			break;
		default:
			break;
		}
	}

	cpu_eth_init(bis);
#endif /* CONFIG_FMAN_ENET */

	return pci_eth_init(bis);
}
