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
net
ethernet
xilinx
ll_temac_mdio.c
Go to the documentation of this file.
1
/*
2
* MDIO bus driver for the Xilinx TEMAC device
3
*
4
* Copyright (c) 2009 Secret Lab Technologies, Ltd.
5
*/
6
7
#include <
linux/io.h
>
8
#include <linux/netdevice.h>
9
#include <
linux/mutex.h
>
10
#include <
linux/phy.h
>
11
#include <
linux/of.h
>
12
#include <
linux/of_device.h
>
13
#include <
linux/of_address.h
>
14
#include <linux/slab.h>
15
#include <
linux/of_mdio.h
>
16
17
#include "
ll_temac.h
"
18
19
/* ---------------------------------------------------------------------
20
* MDIO Bus functions
21
*/
22
static
int
temac_mdio_read(
struct
mii_bus
*
bus
,
int
phy_id
,
int
reg
)
23
{
24
struct
temac_local
*
lp
= bus->
priv
;
25
u32
rc
;
26
27
/* Write the PHY address to the MIIM Access Initiator register.
28
* When the transfer completes, the PHY register value will appear
29
* in the LSW0 register */
30
mutex_lock
(&lp->
indirect_mutex
);
31
temac_iow
(lp,
XTE_LSW0_OFFSET
, (phy_id << 5) | reg);
32
rc =
temac_indirect_in32
(lp,
XTE_MIIMAI_OFFSET
);
33
mutex_unlock
(&lp->
indirect_mutex
);
34
35
dev_dbg
(lp->
dev
,
"temac_mdio_read(phy_id=%i, reg=%x) == %x\n"
,
36
phy_id, reg, rc);
37
38
return
rc
;
39
}
40
41
static
int
temac_mdio_write(
struct
mii_bus
*bus,
int
phy_id,
int
reg,
u16
val
)
42
{
43
struct
temac_local
*lp = bus->
priv
;
44
45
dev_dbg
(lp->
dev
,
"temac_mdio_write(phy_id=%i, reg=%x, val=%x)\n"
,
46
phy_id, reg, val);
47
48
/* First write the desired value into the write data register
49
* and then write the address into the access initiator register
50
*/
51
mutex_lock
(&lp->
indirect_mutex
);
52
temac_indirect_out32
(lp,
XTE_MGTDR_OFFSET
, val);
53
temac_indirect_out32
(lp,
XTE_MIIMAI_OFFSET
, (phy_id << 5) | reg);
54
mutex_unlock
(&lp->
indirect_mutex
);
55
56
return
0;
57
}
58
59
int
temac_mdio_setup
(
struct
temac_local
*lp,
struct
device_node
*np)
60
{
61
struct
mii_bus
*
bus
;
62
const
u32
*bus_hz;
63
int
clk_div
;
64
int
rc
,
size
;
65
struct
resource
res;
66
67
/* Calculate a reasonable divisor for the clock rate */
68
clk_div = 0x3f;
/* worst-case default setting */
69
bus_hz =
of_get_property
(np,
"clock-frequency"
, &size);
70
if
(bus_hz && size >=
sizeof
(*bus_hz)) {
71
clk_div = (*bus_hz) / (2500 * 1000 * 2) - 1;
72
if
(clk_div < 1)
73
clk_div = 1;
74
if
(clk_div > 0x3f)
75
clk_div = 0x3f;
76
}
77
78
/* Enable the MDIO bus by asserting the enable bit and writing
79
* in the clock config */
80
mutex_lock
(&lp->
indirect_mutex
);
81
temac_indirect_out32
(lp,
XTE_MC_OFFSET
, 1 << 6 | clk_div);
82
mutex_unlock
(&lp->
indirect_mutex
);
83
84
bus = mdiobus_alloc();
85
if
(!bus)
86
return
-
ENOMEM
;
87
88
of_address_to_resource
(np, 0, &res);
89
snprintf
(bus->
id
,
MII_BUS_ID_SIZE
,
"%.8llx"
,
90
(
unsigned
long
long
)res.
start
);
91
bus->
priv
= lp;
92
bus->
name
=
"Xilinx TEMAC MDIO"
;
93
bus->
read
= temac_mdio_read;
94
bus->
write
= temac_mdio_write;
95
bus->
parent
= lp->
dev
;
96
bus->
irq
= lp->
mdio_irqs
;
/* preallocated IRQ table */
97
98
lp->
mii_bus
=
bus
;
99
100
rc =
of_mdiobus_register
(bus, np);
101
if
(rc)
102
goto
err_register;
103
104
mutex_lock
(&lp->
indirect_mutex
);
105
dev_dbg
(lp->
dev
,
"MDIO bus registered; MC:%x\n"
,
106
temac_indirect_in32
(lp,
XTE_MC_OFFSET
));
107
mutex_unlock
(&lp->
indirect_mutex
);
108
return
0;
109
110
err_register:
111
mdiobus_free
(bus);
112
return
rc
;
113
}
114
115
void
temac_mdio_teardown
(
struct
temac_local
*lp)
116
{
117
mdiobus_unregister
(lp->
mii_bus
);
118
kfree
(lp->
mii_bus
->irq);
119
mdiobus_free
(lp->
mii_bus
);
120
lp->
mii_bus
=
NULL
;
121
}
122
Generated on Thu Jan 10 2013 14:06:12 for Linux Kernel by
1.8.2