| /* | 
 |  * Copyright 2013 Freescale Semiconductor, Inc. | 
 |  * | 
 |  * SPDX-License-Identifier:	GPL-2.0+ | 
 |  */ | 
 |  | 
 | /* | 
 |  * The RGMII PHYs are provided by the two on-board PHY connected to | 
 |  * dTSEC instances 4 and 5. The SGMII PHYs are provided by one on-board | 
 |  * PHY or by the standard four-port SGMII riser card (VSC). | 
 |  */ | 
 |  | 
 | #include <common.h> | 
 | #include <netdev.h> | 
 | #include <asm/fsl_serdes.h> | 
 | #include <asm/immap_85xx.h> | 
 | #include <fm_eth.h> | 
 | #include <fsl_mdio.h> | 
 | #include <malloc.h> | 
 | #include <fsl_dtsec.h> | 
 | #include <vsc9953.h> | 
 |  | 
 | #include "../common/fman.h" | 
 | #include "../common/qixis.h" | 
 |  | 
 | #include "t1040qds_qixis.h" | 
 |  | 
 | #ifdef CONFIG_FMAN_ENET | 
 |  /* - In T1040 there are only 8 SERDES lanes, spread across 2 SERDES banks. | 
 |  *   Bank 1 -> Lanes A, B, C, D | 
 |  *   Bank 2 -> Lanes E, F, G, H | 
 |  */ | 
 |  | 
 |  /* Mapping of 8 SERDES lanes to T1040 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[] = { | 
 | 	0, 0, 0, 0, 0, 0, 0, 0 | 
 | }; | 
 |  | 
 | /* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs | 
 |  * housed. | 
 |  */ | 
 | static int riser_phy_addr[] = { | 
 | 	CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR, | 
 | 	CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR, | 
 | 	CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR, | 
 | 	CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR, | 
 | }; | 
 |  | 
 | /* Slot2 does not have EMI connections */ | 
 | #define EMI_NONE	0xFFFFFFFF | 
 | #define EMI1_RGMII0	0 | 
 | #define EMI1_RGMII1	1 | 
 | #define EMI1_SLOT1	2 | 
 | #define EMI1_SLOT3	3 | 
 | #define EMI1_SLOT4	4 | 
 | #define EMI1_SLOT5	5 | 
 | #define EMI1_SLOT6	6 | 
 | #define EMI1_SLOT7	7 | 
 | #define EMI2		8 | 
 |  | 
 | static int mdio_mux[NUM_FM_PORTS]; | 
 |  | 
 | static const char * const mdio_names[] = { | 
 | 	"T1040_QDS_MDIO0", | 
 | 	"T1040_QDS_MDIO1", | 
 | 	"T1040_QDS_MDIO2", | 
 | 	"T1040_QDS_MDIO3", | 
 | 	"T1040_QDS_MDIO4", | 
 | 	"T1040_QDS_MDIO5", | 
 | 	"T1040_QDS_MDIO6", | 
 | 	"T1040_QDS_MDIO7", | 
 | }; | 
 |  | 
 | struct t1040_qds_mdio { | 
 | 	u8 muxval; | 
 | 	struct mii_dev *realbus; | 
 | }; | 
 |  | 
 | static const char *t1040_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 = t1040_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 t1040_qds_mux_mdio(u8 muxval) | 
 | { | 
 | 	u8 brdcfg4; | 
 | 	if (muxval <= 7) { | 
 | 		brdcfg4 = QIXIS_READ(brdcfg[4]); | 
 | 		brdcfg4 &= ~BRDCFG4_EMISEL_MASK; | 
 | 		brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT); | 
 | 		QIXIS_WRITE(brdcfg[4], brdcfg4); | 
 | 	} | 
 | } | 
 |  | 
 | static int t1040_qds_mdio_read(struct mii_dev *bus, int addr, int devad, | 
 | 				int regnum) | 
 | { | 
 | 	struct t1040_qds_mdio *priv = bus->priv; | 
 |  | 
 | 	t1040_qds_mux_mdio(priv->muxval); | 
 |  | 
 | 	return priv->realbus->read(priv->realbus, addr, devad, regnum); | 
 | } | 
 |  | 
 | static int t1040_qds_mdio_write(struct mii_dev *bus, int addr, int devad, | 
 | 				int regnum, u16 value) | 
 | { | 
 | 	struct t1040_qds_mdio *priv = bus->priv; | 
 |  | 
 | 	t1040_qds_mux_mdio(priv->muxval); | 
 |  | 
 | 	return priv->realbus->write(priv->realbus, addr, devad, regnum, value); | 
 | } | 
 |  | 
 | static int t1040_qds_mdio_reset(struct mii_dev *bus) | 
 | { | 
 | 	struct t1040_qds_mdio *priv = bus->priv; | 
 |  | 
 | 	return priv->realbus->reset(priv->realbus); | 
 | } | 
 |  | 
 | static int t1040_qds_mdio_init(char *realbusname, u8 muxval) | 
 | { | 
 | 	struct t1040_qds_mdio *pmdio; | 
 | 	struct mii_dev *bus = mdio_alloc(); | 
 |  | 
 | 	if (!bus) { | 
 | 		printf("Failed to allocate t1040_qds MDIO bus\n"); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	pmdio = malloc(sizeof(*pmdio)); | 
 | 	if (!pmdio) { | 
 | 		printf("Failed to allocate t1040_qds private data\n"); | 
 | 		free(bus); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	bus->read = t1040_qds_mdio_read; | 
 | 	bus->write = t1040_qds_mdio_write; | 
 | 	bus->reset = t1040_qds_mdio_reset; | 
 | 	sprintf(bus->name, t1040_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 lane_to_slot[] array. | 
 |  * | 
 |  * On the T1040QDS board the mapping is controlled by ?? register. | 
 |  */ | 
 | static void initialize_lane_to_slot(void) | 
 | { | 
 | 	ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; | 
 | 	int serdes1_prtcl = (in_be32(&gur->rcwsr[4]) & | 
 | 				FSL_CORENET2_RCWSR4_SRDS1_PRTCL) | 
 | 		>> FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT; | 
 |  | 
 | 	QIXIS_WRITE(cms[0], 0x07); | 
 |  | 
 | 	switch (serdes1_prtcl) { | 
 | 	case 0x60: | 
 | 	case 0x66: | 
 | 	case 0x67: | 
 | 	case 0x69: | 
 | 		lane_to_slot[1] = 7; | 
 | 		lane_to_slot[2] = 6; | 
 | 		lane_to_slot[3] = 5; | 
 | 		break; | 
 | 	case 0x86: | 
 | 		lane_to_slot[1] = 7; | 
 | 		lane_to_slot[2] = 7; | 
 | 		lane_to_slot[3] = 7; | 
 | 		break; | 
 | 	case 0x87: | 
 | 		lane_to_slot[1] = 7; | 
 | 		lane_to_slot[2] = 7; | 
 | 		lane_to_slot[3] = 7; | 
 | 		lane_to_slot[7] = 7; | 
 | 		break; | 
 | 	case 0x89: | 
 | 		lane_to_slot[1] = 7; | 
 | 		lane_to_slot[2] = 7; | 
 | 		lane_to_slot[3] = 7; | 
 | 		lane_to_slot[6] = 7; | 
 | 		lane_to_slot[7] = 7; | 
 | 		break; | 
 | 	case 0x8d: | 
 | 		lane_to_slot[1] = 7; | 
 | 		lane_to_slot[2] = 7; | 
 | 		lane_to_slot[3] = 7; | 
 | 		lane_to_slot[5] = 3; | 
 | 		lane_to_slot[6] = 3; | 
 | 		lane_to_slot[7] = 3; | 
 | 		break; | 
 | 	case 0x8F: | 
 | 	case 0x85: | 
 | 		lane_to_slot[1] = 7; | 
 | 		lane_to_slot[2] = 6; | 
 | 		lane_to_slot[3] = 5; | 
 | 		lane_to_slot[6] = 3; | 
 | 		lane_to_slot[7] = 3; | 
 | 		break; | 
 | 	case 0xA5: | 
 | 		lane_to_slot[1] = 7; | 
 | 		lane_to_slot[6] = 3; | 
 | 		lane_to_slot[7] = 3; | 
 | 		break; | 
 | 	case 0xA7: | 
 | 		lane_to_slot[1] = 7; | 
 | 		lane_to_slot[2] = 6; | 
 | 		lane_to_slot[3] = 5; | 
 | 		lane_to_slot[7] = 7; | 
 | 		break; | 
 | 	case 0xAA: | 
 | 		lane_to_slot[1] = 7; | 
 | 		lane_to_slot[6] = 7; | 
 | 		lane_to_slot[7] = 7; | 
 | 		break; | 
 | 	case 0x40: | 
 | 		lane_to_slot[2] = 7; | 
 | 		lane_to_slot[3] = 7; | 
 | 		break; | 
 | 	default: | 
 | 		printf("qds: Fman: Unsupported SerDes Protocol 0x%02x\n", | 
 | 		       serdes1_prtcl); | 
 | 		break; | 
 | 	} | 
 | } | 
 |  | 
 | /* | 
 |  * Given the following ... | 
 |  * | 
 |  * 1) A pointer to an Fman Ethernet node (as identified by the 'compat' | 
 |  * compatible string and 'addr' physical address) | 
 |  * | 
 |  * 2) An Fman port | 
 |  * | 
 |  * ... update the phy-handle property of the Ethernet node to point to the | 
 |  * right PHY. This assumes that we already know the PHY for each port. | 
 |  * | 
 |  * The offset of the Fman Ethernet node is also passed in for convenience, but | 
 |  * it is not used, and we recalculate the offset anyway. | 
 |  * | 
 |  * Note that what we call "Fman ports" (enum fm_port) is really an Fman MAC. | 
 |  * Inside the Fman, "ports" are things that connect to MACs. We only call them | 
 |  * ports in U-Boot because on previous Ethernet devices (e.g. Gianfar), MACs | 
 |  * and ports are the same thing. | 
 |  * | 
 |  */ | 
 | void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, | 
 | 			      enum fm_port port, int offset) | 
 | { | 
 | 	phy_interface_t intf = fm_info_get_enet_if(port); | 
 | 	char phy[16]; | 
 |  | 
 | 	/* The RGMII PHY is identified by the MAC connected to it */ | 
 | 	if (intf == PHY_INTERFACE_MODE_RGMII) { | 
 | 		sprintf(phy, "rgmii_phy%u", port == FM1_DTSEC4 ? 1 : 2); | 
 | 		fdt_set_phy_handle(fdt, compat, addr, phy); | 
 | 	} | 
 |  | 
 | 	/* The SGMII PHY is identified by the MAC connected to it */ | 
 | 	if (intf == PHY_INTERFACE_MODE_SGMII) { | 
 | 		int lane = serdes_get_first_lane(FSL_SRDS_1, SGMII_FM1_DTSEC1 | 
 | 						 + port); | 
 | 		u8 slot; | 
 | 		if (lane < 0) | 
 | 			return; | 
 | 		slot = lane_to_slot[lane]; | 
 | 		if (slot) { | 
 | 			/* Slot housing a SGMII riser card */ | 
 | 			sprintf(phy, "phy_s%x_%02x", slot, | 
 | 				(fm_info_get_phy_address(port - FM1_DTSEC1)- | 
 | 				CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR + 1)); | 
 | 			fdt_set_phy_handle(fdt, compat, addr, phy); | 
 | 		} | 
 | 	} | 
 | } | 
 |  | 
 | void fdt_fixup_board_enet(void *fdt) | 
 | { | 
 | 	int i, lane, idx; | 
 |  | 
 | 	for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { | 
 | 		idx = i - FM1_DTSEC1; | 
 | 		switch (fm_info_get_enet_if(i)) { | 
 | 		case PHY_INTERFACE_MODE_SGMII: | 
 | 			lane = serdes_get_first_lane(FSL_SRDS_1, | 
 | 						     SGMII_FM1_DTSEC1 + idx); | 
 | 			if (lane < 0) | 
 | 				break; | 
 |  | 
 | 			switch (mdio_mux[i]) { | 
 | 			case EMI1_SLOT3: | 
 | 				fdt_status_okay_by_alias(fdt, "emi1_slot3"); | 
 | 				break; | 
 | 			case EMI1_SLOT5: | 
 | 				fdt_status_okay_by_alias(fdt, "emi1_slot5"); | 
 | 				break; | 
 | 			case EMI1_SLOT6: | 
 | 				fdt_status_okay_by_alias(fdt, "emi1_slot6"); | 
 | 				break; | 
 | 			case EMI1_SLOT7: | 
 | 				fdt_status_okay_by_alias(fdt, "emi1_slot7"); | 
 | 				break; | 
 | 			} | 
 | 		break; | 
 | 		case PHY_INTERFACE_MODE_RGMII: | 
 | 			if (i == FM1_DTSEC4) | 
 | 				fdt_status_okay_by_alias(fdt, "emi1_rgmii0"); | 
 |  | 
 | 			if (i == FM1_DTSEC5) | 
 | 				fdt_status_okay_by_alias(fdt, "emi1_rgmii1"); | 
 | 			break; | 
 | 		default: | 
 | 			break; | 
 | 		} | 
 | 	} | 
 | } | 
 | #endif /* #ifdef CONFIG_FMAN_ENET */ | 
 |  | 
 | static void set_brdcfg9_for_gtx_clk(void) | 
 | { | 
 | 	u8 brdcfg9; | 
 | 	brdcfg9 = QIXIS_READ(brdcfg[9]); | 
 | /* Initializing EPHY2 clock to RGMII mode */ | 
 | 	brdcfg9 &= ~(BRDCFG9_EPHY2_MASK); | 
 | 	brdcfg9 |= (BRDCFG9_EPHY2_VAL); | 
 | 	QIXIS_WRITE(brdcfg[9], brdcfg9); | 
 | } | 
 |  | 
 | void t1040_handle_phy_interface_sgmii(int i) | 
 | { | 
 | 	int lane, idx, slot; | 
 | 	idx = i - FM1_DTSEC1; | 
 | 	lane = serdes_get_first_lane(FSL_SRDS_1, | 
 | 			SGMII_FM1_DTSEC1 + idx); | 
 |  | 
 | 	if (lane < 0) | 
 | 		return; | 
 | 	slot = lane_to_slot[lane]; | 
 |  | 
 | 	switch (slot) { | 
 | 	case 1: | 
 | 		mdio_mux[i] = EMI1_SLOT1; | 
 | 		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); | 
 | 		break; | 
 | 	case 3: | 
 | 		if (FM1_DTSEC4 == i) | 
 | 			fm_info_set_phy_address(i, riser_phy_addr[0]); | 
 | 		if (FM1_DTSEC5 == i) | 
 | 			fm_info_set_phy_address(i, riser_phy_addr[1]); | 
 |  | 
 | 		mdio_mux[i] = EMI1_SLOT3; | 
 |  | 
 | 		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); | 
 | 		break; | 
 | 	case 4: | 
 | 		mdio_mux[i] = EMI1_SLOT4; | 
 | 		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); | 
 | 		break; | 
 | 	case 5: | 
 | 		/* Slot housing a SGMII riser card? */ | 
 | 		fm_info_set_phy_address(i, riser_phy_addr[0]); | 
 | 		mdio_mux[i] = EMI1_SLOT5; | 
 | 		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); | 
 | 		break; | 
 | 	case 6: | 
 | 		/* Slot housing a SGMII riser card? */ | 
 | 		fm_info_set_phy_address(i, riser_phy_addr[0]); | 
 | 		mdio_mux[i] = EMI1_SLOT6; | 
 | 		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); | 
 | 		break; | 
 | 	case 7: | 
 | 		if (FM1_DTSEC1 == i) | 
 | 			fm_info_set_phy_address(i, riser_phy_addr[0]); | 
 | 		if (FM1_DTSEC2 == i) | 
 | 			fm_info_set_phy_address(i, riser_phy_addr[1]); | 
 | 		if (FM1_DTSEC3 == i) | 
 | 			fm_info_set_phy_address(i, riser_phy_addr[2]); | 
 | 		if (FM1_DTSEC5 == i) | 
 | 			fm_info_set_phy_address(i, riser_phy_addr[3]); | 
 |  | 
 | 		mdio_mux[i] = EMI1_SLOT7; | 
 | 		fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); | 
 | 		break; | 
 | 	default: | 
 | 		break; | 
 | 	} | 
 | 	fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); | 
 | } | 
 | void t1040_handle_phy_interface_rgmii(int i) | 
 | { | 
 | 	fm_info_set_phy_address(i, i == FM1_DTSEC5 ? | 
 | 			CONFIG_SYS_FM1_DTSEC5_PHY_ADDR : | 
 | 			CONFIG_SYS_FM1_DTSEC4_PHY_ADDR); | 
 | 	mdio_mux[i] = (i == FM1_DTSEC5) ? EMI1_RGMII1 : | 
 | 		EMI1_RGMII0; | 
 | 	fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); | 
 | } | 
 |  | 
 | int board_eth_init(bd_t *bis) | 
 | { | 
 | #ifdef CONFIG_FMAN_ENET | 
 | 	struct memac_mdio_info memac_mdio_info; | 
 | 	unsigned int i; | 
 | #ifdef CONFIG_VSC9953 | 
 | 	int lane; | 
 | 	int phy_addr; | 
 | 	phy_interface_t phy_int; | 
 | 	struct mii_dev *bus; | 
 | #endif | 
 |  | 
 | 	printf("Initializing Fman\n"); | 
 | 	set_brdcfg9_for_gtx_clk(); | 
 |  | 
 | 	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; | 
 |  | 
 | 	memac_mdio_info.regs = | 
 | 		(struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR; | 
 | 	memac_mdio_info.name = DEFAULT_FM_MDIO_NAME; | 
 |  | 
 | 	/* Register the real 1G MDIO bus */ | 
 | 	fm_memac_mdio_init(bis, &memac_mdio_info); | 
 |  | 
 | 	/* Register the muxing front-ends to the MDIO buses */ | 
 | 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII0); | 
 | 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1); | 
 | 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1); | 
 | 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3); | 
 | 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4); | 
 | 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5); | 
 | 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT6); | 
 | 	t1040_qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT7); | 
 |  | 
 | 	/* | 
 | 	 * Program on board RGMII PHY addresses. If the SGMII Riser | 
 | 	 * card used, we'll override the PHY address later. For any DTSEC that | 
 | 	 * is RGMII, we'll also override its PHY address later. We assume that | 
 | 	 * DTSEC4 and DTSEC5 are used for RGMII. | 
 | 	 */ | 
 | 	fm_info_set_phy_address(FM1_DTSEC4, CONFIG_SYS_FM1_DTSEC4_PHY_ADDR); | 
 | 	fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_DTSEC5_PHY_ADDR); | 
 |  | 
 | 	for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { | 
 | 		switch (fm_info_get_enet_if(i)) { | 
 | 		case PHY_INTERFACE_MODE_QSGMII: | 
 | 			fm_info_set_mdio(i, NULL); | 
 | 			break; | 
 | 		case PHY_INTERFACE_MODE_SGMII: | 
 | 			t1040_handle_phy_interface_sgmii(i); | 
 | 			break; | 
 |  | 
 | 		case PHY_INTERFACE_MODE_RGMII: | 
 | 			/* Only DTSEC4 and DTSEC5 can be routed to RGMII */ | 
 | 			t1040_handle_phy_interface_rgmii(i); | 
 | 			break; | 
 | 		default: | 
 | 			break; | 
 | 		} | 
 | 	} | 
 |  | 
 | #ifdef CONFIG_VSC9953 | 
 | 	for (i = 0; i < VSC9953_MAX_PORTS; i++) { | 
 | 		lane = -1; | 
 | 		phy_addr = 0; | 
 | 		phy_int = PHY_INTERFACE_MODE_NONE; | 
 | 		switch (i) { | 
 | 		case 0: | 
 | 		case 1: | 
 | 		case 2: | 
 | 		case 3: | 
 | 			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_SW1_A); | 
 | 			/* PHYs connected over QSGMII */ | 
 | 			if (lane >= 0) { | 
 | 				phy_addr = CONFIG_SYS_FM1_QSGMII21_PHY_ADDR + | 
 | 						i; | 
 | 				phy_int = PHY_INTERFACE_MODE_QSGMII; | 
 | 				break; | 
 | 			} | 
 | 			lane = serdes_get_first_lane(FSL_SRDS_1, | 
 | 					SGMII_SW1_MAC1 + i); | 
 |  | 
 | 			if (lane < 0) | 
 | 				break; | 
 |  | 
 | 			/* PHYs connected over QSGMII */ | 
 | 			if (i != 3 || lane_to_slot[lane] == 7) | 
 | 				phy_addr = CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR | 
 | 					+ i; | 
 | 			else | 
 | 				phy_addr = CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR; | 
 | 			phy_int = PHY_INTERFACE_MODE_SGMII; | 
 | 			break; | 
 | 		case 4: | 
 | 		case 5: | 
 | 		case 6: | 
 | 		case 7: | 
 | 			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_SW1_B); | 
 | 			/* PHYs connected over QSGMII */ | 
 | 			if (lane >= 0) { | 
 | 				phy_addr = CONFIG_SYS_FM1_QSGMII11_PHY_ADDR + | 
 | 						i - 4; | 
 | 				phy_int = PHY_INTERFACE_MODE_QSGMII; | 
 | 				break; | 
 | 			} | 
 | 			lane = serdes_get_first_lane(FSL_SRDS_1, | 
 | 					SGMII_SW1_MAC1 + i); | 
 | 			/* PHYs connected over SGMII */ | 
 | 			if (lane >= 0) { | 
 | 				phy_addr = CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR | 
 | 						+ i - 3; | 
 | 				phy_int = PHY_INTERFACE_MODE_SGMII; | 
 | 			} | 
 | 			break; | 
 | 		case 8: | 
 | 			if (serdes_get_first_lane(FSL_SRDS_1, | 
 | 						  SGMII_FM1_DTSEC1) < 0) | 
 | 				/* FM1@DTSEC1 is connected to SW1@PORT8 */ | 
 | 				vsc9953_port_enable(i); | 
 | 			break; | 
 | 		case 9: | 
 | 			if (serdes_get_first_lane(FSL_SRDS_1, | 
 | 						  SGMII_FM1_DTSEC2) < 0) { | 
 | 				/* Enable L2 On MAC2 using SCFG */ | 
 | 				struct ccsr_scfg *scfg = (struct ccsr_scfg *) | 
 | 						CONFIG_SYS_MPC85xx_SCFG; | 
 |  | 
 | 				out_be32(&scfg->esgmiiselcr, | 
 | 					 in_be32(&scfg->esgmiiselcr) | | 
 | 					 (0x80000000)); | 
 | 				vsc9953_port_enable(i); | 
 | 			} | 
 | 			break; | 
 | 		} | 
 |  | 
 | 		if (lane >= 0) { | 
 | 			bus = mii_dev_for_muxval(lane_to_slot[lane]); | 
 | 			vsc9953_port_info_set_mdio(i, bus); | 
 | 			vsc9953_port_enable(i); | 
 | 		} | 
 | 		vsc9953_port_info_set_phy_address(i, phy_addr); | 
 | 		vsc9953_port_info_set_phy_int(i, phy_int); | 
 | 	} | 
 |  | 
 | #endif | 
 | 	cpu_eth_init(bis); | 
 | #endif | 
 |  | 
 | 	return pci_eth_init(bis); | 
 | } |