1
2
3
4
5
6
7
8
9#ifndef _PHY_H
10#define _PHY_H
11
12#include <dm.h>
13#include <linux/list.h>
14#include <linux/mii.h>
15#include <linux/ethtool.h>
16#include <linux/mdio.h>
17#include <phy_interface.h>
18
19#define PHY_FIXED_ID 0xa5a55a5a
20
21
22
23
24#define PHY_GMII2RGMII_ID 0x5a5a5a5a
25
26#define PHY_MAX_ADDR 32
27
28#define PHY_FLAG_BROKEN_RESET (1 << 0)
29
30#define PHY_DEFAULT_FEATURES (SUPPORTED_Autoneg | \
31 SUPPORTED_TP | \
32 SUPPORTED_MII)
33
34#define PHY_10BT_FEATURES (SUPPORTED_10baseT_Half | \
35 SUPPORTED_10baseT_Full)
36
37#define PHY_100BT_FEATURES (SUPPORTED_100baseT_Half | \
38 SUPPORTED_100baseT_Full)
39
40#define PHY_1000BT_FEATURES (SUPPORTED_1000baseT_Half | \
41 SUPPORTED_1000baseT_Full)
42
43#define PHY_BASIC_FEATURES (PHY_10BT_FEATURES | \
44 PHY_100BT_FEATURES | \
45 PHY_DEFAULT_FEATURES)
46
47#define PHY_GBIT_FEATURES (PHY_BASIC_FEATURES | \
48 PHY_1000BT_FEATURES)
49
50#define PHY_10G_FEATURES (PHY_GBIT_FEATURES | \
51 SUPPORTED_10000baseT_Full)
52
53#ifndef PHY_ANEG_TIMEOUT
54#define PHY_ANEG_TIMEOUT 4000
55#endif
56
57
58struct phy_device;
59
60#define MDIO_NAME_LEN 32
61
62struct mii_dev {
63 struct list_head link;
64 char name[MDIO_NAME_LEN];
65 void *priv;
66 int (*read)(struct mii_dev *bus, int addr, int devad, int reg);
67 int (*write)(struct mii_dev *bus, int addr, int devad, int reg,
68 u16 val);
69 int (*reset)(struct mii_dev *bus);
70 struct phy_device *phymap[PHY_MAX_ADDR];
71 u32 phy_mask;
72};
73
74
75
76
77
78
79
80
81
82
83
84struct phy_driver {
85 char *name;
86 unsigned int uid;
87 unsigned int mask;
88 unsigned int mmds;
89
90 u32 features;
91
92
93
94 int (*probe)(struct phy_device *phydev);
95
96
97
98 int (*config)(struct phy_device *phydev);
99
100
101 int (*startup)(struct phy_device *phydev);
102
103
104 int (*shutdown)(struct phy_device *phydev);
105
106 int (*readext)(struct phy_device *phydev, int addr, int devad, int reg);
107 int (*writeext)(struct phy_device *phydev, int addr, int devad, int reg,
108 u16 val);
109
110
111 int (*read_mmd)(struct phy_device *phydev, int devad, int reg);
112
113
114 int (*write_mmd)(struct phy_device *phydev, int devad, int reg,
115 u16 val);
116
117 struct list_head list;
118
119
120 ulong data;
121};
122
123struct phy_device {
124
125
126 struct mii_dev *bus;
127 struct phy_driver *drv;
128 void *priv;
129
130#ifdef CONFIG_DM_ETH
131 struct udevice *dev;
132 ofnode node;
133#else
134 struct eth_device *dev;
135#endif
136
137
138
139
140 int speed;
141 int duplex;
142
143
144 int link;
145 int port;
146 phy_interface_t interface;
147
148 u32 advertising;
149 u32 supported;
150 u32 mmds;
151
152 int autoneg;
153 int addr;
154 int pause;
155 int asym_pause;
156 u32 phy_id;
157 bool is_c45;
158 u32 flags;
159};
160
161struct fixed_link {
162 int phy_id;
163 int duplex;
164 int link_speed;
165 int pause;
166 int asym_pause;
167};
168
169static inline int phy_read(struct phy_device *phydev, int devad, int regnum)
170{
171 struct mii_dev *bus = phydev->bus;
172
173 return bus->read(bus, phydev->addr, devad, regnum);
174}
175
176static inline int phy_write(struct phy_device *phydev, int devad, int regnum,
177 u16 val)
178{
179 struct mii_dev *bus = phydev->bus;
180
181 return bus->write(bus, phydev->addr, devad, regnum, val);
182}
183
184static inline void phy_mmd_start_indirect(struct phy_device *phydev, int devad,
185 int regnum)
186{
187
188 phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL, devad);
189
190
191 phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, regnum);
192
193
194 phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL,
195 (devad | MII_MMD_CTRL_NOINCR));
196}
197
198static inline int phy_read_mmd(struct phy_device *phydev, int devad,
199 int regnum)
200{
201 struct phy_driver *drv = phydev->drv;
202
203 if (regnum > (u16)~0 || devad > 32)
204 return -EINVAL;
205
206
207 if (drv->read_mmd)
208 return drv->read_mmd(phydev, devad, regnum);
209
210
211 if ((drv->features & PHY_10G_FEATURES) == PHY_10G_FEATURES ||
212 devad == MDIO_DEVAD_NONE || !devad)
213 return phy_read(phydev, devad, regnum);
214
215
216 phy_mmd_start_indirect(phydev, devad, regnum);
217
218
219 return phy_read(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA);
220}
221
222static inline int phy_write_mmd(struct phy_device *phydev, int devad,
223 int regnum, u16 val)
224{
225 struct phy_driver *drv = phydev->drv;
226
227 if (regnum > (u16)~0 || devad > 32)
228 return -EINVAL;
229
230
231 if (drv->write_mmd)
232 return drv->write_mmd(phydev, devad, regnum, val);
233
234
235 if ((drv->features & PHY_10G_FEATURES) == PHY_10G_FEATURES ||
236 devad == MDIO_DEVAD_NONE || !devad)
237 return phy_write(phydev, devad, regnum, val);
238
239
240 phy_mmd_start_indirect(phydev, devad, regnum);
241
242
243 return phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, val);
244}
245
246#ifdef CONFIG_PHYLIB_10G
247extern struct phy_driver gen10g_driver;
248
249
250static inline int is_10g_interface(phy_interface_t interface)
251{
252 return interface == PHY_INTERFACE_MODE_XGMII;
253}
254
255#endif
256
257
258
259
260
261
262
263
264int phy_init(void);
265
266
267
268
269
270
271
272
273
274int phy_reset(struct phy_device *phydev);
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
291 phy_interface_t interface);
292
293#ifdef CONFIG_DM_ETH
294
295
296
297
298
299
300void phy_connect_dev(struct phy_device *phydev, struct udevice *dev);
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318struct phy_device *phy_connect(struct mii_dev *bus, int addr,
319 struct udevice *dev,
320 phy_interface_t interface);
321
322static inline ofnode phy_get_ofnode(struct phy_device *phydev)
323{
324 if (ofnode_valid(phydev->node))
325 return phydev->node;
326 else
327 return dev_ofnode(phydev->dev);
328}
329#else
330
331
332
333
334
335
336void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev);
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354struct phy_device *phy_connect(struct mii_dev *bus, int addr,
355 struct eth_device *dev,
356 phy_interface_t interface);
357
358static inline ofnode phy_get_ofnode(struct phy_device *phydev)
359{
360 return ofnode_null();
361}
362#endif
363int phy_startup(struct phy_device *phydev);
364int phy_config(struct phy_device *phydev);
365int phy_shutdown(struct phy_device *phydev);
366int phy_register(struct phy_driver *drv);
367int phy_set_supported(struct phy_device *phydev, u32 max_speed);
368int genphy_config_aneg(struct phy_device *phydev);
369int genphy_restart_aneg(struct phy_device *phydev);
370int genphy_update_link(struct phy_device *phydev);
371int genphy_parse_link(struct phy_device *phydev);
372int genphy_config(struct phy_device *phydev);
373int genphy_startup(struct phy_device *phydev);
374int genphy_shutdown(struct phy_device *phydev);
375int gen10g_config(struct phy_device *phydev);
376int gen10g_startup(struct phy_device *phydev);
377int gen10g_shutdown(struct phy_device *phydev);
378int gen10g_discover_mmds(struct phy_device *phydev);
379
380int phy_b53_init(void);
381int phy_mv88e61xx_init(void);
382int phy_aquantia_init(void);
383int phy_atheros_init(void);
384int phy_broadcom_init(void);
385int phy_cortina_init(void);
386int phy_davicom_init(void);
387int phy_et1011c_init(void);
388int phy_lxt_init(void);
389int phy_marvell_init(void);
390int phy_micrel_ksz8xxx_init(void);
391int phy_micrel_ksz90x1_init(void);
392int phy_meson_gxl_init(void);
393int phy_natsemi_init(void);
394int phy_realtek_init(void);
395int phy_smsc_init(void);
396int phy_teranetics_init(void);
397int phy_ti_init(void);
398int phy_vitesse_init(void);
399int phy_xilinx_init(void);
400int phy_mscc_init(void);
401int phy_fixed_init(void);
402int phy_xilinx_gmii2rgmii_init(void);
403
404int board_phy_config(struct phy_device *phydev);
405int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id);
406
407
408
409
410
411
412
413int phy_get_interface_by_name(const char *str);
414
415
416
417
418
419
420static inline bool phy_interface_is_rgmii(struct phy_device *phydev)
421{
422 return phydev->interface >= PHY_INTERFACE_MODE_RGMII &&
423 phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID;
424}
425
426
427
428
429
430
431static inline bool phy_interface_is_sgmii(struct phy_device *phydev)
432{
433 return phydev->interface >= PHY_INTERFACE_MODE_SGMII &&
434 phydev->interface <= PHY_INTERFACE_MODE_QSGMII;
435}
436
437
438#define PHY_UID_CS4340 0x13e51002
439#define PHY_UID_CS4223 0x03e57003
440#define PHY_UID_TN2020 0x00a19410
441#define PHY_UID_IN112525_S03 0x02107440
442
443#endif
444