Commit ffee1dde3c4cb2721c56c78e0360affec1c23d3f

Authored by Zhao Qiang
Committed by York Sun
1 parent d56898249c

SGMII:fix PHY addresses for QSGMII Riser Card working in SGMII mode

Fix PHY addresses for QSGMII Riser Card working in
SGMII mode on board P3041/P5020/P4080/P5040/B4860.

QSGMII Riser Card can work in SGMII mode, but
having the different PHY addresses.
So the following steps should be done:
	1. Confirm whether QSGMII Riser Card is used.
	2. If yes, set the proper PHY address.
Generally, the function is_qsgmii_riser_card() is
for step 1, and set_sgmii_phy() for step 2.

However, there are still some special situations,
take P5040 and B4860 as examples, the PHY addresses
need to be changed when serdes protocol is changed,
so it is necessary to confirm the protocol before
setting PHY addresses.

Signed-off-by: Zhao Qiang <B45475@freescale.com>

Showing 8 changed files with 140 additions and 0 deletions Side-by-side Diff

board/freescale/b4860qds/b4860qds_qixis.h
... ... @@ -21,5 +21,10 @@
21 21  
22 22 #define QIXIS_SRDS1CLK_122 0x5a
23 23 #define QIXIS_SRDS1CLK_125 0x5e
  24 +
  25 +/* SGMII */
  26 +#define PHY_BASE_ADDR 0x18
  27 +#define PORT_NUM 0x04
  28 +#define REGNUM 0x00
24 29 #endif
board/freescale/b4860qds/eth_b4860qds.c
... ... @@ -150,6 +150,8 @@
150 150 struct memac_mdio_info tg_memac_mdio_info;
151 151 unsigned int i;
152 152 unsigned int serdes1_prtcl, serdes2_prtcl;
  153 + int qsgmii;
  154 + struct mii_dev *bus;
153 155 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
154 156 serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
155 157 FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
... ... @@ -279,6 +281,22 @@
279 281 printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n",
280 282 serdes2_prtcl);
281 283 break;
  284 + }
  285 +
  286 + /*set PHY address for QSGMII Riser Card on slot2*/
  287 + bus = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME);
  288 + qsgmii = is_qsgmii_riser_card(bus, PHY_BASE_ADDR, PORT_NUM, REGNUM);
  289 +
  290 + if (qsgmii) {
  291 + switch (serdes2_prtcl) {
  292 + case 0xb2:
  293 + case 0x8d:
  294 + fm_info_set_phy_address(FM1_DTSEC3, PHY_BASE_ADDR);
  295 + fm_info_set_phy_address(FM1_DTSEC4, PHY_BASE_ADDR + 1);
  296 + break;
  297 + default:
  298 + break;
  299 + }
282 300 }
283 301  
284 302 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
board/freescale/corenet_ds/eth_hydra.c
... ... @@ -76,6 +76,8 @@
76 76  
77 77 #define BRDCFG2_REG_GPIO_SEL 0x20
78 78  
  79 +#define PHY_BASE_ADDR 0x00
  80 +
79 81 /*
80 82 * BRDCFG1 mask and value for each MAC
81 83 *
... ... @@ -365,6 +367,7 @@
365 367 struct tgec_mdio_info tgec_mdio_info;
366 368 unsigned int i, slot;
367 369 int lane;
  370 + struct mii_dev *bus;
368 371  
369 372 printf("Initializing Fman\n");
370 373  
... ... @@ -469,6 +472,9 @@
469 472 break;
470 473 }
471 474 }
  475 +
  476 + bus = miiphy_get_dev_by_name("HYDRA_SGMII_MDIO");
  477 + set_sgmii_phy(bus, FM1_DTSEC1, CONFIG_SYS_NUM_FM1_DTSEC, PHY_BASE_ADDR);
472 478  
473 479 /*
474 480 * For 10G, we only support one XAUI card per Fman. If present, then we
board/freescale/corenet_ds/eth_p4080.c
... ... @@ -37,6 +37,9 @@
37 37 #define EMI1_MASK 0xc0000000
38 38 #define EMI2_MASK 0x30000000
39 39  
  40 +#define PHY_BASE_ADDR 0x00
  41 +#define PHY_BASE_ADDR_SLOT5 0x10
  42 +
40 43 static int mdio_mux[NUM_FM_PORTS];
41 44  
42 45 static char *mdio_names[16] = {
... ... @@ -290,6 +293,7 @@
290 293 int i;
291 294 struct fsl_pq_mdio_info dtsec_mdio_info;
292 295 struct tgec_mdio_info tgec_mdio_info;
  296 + struct mii_dev *bus;
293 297  
294 298 /* Initialize the mdio_mux array so we can recognize empty elements */
295 299 for (i = 0; i < NUM_FM_PORTS; i++)
... ... @@ -370,6 +374,9 @@
370 374 break;
371 375 }
372 376 }
  377 + bus = mii_dev_for_muxval(EMI1_SLOT5);
  378 + set_sgmii_phy(bus, FM1_DTSEC1,
  379 + CONFIG_SYS_NUM_FM1_DTSEC, PHY_BASE_ADDR_SLOT5);
