Commit 9bf499ace8dd0d4b9c092081425696c150ffc563

Authored by Shaohui Xie
Committed by York Sun
1 parent 2475367670

powerpc/T4240QDS/eth: some fix for XFI

XFI is supported on T4QDS-XFI board, which removed slot3, and four LANEs
of serdes2 are routed to a SFP+ cages, which to house fiber cable or
direct attach cable(copper), the copper cable is used to emulate the
10GBASE-KR scenario.

So, for XFI usage, there are two scenarios, one will use fiber cable,
another will use copper cable. For fiber cable, there is NO PHY, while
for copper cable, we need to use internal PHY which exist in Serdes to
do auto-negotiation and link training, which implemented in kernel.
We use hwconfig to define cable type for XFI, and fixup dtb based on the
cable type.

For copper cable, set below env in hwconfig:

fsl_10gkr_copper:<10g_mac_name>

the <10g_mac_name> can be fm1_10g1, fm1_10g2, fm2_10g1, fm2_10g2. The
four <10g_mac_name>s do not have to be coexist in hwconfig. For XFI ports,
if a given 10G port will use the copper cable for 10GBASE-KR, set the
<10g_mac_name> of the port in hwconfig, otherwise, fiber cable will be
assumed to be used for the port.

For ex. if four XFI ports will both use copper cable, the hwconfig
should contain:

fsl_10gkr_copper:fm1_10g1,fm1_10g2,fm2_10g1,fm2_10g2

For fiber cable:

1. give PHY address to a XFI port, otherwise, the XFI ports will not be
available in U-boot, there is no PHY physically for XFI when using fiber
cable, this is just to make U-boot happy and we can use the XFI ports
in U-boot.
2. fixup dtb to use fixed-link in case of fiber cable which has no PHY.
Kernel requests that a MAC must have a PHY or fixed-link.

When using XFI protocol, the MAC 9/10 on FM1 should init as 10G interface.

Change serdes 2 protocol 56 to 55 which has same feature as 56 since 56
is not valid any longer.

Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
Reviewed-by: York Sun <yorksun@freescale.com>

Showing 3 changed files with 142 additions and 18 deletions Side-by-side Diff

board/freescale/t4qds/eth.c
... ... @@ -23,6 +23,7 @@
23 23 #include <phy.h>
24 24 #include <asm/fsl_dtsec.h>
25 25 #include <asm/fsl_serdes.h>
  26 +#include <hwconfig.h>
26 27 #include "../common/qixis.h"
27 28 #include "../common/fman.h"
28 29  
29 30  
... ... @@ -173,7 +174,11 @@
173 174 enum fm_port port, int offset)
174 175 {
175 176 int interface = fm_info_get_enet_if(port);
  177 + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
  178 + u32 prtcl2 = in_be32(&gur->rcwsr[4]) & FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
176 179  
  180 + prtcl2 >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
  181 +
177 182 if (interface == PHY_INTERFACE_MODE_SGMII ||
178 183 interface == PHY_INTERFACE_MODE_QSGMII) {
179 184 switch (port) {
... ... @@ -262,6 +267,76 @@
262 267 default:
263 268 break;
264 269 }
  270 + } else if (interface == PHY_INTERFACE_MODE_XGMII &&
  271 + ((prtcl2 == 55) || (prtcl2 == 57))) {
  272 + /*
  273 + * if the 10G is XFI, check hwconfig to see what is the
  274 + * media type, there are two types, fiber or copper,
  275 + * fix the dtb accordingly.
  276 + */
  277 + int media_type = 0;
  278 + struct fixed_link f_link;
  279 + char lane_mode[20] = {"10GBASE-KR"};
  280 + char buf[32] = "serdes-2,";
  281 + int off;
  282 +
  283 + switch (port) {
  284 + case FM1_10GEC1:
  285 + if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g1")) {
  286 + media_type = 1;
  287 + fdt_set_phy_handle(blob, prop, pa,
  288 + "phy_xfi1");
  289 + sprintf(buf, "%s%s%s", buf, "lane-a,",
  290 + (char *)lane_mode);
  291 + }
  292 + break;
  293 + case FM1_10GEC2:
  294 + if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g2")) {
  295 + media_type = 1;
  296 + fdt_set_phy_handle(blob, prop, pa,
  297 + "phy_xfi2");
  298 + sprintf(buf, "%s%s%s", buf, "lane-b,",
  299 + (char *)lane_mode);
  300 + }
  301 + break;
  302 + case FM2_10GEC1:
  303 + if (hwconfig_sub("fsl_10gkr_copper", "fm2_10g1")) {
  304 + media_type = 1;
  305 + fdt_set_phy_handle(blob, prop, pa,
  306 + "phy_xfi3");
  307 + sprintf(buf, "%s%s%s", buf, "lane-d,",
  308 + (char *)lane_mode);
  309 + }
  310 + break;
  311 + case FM2_10GEC2:
  312 + if (hwconfig_sub("fsl_10gkr_copper", "fm2_10g2")) {
  313 + media_type = 1;
  314 + fdt_set_phy_handle(blob, prop, pa,
  315 + "phy_xfi4");
  316 + sprintf(buf, "%s%s%s", buf, "lane-c,",
  317 + (char *)lane_mode);
  318 + }
  319 + break;
  320 + default:
  321 + return;
  322 + }
  323 +
  324 + if (!media_type) {
  325 + /* fixed-link is used for XFI fiber cable */
  326 + fdt_delprop(blob, offset, "phy-handle");
  327 + f_link.phy_id = port;
  328 + f_link.duplex = 1;
  329 + f_link.link_speed = 10000;
  330 + f_link.pause = 0;
  331 + f_link.asym_pause = 0;
  332 + fdt_setprop(blob, offset, "fixed-link", &f_link,
  333 + sizeof(f_link));
  334 + } else {
  335 + /* set property for copper cable */
  336 + off = fdt_node_offset_by_compat_reg(blob,
  337 + "fsl,fman-memac-mdio", pa + 0x1000);
  338 + fdt_setprop_string(blob, off, "lane-instance", buf);
  339 + }
