1
2
3
4
5
6#ifndef __LINUX_MDIO_H__
7#define __LINUX_MDIO_H__
8
9#include <uapi/linux/mdio.h>
10#include <linux/mod_devicetable.h>
11
12
13
14
15#define MII_ADDR_C45 (1<<30)
16#define MII_DEVADDR_C45_SHIFT 16
17#define MII_REGADDR_C45_MASK GENMASK(15, 0)
18
19struct gpio_desc;
20struct mii_bus;
21struct reset_control;
22
23
24
25
26
27
28enum mdio_mutex_lock_class {
29 MDIO_MUTEX_NORMAL,
30 MDIO_MUTEX_MUX,
31 MDIO_MUTEX_NESTED,
32};
33
34struct mdio_device {
35 struct device dev;
36
37 struct mii_bus *bus;
38 char modalias[MDIO_NAME_SIZE];
39
40 int (*bus_match)(struct device *dev, struct device_driver *drv);
41 void (*device_free)(struct mdio_device *mdiodev);
42 void (*device_remove)(struct mdio_device *mdiodev);
43
44
45 int addr;
46 int flags;
47 struct gpio_desc *reset_gpio;
48 struct reset_control *reset_ctrl;
49 unsigned int reset_assert_delay;
50 unsigned int reset_deassert_delay;
51};
52
53static inline struct mdio_device *to_mdio_device(const struct device *dev)
54{
55 return container_of(dev, struct mdio_device, dev);
56}
57
58
59struct mdio_driver_common {
60 struct device_driver driver;
61 int flags;
62};
63#define MDIO_DEVICE_FLAG_PHY 1
64
65static inline struct mdio_driver_common *
66to_mdio_common_driver(const struct device_driver *driver)
67{
68 return container_of(driver, struct mdio_driver_common, driver);
69}
70
71
72struct mdio_driver {
73 struct mdio_driver_common mdiodrv;
74
75
76
77
78
79 int (*probe)(struct mdio_device *mdiodev);
80
81
82 void (*remove)(struct mdio_device *mdiodev);
83
84
85 void (*shutdown)(struct mdio_device *mdiodev);
86};
87
88static inline struct mdio_driver *
89to_mdio_driver(const struct device_driver *driver)
90{
91 return container_of(to_mdio_common_driver(driver), struct mdio_driver,
92 mdiodrv);
93}
94
95
96static inline void mdiodev_set_drvdata(struct mdio_device *mdio, void *data)
97{
98 dev_set_drvdata(&mdio->dev, data);
99}
100
101static inline void *mdiodev_get_drvdata(struct mdio_device *mdio)
102{
103 return dev_get_drvdata(&mdio->dev);
104}
105
106void mdio_device_free(struct mdio_device *mdiodev);
107struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr);
108int mdio_device_register(struct mdio_device *mdiodev);
109void mdio_device_remove(struct mdio_device *mdiodev);
110void mdio_device_reset(struct mdio_device *mdiodev, int value);
111int mdio_driver_register(struct mdio_driver *drv);
112void mdio_driver_unregister(struct mdio_driver *drv);
113int mdio_device_bus_match(struct device *dev, struct device_driver *drv);
114
115static inline bool mdio_phy_id_is_c45(int phy_id)
116{
117 return (phy_id & MDIO_PHY_ID_C45) && !(phy_id & ~MDIO_PHY_ID_C45_MASK);
118}
119
120static inline __u16 mdio_phy_id_prtad(int phy_id)
121{
122 return (phy_id & MDIO_PHY_ID_PRTAD) >> 5;
123}
124
125static inline __u16 mdio_phy_id_devad(int phy_id)
126{
127 return phy_id & MDIO_PHY_ID_DEVAD;
128}
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144struct mdio_if_info {
145 int prtad;
146 u32 mmds;
147 unsigned mode_support;
148
149 struct net_device *dev;
150 int (*mdio_read)(struct net_device *dev, int prtad, int devad,
151 u16 addr);
152 int (*mdio_write)(struct net_device *dev, int prtad, int devad,
153 u16 addr, u16 val);
154};
155
156#define MDIO_PRTAD_NONE (-1)
157#define MDIO_DEVAD_NONE (-1)
158#define MDIO_SUPPORTS_C22 1
159#define MDIO_SUPPORTS_C45 2
160#define MDIO_EMULATE_C22 4
161
162struct ethtool_cmd;
163struct ethtool_pauseparam;
164extern int mdio45_probe(struct mdio_if_info *mdio, int prtad);
165extern int mdio_set_flag(const struct mdio_if_info *mdio,
166 int prtad, int devad, u16 addr, int mask,
167 bool sense);
168extern int mdio45_links_ok(const struct mdio_if_info *mdio, u32 mmds);
169extern int mdio45_nway_restart(const struct mdio_if_info *mdio);
170extern void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
171 struct ethtool_cmd *ecmd,
172 u32 npage_adv, u32 npage_lpa);
173extern void
174mdio45_ethtool_ksettings_get_npage(const struct mdio_if_info *mdio,
175 struct ethtool_link_ksettings *cmd,
176 u32 npage_adv, u32 npage_lpa);
177
178
179
180
181
182
183
184
185
186
187
188static inline void mdio45_ethtool_gset(const struct mdio_if_info *mdio,
189 struct ethtool_cmd *ecmd)
190{
191 mdio45_ethtool_gset_npage(mdio, ecmd, 0, 0);
192}
193
194
195
196
197
198
199
200
201
202
203
204static inline void
205mdio45_ethtool_ksettings_get(const struct mdio_if_info *mdio,
206 struct ethtool_link_ksettings *cmd)
207{
208 mdio45_ethtool_ksettings_get_npage(mdio, cmd, 0, 0);
209}
210
211extern int mdio_mii_ioctl(const struct mdio_if_info *mdio,
212 struct mii_ioctl_data *mii_data, int cmd);
213
214
215
216
217
218
219
220
221static inline u32 mmd_eee_cap_to_ethtool_sup_t(u16 eee_cap)
222{
223 u32 supported = 0;
224
225 if (eee_cap & MDIO_EEE_100TX)
226 supported |= SUPPORTED_100baseT_Full;
227 if (eee_cap & MDIO_EEE_1000T)
228 supported |= SUPPORTED_1000baseT_Full;
229 if (eee_cap & MDIO_EEE_10GT)
230 supported |= SUPPORTED_10000baseT_Full;
231 if (eee_cap & MDIO_EEE_1000KX)
232 supported |= SUPPORTED_1000baseKX_Full;
233 if (eee_cap & MDIO_EEE_10GKX4)
234 supported |= SUPPORTED_10000baseKX4_Full;
235 if (eee_cap & MDIO_EEE_10GKR)
236 supported |= SUPPORTED_10000baseKR_Full;
237
238 return supported;
239}
240
241
242
243
244
245
246
247
248
249static inline u32 mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv)
250{
251 u32 adv = 0;
252
253 if (eee_adv & MDIO_EEE_100TX)
254 adv |= ADVERTISED_100baseT_Full;
255 if (eee_adv & MDIO_EEE_1000T)
256 adv |= ADVERTISED_1000baseT_Full;
257 if (eee_adv & MDIO_EEE_10GT)
258 adv |= ADVERTISED_10000baseT_Full;
259 if (eee_adv & MDIO_EEE_1000KX)
260 adv |= ADVERTISED_1000baseKX_Full;
261 if (eee_adv & MDIO_EEE_10GKX4)
262 adv |= ADVERTISED_10000baseKX4_Full;
263 if (eee_adv & MDIO_EEE_10GKR)
264 adv |= ADVERTISED_10000baseKR_Full;
265
266 return adv;
267}
268
269
270
271
272
273
274
275
276
277static inline u16 ethtool_adv_to_mmd_eee_adv_t(u32 adv)
278{
279 u16 reg = 0;
280
281 if (adv & ADVERTISED_100baseT_Full)
282 reg |= MDIO_EEE_100TX;
283 if (adv & ADVERTISED_1000baseT_Full)
284 reg |= MDIO_EEE_1000T;
285 if (adv & ADVERTISED_10000baseT_Full)
286 reg |= MDIO_EEE_10GT;
287 if (adv & ADVERTISED_1000baseKX_Full)
288 reg |= MDIO_EEE_1000KX;
289 if (adv & ADVERTISED_10000baseKX4_Full)
290 reg |= MDIO_EEE_10GKX4;
291 if (adv & ADVERTISED_10000baseKR_Full)
292 reg |= MDIO_EEE_10GKR;
293
294 return reg;
295}
296
297
298
299
300
301
302
303
304
305static inline u32 linkmode_adv_to_mii_10gbt_adv_t(unsigned long *advertising)
306{
307 u32 result = 0;
308
309 if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
310 advertising))
311 result |= MDIO_AN_10GBT_CTRL_ADV2_5G;
312 if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
313 advertising))
314 result |= MDIO_AN_10GBT_CTRL_ADV5G;
315 if (linkmode_test_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
316 advertising))
317 result |= MDIO_AN_10GBT_CTRL_ADV10G;
318
319 return result;
320}
321
322
323
324
325
326
327
328
329
330static inline void mii_10gbt_stat_mod_linkmode_lpa_t(unsigned long *advertising,
331 u32 lpa)
332{
333 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
334 advertising, lpa & MDIO_AN_10GBT_STAT_LP2_5G);
335 linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
336 advertising, lpa & MDIO_AN_10GBT_STAT_LP5G);
337 linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
338 advertising, lpa & MDIO_AN_10GBT_STAT_LP10G);
339}
340
341int __mdiobus_read(struct mii_bus *bus, int addr, u32 regnum);
342int __mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val);
343int __mdiobus_modify_changed(struct mii_bus *bus, int addr, u32 regnum,
344 u16 mask, u16 set);
345
346int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum);
347int mdiobus_read_nested(struct mii_bus *bus, int addr, u32 regnum);
348int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val);
349int mdiobus_write_nested(struct mii_bus *bus, int addr, u32 regnum, u16 val);
350int mdiobus_modify(struct mii_bus *bus, int addr, u32 regnum, u16 mask,
351 u16 set);
352
353static inline u32 mdiobus_c45_addr(int devad, u16 regnum)
354{
355 return MII_ADDR_C45 | devad << MII_DEVADDR_C45_SHIFT | regnum;
356}
357
358static inline int __mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
359 u16 regnum)
360{
361 return __mdiobus_read(bus, prtad, mdiobus_c45_addr(devad, regnum));
362}
363
364static inline int __mdiobus_c45_write(struct mii_bus *bus, int prtad, int devad,
365 u16 regnum, u16 val)
366{
367 return __mdiobus_write(bus, prtad, mdiobus_c45_addr(devad, regnum),
368 val);
369}
370
371static inline int mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
372 u16 regnum)
373{
374 return mdiobus_read(bus, prtad, mdiobus_c45_addr(devad, regnum));
375}
376
377static inline int mdiobus_c45_write(struct mii_bus *bus, int prtad, int devad,
378 u16 regnum, u16 val)
379{
380 return mdiobus_write(bus, prtad, mdiobus_c45_addr(devad, regnum), val);
381}
382
383int mdiobus_register_device(struct mdio_device *mdiodev);
384int mdiobus_unregister_device(struct mdio_device *mdiodev);
385bool mdiobus_is_registered_device(struct mii_bus *bus, int addr);
386struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr);
387
388
389
390
391
392
393
394
395
396#define mdio_module_driver(_mdio_driver) \
397static int __init mdio_module_init(void) \
398{ \
399 return mdio_driver_register(&_mdio_driver); \
400} \
401module_init(mdio_module_init); \
402static void __exit mdio_module_exit(void) \
403{ \
404 mdio_driver_unregister(&_mdio_driver); \
405} \
406module_exit(mdio_module_exit)
407
408#endif
409