373 380  
374 381 for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) {
375 382 int idx = i - FM1_10GEC1, lane, slot;
... ... @@ -434,6 +441,11 @@
434 441 break;
435 442 }
436 443 }
  444 +
  445 + bus = mii_dev_for_muxval(EMI1_SLOT3);
  446 + set_sgmii_phy(bus, FM2_DTSEC1, CONFIG_SYS_NUM_FM2_DTSEC, PHY_BASE_ADDR);
  447 + bus = mii_dev_for_muxval(EMI1_SLOT4);
  448 + set_sgmii_phy(bus, FM2_DTSEC1, CONFIG_SYS_NUM_FM2_DTSEC, PHY_BASE_ADDR);
437 449  
438 450 for (i = FM2_10GEC1; i < FM2_10GEC1 + CONFIG_SYS_NUM_FM2_10GEC; i++) {
439 451 int idx = i - FM2_10GEC1, lane, slot;
board/freescale/corenet_ds/eth_superhydra.c
... ... @@ -77,6 +77,12 @@
77 77  
78 78 #define BRDCFG2_REG_GPIO_SEL 0x20
79 79  
  80 +/* SGMII */
  81 +#define PHY_BASE_ADDR 0x00
  82 +#define REGNUM 0x00
  83 +#define PORT_NUM_FM1 0x04
  84 +#define PORT_NUM_FM2 0x02
  85 +
80 86 /*
81 87 * BRDCFG1 mask and value for each MAC
82 88 *
... ... @@ -415,6 +421,9 @@
415 421 struct tgec_mdio_info tgec_mdio_info;
416 422 unsigned int i, slot;
417 423 int lane;
  424 + struct mii_dev *bus;
  425 + int qsgmii;
  426 + int phy_real_addr;
418 427 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
419 428 int srds_prtcl = (in_be32(&gur->rcwsr[4]) &
420 429 FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26;
... ... @@ -575,6 +584,42 @@
575 584 }
576 585 }
577 586  
  587 + bus = miiphy_get_dev_by_name("SUPER_HYDRA_FM1_SGMII_MDIO");
  588 + qsgmii = is_qsgmii_riser_card(bus, PHY_BASE_ADDR, PORT_NUM_FM1, REGNUM);
  589 +
  590 + if (qsgmii) {
  591 + for (i = FM1_DTSEC1; i < FM1_DTSEC1 + PORT_NUM_FM1; i++) {
  592 + if (fm_info_get_enet_if(i) ==
  593 + PHY_INTERFACE_MODE_SGMII) {
  594 + phy_real_addr = PHY_BASE_ADDR + i - FM1_DTSEC1;
  595 + fm_info_set_phy_address(i, phy_real_addr);
  596 + }
  597 + }
  598 + switch (srds_prtcl) {
  599 + case 0x00:
  600 + case 0x03:
  601 + case 0x04:
  602 + case 0x06:
  603 + case 0x11:
  604 + case 0x2a:
  605 + case 0x34:
  606 + case 0x36:
  607 + fm_info_set_phy_address(FM1_DTSEC3, PHY_BASE_ADDR + 2);
  608 + fm_info_set_phy_address(FM1_DTSEC4, PHY_BASE_ADDR + 3);
  609 + break;
  610 + case 0x01:
  611 + case 0x02:
  612 + case 0x05:
  613 + case 0x07:
  614 + case 0x35:
  615 + fm_info_set_phy_address(FM1_DTSEC3, PHY_BASE_ADDR + 0);
  616 + fm_info_set_phy_address(FM1_DTSEC4, PHY_BASE_ADDR + 1);
  617 + break;
  618 + default:
  619 + break;
  620 + }
  621 + }
  622 +
578 623 /*
579 624 * For 10G, we only support one XAUI card per Fman. If present, then we
580 625 * force its routing and never touch those bits again, which removes the
... ... @@ -685,6 +730,11 @@
685 730 break;
686 731 }
687 732 }
  733 +
  734 + bus = miiphy_get_dev_by_name("SUPER_HYDRA_FM2_SGMII_MDIO");
  735 + set_sgmii_phy(bus, FM2_DTSEC3, PORT_NUM_FM2, PHY_BASE_ADDR);
  736 + bus = miiphy_get_dev_by_name("SUPER_HYDRA_FM3_SGMII_MDIO");
  737 + set_sgmii_phy(bus, FM2_DTSEC1, PORT_NUM_FM2, PHY_BASE_ADDR);
688 738  
689 739 /*
690 740 * For 10G, we only support one XAUI card per Fman. If present, then we
... ... @@ -21,6 +21,7 @@
21 21 #define TX_PORT_1G_BASE 0x28
22 22 #define MAX_NUM_TX_PORT_1G CONFIG_SYS_NUM_FM1_DTSEC
23 23 #define TX_PORT_10G_BASE 0x30
  24 +#define MIIM_TIMEOUT 0xFFFF
24 25  
25 26 struct fm_muram {
26 27 u32 base;
drivers/net/fm/init.c
... ... @@ -274,4 +274,48 @@
274 274 }
275 275 #endif
276 276 }
  277 +
  278 +/*QSGMII Riser Card can work in SGMII mode, but the PHY address is different.
  279 + *This function scans which Riser Card being used(QSGMII or SGMII Riser Card),
  280 + *then set the correct PHY address
  281 + */
  282 +void set_sgmii_phy(struct mii_dev *bus, enum fm_port base_port,
  283 + unsigned int port_num, int phy_base_addr)
  284 +{
  285 + unsigned int regnum = 0;
  286 + int qsgmii;
  287 + int i;
  288 + int phy_real_addr;
  289 +
  290 + qsgmii = is_qsgmii_riser_card(bus, phy_base_addr, port_num, regnum);
  291 +
  292 + if (!qsgmii)
  293 + return;
  294 +
  295 + for (i = base_port; i < base_port + port_num; i++) {
  296 + if (fm_info_get_enet_if(i) == PHY_INTERFACE_MODE_SGMII) {
  297 + phy_real_addr = phy_base_addr + i - base_port;
  298 + fm_info_set_phy_address(i, phy_real_addr);
  299 + }
  300 + }
  301 +}
  302 +
  303 +/*to check whether qsgmii riser card is used*/
  304 +int is_qsgmii_riser_card(struct mii_dev *bus, int phy_base_addr,
  305 + unsigned int port_num, unsigned regnum)
  306 +{
  307 + int i;
  308 + int val;
  309 +
  310 + if (!bus)
  311 + return 0;
  312 +
  313 + for (i = phy_base_addr; i < phy_base_addr + port_num; i++) {
  314 + val = bus->read(bus, i, MDIO_DEVAD_NONE, regnum);
  315 + if (val != MIIM_TIMEOUT)
  316 + return 1;
  317 + }
  318 +
  319 + return 0;
  320 +}
... ... @@ -149,6 +149,10 @@
149 149 int fm_info_get_phy_address(enum fm_port port);
150 150 void fm_info_set_mdio(enum fm_port port, struct mii_dev *bus);
151 151 void fm_disable_port(enum fm_port port);
  152 +void set_sgmii_phy(struct mii_dev *bus, enum fm_port base_port,
  153 + unsigned int port_num, int phy_base_addr);
  154 +int is_qsgmii_riser_card(struct mii_dev *bus, int phy_base_addr,
  155 + unsigned int port_num, unsigned regnum);
152 156  
153 157 #endif