xref: /rk3399_rockchip-uboot/board/freescale/ls2080aqds/eth.c (revision fc35addea2c0fa5add065c5ea09e206d4cba1abd)
1 /*
2  * Copyright 2015 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <netdev.h>
9 #include <asm/io.h>
10 #include <asm/arch/fsl_serdes.h>
11 #include <hwconfig.h>
12 #include <fsl_mdio.h>
13 #include <malloc.h>
14 #include <fm_eth.h>
15 #include <i2c.h>
16 #include <miiphy.h>
17 #include <fsl-mc/ldpaa_wriop.h>
18 
19 #include "../common/qixis.h"
20 
21 #include "ls2080aqds_qixis.h"
22 
23 #define MC_BOOT_ENV_VAR "mcinitcmd"
24 
25 #ifdef CONFIG_FSL_MC_ENET
26  /* - In LS2080A there are only 16 SERDES lanes, spread across 2 SERDES banks.
27  *   Bank 1 -> Lanes A, B, C, D, E, F, G, H
28  *   Bank 2 -> Lanes A,B, C, D, E, F, G, H
29  */
30 
31  /* Mapping of 16 SERDES lanes to LS2080A QDS board slots. A value of '0' here
32   * means that the mapping must be determined dynamically, or that the lane
33   * maps to something other than a board slot.
34   */
35 
36 static u8 lane_to_slot_fsm1[] = {
37 	0, 0, 0, 0, 0, 0, 0, 0
38 };
39 
40 static u8 lane_to_slot_fsm2[] = {
41 	0, 0, 0, 0, 0, 0, 0, 0
42 };
43 
44 /* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs
45  * housed.
46  */
47 
48 static int xqsgii_riser_phy_addr[] = {
49 	XQSGMII_CARD_PHY1_PORT0_ADDR,
50 	XQSGMII_CARD_PHY2_PORT0_ADDR,
51 	XQSGMII_CARD_PHY3_PORT0_ADDR,
52 	XQSGMII_CARD_PHY4_PORT0_ADDR,
53 	XQSGMII_CARD_PHY3_PORT2_ADDR,
54 	XQSGMII_CARD_PHY1_PORT2_ADDR,
55 	XQSGMII_CARD_PHY4_PORT2_ADDR,
56 	XQSGMII_CARD_PHY2_PORT2_ADDR,
57 };
58 
59 static int sgmii_riser_phy_addr[] = {
60 	SGMII_CARD_PORT1_PHY_ADDR,
61 	SGMII_CARD_PORT2_PHY_ADDR,
62 	SGMII_CARD_PORT3_PHY_ADDR,
63 	SGMII_CARD_PORT4_PHY_ADDR,
64 };
65 
66 /* Slot2 does not have EMI connections */
67 #define EMI_NONE	0xFF
68 #define EMI1_SLOT1	0
69 #define EMI1_SLOT2	1
70 #define EMI1_SLOT3	2
71 #define EMI1_SLOT4	3
72 #define EMI1_SLOT5	4
73 #define EMI1_SLOT6	5
74 #define EMI2		6
75 #define SFP_TX		0
76 
77 static const char * const mdio_names[] = {
78 	"LS2080A_QDS_MDIO0",
79 	"LS2080A_QDS_MDIO1",
80 	"LS2080A_QDS_MDIO2",
81 	"LS2080A_QDS_MDIO3",
82 	"LS2080A_QDS_MDIO4",
83 	"LS2080A_QDS_MDIO5",
84 	DEFAULT_WRIOP_MDIO2_NAME,
85 };
86 
87 struct ls2080a_qds_mdio {
88 	u8 muxval;
89 	struct mii_dev *realbus;
90 };
91 
92 static void sgmii_configure_repeater(int serdes_port)
93 {
94 	struct mii_dev *bus;
95 	uint8_t a = 0xf;
96 	int i, j, ret;
97 	int dpmac_id = 0, dpmac, mii_bus = 0;
98 	unsigned short value;
99 	char dev[2][20] = {"LS2080A_QDS_MDIO0", "LS2080A_QDS_MDIO3"};
100 	uint8_t i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5f, 0x60};
101 
102 	uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
103 	uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
104 	uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
105 	uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};
106 
107 	int *riser_phy_addr = &xqsgii_riser_phy_addr[0];
108 
109 	/* Set I2c to Slot 1 */
110 	i2c_write(0x77, 0, 0, &a, 1);
111 
112 	for (dpmac = 0; dpmac < 8; dpmac++) {
113 		/* Check the PHY status */
114 		switch (serdes_port) {
115 		case 1:
116 			mii_bus = 0;
117 			dpmac_id = dpmac + 1;
118 			break;
119 		case 2:
120 			mii_bus = 1;
121 			dpmac_id = dpmac + 9;
122 			a = 0xb;
123 			i2c_write(0x76, 0, 0, &a, 1);
124 			break;
125 		}
126 
127 		ret = miiphy_set_current_dev(dev[mii_bus]);
128 		if (ret > 0)
129 			goto error;
130 
131 		bus = mdio_get_current_dev();
132 		debug("Reading from bus %s\n", bus->name);
133 
134 		ret = miiphy_write(dev[mii_bus], riser_phy_addr[dpmac], 0x1f,
135 				   3);
136 		if (ret > 0)
137 			goto error;
138 
139 		mdelay(10);
140 		ret = miiphy_read(dev[mii_bus], riser_phy_addr[dpmac], 0x11,
141 				  &value);
142 		if (ret > 0)
143 			goto error;
144 
145 		mdelay(10);
146 
147 		if ((value & 0xfff) == 0x40f) {
148 			printf("DPMAC %d:PHY is ..... Configured\n", dpmac_id);
149 			continue;
150 		}
151 
152 		for (i = 0; i < 4; i++) {
153 			for (j = 0; j < 4; j++) {
154 				a = 0x18;
155 				i2c_write(i2c_addr[dpmac], 6, 1, &a, 1);
156 				a = 0x38;
157 				i2c_write(i2c_addr[dpmac], 4, 1, &a, 1);
158 				a = 0x4;
159 				i2c_write(i2c_addr[dpmac], 8, 1, &a, 1);
160 
161 				i2c_write(i2c_addr[dpmac], 0xf, 1,
162 					  &ch_a_eq[i], 1);
163 				i2c_write(i2c_addr[dpmac], 0x11, 1,
164 					  &ch_a_ctl2[j], 1);
165 
166 				i2c_write(i2c_addr[dpmac], 0x16, 1,
167 					  &ch_b_eq[i], 1);
168 				i2c_write(i2c_addr[dpmac], 0x18, 1,
169 					  &ch_b_ctl2[j], 1);
170 
171 				a = 0x14;
172 				i2c_write(i2c_addr[dpmac], 0x23, 1, &a, 1);
173 				a = 0xb5;
174 				i2c_write(i2c_addr[dpmac], 0x2d, 1, &a, 1);
175 				a = 0x20;
176 				i2c_write(i2c_addr[dpmac], 4, 1, &a, 1);
177 				mdelay(100);
178 				ret = miiphy_read(dev[mii_bus],
179 						  riser_phy_addr[dpmac],
180 						  0x11, &value);
181 				if (ret > 0)
182 					goto error;
183 
184 				mdelay(1);
185 				ret = miiphy_read(dev[mii_bus],
186 						  riser_phy_addr[dpmac],
187 						  0x11, &value);
188 				if (ret > 0)
189 					goto error;
190 				mdelay(10);
191 
192 				if ((value & 0xfff) == 0x40f) {
193 					printf("DPMAC %d :PHY is configured ",
194 					       dpmac_id);
195 					printf("after setting repeater 0x%x\n",
196 					       value);
197 					i = 5;
198 					j = 5;
199 				} else
200 					printf("DPMAC %d :PHY is failed to ",
201 					       dpmac_id);
202 					printf("configure the repeater 0x%x\n",
203 					       value);
204 				}
205 		}
206 	}
207 error:
208 	if (ret)
209 		printf("DPMAC %d ..... FAILED to configure PHY\n", dpmac_id);
210 	return;
211 }
212 
213 static void qsgmii_configure_repeater(int dpmac)
214 {
215 	uint8_t a = 0xf;
216 	int i, j;
217 	int i2c_phy_addr = 0;
218 	int phy_addr = 0;
219 	int i2c_addr[] = {0x58, 0x59, 0x5a, 0x5b};
220 
221 	uint8_t ch_a_eq[] = {0x1, 0x2, 0x3, 0x7};
222 	uint8_t ch_a_ctl2[] = {0x81, 0x82, 0x83, 0x84};
223 	uint8_t ch_b_eq[] = {0x1, 0x2, 0x3, 0x7};
224 	uint8_t ch_b_ctl2[] = {0x81, 0x82, 0x83, 0x84};
225 
226 	const char *dev = "LS2080A_QDS_MDIO0";
227 	int ret = 0;
228 	unsigned short value;
229 
230 	/* Set I2c to Slot 1 */
231 	i2c_write(0x77, 0, 0, &a, 1);
232 
233 	switch (dpmac) {
234 	case 1:
235 	case 2:
236 	case 3:
237 	case 4:
238 		i2c_phy_addr = i2c_addr[0];
239 		phy_addr = 0;
240 		break;
241 
242 	case 5:
243 	case 6:
244 	case 7:
245 	case 8:
246 		i2c_phy_addr = i2c_addr[1];
247 		phy_addr = 4;
248 		break;
249 
250 	case 9:
251 	case 10:
252 	case 11:
253 	case 12:
254 		i2c_phy_addr = i2c_addr[2];
255 		phy_addr = 8;
256 		break;
257 
258 	case 13:
259 	case 14:
260 	case 15:
261 	case 16:
262 		i2c_phy_addr = i2c_addr[3];
263 		phy_addr = 0xc;
264 		break;
265 	}
266 
267 	/* Check the PHY status */
268 	ret = miiphy_set_current_dev(dev);
269 	ret = miiphy_write(dev, phy_addr, 0x1f, 3);
270 	mdelay(10);
271 	ret = miiphy_read(dev, phy_addr, 0x11, &value);
272 	mdelay(10);
273 	ret = miiphy_read(dev, phy_addr, 0x11, &value);
274 	mdelay(10);
275 	if ((value & 0xf) == 0xf) {
276 		printf("DPMAC %d :PHY is ..... Configured\n", dpmac);
277 		return;
278 	}
279 
280 	for (i = 0; i < 4; i++) {
281 		for (j = 0; j < 4; j++) {
282 			a = 0x18;
283 			i2c_write(i2c_phy_addr, 6, 1, &a, 1);
284 			a = 0x38;
285 			i2c_write(i2c_phy_addr, 4, 1, &a, 1);
286 			a = 0x4;
287 			i2c_write(i2c_phy_addr, 8, 1, &a, 1);
288 
289 			i2c_write(i2c_phy_addr, 0xf, 1, &ch_a_eq[i], 1);
290 			i2c_write(i2c_phy_addr, 0x11, 1, &ch_a_ctl2[j], 1);
291 
292 			i2c_write(i2c_phy_addr, 0x16, 1, &ch_b_eq[i], 1);
293 			i2c_write(i2c_phy_addr, 0x18, 1, &ch_b_ctl2[j], 1);
294 
295 			a = 0x14;
296 			i2c_write(i2c_phy_addr, 0x23, 1, &a, 1);
297 			a = 0xb5;
298 			i2c_write(i2c_phy_addr, 0x2d, 1, &a, 1);
299 			a = 0x20;
300 			i2c_write(i2c_phy_addr, 4, 1, &a, 1);
301 			mdelay(100);
302 			ret = miiphy_read(dev, phy_addr, 0x11, &value);
303 			if (ret > 0)
304 				goto error;
305 			mdelay(1);
306 			ret = miiphy_read(dev, phy_addr, 0x11, &value);
307 			if (ret > 0)
308 				goto error;
309 			mdelay(10);
310 			if ((value & 0xf) == 0xf) {
311 				printf("DPMAC %d :PHY is ..... Configured\n",
312 				       dpmac);
313 				return;
314 			}
315 		}
316 	}
317 error:
318 	printf("DPMAC %d :PHY ..... FAILED to configure PHY\n", dpmac);
319 	return;
320 }
321 
322 static const char *ls2080a_qds_mdio_name_for_muxval(u8 muxval)
323 {
324 	return mdio_names[muxval];
325 }
326 
327 struct mii_dev *mii_dev_for_muxval(u8 muxval)
328 {
329 	struct mii_dev *bus;
330 	const char *name = ls2080a_qds_mdio_name_for_muxval(muxval);
331 
332 	if (!name) {
333 		printf("No bus for muxval %x\n", muxval);
334 		return NULL;
335 	}
336 
337 	bus = miiphy_get_dev_by_name(name);
338 
339 	if (!bus) {
340 		printf("No bus by name %s\n", name);
341 		return NULL;
342 	}
343 
344 	return bus;
345 }
346 
347 static void ls2080a_qds_enable_SFP_TX(u8 muxval)
348 {
349 	u8 brdcfg9;
350 
351 	brdcfg9 = QIXIS_READ(brdcfg[9]);
352 	brdcfg9 &= ~BRDCFG9_SFPTX_MASK;
353 	brdcfg9 |= (muxval << BRDCFG9_SFPTX_SHIFT);
354 	QIXIS_WRITE(brdcfg[9], brdcfg9);
355 }
356 
357 static void ls2080a_qds_mux_mdio(u8 muxval)
358 {
359 	u8 brdcfg4;
360 
361 	if (muxval <= 5) {
362 		brdcfg4 = QIXIS_READ(brdcfg[4]);
363 		brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
364 		brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
365 		QIXIS_WRITE(brdcfg[4], brdcfg4);
366 	}
367 }
368 
369 static int ls2080a_qds_mdio_read(struct mii_dev *bus, int addr,
370 				 int devad, int regnum)
371 {
372 	struct ls2080a_qds_mdio *priv = bus->priv;
373 
374 	ls2080a_qds_mux_mdio(priv->muxval);
375 
376 	return priv->realbus->read(priv->realbus, addr, devad, regnum);
377 }
378 
379 static int ls2080a_qds_mdio_write(struct mii_dev *bus, int addr, int devad,
380 				  int regnum, u16 value)
381 {
382 	struct ls2080a_qds_mdio *priv = bus->priv;
383 
384 	ls2080a_qds_mux_mdio(priv->muxval);
385 
386 	return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
387 }
388 
389 static int ls2080a_qds_mdio_reset(struct mii_dev *bus)
390 {
391 	struct ls2080a_qds_mdio *priv = bus->priv;
392 
393 	return priv->realbus->reset(priv->realbus);
394 }
395 
396 static int ls2080a_qds_mdio_init(char *realbusname, u8 muxval)
397 {
398 	struct ls2080a_qds_mdio *pmdio;
399 	struct mii_dev *bus = mdio_alloc();
400 
401 	if (!bus) {
402 		printf("Failed to allocate ls2080a_qds MDIO bus\n");
403 		return -1;
404 	}
405 
406 	pmdio = malloc(sizeof(*pmdio));
407 	if (!pmdio) {
408 		printf("Failed to allocate ls2080a_qds private data\n");
409 		free(bus);
410 		return -1;
411 	}
412 
413 	bus->read = ls2080a_qds_mdio_read;
414 	bus->write = ls2080a_qds_mdio_write;
415 	bus->reset = ls2080a_qds_mdio_reset;
416 	strcpy(bus->name, ls2080a_qds_mdio_name_for_muxval(muxval));
417 
418 	pmdio->realbus = miiphy_get_dev_by_name(realbusname);
419 
420 	if (!pmdio->realbus) {
421 		printf("No bus with name %s\n", realbusname);
422 		free(bus);
423 		free(pmdio);
424 		return -1;
425 	}
426 
427 	pmdio->muxval = muxval;
428 	bus->priv = pmdio;
429 
430 	return mdio_register(bus);
431 }
432 
433 /*
434  * Initialize the dpmac_info array.
435  *
436  */
437 static void initialize_dpmac_to_slot(void)
438 {
439 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
440 	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
441 				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
442 		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
443 	int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
444 				FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
445 		>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
446 
447 	char *env_hwconfig;
448 	env_hwconfig = getenv("hwconfig");
449 
450 	switch (serdes1_prtcl) {
451 	case 0x07:
452 	case 0x09:
453 	case 0x33:
454 		printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
455 		       serdes1_prtcl);
456 		lane_to_slot_fsm1[0] = EMI1_SLOT1;
457 		lane_to_slot_fsm1[1] = EMI1_SLOT1;
458 		lane_to_slot_fsm1[2] = EMI1_SLOT1;
459 		lane_to_slot_fsm1[3] = EMI1_SLOT1;
460 		if (hwconfig_f("xqsgmii", env_hwconfig)) {
461 			lane_to_slot_fsm1[4] = EMI1_SLOT1;
462 			lane_to_slot_fsm1[5] = EMI1_SLOT1;
463 			lane_to_slot_fsm1[6] = EMI1_SLOT1;
464 			lane_to_slot_fsm1[7] = EMI1_SLOT1;
465 		} else {
466 			lane_to_slot_fsm1[4] = EMI1_SLOT2;
467 			lane_to_slot_fsm1[5] = EMI1_SLOT2;
468 			lane_to_slot_fsm1[6] = EMI1_SLOT2;
469 			lane_to_slot_fsm1[7] = EMI1_SLOT2;
470 		}
471 		break;
472 
473 	case 0x39:
474 		printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
475 		       serdes1_prtcl);
476 		if (hwconfig_f("xqsgmii", env_hwconfig)) {
477 			lane_to_slot_fsm1[0] = EMI1_SLOT3;
478 			lane_to_slot_fsm1[1] = EMI1_SLOT3;
479 			lane_to_slot_fsm1[2] = EMI1_SLOT3;
480 			lane_to_slot_fsm1[3] = EMI_NONE;
481 		} else {
482 			lane_to_slot_fsm1[0] = EMI_NONE;
483 			lane_to_slot_fsm1[1] = EMI_NONE;
484 			lane_to_slot_fsm1[2] = EMI_NONE;
485 			lane_to_slot_fsm1[3] = EMI_NONE;
486 		}
487 		lane_to_slot_fsm1[4] = EMI1_SLOT3;
488 		lane_to_slot_fsm1[5] = EMI1_SLOT3;
489 		lane_to_slot_fsm1[6] = EMI1_SLOT3;
490 		lane_to_slot_fsm1[7] = EMI_NONE;
491 		break;
492 
493 	case 0x4D:
494 		printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
495 		       serdes1_prtcl);
496 		if (hwconfig_f("xqsgmii", env_hwconfig)) {
497 			lane_to_slot_fsm1[0] = EMI1_SLOT3;
498 			lane_to_slot_fsm1[1] = EMI1_SLOT3;
499 			lane_to_slot_fsm1[2] = EMI_NONE;
500 			lane_to_slot_fsm1[3] = EMI_NONE;
501 		} else {
502 			lane_to_slot_fsm1[0] = EMI_NONE;
503 			lane_to_slot_fsm1[1] = EMI_NONE;
504 			lane_to_slot_fsm1[2] = EMI_NONE;
505 			lane_to_slot_fsm1[3] = EMI_NONE;
506 		}
507 		lane_to_slot_fsm1[4] = EMI1_SLOT3;
508 		lane_to_slot_fsm1[5] = EMI1_SLOT3;
509 		lane_to_slot_fsm1[6] = EMI_NONE;
510 		lane_to_slot_fsm1[7] = EMI_NONE;
511 		break;
512 
513 	case 0x2A:
514 	case 0x4B:
515 	case 0x4C:
516 		printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
517 		       serdes1_prtcl);
518 		break;
519 	default:
520 		printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
521 		       __func__, serdes1_prtcl);
522 		break;
523 	}
524 
525 	switch (serdes2_prtcl) {
526 	case 0x07:
527 	case 0x08:
528 	case 0x09:
529 	case 0x49:
530 		printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
531 		       serdes2_prtcl);
532 		lane_to_slot_fsm2[0] = EMI1_SLOT4;
533 		lane_to_slot_fsm2[1] = EMI1_SLOT4;
534 		lane_to_slot_fsm2[2] = EMI1_SLOT4;
535 		lane_to_slot_fsm2[3] = EMI1_SLOT4;
536 
537 		if (hwconfig_f("xqsgmii", env_hwconfig)) {
538 			lane_to_slot_fsm2[4] = EMI1_SLOT4;
539 			lane_to_slot_fsm2[5] = EMI1_SLOT4;
540 			lane_to_slot_fsm2[6] = EMI1_SLOT4;
541 			lane_to_slot_fsm2[7] = EMI1_SLOT4;
542 		} else {
543 			/* No MDIO physical connection */
544 			lane_to_slot_fsm2[4] = EMI1_SLOT6;
545 			lane_to_slot_fsm2[5] = EMI1_SLOT6;
546 			lane_to_slot_fsm2[6] = EMI1_SLOT6;
547 			lane_to_slot_fsm2[7] = EMI1_SLOT6;
548 		}
549 		break;
550 
551 	case 0x47:
552 		printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
553 		       serdes2_prtcl);
554 		lane_to_slot_fsm2[0] = EMI_NONE;
555 		lane_to_slot_fsm2[1] = EMI1_SLOT5;
556 		lane_to_slot_fsm2[2] = EMI1_SLOT5;
557 		lane_to_slot_fsm2[3] = EMI1_SLOT5;
558 
559 		if (hwconfig_f("xqsgmii", env_hwconfig)) {
560 			lane_to_slot_fsm2[4] = EMI_NONE;
561 			lane_to_slot_fsm2[5] = EMI1_SLOT5;
562 			lane_to_slot_fsm2[6] = EMI1_SLOT5;
563 			lane_to_slot_fsm2[7] = EMI1_SLOT5;
564 		}
565 		break;
566 
567 	case 0x57:
568 		printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
569 		       serdes2_prtcl);
570 		if (hwconfig_f("xqsgmii", env_hwconfig)) {
571 			lane_to_slot_fsm2[0] = EMI_NONE;
572 			lane_to_slot_fsm2[1] = EMI_NONE;
573 			lane_to_slot_fsm2[2] = EMI_NONE;
574 			lane_to_slot_fsm2[3] = EMI_NONE;
575 		}
576 		lane_to_slot_fsm2[4] = EMI_NONE;
577 		lane_to_slot_fsm2[5] = EMI_NONE;
578 		lane_to_slot_fsm2[6] = EMI1_SLOT5;
579 		lane_to_slot_fsm2[7] = EMI1_SLOT5;
580 		break;
581 
582 	default:
583 		printf(" %s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
584 		       __func__ , serdes2_prtcl);
585 		break;
586 	}
587 }
588 
589 void ls2080a_handle_phy_interface_sgmii(int dpmac_id)
590 {
591 	int lane, slot;
592 	struct mii_dev *bus;
593 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
594 	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
595 				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
596 		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
597 	int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
598 				FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
599 		>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
600 
601 	int *riser_phy_addr;
602 	char *env_hwconfig = getenv("hwconfig");
603 
604 	if (hwconfig_f("xqsgmii", env_hwconfig))
605 		riser_phy_addr = &xqsgii_riser_phy_addr[0];
606 	else
607 		riser_phy_addr = &sgmii_riser_phy_addr[0];
608 
609 	if (dpmac_id > WRIOP1_DPMAC9)
610 		goto serdes2;
611 
612 	switch (serdes1_prtcl) {
613 	case 0x07:
614 	case 0x39:
615 	case 0x4D:
616 		lane = serdes_get_first_lane(FSL_SRDS_1, SGMII1 + dpmac_id - 1);
617 
618 		slot = lane_to_slot_fsm1[lane];
619 
620 		switch (++slot) {
621 		case 1:
622 			/* Slot housing a SGMII riser card? */
623 			wriop_set_phy_address(dpmac_id,
624 					      riser_phy_addr[dpmac_id - 1]);
625 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
626 			bus = mii_dev_for_muxval(EMI1_SLOT1);
627 			wriop_set_mdio(dpmac_id, bus);
628 			break;
629 		case 2:
630 			/* Slot housing a SGMII riser card? */
631 			wriop_set_phy_address(dpmac_id,
632 					      riser_phy_addr[dpmac_id - 1]);
633 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT2;
634 			bus = mii_dev_for_muxval(EMI1_SLOT2);
635 			wriop_set_mdio(dpmac_id, bus);
636 			break;
637 		case 3:
638 			if (slot == EMI_NONE)
639 				return;
640 			if (serdes1_prtcl == 0x39) {
641 				wriop_set_phy_address(dpmac_id,
642 					riser_phy_addr[dpmac_id - 2]);
643 				if (dpmac_id >= 6 && hwconfig_f("xqsgmii",
644 								env_hwconfig))
645 					wriop_set_phy_address(dpmac_id,
646 						riser_phy_addr[dpmac_id - 3]);
647 			} else {
648 				wriop_set_phy_address(dpmac_id,
649 					riser_phy_addr[dpmac_id - 2]);
650 				if (dpmac_id >= 7 && hwconfig_f("xqsgmii",
651 								env_hwconfig))
652 					wriop_set_phy_address(dpmac_id,
653 						riser_phy_addr[dpmac_id - 3]);
654 			}
655 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT3;
656 			bus = mii_dev_for_muxval(EMI1_SLOT3);
657 			wriop_set_mdio(dpmac_id, bus);
658 			break;
659 		case 4:
660 			break;
661 		case 5:
662 			break;
663 		case 6:
664 			break;
665 		}
666 	break;
667 	default:
668 		printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
669 		       __func__ , serdes1_prtcl);
670 	break;
671 	}
672 
673 serdes2:
674 	switch (serdes2_prtcl) {
675 	case 0x07:
676 	case 0x08:
677 	case 0x49:
678 	case 0x47:
679 	case 0x57:
680 		lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 +
681 							(dpmac_id - 9));
682 		slot = lane_to_slot_fsm2[lane];
683 
684 		switch (++slot) {
685 		case 1:
686 			break;
687 		case 3:
688 			break;
689 		case 4:
690 			/* Slot housing a SGMII riser card? */
691 			wriop_set_phy_address(dpmac_id,
692 					      riser_phy_addr[dpmac_id - 9]);
693 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT4;
694 			bus = mii_dev_for_muxval(EMI1_SLOT4);
695 			wriop_set_mdio(dpmac_id, bus);
696 		break;
697 		case 5:
698 			if (slot == EMI_NONE)
699 				return;
700 			if (serdes2_prtcl == 0x47) {
701 				wriop_set_phy_address(dpmac_id,
702 					      riser_phy_addr[dpmac_id - 10]);
703 				if (dpmac_id >= 14 && hwconfig_f("xqsgmii",
704 								 env_hwconfig))
705 					wriop_set_phy_address(dpmac_id,
706 						riser_phy_addr[dpmac_id - 11]);
707 			} else {
708 				wriop_set_phy_address(dpmac_id,
709 					riser_phy_addr[dpmac_id - 11]);
710 			}
711 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT5;
712 			bus = mii_dev_for_muxval(EMI1_SLOT5);
713 			wriop_set_mdio(dpmac_id, bus);
714 			break;
715 		case 6:
716 			/* Slot housing a SGMII riser card? */
717 			wriop_set_phy_address(dpmac_id,
718 					      riser_phy_addr[dpmac_id - 13]);
719 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT6;
720 			bus = mii_dev_for_muxval(EMI1_SLOT6);
721 			wriop_set_mdio(dpmac_id, bus);
722 		break;
723 	}
724 	break;
725 	default:
726 		printf("%s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
727 		       __func__, serdes2_prtcl);
728 	break;
729 	}
730 }
731 
732 void ls2080a_handle_phy_interface_qsgmii(int dpmac_id)
733 {
734 	int lane = 0, slot;
735 	struct mii_dev *bus;
736 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
737 	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
738 				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
739 		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
740 
741 	switch (serdes1_prtcl) {
742 	case 0x33:
743 		switch (dpmac_id) {
744 		case 1:
745 		case 2:
746 		case 3:
747 		case 4:
748 			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_A);
749 		break;
750 		case 5:
751 		case 6:
752 		case 7:
753 		case 8:
754 			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_B);
755 		break;
756 		case 9:
757 		case 10:
758 		case 11:
759 		case 12:
760 			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_C);
761 		break;
762 		case 13:
763 		case 14:
764 		case 15:
765 		case 16:
766 			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_D);
767 		break;
768 	}
769 
770 		slot = lane_to_slot_fsm1[lane];
771 
772 		switch (++slot) {
773 		case 1:
774 			/* Slot housing a QSGMII riser card? */
775 			wriop_set_phy_address(dpmac_id, dpmac_id - 1);
776 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
777 			bus = mii_dev_for_muxval(EMI1_SLOT1);
778 			wriop_set_mdio(dpmac_id, bus);
779 			break;
780 		case 3:
781 			break;
782 		case 4:
783 			break;
784 		case 5:
785 		break;
786 		case 6:
787 			break;
788 	}
789 	break;
790 	default:
791 		printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
792 		       serdes1_prtcl);
793 	break;
794 	}
795 
796 	qsgmii_configure_repeater(dpmac_id);
797 }
798 
799 void ls2080a_handle_phy_interface_xsgmii(int i)
800 {
801 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
802 	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
803 				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
804 		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
805 
806 	switch (serdes1_prtcl) {
807 	case 0x2A:
808 	case 0x4B:
809 	case 0x4C:
810 		/*
811 		 * XFI does not need a PHY to work, but to avoid U-Boot use
812 		 * default PHY address which is zero to a MAC when it found
813 		 * a MAC has no PHY address, we give a PHY address to XFI
814 		 * MAC, and should not use a real XAUI PHY address, since
815 		 * MDIO can access it successfully, and then MDIO thinks
816 		 * the XAUI card is used for the XFI MAC, which will cause
817 		 * error.
818 		 */
819 		wriop_set_phy_address(i, i + 4);
820 		ls2080a_qds_enable_SFP_TX(SFP_TX);
821 
822 		break;
823 	default:
824 		printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
825 		       serdes1_prtcl);
826 		break;
827 	}
828 }
829 #endif
830 
831 int board_eth_init(bd_t *bis)
832 {
833 	int error;
834 	char *mc_boot_env_var;
835 #ifdef CONFIG_FSL_MC_ENET
836 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
837 	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
838 				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
839 		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
840 	int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
841 				FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
842 		>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
843 
844 	struct memac_mdio_info *memac_mdio0_info;
845 	struct memac_mdio_info *memac_mdio1_info;
846 	unsigned int i;
847 	char *env_hwconfig;
848 
849 	env_hwconfig = getenv("hwconfig");
850 
851 	initialize_dpmac_to_slot();
852 
853 	memac_mdio0_info = (struct memac_mdio_info *)malloc(
854 					sizeof(struct memac_mdio_info));
855 	memac_mdio0_info->regs =
856 		(struct memac_mdio_controller *)
857 					CONFIG_SYS_FSL_WRIOP1_MDIO1;
858 	memac_mdio0_info->name = DEFAULT_WRIOP_MDIO1_NAME;
859 
860 	/* Register the real MDIO1 bus */
861 	fm_memac_mdio_init(bis, memac_mdio0_info);
862 
863 	memac_mdio1_info = (struct memac_mdio_info *)malloc(
864 					sizeof(struct memac_mdio_info));
865 	memac_mdio1_info->regs =
866 		(struct memac_mdio_controller *)
867 					CONFIG_SYS_FSL_WRIOP1_MDIO2;
868 	memac_mdio1_info->name = DEFAULT_WRIOP_MDIO2_NAME;
869 
870 	/* Register the real MDIO2 bus */
871 	fm_memac_mdio_init(bis, memac_mdio1_info);
872 
873 	/* Register the muxing front-ends to the MDIO buses */
874 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT1);
875 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT2);
876 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT3);
877 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT4);
878 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT5);
879 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT6);
880 
881 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO2_NAME, EMI2);
882 
883 	for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
884 		switch (wriop_get_enet_if(i)) {
885 		case PHY_INTERFACE_MODE_QSGMII:
886 			ls2080a_handle_phy_interface_qsgmii(i);
887 			break;
888 		case PHY_INTERFACE_MODE_SGMII:
889 			ls2080a_handle_phy_interface_sgmii(i);
890 			break;
891 		case PHY_INTERFACE_MODE_XGMII:
892 			ls2080a_handle_phy_interface_xsgmii(i);
893 			break;
894 		default:
895 			break;
896 
897 		if (i == 16)
898 			i = NUM_WRIOP_PORTS;
899 		}
900 	}
901 
902 	mc_boot_env_var = getenv(MC_BOOT_ENV_VAR);
903 	if (mc_boot_env_var)
904 		run_command_list(mc_boot_env_var, -1, 0);
905 	error = cpu_eth_init(bis);
906 
907 	if (hwconfig_f("xqsgmii", env_hwconfig)) {
908 		if (serdes1_prtcl == 0x7)
909 			sgmii_configure_repeater(1);
910 		if (serdes2_prtcl == 0x7 || serdes2_prtcl == 0x8 ||
911 		    serdes2_prtcl == 0x49)
912 			sgmii_configure_repeater(2);
913 	}
914 #endif
915 	error = pci_eth_init(bis);
916 	return error;
917 }
918 
919 #ifdef CONFIG_FSL_MC_ENET
920 
921 #endif
922