Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
of
of_mdio.c
Go to the documentation of this file.
1
/*
2
* OF helpers for the MDIO (Ethernet PHY) API
3
*
4
* Copyright (c) 2009 Secret Lab Technologies, Ltd.
5
*
6
* This file is released under the GPLv2
7
*
8
* This file provides helper functions for extracting PHY device information
9
* out of the OpenFirmware device tree and using it to populate an mii_bus.
10
*/
11
12
#include <linux/kernel.h>
13
#include <linux/device.h>
14
#include <linux/netdevice.h>
15
#include <
linux/err.h
>
16
#include <
linux/phy.h
>
17
#include <
linux/of.h
>
18
#include <
linux/of_irq.h
>
19
#include <
linux/of_mdio.h
>
20
#include <linux/module.h>
21
22
MODULE_AUTHOR
(
"Grant Likely <
[email protected]
>"
);
23
MODULE_LICENSE
(
"GPL"
);
24
33
int
of_mdiobus_register
(
struct
mii_bus
*mdio,
struct
device_node
*np)
34
{
35
struct
phy_device
*
phy
;
36
struct
device_node
*
child
;
37
int
rc
,
i
;
38
39
/* Mask out all PHYs from auto probing. Instead the PHYs listed in
40
* the device tree are populated after the bus has been registered */
41
mdio->
phy_mask
= ~0;
42
43
/* Clear all the IRQ properties */
44
if
(mdio->
irq
)
45
for
(i=0; i<
PHY_MAX_ADDR
; i++)
46
mdio->
irq
[i] =
PHY_POLL
;
47
48
mdio->
dev
.of_node = np;
49
50
/* Register the MDIO bus */
51
rc =
mdiobus_register
(mdio);
52
if
(rc)
53
return
rc
;
54
55
/* Loop over the child nodes and register a phy_device for each one */
56
for_each_child_of_node
(np, child) {
57
const
__be32
*
paddr
;
58
u32
addr
;
59
int
len
;
60
bool
is_c45;
61
62
/* A PHY must have a reg property in the range [0-31] */
63
paddr =
of_get_property
(child,
"reg"
, &len);
64
if
(!paddr || len <
sizeof
(*paddr)) {
65
dev_err
(&mdio->
dev
,
"%s has invalid PHY address\n"
,
66
child->
full_name
);
67
continue
;
68
}
69
70
addr =
be32_to_cpup
(paddr);
71
if
(addr >= 32) {
72
dev_err
(&mdio->
dev
,
"%s PHY address %i is too large\n"
,
73
child->
full_name
, addr);
74
continue
;
75
}
76
77
if
(mdio->
irq
) {
78
mdio->
irq
[
addr
] =
irq_of_parse_and_map
(child, 0);
79
if
(!mdio->
irq
[addr])
80
mdio->
irq
[
addr
] =
PHY_POLL
;
81
}
82
83
is_c45 =
of_device_is_compatible
(child,
84
"ethernet-phy-ieee802.3-c45"
);
85
phy =
get_phy_device
(mdio, addr, is_c45);
86
87
if
(!phy || IS_ERR(phy)) {
88
phy =
phy_device_create
(mdio, addr, 0,
false
,
NULL
);
89
if
(!phy || IS_ERR(phy)) {
90
dev_err
(&mdio->
dev
,
91
"error creating PHY at address %i\n"
,
92
addr);
93
continue
;
94
}
95
}
96
97
/* Associate the OF node with the device structure so it
98
* can be looked up later */
99
of_node_get(child);
100
phy->
dev
.of_node =
child
;
101
102
/* All data is now stored in the phy struct; register it */
103
rc =
phy_device_register
(phy);
104
if
(rc) {
105
phy_device_free
(phy);
106
of_node_put(child);
107
continue
;
108
}
109
110
dev_dbg
(&mdio->
dev
,
"registered phy %s at address %i\n"
,
111
child->
name
, addr);
112
}
113
114
return
0;
115
}
116
EXPORT_SYMBOL
(
of_mdiobus_register
);
117
118
/* Helper function for of_phy_find_device */
119
static
int
of_phy_match(
struct
device
*
dev
,
void
*phy_np)
120
{
121
return
dev->
of_node
== phy_np;
122
}
123
130
struct
phy_device
*
of_phy_find_device
(
struct
device_node
*phy_np)
131
{
132
struct
device
*
d
;
133
if
(!phy_np)
134
return
NULL
;
135
136
d =
bus_find_device
(&
mdio_bus_type
,
NULL
, phy_np, of_phy_match);
137
return
d ?
to_phy_device
(d) :
NULL
;
138
}
139
EXPORT_SYMBOL
(
of_phy_find_device
);
140
150
struct
phy_device
*
of_phy_connect
(
struct
net_device
*
dev
,
151
struct
device_node
*phy_np,
152
void
(*hndlr)(
struct
net_device
*),
u32
flags
,
153
phy_interface_t
iface)
154
{
155
struct
phy_device
*
phy
=
of_phy_find_device
(phy_np);
156
157
if
(!phy)
158
return
NULL
;
159
160
return
phy_connect_direct
(dev, phy, hndlr, flags, iface) ?
NULL
:
phy
;
161
}
162
EXPORT_SYMBOL
(
of_phy_connect
);
163
174
struct
phy_device
*
of_phy_connect_fixed_link
(
struct
net_device
*dev,
175
void
(*hndlr)(
struct
net_device
*),
176
phy_interface_t
iface)
177
{
178
struct
device_node
*net_np;
179
char
bus_id[
MII_BUS_ID_SIZE
+ 3];
180
struct
phy_device
*
phy
;
181
const
__be32
*
phy_id
;
182
int
sz;
183
184
if
(!dev->
dev
.parent)
185
return
NULL
;
186
187
net_np = dev->
dev
.parent->of_node;
188
if
(!net_np)
189
return
NULL
;
190
191
phy_id =
of_get_property
(net_np,
"fixed-link"
, &sz);
192
if
(!phy_id || sz <
sizeof
(*phy_id))
193
return
NULL
;
194
195
sprintf
(bus_id,
PHY_ID_FMT
,
"fixed-0"
,
be32_to_cpu
(phy_id[0]));
196
197
phy =
phy_connect
(dev, bus_id, hndlr, 0, iface);
198
return
IS_ERR(phy) ?
NULL
:
phy
;
199
}
200
EXPORT_SYMBOL
(
of_phy_connect_fixed_link
);
Generated on Thu Jan 10 2013 14:13:35 for Linux Kernel by
1.8.2