]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
cba46148 TT |
2 | /* |
3 | * Copyright 2009-2011 Freescale Semiconductor, Inc. | |
4 | * Author: Timur Tabi <timur@freescale.com> | |
cba46148 TT |
5 | */ |
6 | ||
7 | /* | |
8 | * This file handles the board muxing between the Fman Ethernet MACs and | |
9 | * the RGMII/SGMII/XGMII PHYs on a Freescale P3041/P5020 "Hydra" reference | |
10 | * board. The RGMII PHYs are the two on-board 1Gb ports. The SGMII PHYs are | |
11 | * provided by the standard Freescale four-port SGMII riser card. The 10Gb | |
12 | * XGMII PHY is provided via the XAUI riser card. Since there is only one | |
13 | * Fman device on a P3041 and P5020, we only support one SGMII card and one | |
14 | * RGMII card. | |
15 | * | |
16 | * Muxing is handled via the PIXIS BRDCFG1 register. The EMI1 bits control | |
17 | * muxing among the RGMII PHYs and the SGMII PHYs. The value for RGMII is | |
18 | * always the same (0). The value for SGMII depends on which slot the riser is | |
19 | * inserted in. The EMI2 bits control muxing for the the XGMII. Like SGMII, | |
20 | * the value is based on which slot the XAUI is inserted in. | |
21 | * | |
22 | * The SERDES configuration is used to determine where the SGMII and XAUI cards | |
23 | * exist, and also which Fman MACs are routed to which PHYs. So for a given | |
24 | * Fman MAC, there is one and only PHY it connects to. MACs cannot be routed | |
25 | * to PHYs dynamically. | |
26 | * | |
27 | * | |
28 | * This file also updates the device tree in three ways: | |
29 | * | |
30 | * 1) The status of each virtual MDIO node that is referenced by an Ethernet | |
31 | * node is set to "okay". | |
32 | * | |
33 | * 2) The phy-handle property of each active Ethernet MAC node is set to the | |
34 | * appropriate PHY node. | |
35 | * | |
36 | * 3) The "mux value" for each virtual MDIO node is set to the correct value, | |
37 | * if necessary. Some virtual MDIO nodes do not have configurable mux | |
38 | * values, so those values are hard-coded in the DTS. On the HYDRA board, | |
39 | * the virtual MDIO node for the SGMII card needs to be updated. | |
40 | * | |
41 | * For all this to work, the device tree needs to have the following: | |
42 | * | |
43 | * 1) An alias for each PHY node that an Ethernet node could be routed to. | |
44 | * | |
45 | * 2) An alias for each real and virtual MDIO node that is disabled by default | |
46 | * and might need to be enabled, and also might need to have its mux-value | |
47 | * updated. | |
48 | */ | |
49 | ||
50 | #include <common.h> | |
90526e9f | 51 | #include <net.h> |
cba46148 TT |
52 | #include <netdev.h> |
53 | #include <asm/fsl_serdes.h> | |
54 | #include <fm_eth.h> | |
55 | #include <fsl_mdio.h> | |
56 | #include <malloc.h> | |
2a523f52 | 57 | #include <fdt_support.h> |
8225b2fd | 58 | #include <fsl_dtsec.h> |
cba46148 TT |
59 | |
60 | #include "../common/ngpixis.h" | |
61 | #include "../common/fman.h" | |
62 | ||
63 | #ifdef CONFIG_FMAN_ENET | |
64 | ||
b41f1263 | 65 | #define BRDCFG1_EMI1_SEL_MASK 0x78 |
cba46148 TT |
66 | #define BRDCFG1_EMI1_SEL_SLOT1 0x10 |
67 | #define BRDCFG1_EMI1_SEL_SLOT2 0x20 | |
68 | #define BRDCFG1_EMI1_SEL_SLOT5 0x30 | |
69 | #define BRDCFG1_EMI1_SEL_SLOT6 0x40 | |
70 | #define BRDCFG1_EMI1_SEL_SLOT7 0x50 | |
71 | #define BRDCFG1_EMI1_SEL_RGMII 0x00 | |
72 | #define BRDCFG1_EMI1_EN 0x08 | |
73 | #define BRDCFG1_EMI2_SEL_MASK 0x06 | |
74 | #define BRDCFG1_EMI2_SEL_SLOT1 0x00 | |
75 | #define BRDCFG1_EMI2_SEL_SLOT2 0x02 | |
76 | ||
77 | #define BRDCFG2_REG_GPIO_SEL 0x20 | |
78 | ||
ffee1dde ZQ |
79 | #define PHY_BASE_ADDR 0x00 |
80 | ||
cba46148 TT |
81 | /* |
82 | * BRDCFG1 mask and value for each MAC | |
83 | * | |
84 | * This array contains the BRDCFG1 values (in mask/val format) that route the | |
85 | * MDIO bus to a particular RGMII or SGMII PHY. | |
86 | */ | |
87 | struct { | |
88 | u8 mask; | |
89 | u8 val; | |
90 | } mdio_mux[NUM_FM_PORTS]; | |
91 | ||
92 | /* | |
93 | * Mapping of all 18 SERDES lanes to board slots. A value of '0' here means | |
94 | * that the mapping must be determined dynamically, or that the lane maps to | |
95 | * something other than a board slot | |
96 | */ | |
97 | static u8 lane_to_slot[] = { | |
98 | 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 0, 0 | |
99 | }; | |
100 | ||
101 | /* | |
102 | * Set the board muxing for a given MAC | |
103 | * | |
104 | * The MDIO layer calls this function every time it wants to talk to a PHY. | |
105 | */ | |
106 | void hydra_mux_mdio(u8 mask, u8 val) | |
107 | { | |
108 | clrsetbits_8(&pixis->brdcfg1, mask, val); | |
109 | } | |
110 | ||
111 | struct hydra_mdio { | |
112 | u8 mask; | |
113 | u8 val; | |
114 | struct mii_dev *realbus; | |
115 | }; | |
116 | ||
117 | static int hydra_mdio_read(struct mii_dev *bus, int addr, int devad, | |
118 | int regnum) | |
119 | { | |
120 | struct hydra_mdio *priv = bus->priv; | |
121 | ||
122 | hydra_mux_mdio(priv->mask, priv->val); | |
123 | ||
124 | return priv->realbus->read(priv->realbus, addr, devad, regnum); | |
125 | } | |
126 | ||
127 | static int hydra_mdio_write(struct mii_dev *bus, int addr, int devad, | |
128 | int regnum, u16 value) | |
129 | { | |
130 | struct hydra_mdio *priv = bus->priv; | |
131 | ||
132 | hydra_mux_mdio(priv->mask, priv->val); | |
133 | ||
134 | return priv->realbus->write(priv->realbus, addr, devad, regnum, value); | |
135 | } | |
136 | ||
137 | static int hydra_mdio_reset(struct mii_dev *bus) | |
138 | { | |
139 | struct hydra_mdio *priv = bus->priv; | |
140 | ||
141 | return priv->realbus->reset(priv->realbus); | |
142 | } | |
143 | ||
144 | static void hydra_mdio_set_mux(char *name, u8 mask, u8 val) | |
145 | { | |
146 | struct mii_dev *bus = miiphy_get_dev_by_name(name); | |
147 | struct hydra_mdio *priv = bus->priv; | |
148 | ||
149 | priv->mask = mask; | |
150 | priv->val = val; | |
151 | } | |
152 | ||
153 | static int hydra_mdio_init(char *realbusname, char *fakebusname) | |
154 | { | |
155 | struct hydra_mdio *hmdio; | |
156 | struct mii_dev *bus = mdio_alloc(); | |
157 | ||
158 | if (!bus) { | |
159 | printf("Failed to allocate Hydra MDIO bus\n"); | |
160 | return -1; | |
161 | } | |
162 | ||
163 | hmdio = malloc(sizeof(*hmdio)); | |
164 | if (!hmdio) { | |
165 | printf("Failed to allocate Hydra private data\n"); | |
166 | free(bus); | |
167 | return -1; | |
168 | } | |
169 | ||
170 | bus->read = hydra_mdio_read; | |
171 | bus->write = hydra_mdio_write; | |
172 | bus->reset = hydra_mdio_reset; | |
192bc694 | 173 | strcpy(bus->name, fakebusname); |
cba46148 TT |
174 | |
175 | hmdio->realbus = miiphy_get_dev_by_name(realbusname); | |
176 | ||
177 | if (!hmdio->realbus) { | |
178 | printf("No bus with name %s\n", realbusname); | |
179 | free(bus); | |
180 | free(hmdio); | |
181 | return -1; | |
182 | } | |
183 | ||
184 | bus->priv = hmdio; | |
185 | ||
186 | return mdio_register(bus); | |
187 | } | |
188 | ||
cba46148 TT |
189 | /* |
190 | * Given an alias or a path for a node, set the mux value of that node. | |
191 | * | |
192 | * If 'alias' is not a valid alias, then it is treated as a full path to the | |
193 | * node. No error checking is performed. | |
194 | * | |
195 | * This function is normally called to set the fsl,hydra-mdio-muxval property | |
196 | * of a virtual MDIO node. | |
197 | */ | |
198 | static void fdt_set_mdio_mux(void *fdt, const char *alias, u32 mux) | |
199 | { | |
200 | const char *path = fdt_get_alias(fdt, alias); | |
201 | ||
202 | if (!path) | |
203 | path = alias; | |
204 | ||
b41f1263 CL |
205 | do_fixup_by_path(fdt, path, "reg", |
206 | &mux, sizeof(mux), 1); | |
cba46148 TT |
207 | do_fixup_by_path(fdt, path, "fsl,hydra-mdio-muxval", |
208 | &mux, sizeof(mux), 1); | |
209 | } | |
210 | ||
211 | /* | |
212 | * Given the following ... | |
213 | * | |
214 | * 1) A pointer to an Fman Ethernet node (as identified by the 'compat' | |
215 | * compatible string and 'addr' physical address) | |
216 | * | |
217 | * 2) An Fman port | |
218 | * | |
219 | * ... update the phy-handle property of the Ethernet node to point to the | |
220 | * right PHY. This assumes that we already know the PHY for each port. That | |
221 | * information is stored in mdio_mux[]. | |
222 | * | |
223 | * The offset of the Fman Ethernet node is also passed in for convenience, but | |
224 | * it is not used, and we recalculate the offset anyway. | |
225 | * | |
226 | * Note that what we call "Fman ports" (enum fm_port) is really an Fman MAC. | |
227 | * Inside the Fman, "ports" are things that connect to MACs. We only call them | |
228 | * ports in U-Boot because on previous Ethernet devices (e.g. Gianfar), MACs | |
229 | * and ports are the same thing. | |
230 | * | |
231 | * Note that this code would be cleaner if had a function called | |
232 | * fm_info_get_phy_address(), which returns a value from the fm1_dtsec_info[] | |
233 | * array. That's because all we're doing is figuring out the PHY address for | |
234 | * a given Fman MAC and writing it to the device tree. Well, we already did | |
235 | * the hard work to figure that out in board_eth_init(), so it's silly to | |
236 | * repeat that here. | |
237 | */ | |
238 | void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, | |
239 | enum fm_port port, int offset) | |
240 | { | |
241 | unsigned int mux = mdio_mux[port].val & mdio_mux[port].mask; | |
242 | char phy[16]; | |
243 | ||
244 | if (port == FM1_10GEC1) { | |
245 | /* XAUI */ | |
246 | int lane = serdes_get_first_lane(XAUI_FM1); | |
247 | if (lane >= 0) { | |
248 | /* The XAUI PHY is identified by the slot */ | |
249 | sprintf(phy, "phy_xgmii_%u", lane_to_slot[lane]); | |
250 | fdt_set_phy_handle(fdt, compat, addr, phy); | |
251 | } | |
252 | return; | |
253 | } | |
254 | ||
af7219de | 255 | if (mux == (BRDCFG1_EMI1_SEL_RGMII | BRDCFG1_EMI1_EN)) { |
cba46148 TT |
256 | /* RGMII */ |
257 | /* The RGMII PHY is identified by the MAC connected to it */ | |
258 | sprintf(phy, "phy_rgmii_%u", port == FM1_DTSEC4 ? 0 : 1); | |
259 | fdt_set_phy_handle(fdt, compat, addr, phy); | |
af7219de | 260 | return; |
cba46148 TT |
261 | } |
262 | ||
263 | /* If it's not RGMII or XGMII, it must be SGMII */ | |
264 | if (mux) { | |
265 | /* The SGMII PHY is identified by the MAC connected to it */ | |
266 | sprintf(phy, "phy_sgmii_%x", | |
267 | CONFIG_SYS_FM1_DTSEC1_PHY_ADDR + (port - FM1_DTSEC1)); | |
268 | fdt_set_phy_handle(fdt, compat, addr, phy); | |
269 | } | |
270 | } | |
271 | ||
272 | #define PIXIS_SW2_LANE_23_SEL 0x80 | |
273 | #define PIXIS_SW2_LANE_45_SEL 0x40 | |
274 | #define PIXIS_SW2_LANE_67_SEL_MASK 0x30 | |
275 | #define PIXIS_SW2_LANE_67_SEL_5 0x00 | |
276 | #define PIXIS_SW2_LANE_67_SEL_6 0x20 | |
277 | #define PIXIS_SW2_LANE_67_SEL_7 0x10 | |
278 | #define PIXIS_SW2_LANE_8_SEL 0x08 | |
279 | #define PIXIS_SW2_LANE_1617_SEL 0x04 | |
280 | ||
281 | /* | |
282 | * Initialize the lane_to_slot[] array. | |
283 | * | |
284 | * On the P4080DS "Expedition" board, the mapping of SERDES lanes to board | |
285 | * slots is hard-coded. On the Hydra board, however, the mapping is controlled | |
286 | * by board switch SW2, so the lane_to_slot[] array needs to be dynamically | |
287 | * initialized. | |
288 | */ | |
289 | static void initialize_lane_to_slot(void) | |
290 | { | |
291 | u8 sw2 = in_8(&PIXIS_SW(2)); | |
292 | ||
293 | lane_to_slot[2] = (sw2 & PIXIS_SW2_LANE_23_SEL) ? 7 : 4; | |
294 | lane_to_slot[3] = lane_to_slot[2]; | |
295 | ||
296 | lane_to_slot[4] = (sw2 & PIXIS_SW2_LANE_45_SEL) ? 7 : 6; | |
297 | lane_to_slot[5] = lane_to_slot[4]; | |
298 | ||
299 | switch (sw2 & PIXIS_SW2_LANE_67_SEL_MASK) { | |
300 | case PIXIS_SW2_LANE_67_SEL_5: | |
301 | lane_to_slot[6] = 5; | |
302 | break; | |
303 | case PIXIS_SW2_LANE_67_SEL_6: | |
304 | lane_to_slot[6] = 6; | |
305 | break; | |
306 | case PIXIS_SW2_LANE_67_SEL_7: | |
307 | lane_to_slot[6] = 7; | |
308 | break; | |
309 | } | |
310 | lane_to_slot[7] = lane_to_slot[6]; | |
311 | ||
312 | lane_to_slot[8] = (sw2 & PIXIS_SW2_LANE_8_SEL) ? 3 : 0; | |
313 | ||
314 | lane_to_slot[16] = (sw2 & PIXIS_SW2_LANE_1617_SEL) ? 1 : 0; | |
315 | lane_to_slot[17] = lane_to_slot[16]; | |
316 | } | |
317 | ||
318 | #endif /* #ifdef CONFIG_FMAN_ENET */ | |
319 | ||
320 | /* | |
321 | * Configure the status for the virtual MDIO nodes | |
322 | * | |
323 | * Rather than create the virtual MDIO nodes from scratch for each active | |
324 | * virtual MDIO, we expect the DTS to have the nodes defined already, and we | |
325 | * only enable the ones that are actually active. | |
326 | * | |
327 | * We assume that the DTS already hard-codes the status for all the | |
328 | * virtual MDIO nodes to "disabled", so all we need to do is enable the | |
329 | * active ones. | |
330 | * | |
331 | * For SGMII, we also need to set the mux value in the node. | |
332 | */ | |
333 | void fdt_fixup_board_enet(void *fdt) | |
334 | { | |
335 | #ifdef CONFIG_FMAN_ENET | |
336 | unsigned int i; | |
337 | int lane; | |
338 | ||
339 | for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { | |
340 | int idx = i - FM1_DTSEC1; | |
341 | ||
342 | switch (fm_info_get_enet_if(i)) { | |
343 | case PHY_INTERFACE_MODE_SGMII: | |
344 | lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx); | |
345 | if (lane >= 0) { | |
2a523f52 | 346 | fdt_status_okay_by_alias(fdt, "emi1_sgmii"); |
cba46148 TT |
347 | /* Also set the MUX value */ |
348 | fdt_set_mdio_mux(fdt, "emi1_sgmii", | |
349 | mdio_mux[i].val); | |
350 | } | |
351 | break; | |
352 | case PHY_INTERFACE_MODE_RGMII: | |
2a523f52 | 353 | fdt_status_okay_by_alias(fdt, "emi1_rgmii"); |
cba46148 TT |
354 | break; |
355 | default: | |
356 | break; | |
357 | } | |
358 | } | |
359 | ||
360 | lane = serdes_get_first_lane(XAUI_FM1); | |
361 | if (lane >= 0) | |
2a523f52 | 362 | fdt_status_okay_by_alias(fdt, "emi2_xgmii"); |
cba46148 TT |
363 | #endif |
364 | } | |
365 | ||
366 | int board_eth_init(bd_t *bis) | |
367 | { | |
368 | #ifdef CONFIG_FMAN_ENET | |
cba46148 TT |
369 | struct fsl_pq_mdio_info dtsec_mdio_info; |
370 | struct tgec_mdio_info tgec_mdio_info; | |
371 | unsigned int i, slot; | |
372 | int lane; | |
ffee1dde | 373 | struct mii_dev *bus; |
cba46148 TT |
374 | |
375 | printf("Initializing Fman\n"); | |
376 | ||
377 | initialize_lane_to_slot(); | |
378 | ||
cba46148 TT |
379 | /* We want to use the PIXIS to configure MUX routing, not GPIOs. */ |
380 | setbits_8(&pixis->brdcfg2, BRDCFG2_REG_GPIO_SEL); | |
381 | ||
382 | memset(mdio_mux, 0, sizeof(mdio_mux)); | |
383 | ||
384 | dtsec_mdio_info.regs = | |
385 | (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR; | |
386 | dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME; | |
387 | ||
388 | /* Register the real 1G MDIO bus */ | |
389 | fsl_pq_mdio_init(bis, &dtsec_mdio_info); | |
390 | ||
391 | tgec_mdio_info.regs = | |
392 | (struct tgec_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR; | |
393 | tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME; | |
394 | ||
395 | /* Register the real 10G MDIO bus */ | |
396 | fm_tgec_mdio_init(bis, &tgec_mdio_info); | |
397 | ||
398 | /* Register the three virtual MDIO front-ends */ | |
399 | hydra_mdio_init(DEFAULT_FM_MDIO_NAME, "HYDRA_RGMII_MDIO"); | |
400 | hydra_mdio_init(DEFAULT_FM_MDIO_NAME, "HYDRA_SGMII_MDIO"); | |
401 | ||
402 | /* | |
403 | * Program the DTSEC PHY addresses assuming that they are all SGMII. | |
404 | * For any DTSEC that's RGMII, we'll override its PHY address later. | |
405 | * We assume that DTSEC5 is only used for RGMII. | |
406 | */ | |
407 | fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR); | |
408 | fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR); | |
409 | fm_info_set_phy_address(FM1_DTSEC3, CONFIG_SYS_FM1_DTSEC3_PHY_ADDR); | |
410 | fm_info_set_phy_address(FM1_DTSEC4, CONFIG_SYS_FM1_DTSEC4_PHY_ADDR); | |
411 | ||
412 | for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { | |
413 | int idx = i - FM1_DTSEC1; | |
414 | ||
415 | switch (fm_info_get_enet_if(i)) { | |
416 | case PHY_INTERFACE_MODE_SGMII: | |
417 | lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx); | |
418 | if (lane < 0) | |
419 | break; | |
420 | slot = lane_to_slot[lane]; | |
421 | mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK; | |
422 | switch (slot) { | |
423 | case 1: | |
424 | /* Always DTSEC5 on Bank 3 */ | |
425 | mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT1 | | |
426 | BRDCFG1_EMI1_EN; | |
427 | break; | |
428 | case 2: | |
429 | mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT2 | | |
430 | BRDCFG1_EMI1_EN; | |
431 | break; | |
432 | case 5: | |
433 | mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT5 | | |
434 | BRDCFG1_EMI1_EN; | |
435 | break; | |
436 | case 6: | |
437 | mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT6 | | |
438 | BRDCFG1_EMI1_EN; | |
439 | break; | |
440 | case 7: | |
441 | mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT7 | | |
442 | BRDCFG1_EMI1_EN; | |
443 | break; | |
444 | }; | |
445 | ||
446 | hydra_mdio_set_mux("HYDRA_SGMII_MDIO", | |
447 | mdio_mux[i].mask, mdio_mux[i].val); | |
448 | fm_info_set_mdio(i, | |
449 | miiphy_get_dev_by_name("HYDRA_SGMII_MDIO")); | |
450 | break; | |
451 | case PHY_INTERFACE_MODE_RGMII: | |
452 | /* | |
453 | * If DTSEC4 is RGMII, then it's routed via via EC1 to | |
454 | * the first on-board RGMII port. If DTSEC5 is RGMII, | |
455 | * then it's routed via via EC2 to the second on-board | |
456 | * RGMII port. The other DTSECs cannot be routed to | |
457 | * RGMII. | |
458 | */ | |
459 | fm_info_set_phy_address(i, i == FM1_DTSEC4 ? 0 : 1); | |
460 | mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK; | |
461 | mdio_mux[i].val = BRDCFG1_EMI1_SEL_RGMII | | |
462 | BRDCFG1_EMI1_EN; | |
463 | hydra_mdio_set_mux("HYDRA_RGMII_MDIO", | |
464 | mdio_mux[i].mask, mdio_mux[i].val); | |
465 | fm_info_set_mdio(i, | |
466 | miiphy_get_dev_by_name("HYDRA_RGMII_MDIO")); | |
467 | break; | |
468 | case PHY_INTERFACE_MODE_NONE: | |
469 | fm_info_set_phy_address(i, 0); | |
470 | break; | |
471 | default: | |
472 | printf("Fman1: DTSEC%u set to unknown interface %i\n", | |
473 | idx + 1, fm_info_get_enet_if(i)); | |
474 | fm_info_set_phy_address(i, 0); | |
475 | break; | |
476 | } | |
477 | } | |
478 | ||
ffee1dde ZQ |
479 | bus = miiphy_get_dev_by_name("HYDRA_SGMII_MDIO"); |
480 | set_sgmii_phy(bus, FM1_DTSEC1, CONFIG_SYS_NUM_FM1_DTSEC, PHY_BASE_ADDR); | |
481 | ||
cba46148 TT |
482 | /* |
483 | * For 10G, we only support one XAUI card per Fman. If present, then we | |
484 | * force its routing and never touch those bits again, which removes the | |
485 | * need for Linux to do any muxing. This works because of the way | |
486 | * BRDCFG1 is defined, but it's a bit hackish. | |
487 | * | |
488 | * The PHY address for the XAUI card depends on which slot it's in. The | |
489 | * macros we use imply that the PHY address is based on which FM, but | |
490 | * that's not true. On the P4080DS, FM1 could only use XAUI in slot 5, | |
491 | * and FM2 could only use a XAUI in slot 4. On the Hydra board, we | |
492 | * check the actual slot and just use the macros as-is, even though | |
493 | * the P3041 and P5020 only have one Fman. | |
494 | */ | |
495 | lane = serdes_get_first_lane(XAUI_FM1); | |
496 | if (lane >= 0) { | |
497 | slot = lane_to_slot[lane]; | |
498 | if (slot == 1) { | |
499 | /* XAUI card is in slot 1 */ | |
500 | clrsetbits_8(&pixis->brdcfg1, BRDCFG1_EMI2_SEL_MASK, | |
501 | BRDCFG1_EMI2_SEL_SLOT1); | |
502 | fm_info_set_phy_address(FM1_10GEC1, | |
503 | CONFIG_SYS_FM1_10GEC1_PHY_ADDR); | |
504 | } else { | |
505 | /* XAUI card is in slot 2 */ | |
506 | clrsetbits_8(&pixis->brdcfg1, BRDCFG1_EMI2_SEL_MASK, | |
507 | BRDCFG1_EMI2_SEL_SLOT2); | |
508 | fm_info_set_phy_address(FM1_10GEC1, | |
509 | CONFIG_SYS_FM2_10GEC1_PHY_ADDR); | |
510 | } | |
511 | } | |
512 | ||
513 | fm_info_set_mdio(FM1_10GEC1, | |
514 | miiphy_get_dev_by_name(DEFAULT_FM_TGEC_MDIO_NAME)); | |
515 | ||
516 | cpu_eth_init(bis); | |
517 | #endif | |
518 | ||
519 | return pci_eth_init(bis); | |
520 | } |