summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/freescale/common/sgmii_riser.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/board/freescale/common/sgmii_riser.c b/board/freescale/common/sgmii_riser.c
index 4f40a1d..5c3c593 100644
--- a/board/freescale/common/sgmii_riser.c
+++ b/board/freescale/common/sgmii_riser.c
@@ -17,6 +17,7 @@
#include <net.h>
#include <libfdt.h>
#include <tsec.h>
+#include <fdt_support.h>
void fsl_sgmii_riser_init(struct tsec_info_struct *tsec_info, int num)
{
@@ -31,6 +32,7 @@ void fsl_sgmii_riser_fdt_fixup(void *fdt)
{
struct eth_device *dev;
int node;
+ int mdio_node;
int i = -1;
int etsec_num = 0;
@@ -40,16 +42,38 @@ void fsl_sgmii_riser_fdt_fixup(void *fdt)
while ((dev = eth_get_dev_by_index(++i)) != NULL) {
struct tsec_private *priv;
+ int phy_node;
int enet_node;
+ uint32_t ph;
+ char sgmii_phy[16];
char enet[16];
const u32 *phyh;
- int phynode;
const char *model;
const char *path;
if (!strstr(dev->name, "eTSEC"))
continue;
+ priv = dev->priv;
+ if (!(priv->flags & TSEC_SGMII)) {
+ etsec_num++;
+ continue;
+ }
+
+ mdio_node = fdt_node_offset_by_compatible(fdt, -1,
+ "fsl,gianfar-mdio");
+ if (mdio_node < 0)
+ return;
+
+ sprintf(sgmii_phy, "sgmii-phy@%d", etsec_num);
+ phy_node = fdt_subnode_offset(fdt, mdio_node, sgmii_phy);
+ if (phy_node > 0) {
+ fdt_increase_size(fdt, 32);
+ ph = fdt_create_phandle(fdt, phy_node);
+ if (!ph)
+ continue;
+ }
+
sprintf(enet, "ethernet%d", etsec_num++);
path = fdt_getprop(fdt, node, enet, NULL);
if (!path) {
@@ -74,15 +98,32 @@ void fsl_sgmii_riser_fdt_fixup(void *fdt)
if (!strstr(model, "TSEC"))
continue;
- phyh = fdt_getprop(fdt, enet_node, "phy-handle", NULL);
- if (!phyh)
- continue;
+ if (phy_node < 0) {
+ /*
+ * This part is only for old device tree without
+ * sgmii_phy nodes. It's kept just for compatible
+ * reason. Soon to be deprecated if all device tree
+ * get updated.
+ */
+ phyh = fdt_getprop(fdt, enet_node, "phy-handle", NULL);
+ if (!phyh)
+ continue;
- phynode = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*phyh));
+ phy_node = fdt_node_offset_by_phandle(fdt,
+ fdt32_to_cpu(*phyh));
- priv = dev->priv;
+ priv = dev->priv;
- if (priv->flags & TSEC_SGMII)
- fdt_setprop_cell(fdt, phynode, "reg", priv->phyaddr);
+ if (priv->flags & TSEC_SGMII)
+ fdt_setprop_cell(fdt, phy_node, "reg",
+ priv->phyaddr);
+ } else {
+ fdt_setprop(fdt, enet_node, "phy-handle", &ph,
+ sizeof(ph));
+ fdt_setprop_string(fdt, enet_node,
+ "phy-connection-type",
+ phy_string_for_interface(
+ PHY_INTERFACE_MODE_SGMII));
+ }
}
}