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	0xFFFFFFFF
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 0x2A:
474 		printf("qds: WRIOP: Supported SerDes1 Protocol 0x%02x\n",
475 		       serdes1_prtcl);
476 		break;
477 	default:
478 		printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
479 		       __func__, serdes1_prtcl);
480 		break;
481 	}
482 
483 	switch (serdes2_prtcl) {
484 	case 0x07:
485 	case 0x08:
486 	case 0x09:
487 	case 0x49:
488 		printf("qds: WRIOP: Supported SerDes2 Protocol 0x%02x\n",
489 		       serdes2_prtcl);
490 		lane_to_slot_fsm2[0] = EMI1_SLOT4;
491 		lane_to_slot_fsm2[1] = EMI1_SLOT4;
492 		lane_to_slot_fsm2[2] = EMI1_SLOT4;
493 		lane_to_slot_fsm2[3] = EMI1_SLOT4;
494 
495 		if (hwconfig_f("xqsgmii", env_hwconfig)) {
496 			lane_to_slot_fsm2[4] = EMI1_SLOT4;
497 			lane_to_slot_fsm2[5] = EMI1_SLOT4;
498 			lane_to_slot_fsm2[6] = EMI1_SLOT4;
499 			lane_to_slot_fsm2[7] = EMI1_SLOT4;
500 		} else {
501 			/* No MDIO physical connection */
502 			lane_to_slot_fsm2[4] = EMI1_SLOT6;
503 			lane_to_slot_fsm2[5] = EMI1_SLOT6;
504 			lane_to_slot_fsm2[6] = EMI1_SLOT6;
505 			lane_to_slot_fsm2[7] = EMI1_SLOT6;
506 		}
507 		break;
508 	default:
509 		printf(" %s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
510 		       __func__ , serdes2_prtcl);
511 		break;
512 	}
513 }
514 
515 void ls2080a_handle_phy_interface_sgmii(int dpmac_id)
516 {
517 	int lane, slot;
518 	struct mii_dev *bus;
519 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
520 	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
521 				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
522 		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
523 	int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
524 				FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
525 		>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
526 
527 	int *riser_phy_addr;
528 	char *env_hwconfig = getenv("hwconfig");
529 
530 	if (hwconfig_f("xqsgmii", env_hwconfig))
531 		riser_phy_addr = &xqsgii_riser_phy_addr[0];
532 	else
533 		riser_phy_addr = &sgmii_riser_phy_addr[0];
534 
535 	if (dpmac_id > WRIOP1_DPMAC9)
536 		goto serdes2;
537 
538 	switch (serdes1_prtcl) {
539 	case 0x07:
540 
541 		lane = serdes_get_first_lane(FSL_SRDS_1, SGMII1 + dpmac_id);
542 		slot = lane_to_slot_fsm1[lane];
543 
544 		switch (++slot) {
545 		case 1:
546 			/* Slot housing a SGMII riser card? */
547 			wriop_set_phy_address(dpmac_id,
548 					      riser_phy_addr[dpmac_id - 1]);
549 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
550 			bus = mii_dev_for_muxval(EMI1_SLOT1);
551 			wriop_set_mdio(dpmac_id, bus);
552 			break;
553 		case 2:
554 			/* Slot housing a SGMII riser card? */
555 			wriop_set_phy_address(dpmac_id,
556 					      riser_phy_addr[dpmac_id - 1]);
557 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT2;
558 			bus = mii_dev_for_muxval(EMI1_SLOT2);
559 			wriop_set_mdio(dpmac_id, bus);
560 			break;
561 		case 3:
562 			break;
563 		case 4:
564 			break;
565 		case 5:
566 			break;
567 		case 6:
568 			break;
569 		}
570 	break;
571 	default:
572 		printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
573 		       __func__ , serdes1_prtcl);
574 	break;
575 	}
576 
577 serdes2:
578 	switch (serdes2_prtcl) {
579 	case 0x07:
580 	case 0x08:
581 	case 0x49:
582 		lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 +
583 							(dpmac_id - 9));
584 		slot = lane_to_slot_fsm2[lane];
585 
586 		switch (++slot) {
587 		case 1:
588 			break;
589 		case 3:
590 			break;
591 		case 4:
592 			/* Slot housing a SGMII riser card? */
593 			wriop_set_phy_address(dpmac_id,
594 					      riser_phy_addr[dpmac_id - 9]);
595 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT4;
596 			bus = mii_dev_for_muxval(EMI1_SLOT4);
597 			wriop_set_mdio(dpmac_id, bus);
598 		break;
599 		case 5:
600 		break;
601 		case 6:
602 			/* Slot housing a SGMII riser card? */
603 			wriop_set_phy_address(dpmac_id,
604 					      riser_phy_addr[dpmac_id - 13]);
605 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT6;
606 			bus = mii_dev_for_muxval(EMI1_SLOT6);
607 			wriop_set_mdio(dpmac_id, bus);
608 		break;
609 	}
610 	break;
611 	default:
612 		printf("%s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
613 		       __func__, serdes2_prtcl);
614 	break;
615 	}
616 }
617 
618 void ls2080a_handle_phy_interface_qsgmii(int dpmac_id)
619 {
620 	int lane = 0, slot;
621 	struct mii_dev *bus;
622 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
623 	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
624 				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
625 		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
626 
627 	switch (serdes1_prtcl) {
628 	case 0x33:
629 		switch (dpmac_id) {
630 		case 1:
631 		case 2:
632 		case 3:
633 		case 4:
634 			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_A);
635 		break;
636 		case 5:
637 		case 6:
638 		case 7:
639 		case 8:
640 			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_B);
641 		break;
642 		case 9:
643 		case 10:
644 		case 11:
645 		case 12:
646 			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_C);
647 		break;
648 		case 13:
649 		case 14:
650 		case 15:
651 		case 16:
652 			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_D);
653 		break;
654 	}
655 
656 		slot = lane_to_slot_fsm1[lane];
657 
658 		switch (++slot) {
659 		case 1:
660 			/* Slot housing a QSGMII riser card? */
661 			wriop_set_phy_address(dpmac_id, dpmac_id - 1);
662 			dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
663 			bus = mii_dev_for_muxval(EMI1_SLOT1);
664 			wriop_set_mdio(dpmac_id, bus);
665 			break;
666 		case 3:
667 			break;
668 		case 4:
669 			break;
670 		case 5:
671 		break;
672 		case 6:
673 			break;
674 	}
675 	break;
676 	default:
677 		printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
678 		       serdes1_prtcl);
679 	break;
680 	}
681 
682 	qsgmii_configure_repeater(dpmac_id);
683 }
684 
685 void ls2080a_handle_phy_interface_xsgmii(int i)
686 {
687 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
688 	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
689 				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
690 		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
691 
692 	switch (serdes1_prtcl) {
693 	case 0x2A:
694 		/*
695 		 * XFI does not need a PHY to work, but to avoid U-Boot use
696 		 * default PHY address which is zero to a MAC when it found
697 		 * a MAC has no PHY address, we give a PHY address to XFI
698 		 * MAC, and should not use a real XAUI PHY address, since
699 		 * MDIO can access it successfully, and then MDIO thinks
700 		 * the XAUI card is used for the XFI MAC, which will cause
701 		 * error.
702 		 */
703 		wriop_set_phy_address(i, i + 4);
704 		ls2080a_qds_enable_SFP_TX(SFP_TX);
705 
706 		break;
707 	default:
708 		printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
709 		       serdes1_prtcl);
710 		break;
711 	}
712 }
713 #endif
714 
715 int board_eth_init(bd_t *bis)
716 {
717 	int error;
718 	char *mc_boot_env_var;
719 #ifdef CONFIG_FSL_MC_ENET
720 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
721 	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
722 				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
723 		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
724 	int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
725 				FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
726 		>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
727 
728 	struct memac_mdio_info *memac_mdio0_info;
729 	struct memac_mdio_info *memac_mdio1_info;
730 	unsigned int i;
731 	char *env_hwconfig;
732 
733 	env_hwconfig = getenv("hwconfig");
734 
735 	initialize_dpmac_to_slot();
736 
737 	memac_mdio0_info = (struct memac_mdio_info *)malloc(
738 					sizeof(struct memac_mdio_info));
739 	memac_mdio0_info->regs =
740 		(struct memac_mdio_controller *)
741 					CONFIG_SYS_FSL_WRIOP1_MDIO1;
742 	memac_mdio0_info->name = DEFAULT_WRIOP_MDIO1_NAME;
743 
744 	/* Register the real MDIO1 bus */
745 	fm_memac_mdio_init(bis, memac_mdio0_info);
746 
747 	memac_mdio1_info = (struct memac_mdio_info *)malloc(
748 					sizeof(struct memac_mdio_info));
749 	memac_mdio1_info->regs =
750 		(struct memac_mdio_controller *)
751 					CONFIG_SYS_FSL_WRIOP1_MDIO2;
752 	memac_mdio1_info->name = DEFAULT_WRIOP_MDIO2_NAME;
753 
754 	/* Register the real MDIO2 bus */
755 	fm_memac_mdio_init(bis, memac_mdio1_info);
756 
757 	/* Register the muxing front-ends to the MDIO buses */
758 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT1);
759 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT2);
760 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT3);
761 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT4);
762 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT5);
763 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT6);
764 
765 	ls2080a_qds_mdio_init(DEFAULT_WRIOP_MDIO2_NAME, EMI2);
766 
767 	for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
768 		switch (wriop_get_enet_if(i)) {
769 		case PHY_INTERFACE_MODE_QSGMII:
770 			ls2080a_handle_phy_interface_qsgmii(i);
771 			break;
772 		case PHY_INTERFACE_MODE_SGMII:
773 			ls2080a_handle_phy_interface_sgmii(i);
774 			break;
775 		case PHY_INTERFACE_MODE_XGMII:
776 			ls2080a_handle_phy_interface_xsgmii(i);
777 			break;
778 		default:
779 			break;
780 
781 		if (i == 16)
782 			i = NUM_WRIOP_PORTS;
783 		}
784 	}
785 
786 	mc_boot_env_var = getenv(MC_BOOT_ENV_VAR);
787 	if (mc_boot_env_var)
788 		run_command_list(mc_boot_env_var, -1, 0);
789 	error = cpu_eth_init(bis);
790 
791 	if (hwconfig_f("xqsgmii", env_hwconfig)) {
792 		if (serdes1_prtcl == 0x7)
793 			sgmii_configure_repeater(1);
794 		if (serdes2_prtcl == 0x7 || serdes2_prtcl == 0x8 ||
795 		    serdes2_prtcl == 0x49)
796 			sgmii_configure_repeater(2);
797 	}
798 #endif
799 	error = pci_eth_init(bis);
800 	return error;
801 }
802 
803 #ifdef CONFIG_FSL_MC_ENET
804 
805 #endif
806