diff options
| -rw-r--r-- | board/freescale/b4860qds/b4860qds_qixis.h | 5 | ||||
| -rw-r--r-- | board/freescale/b4860qds/eth_b4860qds.c | 18 | ||||
| -rw-r--r-- | board/freescale/corenet_ds/eth_hydra.c | 6 | ||||
| -rw-r--r-- | board/freescale/corenet_ds/eth_p4080.c | 12 | ||||
| -rw-r--r-- | board/freescale/corenet_ds/eth_superhydra.c | 50 | ||||
| -rw-r--r-- | drivers/net/fm/fm.h | 1 | ||||
| -rw-r--r-- | drivers/net/fm/init.c | 44 | ||||
| -rw-r--r-- | include/fm_eth.h | 4 | 
8 files changed, 140 insertions, 0 deletions
| diff --git a/board/freescale/b4860qds/b4860qds_qixis.h b/board/freescale/b4860qds/b4860qds_qixis.h index 2fabbc7b3..272afc1ae 100644 --- a/board/freescale/b4860qds/b4860qds_qixis.h +++ b/board/freescale/b4860qds/b4860qds_qixis.h @@ -21,4 +21,9 @@  #define QIXIS_SRDS1CLK_122		0x5a  #define QIXIS_SRDS1CLK_125		0x5e + +/* SGMII */ +#define PHY_BASE_ADDR		0x18 +#define PORT_NUM		0x04 +#define REGNUM			0x00  #endif diff --git a/board/freescale/b4860qds/eth_b4860qds.c b/board/freescale/b4860qds/eth_b4860qds.c index dc4ef80fc..a8fc84519 100644 --- a/board/freescale/b4860qds/eth_b4860qds.c +++ b/board/freescale/b4860qds/eth_b4860qds.c @@ -150,6 +150,8 @@ int board_eth_init(bd_t *bis)  	struct memac_mdio_info tg_memac_mdio_info;  	unsigned int i;  	unsigned int  serdes1_prtcl, serdes2_prtcl; +	int qsgmii; +	struct mii_dev *bus;  	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);  	serdes1_prtcl = in_be32(&gur->rcwsr[4]) &  		FSL_CORENET2_RCWSR4_SRDS1_PRTCL; @@ -281,6 +283,22 @@ int board_eth_init(bd_t *bis)  		break;  	} +	/*set PHY address for QSGMII Riser Card on slot2*/ +	bus = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME); +	qsgmii = is_qsgmii_riser_card(bus, PHY_BASE_ADDR, PORT_NUM, REGNUM); + +	if (qsgmii) { +		switch (serdes2_prtcl) { +		case 0xb2: +		case 0x8d: +			fm_info_set_phy_address(FM1_DTSEC3, PHY_BASE_ADDR); +			fm_info_set_phy_address(FM1_DTSEC4, PHY_BASE_ADDR + 1); +			break; +		default: +			break; +		} +	} +  	for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {  		int idx = i - FM1_DTSEC1; diff --git a/board/freescale/corenet_ds/eth_hydra.c b/board/freescale/corenet_ds/eth_hydra.c index a594efcad..35825c4ae 100644 --- a/board/freescale/corenet_ds/eth_hydra.c +++ b/board/freescale/corenet_ds/eth_hydra.c @@ -76,6 +76,8 @@  #define BRDCFG2_REG_GPIO_SEL	0x20 +#define PHY_BASE_ADDR		0x00 +  /*   * BRDCFG1 mask and value for each MAC   * @@ -365,6 +367,7 @@ int board_eth_init(bd_t *bis)  	struct tgec_mdio_info tgec_mdio_info;  	unsigned int i, slot;  	int lane; +	struct mii_dev *bus;  	printf("Initializing Fman\n"); @@ -470,6 +473,9 @@ int board_eth_init(bd_t *bis)  		}  	} +	bus = miiphy_get_dev_by_name("HYDRA_SGMII_MDIO"); +	set_sgmii_phy(bus, FM1_DTSEC1, CONFIG_SYS_NUM_FM1_DTSEC, PHY_BASE_ADDR); +  	/*  	 * For 10G, we only support one XAUI card per Fman.  If present, then we  	 * force its routing and never touch those bits again, which removes the diff --git a/board/freescale/corenet_ds/eth_p4080.c b/board/freescale/corenet_ds/eth_p4080.c index 597d0cbf2..e5beb5517 100644 --- a/board/freescale/corenet_ds/eth_p4080.c +++ b/board/freescale/corenet_ds/eth_p4080.c @@ -37,6 +37,9 @@  #define EMI1_MASK	0xc0000000  #define EMI2_MASK	0x30000000 +#define PHY_BASE_ADDR	0x00 +#define PHY_BASE_ADDR_SLOT5	0x10 +  static int mdio_mux[NUM_FM_PORTS];  static char *mdio_names[16] = { @@ -290,6 +293,7 @@ int board_eth_init(bd_t *bis)  	int i;  	struct fsl_pq_mdio_info dtsec_mdio_info;  	struct tgec_mdio_info tgec_mdio_info; +	struct mii_dev *bus;  	/* Initialize the mdio_mux array so we can recognize empty elements */  	for (i = 0; i < NUM_FM_PORTS; i++) @@ -370,6 +374,9 @@ int board_eth_init(bd_t *bis)  			break;  		}  	} +	bus = mii_dev_for_muxval(EMI1_SLOT5); +	set_sgmii_phy(bus, FM1_DTSEC1, +		      CONFIG_SYS_NUM_FM1_DTSEC, PHY_BASE_ADDR_SLOT5);  	for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) {  		int idx = i - FM1_10GEC1, lane, slot; @@ -435,6 +442,11 @@ int board_eth_init(bd_t *bis)  		}  	} +	bus = mii_dev_for_muxval(EMI1_SLOT3); +	set_sgmii_phy(bus, FM2_DTSEC1, CONFIG_SYS_NUM_FM2_DTSEC, PHY_BASE_ADDR); +	bus = mii_dev_for_muxval(EMI1_SLOT4); +	set_sgmii_phy(bus, FM2_DTSEC1, CONFIG_SYS_NUM_FM2_DTSEC, PHY_BASE_ADDR); +  	for (i = FM2_10GEC1; i < FM2_10GEC1 + CONFIG_SYS_NUM_FM2_10GEC; i++) {  		int idx = i - FM2_10GEC1, lane, slot;  		switch (fm_info_get_enet_if(i)) { diff --git a/board/freescale/corenet_ds/eth_superhydra.c b/board/freescale/corenet_ds/eth_superhydra.c index 91ac1962e..ad1bffd74 100644 --- a/board/freescale/corenet_ds/eth_superhydra.c +++ b/board/freescale/corenet_ds/eth_superhydra.c @@ -77,6 +77,12 @@  #define BRDCFG2_REG_GPIO_SEL	0x20 +/* SGMII */ +#define PHY_BASE_ADDR		0x00 +#define REGNUM			0x00 +#define PORT_NUM_FM1		0x04 +#define PORT_NUM_FM2		0x02 +  /*   * BRDCFG1 mask and value for each MAC   * @@ -415,6 +421,9 @@ int board_eth_init(bd_t *bis)  	struct tgec_mdio_info tgec_mdio_info;  	unsigned int i, slot;  	int lane; +	struct mii_dev *bus; +	int qsgmii; +	int phy_real_addr;  	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);  	int srds_prtcl = (in_be32(&gur->rcwsr[4]) &  				FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; @@ -575,6 +584,42 @@ int board_eth_init(bd_t *bis)  		}  	} +	bus = miiphy_get_dev_by_name("SUPER_HYDRA_FM1_SGMII_MDIO"); +	qsgmii = is_qsgmii_riser_card(bus, PHY_BASE_ADDR, PORT_NUM_FM1, REGNUM); + +	if (qsgmii) { +		for (i = FM1_DTSEC1; i < FM1_DTSEC1 + PORT_NUM_FM1; i++) { +			if (fm_info_get_enet_if(i) == +					PHY_INTERFACE_MODE_SGMII) { +				phy_real_addr = PHY_BASE_ADDR + i - FM1_DTSEC1; +				fm_info_set_phy_address(i, phy_real_addr); +			} +		} +		switch (srds_prtcl) { +		case 0x00: +		case 0x03: +		case 0x04: +		case 0x06: +		case 0x11: +		case 0x2a: +		case 0x34: +		case 0x36: +			fm_info_set_phy_address(FM1_DTSEC3, PHY_BASE_ADDR + 2); +			fm_info_set_phy_address(FM1_DTSEC4, PHY_BASE_ADDR + 3); +			break; +		case 0x01: +		case 0x02: +		case 0x05: +		case 0x07: +		case 0x35: +			fm_info_set_phy_address(FM1_DTSEC3, PHY_BASE_ADDR + 0); +			fm_info_set_phy_address(FM1_DTSEC4, PHY_BASE_ADDR + 1); +			break; +		default: +			break; +		} +	} +  	/*  	 * For 10G, we only support one XAUI card per Fman.  If present, then we  	 * force its routing and never touch those bits again, which removes the @@ -686,6 +731,11 @@ int board_eth_init(bd_t *bis)  		}  	} +	bus = miiphy_get_dev_by_name("SUPER_HYDRA_FM2_SGMII_MDIO"); +	set_sgmii_phy(bus, FM2_DTSEC3, PORT_NUM_FM2, PHY_BASE_ADDR); +	bus = miiphy_get_dev_by_name("SUPER_HYDRA_FM3_SGMII_MDIO"); +	set_sgmii_phy(bus, FM2_DTSEC1, PORT_NUM_FM2, PHY_BASE_ADDR); +  	/*  	 * For 10G, we only support one XAUI card per Fman.  If present, then we  	 * force its routing and never touch those bits again, which removes the diff --git a/drivers/net/fm/fm.h b/drivers/net/fm/fm.h index 38fdbcdc4..5f197a982 100644 --- a/drivers/net/fm/fm.h +++ b/drivers/net/fm/fm.h @@ -21,6 +21,7 @@  #define TX_PORT_1G_BASE		0x28  #define MAX_NUM_TX_PORT_1G	CONFIG_SYS_NUM_FM1_DTSEC  #define TX_PORT_10G_BASE	0x30 +#define MIIM_TIMEOUT    0xFFFF  struct fm_muram {  	u32 base; diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c index 14fa2ce59..2d13145f1 100644 --- a/drivers/net/fm/init.c +++ b/drivers/net/fm/init.c @@ -274,3 +274,47 @@ void fdt_fixup_fman_ethernet(void *blob)  	}  #endif  } + +/*QSGMII Riser Card can work in SGMII mode, but the PHY address is different. + *This function scans which Riser Card being used(QSGMII or SGMII Riser Card), + *then set the correct PHY address + */ +void set_sgmii_phy(struct mii_dev *bus, enum fm_port base_port, +		unsigned int port_num, int phy_base_addr) +{ +	unsigned int regnum = 0; +	int qsgmii; +	int i; +	int phy_real_addr; + +	qsgmii = is_qsgmii_riser_card(bus, phy_base_addr, port_num, regnum); + +	if (!qsgmii) +		return; + +	for (i = base_port; i < base_port + port_num; i++) { +		if (fm_info_get_enet_if(i) == PHY_INTERFACE_MODE_SGMII) { +			phy_real_addr = phy_base_addr + i - base_port; +			fm_info_set_phy_address(i, phy_real_addr); +		} +	} +} + +/*to check whether qsgmii riser card is used*/ +int is_qsgmii_riser_card(struct mii_dev *bus, int phy_base_addr, +		unsigned int port_num, unsigned regnum) +{ +	int i; +	int val; + +	if (!bus) +		return 0; + +	for (i = phy_base_addr; i < phy_base_addr + port_num; i++) { +		val = bus->read(bus, i, MDIO_DEVAD_NONE, regnum); +		if (val != MIIM_TIMEOUT) +			return 1; +	} + +	return 0; +} diff --git a/include/fm_eth.h b/include/fm_eth.h index 90562dc9f..114bb8cf2 100644 --- a/include/fm_eth.h +++ b/include/fm_eth.h @@ -149,5 +149,9 @@ void fm_info_set_phy_address(enum fm_port port, int address);  int fm_info_get_phy_address(enum fm_port port);  void fm_info_set_mdio(enum fm_port port, struct mii_dev *bus);  void fm_disable_port(enum fm_port port); +void set_sgmii_phy(struct mii_dev *bus, enum fm_port base_port, +		unsigned int port_num, int phy_base_addr); +int is_qsgmii_riser_card(struct mii_dev *bus, int phy_base_addr, +		unsigned int port_num, unsigned regnum);  #endif |