265 340 }
266 341 }
267 342  
... ... @@ -295,8 +370,23 @@
295 370 break;
296 371 case PHY_INTERFACE_MODE_XGMII:
297 372 /* check if it's XFI interface for 10g */
298   - if ((prtcl2 == 56) || (prtcl2 == 57)) {
299   - fdt_status_okay_by_alias(fdt, "emi2_xfislot3");
  373 + if ((prtcl2 == 55) || (prtcl2 == 57)) {
  374 + if (i == FM1_10GEC1 && hwconfig_sub(
  375 + "fsl_10gkr_copper", "fm1_10g1"))
  376 + fdt_status_okay_by_alias(
  377 + fdt, "xfi_pcs_mdio1");
  378 + if (i == FM1_10GEC2 && hwconfig_sub(
  379 + "fsl_10gkr_copper", "fm1_10g2"))
  380 + fdt_status_okay_by_alias(
  381 + fdt, "xfi_pcs_mdio2");
  382 + if (i == FM2_10GEC1 && hwconfig_sub(
  383 + "fsl_10gkr_copper", "fm2_10g1"))
  384 + fdt_status_okay_by_alias(
  385 + fdt, "xfi_pcs_mdio3");
  386 + if (i == FM2_10GEC2 && hwconfig_sub(
  387 + "fsl_10gkr_copper", "fm2_10g2"))
  388 + fdt_status_okay_by_alias(
  389 + fdt, "xfi_pcs_mdio4");
300 390 break;
301 391 }
302 392 switch (i) {
... ... @@ -460,7 +550,7 @@
460 550 fm_info_set_phy_address(FM1_DTSEC4, slot_qsgmii_phyaddr[2][3]);
461 551 fm_info_set_phy_address(FM1_DTSEC5, slot_qsgmii_phyaddr[1][0]);
462 552 fm_info_set_phy_address(FM1_DTSEC6, slot_qsgmii_phyaddr[1][1]);
463   - if ((srds_prtcl_s2 != 56) && (srds_prtcl_s2 != 57)) {
  553 + if ((srds_prtcl_s2 != 55) && (srds_prtcl_s2 != 57)) {
464 554 fm_info_set_phy_address(FM1_DTSEC9,
465 555 slot_qsgmii_phyaddr[1][3]);
466 556 fm_info_set_phy_address(FM1_DTSEC10,
... ... @@ -475,7 +565,7 @@
475 565 fm_info_set_phy_address(FM1_DTSEC4, slot_qsgmii_phyaddr[2][3]);
476 566 fm_info_set_phy_address(FM1_DTSEC5, slot_qsgmii_phyaddr[1][0]);
477 567 fm_info_set_phy_address(FM1_DTSEC6, slot_qsgmii_phyaddr[1][1]);
478   - if ((srds_prtcl_s2 != 56) && (srds_prtcl_s2 != 57)) {
  568 + if ((srds_prtcl_s2 != 55) && (srds_prtcl_s2 != 57)) {
479 569 fm_info_set_phy_address(FM1_DTSEC9,
480 570 slot_qsgmii_phyaddr[1][2]);
481 571 fm_info_set_phy_address(FM1_DTSEC10,
... ... @@ -490,7 +580,7 @@
490 580 case 48:
491 581 fm_info_set_phy_address(FM1_DTSEC5, slot_qsgmii_phyaddr[1][0]);
492 582 fm_info_set_phy_address(FM1_DTSEC6, slot_qsgmii_phyaddr[1][1]);
493   - if ((srds_prtcl_s2 != 56) && (srds_prtcl_s2 != 57)) {
  583 + if ((srds_prtcl_s2 != 55) && (srds_prtcl_s2 != 57)) {
494 584 fm_info_set_phy_address(FM1_DTSEC10,
495 585 slot_qsgmii_phyaddr[1][2]);
496 586 fm_info_set_phy_address(FM1_DTSEC9,
497 587  
... ... @@ -567,13 +657,18 @@
567 657 idx = i - FM1_10GEC1;
568 658 switch (fm_info_get_enet_if(i)) {
569 659 case PHY_INTERFACE_MODE_XGMII:
570   - lane = serdes_get_first_lane(FSL_SRDS_1,
  660 + if ((srds_prtcl_s2 == 55) || (srds_prtcl_s2 == 57)) {
  661 + /* A fake PHY address to make U-boot happy */
  662 + fm_info_set_phy_address(i, i);
  663 + } else {
  664 + lane = serdes_get_first_lane(FSL_SRDS_1,
571 665 XAUI_FM1_MAC9 + idx);
572   - if (lane < 0)
573   - break;
574   - slot = lane_to_slot_fsm1[lane];
575   - if (QIXIS_READ(present2) & (1 << (slot - 1)))
576   - fm_disable_port(i);
  666 + if (lane < 0)
  667 + break;
  668 + slot = lane_to_slot_fsm1[lane];
  669 + if (QIXIS_READ(present2) & (1 << (slot - 1)))
  670 + fm_disable_port(i);
  671 + }
577 672 mdio_mux[i] = EMI2;
578 673 fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
579 674 break;
... ... @@ -666,7 +761,7 @@
666 761 fm_info_set_phy_address(FM2_DTSEC3, slot_qsgmii_phyaddr[4][2]);
667 762 fm_info_set_phy_address(FM2_DTSEC4, slot_qsgmii_phyaddr[4][3]);
668 763 break;
669   - case 56:
  764 + case 55:
670 765 case 57:
671 766 /* XFI in Slot3, SGMII in Slot4 */
672 767 fm_info_set_phy_address(FM2_DTSEC1, slot_qsgmii_phyaddr[4][0]);
673 768  
... ... @@ -743,13 +838,18 @@
743 838 idx = i - FM2_10GEC1;
744 839 switch (fm_info_get_enet_if(i)) {
745 840 case PHY_INTERFACE_MODE_XGMII:
746   - lane = serdes_get_first_lane(FSL_SRDS_2,
  841 + if ((srds_prtcl_s2 == 55) || (srds_prtcl_s2 == 57)) {
  842 + /* A fake PHY address to make U-boot happy */
  843 + fm_info_set_phy_address(i, i);
  844 + } else {
  845 + lane = serdes_get_first_lane(FSL_SRDS_2,
747 846 XAUI_FM2_MAC9 + idx);
748   - if (lane < 0)
749   - break;
750   - slot = lane_to_slot_fsm2[lane];
751   - if (QIXIS_READ(present2) & (1 << (slot - 1)))
752   - fm_disable_port(i);
  847 + if (lane < 0)
  848 + break;
  849 + slot = lane_to_slot_fsm2[lane];
  850 + if (QIXIS_READ(present2) & (1 << (slot - 1)))
  851 + fm_disable_port(i);
  852 + }
753 853 mdio_mux[i] = EMI2;
754 854 fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i]));
755 855 break;
... ... @@ -79,6 +79,25 @@
79 79 - High-speed serial flash
80 80 Two Serial port
81 81 Four I2C ports
  82 + XFI
  83 + XFI is supported on T4QDS-XFI board which removed slot3 and routed
  84 + four Lanes A/B/C/D to a SFP+ cages, which to house fiber cable or
  85 + direct attach cable(copper), the copper cable is used to emulate
  86 + 10GBASE-KR scenario.
  87 + So, for XFI usage, there are two scenarios, one will use fiber cable,
  88 + another will use copper cable. An hwconfig env "fsl_10gkr_copper" is
  89 + introduced to indicate a XFI port will use copper cable, and U-boot
  90 + will fixup the dtb accordingly.
  91 + It's used as: fsl_10gkr_copper:<10g_mac_name>
  92 + The <10g_mac_name> can be fm1_10g1, fm1_10g2, fm2_10g1, fm2_10g2, they
  93 + do not have to be coexist in hwconfig. If a MAC is listed in the env
  94 + "fsl_10gkr_copper", it will use copper cable, otherwise, fiber cable
  95 + will be used by default.
  96 + for ex. set "fsl_10gkr_copper:fm1_10g1,fm1_10g2,fm2_10g1,fm2_10g2" in
  97 + hwconfig, then both four XFI ports will use copper cable.
  98 + set "fsl_10gkr_copper:fm1_10g1,fm1_10g2" in hwconfig, then first two
  99 + XFI ports will use copper cable, the other two XFI ports will use fiber
  100 + cable.
82 101  
83 102 Memory map
84 103 ----------
drivers/net/fm/t4240.c
... ... @@ -71,6 +71,11 @@
71 71 (is_serdes_configured(XFI_FM1_MAC10))))
72 72 return PHY_INTERFACE_MODE_XGMII;
73 73  
  74 + if ((port == FM1_DTSEC9 || port == FM1_DTSEC10) &&
  75 + ((is_serdes_configured(XFI_FM1_MAC9)) ||
  76 + (is_serdes_configured(XFI_FM1_MAC10))))
  77 + return PHY_INTERFACE_MODE_XGMII;
  78 +
74 79 if ((port == FM2_10GEC1 || port == FM2_10GEC2) &&
75 80 ((is_serdes_configured(XAUI_FM2_MAC9)) ||
76 81 (is_serdes_configured(XAUI_FM2_MAC10)) ||