sgmii_riser.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. * Freescale SGMII Riser Card
  3. *
  4. * This driver supports the SGMII Riser card found on the
  5. * "DS" style of development board from Freescale.
  6. *
  7. * This software may be used and distributed according to the
  8. * terms of the GNU Public License, Version 2, incorporated
  9. * herein by reference.
  10. *
  11. * Copyright 2008 Freescale Semiconductor, Inc.
  12. *
  13. */
  14. #include <config.h>
  15. #include <common.h>
  16. #include <net.h>
  17. #include <libfdt.h>
  18. #include <tsec.h>
  19. #include <fdt_support.h>
  20. void fsl_sgmii_riser_init(struct tsec_info_struct *tsec_info, int num)
  21. {
  22. int i;
  23. for (i = 0; i < num; i++)
  24. if (tsec_info[i].flags & TSEC_SGMII)
  25. tsec_info[i].phyaddr += SGMII_RISER_PHY_OFFSET;
  26. }
  27. void fsl_sgmii_riser_fdt_fixup(void *fdt)
  28. {
  29. struct eth_device *dev;
  30. int node;
  31. int mdio_node;
  32. int i = -1;
  33. int etsec_num = 0;
  34. node = fdt_path_offset(fdt, "/aliases");
  35. if (node < 0)
  36. return;
  37. while ((dev = eth_get_dev_by_index(++i)) != NULL) {
  38. struct tsec_private *priv;
  39. int phy_node;
  40. int enet_node;
  41. uint32_t ph;
  42. char sgmii_phy[16];
  43. char enet[16];
  44. const u32 *phyh;
  45. const char *model;
  46. const char *path;
  47. if (!strstr(dev->name, "eTSEC"))
  48. continue;
  49. priv = dev->priv;
  50. if (!(priv->flags & TSEC_SGMII)) {
  51. etsec_num++;
  52. continue;
  53. }
  54. mdio_node = fdt_node_offset_by_compatible(fdt, -1,
  55. "fsl,gianfar-mdio");
  56. if (mdio_node < 0)
  57. return;
  58. sprintf(sgmii_phy, "sgmii-phy@%d", etsec_num);
  59. phy_node = fdt_subnode_offset(fdt, mdio_node, sgmii_phy);
  60. if (phy_node > 0) {
  61. fdt_increase_size(fdt, 32);
  62. ph = fdt_create_phandle(fdt, phy_node);
  63. if (!ph)
  64. continue;
  65. }
  66. sprintf(enet, "ethernet%d", etsec_num++);
  67. path = fdt_getprop(fdt, node, enet, NULL);
  68. if (!path) {
  69. debug("No alias for %s\n", enet);
  70. continue;
  71. }
  72. enet_node = fdt_path_offset(fdt, path);
  73. if (enet_node < 0)
  74. continue;
  75. model = fdt_getprop(fdt, enet_node, "model", NULL);
  76. /*
  77. * We only want to do this to eTSECs. On some platforms
  78. * there are more than one type of gianfar-style ethernet
  79. * controller, and as we are creating an implicit connection
  80. * between ethernet nodes and eTSEC devices, it is best to
  81. * make the connection use as much explicit information
  82. * as exists.
  83. */
  84. if (!strstr(model, "TSEC"))
  85. continue;
  86. if (phy_node < 0) {
  87. /*
  88. * This part is only for old device tree without
  89. * sgmii_phy nodes. It's kept just for compatible
  90. * reason. Soon to be deprecated if all device tree
  91. * get updated.
  92. */
  93. phyh = fdt_getprop(fdt, enet_node, "phy-handle", NULL);
  94. if (!phyh)
  95. continue;
  96. phy_node = fdt_node_offset_by_phandle(fdt,
  97. fdt32_to_cpu(*phyh));
  98. priv = dev->priv;
  99. if (priv->flags & TSEC_SGMII)
  100. fdt_setprop_cell(fdt, phy_node, "reg",
  101. priv->phyaddr);
  102. } else {
  103. fdt_setprop(fdt, enet_node, "phy-handle", &ph,
  104. sizeof(ph));
  105. fdt_setprop_string(fdt, enet_node,
  106. "phy-connection-type",
  107. phy_string_for_interface(
  108. PHY_INTERFACE_MODE_SGMII));
  109. }
  110. }
  111. }