xref: /rk3399_rockchip-uboot/drivers/net/tsec.c (revision e677da9723ede30b3072f8b8e290e9d8daea8642)
12439e4bfSJean-Christophe PLAGNIOL-VILLARD /*
22439e4bfSJean-Christophe PLAGNIOL-VILLARD  * Freescale Three Speed Ethernet Controller driver
32439e4bfSJean-Christophe PLAGNIOL-VILLARD  *
4aec84bf6SClaudiu Manoil  * Copyright 2004-2011, 2013 Freescale Semiconductor, Inc.
52439e4bfSJean-Christophe PLAGNIOL-VILLARD  * (C) Copyright 2003, Motorola, Inc.
62439e4bfSJean-Christophe PLAGNIOL-VILLARD  * author Andy Fleming
72439e4bfSJean-Christophe PLAGNIOL-VILLARD  *
89872b736SBin Meng  * SPDX-License-Identifier:	GPL-2.0+
92439e4bfSJean-Christophe PLAGNIOL-VILLARD  */
102439e4bfSJean-Christophe PLAGNIOL-VILLARD 
112439e4bfSJean-Christophe PLAGNIOL-VILLARD #include <config.h>
122439e4bfSJean-Christophe PLAGNIOL-VILLARD #include <common.h>
132439e4bfSJean-Christophe PLAGNIOL-VILLARD #include <malloc.h>
142439e4bfSJean-Christophe PLAGNIOL-VILLARD #include <net.h>
152439e4bfSJean-Christophe PLAGNIOL-VILLARD #include <command.h>
16dd3d1f56SAndy Fleming #include <tsec.h>
17063c1263SAndy Fleming #include <fsl_mdio.h>
180d071cddSKim Phillips #include <asm/errno.h>
19aada81deSchenhui zhao #include <asm/processor.h>
2052d00a81SAlison Wang #include <asm/io.h>
212439e4bfSJean-Christophe PLAGNIOL-VILLARD 
222439e4bfSJean-Christophe PLAGNIOL-VILLARD DECLARE_GLOBAL_DATA_PTR;
232439e4bfSJean-Christophe PLAGNIOL-VILLARD 
24c8a60b53SJoe Hershberger static int tsec_send(struct eth_device *dev, void *packet, int length);
25aada81deSchenhui zhao 
2675b9d4aeSAndy Fleming /* Default initializations for TSEC controllers. */
2775b9d4aeSAndy Fleming 
2875b9d4aeSAndy Fleming static struct tsec_info_struct tsec_info[] = {
2975b9d4aeSAndy Fleming #ifdef CONFIG_TSEC1
3075b9d4aeSAndy Fleming 	STD_TSEC_INFO(1),	/* TSEC1 */
3175b9d4aeSAndy Fleming #endif
3275b9d4aeSAndy Fleming #ifdef CONFIG_TSEC2
3375b9d4aeSAndy Fleming 	STD_TSEC_INFO(2),	/* TSEC2 */
3475b9d4aeSAndy Fleming #endif
3575b9d4aeSAndy Fleming #ifdef CONFIG_MPC85XX_FEC
3675b9d4aeSAndy Fleming 	{
37aec84bf6SClaudiu Manoil 		.regs = TSEC_GET_REGS(2, 0x2000),
3875b9d4aeSAndy Fleming 		.devname = CONFIG_MPC85XX_FEC_NAME,
3975b9d4aeSAndy Fleming 		.phyaddr = FEC_PHY_ADDR,
40063c1263SAndy Fleming 		.flags = FEC_FLAGS,
41063c1263SAndy Fleming 		.mii_devname = DEFAULT_MII_NAME
4275b9d4aeSAndy Fleming 	},			/* FEC */
4375b9d4aeSAndy Fleming #endif
4475b9d4aeSAndy Fleming #ifdef CONFIG_TSEC3
4575b9d4aeSAndy Fleming 	STD_TSEC_INFO(3),	/* TSEC3 */
4675b9d4aeSAndy Fleming #endif
4775b9d4aeSAndy Fleming #ifdef CONFIG_TSEC4
4875b9d4aeSAndy Fleming 	STD_TSEC_INFO(4),	/* TSEC4 */
4975b9d4aeSAndy Fleming #endif
5075b9d4aeSAndy Fleming };
5175b9d4aeSAndy Fleming 
522abe361cSAndy Fleming #define TBIANA_SETTINGS ( \
532abe361cSAndy Fleming 		TBIANA_ASYMMETRIC_PAUSE \
542abe361cSAndy Fleming 		| TBIANA_SYMMETRIC_PAUSE \
552abe361cSAndy Fleming 		| TBIANA_FULL_DUPLEX \
562abe361cSAndy Fleming 		)
572abe361cSAndy Fleming 
5890b5bf21SFelix Radensky /* By default force the TBI PHY into 1000Mbps full duplex when in SGMII mode */
5990b5bf21SFelix Radensky #ifndef CONFIG_TSEC_TBICR_SETTINGS
6072c96a68SKumar Gala #define CONFIG_TSEC_TBICR_SETTINGS ( \
612abe361cSAndy Fleming 		TBICR_PHY_RESET \
6272c96a68SKumar Gala 		| TBICR_ANEG_ENABLE \
632abe361cSAndy Fleming 		| TBICR_FULL_DUPLEX \
642abe361cSAndy Fleming 		| TBICR_SPEED1_SET \
652abe361cSAndy Fleming 		)
6690b5bf21SFelix Radensky #endif /* CONFIG_TSEC_TBICR_SETTINGS */
6746e91674SPeter Tyser 
682abe361cSAndy Fleming /* Configure the TBI for SGMII operation */
692abe361cSAndy Fleming static void tsec_configure_serdes(struct tsec_private *priv)
702abe361cSAndy Fleming {
719872b736SBin Meng 	/*
729872b736SBin Meng 	 * Access TBI PHY registers at given TSEC register offset as opposed
739872b736SBin Meng 	 * to the register offset used for external PHY accesses
749872b736SBin Meng 	 */
75063c1263SAndy Fleming 	tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa),
76063c1263SAndy Fleming 			0, TBI_ANA, TBIANA_SETTINGS);
77063c1263SAndy Fleming 	tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa),
78063c1263SAndy Fleming 			0, TBI_TBICON, TBICON_CLK_SELECT);
79063c1263SAndy Fleming 	tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa),
80063c1263SAndy Fleming 			0, TBI_CR, CONFIG_TSEC_TBICR_SETTINGS);
812439e4bfSJean-Christophe PLAGNIOL-VILLARD }
822439e4bfSJean-Christophe PLAGNIOL-VILLARD 
832439e4bfSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_MCAST_TFTP
842439e4bfSJean-Christophe PLAGNIOL-VILLARD 
852439e4bfSJean-Christophe PLAGNIOL-VILLARD /* CREDITS: linux gianfar driver, slightly adjusted... thanx. */
862439e4bfSJean-Christophe PLAGNIOL-VILLARD 
872439e4bfSJean-Christophe PLAGNIOL-VILLARD /* Set the appropriate hash bit for the given addr */
882439e4bfSJean-Christophe PLAGNIOL-VILLARD 
899872b736SBin Meng /*
909872b736SBin Meng  * The algorithm works like so:
912439e4bfSJean-Christophe PLAGNIOL-VILLARD  * 1) Take the Destination Address (ie the multicast address), and
922439e4bfSJean-Christophe PLAGNIOL-VILLARD  * do a CRC on it (little endian), and reverse the bits of the
932439e4bfSJean-Christophe PLAGNIOL-VILLARD  * result.
942439e4bfSJean-Christophe PLAGNIOL-VILLARD  * 2) Use the 8 most significant bits as a hash into a 256-entry
952439e4bfSJean-Christophe PLAGNIOL-VILLARD  * table.  The table is controlled through 8 32-bit registers:
96876d4515SClaudiu Manoil  * gaddr0-7.  gaddr0's MSB is entry 0, and gaddr7's LSB is entry
97876d4515SClaudiu Manoil  * 255.  This means that the 3 most significant bits in the
982439e4bfSJean-Christophe PLAGNIOL-VILLARD  * hash index which gaddr register to use, and the 5 other bits
992439e4bfSJean-Christophe PLAGNIOL-VILLARD  * indicate which bit (assuming an IBM numbering scheme, which
100876d4515SClaudiu Manoil  * for PowerPC (tm) is usually the case) in the register holds
1019872b736SBin Meng  * the entry.
1029872b736SBin Meng  */
1039872b736SBin Meng static int tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set)
1042439e4bfSJean-Christophe PLAGNIOL-VILLARD {
105b200204eSClaudiu Manoil 	struct tsec_private *priv = (struct tsec_private *)dev->priv;
106876d4515SClaudiu Manoil 	struct tsec __iomem *regs = priv->regs;
107876d4515SClaudiu Manoil 	u32 result, value;
108876d4515SClaudiu Manoil 	u8 whichbit, whichreg;
1092439e4bfSJean-Christophe PLAGNIOL-VILLARD 
110876d4515SClaudiu Manoil 	result = ether_crc(MAC_ADDR_LEN, mcast_mac);
111876d4515SClaudiu Manoil 	whichbit = (result >> 24) & 0x1f; /* the 5 LSB = which bit to set */
112876d4515SClaudiu Manoil 	whichreg = result >> 29; /* the 3 MSB = which reg to set it in */
1132439e4bfSJean-Christophe PLAGNIOL-VILLARD 
114876d4515SClaudiu Manoil 	value = 1 << (31-whichbit);
1152439e4bfSJean-Christophe PLAGNIOL-VILLARD 
116876d4515SClaudiu Manoil 	if (set)
117876d4515SClaudiu Manoil 		setbits_be32(&regs->hash.gaddr0 + whichreg, value);
118876d4515SClaudiu Manoil 	else
119876d4515SClaudiu Manoil 		clrbits_be32(&regs->hash.gaddr0 + whichreg, value);
120876d4515SClaudiu Manoil 
1212439e4bfSJean-Christophe PLAGNIOL-VILLARD 	return 0;
1222439e4bfSJean-Christophe PLAGNIOL-VILLARD }
1232439e4bfSJean-Christophe PLAGNIOL-VILLARD #endif /* Multicast TFTP ? */
12490751910SMingkai Hu 
1259872b736SBin Meng /*
1269872b736SBin Meng  * Initialized required registers to appropriate values, zeroing
12790751910SMingkai Hu  * those we don't care about (unless zero is bad, in which case,
12890751910SMingkai Hu  * choose a more appropriate value)
12990751910SMingkai Hu  */
130aec84bf6SClaudiu Manoil static void init_registers(struct tsec __iomem *regs)
13190751910SMingkai Hu {
13290751910SMingkai Hu 	/* Clear IEVENT */
13390751910SMingkai Hu 	out_be32(&regs->ievent, IEVENT_INIT_CLEAR);
13490751910SMingkai Hu 
13590751910SMingkai Hu 	out_be32(&regs->imask, IMASK_INIT_CLEAR);
13690751910SMingkai Hu 
13790751910SMingkai Hu 	out_be32(&regs->hash.iaddr0, 0);
13890751910SMingkai Hu 	out_be32(&regs->hash.iaddr1, 0);
13990751910SMingkai Hu 	out_be32(&regs->hash.iaddr2, 0);
14090751910SMingkai Hu 	out_be32(&regs->hash.iaddr3, 0);
14190751910SMingkai Hu 	out_be32(&regs->hash.iaddr4, 0);
14290751910SMingkai Hu 	out_be32(&regs->hash.iaddr5, 0);
14390751910SMingkai Hu 	out_be32(&regs->hash.iaddr6, 0);
14490751910SMingkai Hu 	out_be32(&regs->hash.iaddr7, 0);
14590751910SMingkai Hu 
14690751910SMingkai Hu 	out_be32(&regs->hash.gaddr0, 0);
14790751910SMingkai Hu 	out_be32(&regs->hash.gaddr1, 0);
14890751910SMingkai Hu 	out_be32(&regs->hash.gaddr2, 0);
14990751910SMingkai Hu 	out_be32(&regs->hash.gaddr3, 0);
15090751910SMingkai Hu 	out_be32(&regs->hash.gaddr4, 0);
15190751910SMingkai Hu 	out_be32(&regs->hash.gaddr5, 0);
15290751910SMingkai Hu 	out_be32(&regs->hash.gaddr6, 0);
15390751910SMingkai Hu 	out_be32(&regs->hash.gaddr7, 0);
15490751910SMingkai Hu 
15590751910SMingkai Hu 	out_be32(&regs->rctrl, 0x00000000);
15690751910SMingkai Hu 
15790751910SMingkai Hu 	/* Init RMON mib registers */
15882ef75caSClaudiu Manoil 	memset((void *)&regs->rmon, 0, sizeof(regs->rmon));
15990751910SMingkai Hu 
16090751910SMingkai Hu 	out_be32(&regs->rmon.cam1, 0xffffffff);
16190751910SMingkai Hu 	out_be32(&regs->rmon.cam2, 0xffffffff);
16290751910SMingkai Hu 
16390751910SMingkai Hu 	out_be32(&regs->mrblr, MRBLR_INIT_SETTINGS);
16490751910SMingkai Hu 
16590751910SMingkai Hu 	out_be32(&regs->minflr, MINFLR_INIT_SETTINGS);
16690751910SMingkai Hu 
16790751910SMingkai Hu 	out_be32(&regs->attr, ATTR_INIT_SETTINGS);
16890751910SMingkai Hu 	out_be32(&regs->attreli, ATTRELI_INIT_SETTINGS);
16990751910SMingkai Hu 
17090751910SMingkai Hu }
17190751910SMingkai Hu 
1729872b736SBin Meng /*
1739872b736SBin Meng  * Configure maccfg2 based on negotiated speed and duplex
17490751910SMingkai Hu  * reported by PHY handling code
17590751910SMingkai Hu  */
176063c1263SAndy Fleming static void adjust_link(struct tsec_private *priv, struct phy_device *phydev)
17790751910SMingkai Hu {
178aec84bf6SClaudiu Manoil 	struct tsec __iomem *regs = priv->regs;
17990751910SMingkai Hu 	u32 ecntrl, maccfg2;
18090751910SMingkai Hu 
181063c1263SAndy Fleming 	if (!phydev->link) {
182063c1263SAndy Fleming 		printf("%s: No link.\n", phydev->dev->name);
18390751910SMingkai Hu 		return;
18490751910SMingkai Hu 	}
18590751910SMingkai Hu 
18690751910SMingkai Hu 	/* clear all bits relative with interface mode */
18790751910SMingkai Hu 	ecntrl = in_be32(&regs->ecntrl);
18890751910SMingkai Hu 	ecntrl &= ~ECNTRL_R100;
18990751910SMingkai Hu 
19090751910SMingkai Hu 	maccfg2 = in_be32(&regs->maccfg2);
19190751910SMingkai Hu 	maccfg2 &= ~(MACCFG2_IF | MACCFG2_FULL_DUPLEX);
19290751910SMingkai Hu 
193063c1263SAndy Fleming 	if (phydev->duplex)
19490751910SMingkai Hu 		maccfg2 |= MACCFG2_FULL_DUPLEX;
19590751910SMingkai Hu 
196063c1263SAndy Fleming 	switch (phydev->speed) {
19790751910SMingkai Hu 	case 1000:
19890751910SMingkai Hu 		maccfg2 |= MACCFG2_GMII;
19990751910SMingkai Hu 		break;
20090751910SMingkai Hu 	case 100:
20190751910SMingkai Hu 	case 10:
20290751910SMingkai Hu 		maccfg2 |= MACCFG2_MII;
20390751910SMingkai Hu 
2049872b736SBin Meng 		/*
2059872b736SBin Meng 		 * Set R100 bit in all modes although
20690751910SMingkai Hu 		 * it is only used in RGMII mode
20790751910SMingkai Hu 		 */
208063c1263SAndy Fleming 		if (phydev->speed == 100)
20990751910SMingkai Hu 			ecntrl |= ECNTRL_R100;
21090751910SMingkai Hu 		break;
21190751910SMingkai Hu 	default:
212063c1263SAndy Fleming 		printf("%s: Speed was bad\n", phydev->dev->name);
21390751910SMingkai Hu 		break;
21490751910SMingkai Hu 	}
21590751910SMingkai Hu 
21690751910SMingkai Hu 	out_be32(&regs->ecntrl, ecntrl);
21790751910SMingkai Hu 	out_be32(&regs->maccfg2, maccfg2);
21890751910SMingkai Hu 
219063c1263SAndy Fleming 	printf("Speed: %d, %s duplex%s\n", phydev->speed,
220063c1263SAndy Fleming 			(phydev->duplex) ? "full" : "half",
221063c1263SAndy Fleming 			(phydev->port == PORT_FIBRE) ? ", fiber mode" : "");
22290751910SMingkai Hu }
22390751910SMingkai Hu 
224aada81deSchenhui zhao #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129
225aada81deSchenhui zhao /*
226aada81deSchenhui zhao  * When MACCFG1[Rx_EN] is enabled during system boot as part
227aada81deSchenhui zhao  * of the eTSEC port initialization sequence,
228aada81deSchenhui zhao  * the eTSEC Rx logic may not be properly initialized.
229aada81deSchenhui zhao  */
230aada81deSchenhui zhao void redundant_init(struct eth_device *dev)
231aada81deSchenhui zhao {
232aada81deSchenhui zhao 	struct tsec_private *priv = dev->priv;
233aec84bf6SClaudiu Manoil 	struct tsec __iomem *regs = priv->regs;
234aada81deSchenhui zhao 	uint t, count = 0;
235aada81deSchenhui zhao 	int fail = 1;
236aada81deSchenhui zhao 	static const u8 pkt[] = {
237aada81deSchenhui zhao 		0x00, 0x1e, 0x4f, 0x12, 0xcb, 0x2c, 0x00, 0x25,
238aada81deSchenhui zhao 		0x64, 0xbb, 0xd1, 0xab, 0x08, 0x00, 0x45, 0x00,
239aada81deSchenhui zhao 		0x00, 0x5c, 0xdd, 0x22, 0x00, 0x00, 0x80, 0x01,
240aada81deSchenhui zhao 		0x1f, 0x71, 0x0a, 0xc1, 0x14, 0x22, 0x0a, 0xc1,
241aada81deSchenhui zhao 		0x14, 0x6a, 0x08, 0x00, 0xef, 0x7e, 0x02, 0x00,
242aada81deSchenhui zhao 		0x94, 0x05, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
243aada81deSchenhui zhao 		0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
244aada81deSchenhui zhao 		0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
245aada81deSchenhui zhao 		0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
246aada81deSchenhui zhao 		0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
247aada81deSchenhui zhao 		0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
248aada81deSchenhui zhao 		0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
249aada81deSchenhui zhao 		0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
250aada81deSchenhui zhao 		0x71, 0x72};
251aada81deSchenhui zhao 
252aada81deSchenhui zhao 	/* Enable promiscuous mode */
253aada81deSchenhui zhao 	setbits_be32(&regs->rctrl, 0x8);
254aada81deSchenhui zhao 	/* Enable loopback mode */
255aada81deSchenhui zhao 	setbits_be32(&regs->maccfg1, MACCFG1_LOOPBACK);
256aada81deSchenhui zhao 	/* Enable transmit and receive */
257aada81deSchenhui zhao 	setbits_be32(&regs->maccfg1, MACCFG1_RX_EN | MACCFG1_TX_EN);
258aada81deSchenhui zhao 
259aada81deSchenhui zhao 	/* Tell the DMA it is clear to go */
260aada81deSchenhui zhao 	setbits_be32(&regs->dmactrl, DMACTRL_INIT_SETTINGS);
261aada81deSchenhui zhao 	out_be32(&regs->tstat, TSTAT_CLEAR_THALT);
262aada81deSchenhui zhao 	out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
263aada81deSchenhui zhao 	clrbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
264aada81deSchenhui zhao 
265aada81deSchenhui zhao 	do {
2669c9141fdSClaudiu Manoil 		uint16_t status;
267aada81deSchenhui zhao 		tsec_send(dev, (void *)pkt, sizeof(pkt));
268aada81deSchenhui zhao 
269aada81deSchenhui zhao 		/* Wait for buffer to be received */
270*e677da97SBin Meng 		for (t = 0;
271*e677da97SBin Meng 		     in_be16(&priv->rxbd[priv->rx_idx].status) & RXBD_EMPTY;
272362b123fSBin Meng 		     t++) {
273aada81deSchenhui zhao 			if (t >= 10 * TOUT_LOOP) {
274aada81deSchenhui zhao 				printf("%s: tsec: rx error\n", dev->name);
275aada81deSchenhui zhao 				break;
276aada81deSchenhui zhao 			}
277aada81deSchenhui zhao 		}
278aada81deSchenhui zhao 
279362b123fSBin Meng 		if (!memcmp(pkt, net_rx_packets[priv->rx_idx], sizeof(pkt)))
280aada81deSchenhui zhao 			fail = 0;
281aada81deSchenhui zhao 
282*e677da97SBin Meng 		out_be16(&priv->rxbd[priv->rx_idx].length, 0);
2839c9141fdSClaudiu Manoil 		status = RXBD_EMPTY;
284362b123fSBin Meng 		if ((priv->rx_idx + 1) == PKTBUFSRX)
2859c9141fdSClaudiu Manoil 			status |= RXBD_WRAP;
286*e677da97SBin Meng 		out_be16(&priv->rxbd[priv->rx_idx].status, status);
287362b123fSBin Meng 		priv->rx_idx = (priv->rx_idx + 1) % PKTBUFSRX;
288aada81deSchenhui zhao 
289aada81deSchenhui zhao 		if (in_be32(&regs->ievent) & IEVENT_BSY) {
290aada81deSchenhui zhao 			out_be32(&regs->ievent, IEVENT_BSY);
291aada81deSchenhui zhao 			out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
292aada81deSchenhui zhao 		}
293aada81deSchenhui zhao 		if (fail) {
294aada81deSchenhui zhao 			printf("loopback recv packet error!\n");
295aada81deSchenhui zhao 			clrbits_be32(&regs->maccfg1, MACCFG1_RX_EN);
296aada81deSchenhui zhao 			udelay(1000);
297aada81deSchenhui zhao 			setbits_be32(&regs->maccfg1, MACCFG1_RX_EN);
298aada81deSchenhui zhao 		}
299aada81deSchenhui zhao 	} while ((count++ < 4) && (fail == 1));
300aada81deSchenhui zhao 
301aada81deSchenhui zhao 	if (fail)
302aada81deSchenhui zhao 		panic("eTSEC init fail!\n");
303aada81deSchenhui zhao 	/* Disable promiscuous mode */
304aada81deSchenhui zhao 	clrbits_be32(&regs->rctrl, 0x8);
305aada81deSchenhui zhao 	/* Disable loopback mode */
306aada81deSchenhui zhao 	clrbits_be32(&regs->maccfg1, MACCFG1_LOOPBACK);
307aada81deSchenhui zhao }
308aada81deSchenhui zhao #endif
309aada81deSchenhui zhao 
3109872b736SBin Meng /*
3119872b736SBin Meng  * Set up the buffers and their descriptors, and bring up the
31290751910SMingkai Hu  * interface
31390751910SMingkai Hu  */
31490751910SMingkai Hu static void startup_tsec(struct eth_device *dev)
31590751910SMingkai Hu {
31690751910SMingkai Hu 	struct tsec_private *priv = (struct tsec_private *)dev->priv;
317aec84bf6SClaudiu Manoil 	struct tsec __iomem *regs = priv->regs;
3189c9141fdSClaudiu Manoil 	uint16_t status;
3199c9141fdSClaudiu Manoil 	int i;
32090751910SMingkai Hu 
321063c1263SAndy Fleming 	/* reset the indices to zero */
322362b123fSBin Meng 	priv->rx_idx = 0;
323362b123fSBin Meng 	priv->tx_idx = 0;
324aada81deSchenhui zhao #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129
325aada81deSchenhui zhao 	uint svr;
326aada81deSchenhui zhao #endif
327063c1263SAndy Fleming 
32890751910SMingkai Hu 	/* Point to the buffer descriptors */
329*e677da97SBin Meng 	out_be32(&regs->tbase, (u32)&priv->txbd[0]);
330*e677da97SBin Meng 	out_be32(&regs->rbase, (u32)&priv->rxbd[0]);
33190751910SMingkai Hu 
33290751910SMingkai Hu 	/* Initialize the Rx Buffer descriptors */
33390751910SMingkai Hu 	for (i = 0; i < PKTBUFSRX; i++) {
334*e677da97SBin Meng 		out_be16(&priv->rxbd[i].status, RXBD_EMPTY);
335*e677da97SBin Meng 		out_be16(&priv->rxbd[i].length, 0);
336*e677da97SBin Meng 		out_be32(&priv->rxbd[i].bufptr, (u32)net_rx_packets[i]);
33790751910SMingkai Hu 	}
338*e677da97SBin Meng 	status = in_be16(&priv->rxbd[PKTBUFSRX - 1].status);
339*e677da97SBin Meng 	out_be16(&priv->rxbd[PKTBUFSRX - 1].status, status | RXBD_WRAP);
34090751910SMingkai Hu 
34190751910SMingkai Hu 	/* Initialize the TX Buffer Descriptors */
34290751910SMingkai Hu 	for (i = 0; i < TX_BUF_CNT; i++) {
343*e677da97SBin Meng 		out_be16(&priv->txbd[i].status, 0);
344*e677da97SBin Meng 		out_be16(&priv->txbd[i].length, 0);
345*e677da97SBin Meng 		out_be32(&priv->txbd[i].bufptr, 0);
34690751910SMingkai Hu 	}
347*e677da97SBin Meng 	status = in_be16(&priv->txbd[TX_BUF_CNT - 1].status);
348*e677da97SBin Meng 	out_be16(&priv->txbd[TX_BUF_CNT - 1].status, status | TXBD_WRAP);
34990751910SMingkai Hu 
350aada81deSchenhui zhao #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129
351aada81deSchenhui zhao 	svr = get_svr();
352aada81deSchenhui zhao 	if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0))
353aada81deSchenhui zhao 		redundant_init(dev);
354aada81deSchenhui zhao #endif
35590751910SMingkai Hu 	/* Enable Transmit and Receive */
35690751910SMingkai Hu 	setbits_be32(&regs->maccfg1, MACCFG1_RX_EN | MACCFG1_TX_EN);
35790751910SMingkai Hu 
35890751910SMingkai Hu 	/* Tell the DMA it is clear to go */
35990751910SMingkai Hu 	setbits_be32(&regs->dmactrl, DMACTRL_INIT_SETTINGS);
36090751910SMingkai Hu 	out_be32(&regs->tstat, TSTAT_CLEAR_THALT);
36190751910SMingkai Hu 	out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
36290751910SMingkai Hu 	clrbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
36390751910SMingkai Hu }
36490751910SMingkai Hu 
3659872b736SBin Meng /*
3669872b736SBin Meng  * This returns the status bits of the device. The return value
36790751910SMingkai Hu  * is never checked, and this is what the 8260 driver did, so we
36890751910SMingkai Hu  * do the same. Presumably, this would be zero if there were no
36990751910SMingkai Hu  * errors
37090751910SMingkai Hu  */
371c8a60b53SJoe Hershberger static int tsec_send(struct eth_device *dev, void *packet, int length)
37290751910SMingkai Hu {
37390751910SMingkai Hu 	struct tsec_private *priv = (struct tsec_private *)dev->priv;
374aec84bf6SClaudiu Manoil 	struct tsec __iomem *regs = priv->regs;
3759c9141fdSClaudiu Manoil 	uint16_t status;
3769c9141fdSClaudiu Manoil 	int result = 0;
3779c9141fdSClaudiu Manoil 	int i;
37890751910SMingkai Hu 
37990751910SMingkai Hu 	/* Find an empty buffer descriptor */
380*e677da97SBin Meng 	for (i = 0;
381*e677da97SBin Meng 	     in_be16(&priv->txbd[priv->tx_idx].status) & TXBD_READY;
382*e677da97SBin Meng 	     i++) {
38390751910SMingkai Hu 		if (i >= TOUT_LOOP) {
38490751910SMingkai Hu 			debug("%s: tsec: tx buffers full\n", dev->name);
38590751910SMingkai Hu 			return result;
38690751910SMingkai Hu 		}
38790751910SMingkai Hu 	}
38890751910SMingkai Hu 
389*e677da97SBin Meng 	out_be32(&priv->txbd[priv->tx_idx].bufptr, (u32)packet);
390*e677da97SBin Meng 	out_be16(&priv->txbd[priv->tx_idx].length, length);
391*e677da97SBin Meng 	status = in_be16(&priv->txbd[priv->tx_idx].status);
392*e677da97SBin Meng 	out_be16(&priv->txbd[priv->tx_idx].status, status |
3939c9141fdSClaudiu Manoil 		(TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT));
39490751910SMingkai Hu 
39590751910SMingkai Hu 	/* Tell the DMA to go */
39690751910SMingkai Hu 	out_be32(&regs->tstat, TSTAT_CLEAR_THALT);
39790751910SMingkai Hu 
39890751910SMingkai Hu 	/* Wait for buffer to be transmitted */
399*e677da97SBin Meng 	for (i = 0;
400*e677da97SBin Meng 	     in_be16(&priv->txbd[priv->tx_idx].status) & TXBD_READY;
401*e677da97SBin Meng 	     i++) {
40290751910SMingkai Hu 		if (i >= TOUT_LOOP) {
40390751910SMingkai Hu 			debug("%s: tsec: tx error\n", dev->name);
40490751910SMingkai Hu 			return result;
40590751910SMingkai Hu 		}
40690751910SMingkai Hu 	}
40790751910SMingkai Hu 
408362b123fSBin Meng 	priv->tx_idx = (priv->tx_idx + 1) % TX_BUF_CNT;
409*e677da97SBin Meng 	result = in_be16(&priv->txbd[priv->tx_idx].status) & TXBD_STATS;
41090751910SMingkai Hu 
41190751910SMingkai Hu 	return result;
41290751910SMingkai Hu }
41390751910SMingkai Hu 
41490751910SMingkai Hu static int tsec_recv(struct eth_device *dev)
41590751910SMingkai Hu {
41690751910SMingkai Hu 	struct tsec_private *priv = (struct tsec_private *)dev->priv;
417aec84bf6SClaudiu Manoil 	struct tsec __iomem *regs = priv->regs;
41890751910SMingkai Hu 
419*e677da97SBin Meng 	while (!(in_be16(&priv->rxbd[priv->rx_idx].status) & RXBD_EMPTY)) {
420*e677da97SBin Meng 		int length = in_be16(&priv->rxbd[priv->rx_idx].length);
421*e677da97SBin Meng 		uint16_t status = in_be16(&priv->rxbd[priv->rx_idx].status);
422362b123fSBin Meng 		uchar *packet = net_rx_packets[priv->rx_idx];
42390751910SMingkai Hu 
42490751910SMingkai Hu 		/* Send the packet up if there were no errors */
4259c9141fdSClaudiu Manoil 		if (!(status & RXBD_STATS))
426362b123fSBin Meng 			net_process_received_packet(packet, length - 4);
4279c9141fdSClaudiu Manoil 		else
4289c9141fdSClaudiu Manoil 			printf("Got error %x\n", (status & RXBD_STATS));
42990751910SMingkai Hu 
430*e677da97SBin Meng 		out_be16(&priv->rxbd[priv->rx_idx].length, 0);
43190751910SMingkai Hu 
4329c9141fdSClaudiu Manoil 		status = RXBD_EMPTY;
43390751910SMingkai Hu 		/* Set the wrap bit if this is the last element in the list */
434362b123fSBin Meng 		if ((priv->rx_idx + 1) == PKTBUFSRX)
4359c9141fdSClaudiu Manoil 			status |= RXBD_WRAP;
436*e677da97SBin Meng 		out_be16(&priv->rxbd[priv->rx_idx].status, status);
43790751910SMingkai Hu 
438362b123fSBin Meng 		priv->rx_idx = (priv->rx_idx + 1) % PKTBUFSRX;
43990751910SMingkai Hu 	}
44090751910SMingkai Hu 
44190751910SMingkai Hu 	if (in_be32(&regs->ievent) & IEVENT_BSY) {
44290751910SMingkai Hu 		out_be32(&regs->ievent, IEVENT_BSY);
44390751910SMingkai Hu 		out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
44490751910SMingkai Hu 	}
44590751910SMingkai Hu 
44690751910SMingkai Hu 	return -1;
44790751910SMingkai Hu }
44890751910SMingkai Hu 
44990751910SMingkai Hu /* Stop the interface */
45090751910SMingkai Hu static void tsec_halt(struct eth_device *dev)
45190751910SMingkai Hu {
45290751910SMingkai Hu 	struct tsec_private *priv = (struct tsec_private *)dev->priv;
453aec84bf6SClaudiu Manoil 	struct tsec __iomem *regs = priv->regs;
45490751910SMingkai Hu 
45590751910SMingkai Hu 	clrbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
45690751910SMingkai Hu 	setbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
45790751910SMingkai Hu 
45890751910SMingkai Hu 	while ((in_be32(&regs->ievent) & (IEVENT_GRSC | IEVENT_GTSC))
45990751910SMingkai Hu 			!= (IEVENT_GRSC | IEVENT_GTSC))
46090751910SMingkai Hu 		;
46190751910SMingkai Hu 
46290751910SMingkai Hu 	clrbits_be32(&regs->maccfg1, MACCFG1_TX_EN | MACCFG1_RX_EN);
46390751910SMingkai Hu 
46490751910SMingkai Hu 	/* Shut down the PHY, as needed */
465063c1263SAndy Fleming 	phy_shutdown(priv->phydev);
46690751910SMingkai Hu }
46790751910SMingkai Hu 
4689872b736SBin Meng /*
4699872b736SBin Meng  * Initializes data structures and registers for the controller,
47090751910SMingkai Hu  * and brings the interface up. Returns the link status, meaning
47190751910SMingkai Hu  * that it returns success if the link is up, failure otherwise.
4729872b736SBin Meng  * This allows U-Boot to find the first active controller.
47390751910SMingkai Hu  */
47490751910SMingkai Hu static int tsec_init(struct eth_device *dev, bd_t * bd)
47590751910SMingkai Hu {
47690751910SMingkai Hu 	struct tsec_private *priv = (struct tsec_private *)dev->priv;
477aec84bf6SClaudiu Manoil 	struct tsec __iomem *regs = priv->regs;
478b1690bc3SClaudiu Manoil 	u32 tempval;
47911af8d65STimur Tabi 	int ret;
48090751910SMingkai Hu 
48190751910SMingkai Hu 	/* Make sure the controller is stopped */
48290751910SMingkai Hu 	tsec_halt(dev);
48390751910SMingkai Hu 
48490751910SMingkai Hu 	/* Init MACCFG2.  Defaults to GMII */
48590751910SMingkai Hu 	out_be32(&regs->maccfg2, MACCFG2_INIT_SETTINGS);
48690751910SMingkai Hu 
48790751910SMingkai Hu 	/* Init ECNTRL */
48890751910SMingkai Hu 	out_be32(&regs->ecntrl, ECNTRL_INIT_SETTINGS);
48990751910SMingkai Hu 
4909872b736SBin Meng 	/*
4919872b736SBin Meng 	 * Copy the station address into the address registers.
492b1690bc3SClaudiu Manoil 	 * For a station address of 0x12345678ABCD in transmission
493b1690bc3SClaudiu Manoil 	 * order (BE), MACnADDR1 is set to 0xCDAB7856 and
494b1690bc3SClaudiu Manoil 	 * MACnADDR2 is set to 0x34120000.
495b1690bc3SClaudiu Manoil 	 */
496b1690bc3SClaudiu Manoil 	tempval = (dev->enetaddr[5] << 24) | (dev->enetaddr[4] << 16) |
497b1690bc3SClaudiu Manoil 		  (dev->enetaddr[3] << 8)  |  dev->enetaddr[2];
49890751910SMingkai Hu 
49990751910SMingkai Hu 	out_be32(&regs->macstnaddr1, tempval);
50090751910SMingkai Hu 
501b1690bc3SClaudiu Manoil 	tempval = (dev->enetaddr[1] << 24) | (dev->enetaddr[0] << 16);
50290751910SMingkai Hu 
50390751910SMingkai Hu 	out_be32(&regs->macstnaddr2, tempval);
50490751910SMingkai Hu 
50590751910SMingkai Hu 	/* Clear out (for the most part) the other registers */
50690751910SMingkai Hu 	init_registers(regs);
50790751910SMingkai Hu 
50890751910SMingkai Hu 	/* Ready the device for tx/rx */
50990751910SMingkai Hu 	startup_tsec(dev);
51090751910SMingkai Hu 
511063c1263SAndy Fleming 	/* Start up the PHY */
51211af8d65STimur Tabi 	ret = phy_startup(priv->phydev);
51311af8d65STimur Tabi 	if (ret) {
51411af8d65STimur Tabi 		printf("Could not initialize PHY %s\n",
51511af8d65STimur Tabi 		       priv->phydev->dev->name);
51611af8d65STimur Tabi 		return ret;
51711af8d65STimur Tabi 	}
518063c1263SAndy Fleming 
519063c1263SAndy Fleming 	adjust_link(priv, priv->phydev);
520063c1263SAndy Fleming 
52190751910SMingkai Hu 	/* If there's no link, fail */
522063c1263SAndy Fleming 	return priv->phydev->link ? 0 : -1;
52390751910SMingkai Hu }
52490751910SMingkai Hu 
525063c1263SAndy Fleming static phy_interface_t tsec_get_interface(struct tsec_private *priv)
526063c1263SAndy Fleming {
527aec84bf6SClaudiu Manoil 	struct tsec __iomem *regs = priv->regs;
528063c1263SAndy Fleming 	u32 ecntrl;
529063c1263SAndy Fleming 
530063c1263SAndy Fleming 	ecntrl = in_be32(&regs->ecntrl);
531063c1263SAndy Fleming 
532063c1263SAndy Fleming 	if (ecntrl & ECNTRL_SGMII_MODE)
533063c1263SAndy Fleming 		return PHY_INTERFACE_MODE_SGMII;
534063c1263SAndy Fleming 
535063c1263SAndy Fleming 	if (ecntrl & ECNTRL_TBI_MODE) {
536063c1263SAndy Fleming 		if (ecntrl & ECNTRL_REDUCED_MODE)
537063c1263SAndy Fleming 			return PHY_INTERFACE_MODE_RTBI;
538063c1263SAndy Fleming 		else
539063c1263SAndy Fleming 			return PHY_INTERFACE_MODE_TBI;
540063c1263SAndy Fleming 	}
541063c1263SAndy Fleming 
542063c1263SAndy Fleming 	if (ecntrl & ECNTRL_REDUCED_MODE) {
543063c1263SAndy Fleming 		if (ecntrl & ECNTRL_REDUCED_MII_MODE)
544063c1263SAndy Fleming 			return PHY_INTERFACE_MODE_RMII;
545063c1263SAndy Fleming 		else {
546063c1263SAndy Fleming 			phy_interface_t interface = priv->interface;
547063c1263SAndy Fleming 
548063c1263SAndy Fleming 			/*
549063c1263SAndy Fleming 			 * This isn't autodetected, so it must
550063c1263SAndy Fleming 			 * be set by the platform code.
551063c1263SAndy Fleming 			 */
552063c1263SAndy Fleming 			if ((interface == PHY_INTERFACE_MODE_RGMII_ID) ||
553063c1263SAndy Fleming 			    (interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
554063c1263SAndy Fleming 			    (interface == PHY_INTERFACE_MODE_RGMII_RXID))
555063c1263SAndy Fleming 				return interface;
556063c1263SAndy Fleming 
557063c1263SAndy Fleming 			return PHY_INTERFACE_MODE_RGMII;
558063c1263SAndy Fleming 		}
559063c1263SAndy Fleming 	}
560063c1263SAndy Fleming 
561063c1263SAndy Fleming 	if (priv->flags & TSEC_GIGABIT)
562063c1263SAndy Fleming 		return PHY_INTERFACE_MODE_GMII;
563063c1263SAndy Fleming 
564063c1263SAndy Fleming 	return PHY_INTERFACE_MODE_MII;
565063c1263SAndy Fleming }
566063c1263SAndy Fleming 
5679872b736SBin Meng /*
5689872b736SBin Meng  * Discover which PHY is attached to the device, and configure it
56990751910SMingkai Hu  * properly.  If the PHY is not recognized, then return 0
57090751910SMingkai Hu  * (failure).  Otherwise, return 1
57190751910SMingkai Hu  */
57290751910SMingkai Hu static int init_phy(struct eth_device *dev)
57390751910SMingkai Hu {
57490751910SMingkai Hu 	struct tsec_private *priv = (struct tsec_private *)dev->priv;
575063c1263SAndy Fleming 	struct phy_device *phydev;
576aec84bf6SClaudiu Manoil 	struct tsec __iomem *regs = priv->regs;
577063c1263SAndy Fleming 	u32 supported = (SUPPORTED_10baseT_Half |
578063c1263SAndy Fleming 			SUPPORTED_10baseT_Full |
579063c1263SAndy Fleming 			SUPPORTED_100baseT_Half |
580063c1263SAndy Fleming 			SUPPORTED_100baseT_Full);
581063c1263SAndy Fleming 
582063c1263SAndy Fleming 	if (priv->flags & TSEC_GIGABIT)
583063c1263SAndy Fleming 		supported |= SUPPORTED_1000baseT_Full;
58490751910SMingkai Hu 
58590751910SMingkai Hu 	/* Assign a Physical address to the TBI */
58690751910SMingkai Hu 	out_be32(&regs->tbipa, CONFIG_SYS_TBIPA_VALUE);
58790751910SMingkai Hu 
588063c1263SAndy Fleming 	priv->interface = tsec_get_interface(priv);
58990751910SMingkai Hu 
590063c1263SAndy Fleming 	if (priv->interface == PHY_INTERFACE_MODE_SGMII)
59190751910SMingkai Hu 		tsec_configure_serdes(priv);
59290751910SMingkai Hu 
593063c1263SAndy Fleming 	phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface);
5947f233c05SClaudiu Manoil 	if (!phydev)
5957f233c05SClaudiu Manoil 		return 0;
59690751910SMingkai Hu 
597063c1263SAndy Fleming 	phydev->supported &= supported;
598063c1263SAndy Fleming 	phydev->advertising = phydev->supported;
599063c1263SAndy Fleming 
600063c1263SAndy Fleming 	priv->phydev = phydev;
601063c1263SAndy Fleming 
602063c1263SAndy Fleming 	phy_config(phydev);
60390751910SMingkai Hu 
60490751910SMingkai Hu 	return 1;
60590751910SMingkai Hu }
60690751910SMingkai Hu 
6079872b736SBin Meng /*
6089872b736SBin Meng  * Initialize device structure. Returns success if PHY
60990751910SMingkai Hu  * initialization succeeded (i.e. if it recognizes the PHY)
61090751910SMingkai Hu  */
61190751910SMingkai Hu static int tsec_initialize(bd_t *bis, struct tsec_info_struct *tsec_info)
61290751910SMingkai Hu {
61390751910SMingkai Hu 	struct eth_device *dev;
61490751910SMingkai Hu 	int i;
61590751910SMingkai Hu 	struct tsec_private *priv;
61690751910SMingkai Hu 
61790751910SMingkai Hu 	dev = (struct eth_device *)malloc(sizeof *dev);
61890751910SMingkai Hu 
61990751910SMingkai Hu 	if (NULL == dev)
62090751910SMingkai Hu 		return 0;
62190751910SMingkai Hu 
62290751910SMingkai Hu 	memset(dev, 0, sizeof *dev);
62390751910SMingkai Hu 
62490751910SMingkai Hu 	priv = (struct tsec_private *)malloc(sizeof(*priv));
62590751910SMingkai Hu 
62690751910SMingkai Hu 	if (NULL == priv)
62790751910SMingkai Hu 		return 0;
62890751910SMingkai Hu 
62990751910SMingkai Hu 	priv->regs = tsec_info->regs;
63090751910SMingkai Hu 	priv->phyregs_sgmii = tsec_info->miiregs_sgmii;
63190751910SMingkai Hu 
63290751910SMingkai Hu 	priv->phyaddr = tsec_info->phyaddr;
63390751910SMingkai Hu 	priv->flags = tsec_info->flags;
63490751910SMingkai Hu 
63590751910SMingkai Hu 	sprintf(dev->name, tsec_info->devname);
636063c1263SAndy Fleming 	priv->interface = tsec_info->interface;
637063c1263SAndy Fleming 	priv->bus = miiphy_get_dev_by_name(tsec_info->mii_devname);
63890751910SMingkai Hu 	dev->iobase = 0;
63990751910SMingkai Hu 	dev->priv = priv;
64090751910SMingkai Hu 	dev->init = tsec_init;
64190751910SMingkai Hu 	dev->halt = tsec_halt;
64290751910SMingkai Hu 	dev->send = tsec_send;
64390751910SMingkai Hu 	dev->recv = tsec_recv;
64490751910SMingkai Hu #ifdef CONFIG_MCAST_TFTP
64590751910SMingkai Hu 	dev->mcast = tsec_mcast_addr;
64690751910SMingkai Hu #endif
64790751910SMingkai Hu 
6489872b736SBin Meng 	/* Tell U-Boot to get the addr from the env */
64990751910SMingkai Hu 	for (i = 0; i < 6; i++)
65090751910SMingkai Hu 		dev->enetaddr[i] = 0;
65190751910SMingkai Hu 
65290751910SMingkai Hu 	eth_register(dev);
65390751910SMingkai Hu 
65490751910SMingkai Hu 	/* Reset the MAC */
65590751910SMingkai Hu 	setbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
65690751910SMingkai Hu 	udelay(2);  /* Soft Reset must be asserted for 3 TX clocks */
65790751910SMingkai Hu 	clrbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
65890751910SMingkai Hu 
65990751910SMingkai Hu 	/* Try to initialize PHY here, and return */
66090751910SMingkai Hu 	return init_phy(dev);
66190751910SMingkai Hu }
66290751910SMingkai Hu 
66390751910SMingkai Hu /*
66490751910SMingkai Hu  * Initialize all the TSEC devices
66590751910SMingkai Hu  *
66690751910SMingkai Hu  * Returns the number of TSEC devices that were initialized
66790751910SMingkai Hu  */
66890751910SMingkai Hu int tsec_eth_init(bd_t *bis, struct tsec_info_struct *tsecs, int num)
66990751910SMingkai Hu {
67090751910SMingkai Hu 	int i;
67190751910SMingkai Hu 	int ret, count = 0;
67290751910SMingkai Hu 
67390751910SMingkai Hu 	for (i = 0; i < num; i++) {
67490751910SMingkai Hu 		ret = tsec_initialize(bis, &tsecs[i]);
67590751910SMingkai Hu 		if (ret > 0)
67690751910SMingkai Hu 			count += ret;
67790751910SMingkai Hu 	}
67890751910SMingkai Hu 
67990751910SMingkai Hu 	return count;
68090751910SMingkai Hu }
68190751910SMingkai Hu 
68290751910SMingkai Hu int tsec_standard_init(bd_t *bis)
68390751910SMingkai Hu {
684063c1263SAndy Fleming 	struct fsl_pq_mdio_info info;
685063c1263SAndy Fleming 
686aec84bf6SClaudiu Manoil 	info.regs = TSEC_GET_MDIO_REGS_BASE(1);
687063c1263SAndy Fleming 	info.name = DEFAULT_MII_NAME;
688063c1263SAndy Fleming 
689063c1263SAndy Fleming 	fsl_pq_mdio_init(bis, &info);
690063c1263SAndy Fleming 
69190751910SMingkai Hu 	return tsec_eth_init(bis, tsec_info, ARRAY_SIZE(tsec_info));
69290751910SMingkai Hu }
693