1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <config.h>
16#include <common.h>
17#include <net.h>
18#include <linux/libfdt.h>
19#include <tsec.h>
20#include <fdt_support.h>
21
22void fsl_sgmii_riser_init(struct tsec_info_struct *tsec_info, int num)
23{
24 int i;
25
26 for (i = 0; i < num; i++)
27 if (tsec_info[i].flags & TSEC_SGMII)
28 tsec_info[i].phyaddr += SGMII_RISER_PHY_OFFSET;
29}
30
31void fsl_sgmii_riser_fdt_fixup(void *fdt)
32{
33 struct eth_device *dev;
34 int node;
35 int mdio_node;
36 int i = -1;
37 int etsec_num = 0;
38
39 node = fdt_path_offset(fdt, "/aliases");
40 if (node < 0)
41 return;
42
43 while ((dev = eth_get_dev_by_index(++i)) != NULL) {
44 struct tsec_private *priv;
45 int phy_node;
46 int enet_node;
47 uint32_t ph;
48 char sgmii_phy[16];
49 char enet[16];
50 const u32 *phyh;
51 const char *model;
52 const char *path;
53
54 if (!strstr(dev->name, "eTSEC"))
55 continue;
56
57 priv = dev->priv;
58 if (!(priv->flags & TSEC_SGMII)) {
59 etsec_num++;
60 continue;
61 }
62
63 mdio_node = fdt_node_offset_by_compatible(fdt, -1,
64 "fsl,gianfar-mdio");
65 if (mdio_node < 0)
66 return;
67
68 sprintf(sgmii_phy, "sgmii-phy@%d", etsec_num);
69 phy_node = fdt_subnode_offset(fdt, mdio_node, sgmii_phy);
70 if (phy_node > 0) {
71 fdt_increase_size(fdt, 32);
72 ph = fdt_create_phandle(fdt, phy_node);
73 if (!ph)
74 continue;
75 }
76
77 sprintf(enet, "ethernet%d", etsec_num++);
78 path = fdt_getprop(fdt, node, enet, NULL);
79 if (!path) {
80 debug("No alias for %s\n", enet);
81 continue;
82 }
83
84 enet_node = fdt_path_offset(fdt, path);
85 if (enet_node < 0)
86 continue;
87
88 model = fdt_getprop(fdt, enet_node, "model", NULL);
89
90
91
92
93
94
95
96
97
98 if (!strstr(model, "TSEC"))
99 continue;
100
101 if (phy_node < 0) {
102
103
104
105
106
107
108 phyh = fdt_getprop(fdt, enet_node, "phy-handle", NULL);
109 if (!phyh)
110 continue;
111
112 phy_node = fdt_node_offset_by_phandle(fdt,
113 fdt32_to_cpu(*phyh));
114
115 priv = dev->priv;
116
117 if (priv->flags & TSEC_SGMII)
118 fdt_setprop_cell(fdt, phy_node, "reg",
119 priv->phyaddr);
120 } else {
121 fdt_setprop(fdt, enet_node, "phy-handle", &ph,
122 sizeof(ph));
123 fdt_setprop_string(fdt, enet_node,
124 "phy-connection-type",
125 phy_string_for_interface(
126 PHY_INTERFACE_MODE_SGMII));
127 }
128 }
129}
130