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
oki-semi
pch_gbe
pch_gbe_phy.c
Go to the documentation of this file.
1
/*
2
* Copyright (C) 1999 - 2010 Intel Corporation.
3
* Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
4
*
5
* This code was derived from the Intel e1000e Linux driver.
6
*
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; version 2 of the License.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19
*/
20
21
#include "
pch_gbe.h
"
22
#include "
pch_gbe_phy.h
"
23
24
#define PHY_MAX_REG_ADDRESS 0x1F
/* 5 bit address bus (0-0x1F) */
25
26
/* PHY 1000 MII Register/Bit Definitions */
27
/* PHY Registers defined by IEEE */
28
#define PHY_CONTROL 0x00
/* Control Register */
29
#define PHY_STATUS 0x01
/* Status Regiser */
30
#define PHY_ID1 0x02
/* Phy Id Register (word 1) */
31
#define PHY_ID2 0x03
/* Phy Id Register (word 2) */
32
#define PHY_AUTONEG_ADV 0x04
/* Autoneg Advertisement */
33
#define PHY_LP_ABILITY 0x05
/* Link Partner Ability (Base Page) */
34
#define PHY_AUTONEG_EXP 0x06
/* Autoneg Expansion Register */
35
#define PHY_NEXT_PAGE_TX 0x07
/* Next Page TX */
36
#define PHY_LP_NEXT_PAGE 0x08
/* Link Partner Next Page */
37
#define PHY_1000T_CTRL 0x09
/* 1000Base-T Control Register */
38
#define PHY_1000T_STATUS 0x0A
/* 1000Base-T Status Register */
39
#define PHY_EXT_STATUS 0x0F
/* Extended Status Register */
40
#define PHY_PHYSP_CONTROL 0x10
/* PHY Specific Control Register */
41
#define PHY_EXT_PHYSP_CONTROL 0x14
/* Extended PHY Specific Control Register */
42
#define PHY_LED_CONTROL 0x18
/* LED Control Register */
43
#define PHY_EXT_PHYSP_STATUS 0x1B
/* Extended PHY Specific Status Register */
44
45
/* PHY Control Register */
46
#define MII_CR_SPEED_SELECT_MSB 0x0040
/* bits 6,13: 10=1000, 01=100, 00=10 */
47
#define MII_CR_COLL_TEST_ENABLE 0x0080
/* Collision test enable */
48
#define MII_CR_FULL_DUPLEX 0x0100
/* FDX =1, half duplex =0 */
49
#define MII_CR_RESTART_AUTO_NEG 0x0200
/* Restart auto negotiation */
50
#define MII_CR_ISOLATE 0x0400
/* Isolate PHY from MII */
51
#define MII_CR_POWER_DOWN 0x0800
/* Power down */
52
#define MII_CR_AUTO_NEG_EN 0x1000
/* Auto Neg Enable */
53
#define MII_CR_SPEED_SELECT_LSB 0x2000
/* bits 6,13: 10=1000, 01=100, 00=10 */
54
#define MII_CR_LOOPBACK 0x4000
/* 0 = normal, 1 = loopback */
55
#define MII_CR_RESET 0x8000
/* 0 = normal, 1 = PHY reset */
56
#define MII_CR_SPEED_1000 0x0040
57
#define MII_CR_SPEED_100 0x2000
58
#define MII_CR_SPEED_10 0x0000
59
60
/* PHY Status Register */
61
#define MII_SR_EXTENDED_CAPS 0x0001
/* Extended register capabilities */
62
#define MII_SR_JABBER_DETECT 0x0002
/* Jabber Detected */
63
#define MII_SR_LINK_STATUS 0x0004
/* Link Status 1 = link */
64
#define MII_SR_AUTONEG_CAPS 0x0008
/* Auto Neg Capable */
65
#define MII_SR_REMOTE_FAULT 0x0010
/* Remote Fault Detect */
66
#define MII_SR_AUTONEG_COMPLETE 0x0020
/* Auto Neg Complete */
67
#define MII_SR_PREAMBLE_SUPPRESS 0x0040
/* Preamble may be suppressed */
68
#define MII_SR_EXTENDED_STATUS 0x0100
/* Ext. status info in Reg 0x0F */
69
#define MII_SR_100T2_HD_CAPS 0x0200
/* 100T2 Half Duplex Capable */
70
#define MII_SR_100T2_FD_CAPS 0x0400
/* 100T2 Full Duplex Capable */
71
#define MII_SR_10T_HD_CAPS 0x0800
/* 10T Half Duplex Capable */
72
#define MII_SR_10T_FD_CAPS 0x1000
/* 10T Full Duplex Capable */
73
#define MII_SR_100X_HD_CAPS 0x2000
/* 100X Half Duplex Capable */
74
#define MII_SR_100X_FD_CAPS 0x4000
/* 100X Full Duplex Capable */
75
#define MII_SR_100T4_CAPS 0x8000
/* 100T4 Capable */
76
77
/* Phy Id Register (word 2) */
78
#define PHY_REVISION_MASK 0x000F
79
80
/* PHY Specific Control Register */
81
#define PHYSP_CTRL_ASSERT_CRS_TX 0x0800
82
83
84
/* Default value of PHY register */
85
#define PHY_CONTROL_DEFAULT 0x1140
/* Control Register */
86
#define PHY_AUTONEG_ADV_DEFAULT 0x01e0
/* Autoneg Advertisement */
87
#define PHY_NEXT_PAGE_TX_DEFAULT 0x2001
/* Next Page TX */
88
#define PHY_1000T_CTRL_DEFAULT 0x0300
/* 1000Base-T Control Register */
89
#define PHY_PHYSP_CONTROL_DEFAULT 0x01EE
/* PHY Specific Control Register */
90
98
s32
pch_gbe_phy_get_id
(
struct
pch_gbe_hw
*
hw
)
99
{
100
struct
pch_gbe_phy_info
*
phy
= &hw->
phy
;
101
s32
ret
;
102
u16
phy_id1;
103
u16
phy_id2;
104
105
ret =
pch_gbe_phy_read_reg_miic
(hw,
PHY_ID1
, &phy_id1);
106
if
(ret)
107
return
ret
;
108
ret =
pch_gbe_phy_read_reg_miic
(hw,
PHY_ID2
, &phy_id2);
109
if
(ret)
110
return
ret
;
111
/*
112
* PHY_ID1: [bit15-0:ID(21-6)]
113
* PHY_ID2: [bit15-10:ID(5-0)][bit9-4:Model][bit3-0:revision]
114
*/
115
phy->
id
= (
u32
)phy_id1;
116
phy->
id
= ((phy->
id
<< 6) | ((phy_id2 & 0xFC00) >> 10));
117
phy->
revision
= (
u32
) (phy_id2 & 0x000F);
118
pr_debug
(
"phy->id : 0x%08x phy->revision : 0x%08x\n"
,
119
phy->
id
, phy->
revision
);
120
return
0;
121
}
122
132
s32
pch_gbe_phy_read_reg_miic
(
struct
pch_gbe_hw
*
hw
,
u32
offset
,
u16
*
data
)
133
{
134
struct
pch_gbe_phy_info
*
phy
= &hw->
phy
;
135
136
if
(offset >
PHY_MAX_REG_ADDRESS
) {
137
pr_err
(
"PHY Address %d is out of range\n"
, offset);
138
return
-
EINVAL
;
139
}
140
*data =
pch_gbe_mac_ctrl_miim
(hw, phy->
addr
,
PCH_GBE_HAL_MIIM_READ
,
141
offset, (
u16
)0);
142
return
0;
143
}
144
154
s32
pch_gbe_phy_write_reg_miic
(
struct
pch_gbe_hw
*
hw
,
u32
offset
,
u16
data
)
155
{
156
struct
pch_gbe_phy_info
*
phy
= &hw->
phy
;
157
158
if
(offset >
PHY_MAX_REG_ADDRESS
) {
159
pr_err
(
"PHY Address %d is out of range\n"
, offset);
160
return
-
EINVAL
;
161
}
162
pch_gbe_mac_ctrl_miim
(hw, phy->
addr
,
PCH_GBE_HAL_MIIM_WRITE
,
163
offset, data);
164
return
0;
165
}
166
171
void
pch_gbe_phy_sw_reset
(
struct
pch_gbe_hw
*
hw
)
172
{
173
u16
phy_ctrl;
174
175
pch_gbe_phy_read_reg_miic
(hw,
PHY_CONTROL
, &phy_ctrl);
176
phy_ctrl |=
MII_CR_RESET
;
177
pch_gbe_phy_write_reg_miic
(hw,
PHY_CONTROL
, phy_ctrl);
178
udelay
(1);
179
}
180
185
void
pch_gbe_phy_hw_reset
(
struct
pch_gbe_hw
*
hw
)
186
{
187
pch_gbe_phy_write_reg_miic
(hw,
PHY_CONTROL
,
PHY_CONTROL_DEFAULT
);
188
pch_gbe_phy_write_reg_miic
(hw,
PHY_AUTONEG_ADV
,
189
PHY_AUTONEG_ADV_DEFAULT
);
190
pch_gbe_phy_write_reg_miic
(hw,
PHY_NEXT_PAGE_TX
,
191
PHY_NEXT_PAGE_TX_DEFAULT
);
192
pch_gbe_phy_write_reg_miic
(hw,
PHY_1000T_CTRL
,
PHY_1000T_CTRL_DEFAULT
);
193
pch_gbe_phy_write_reg_miic
(hw,
PHY_PHYSP_CONTROL
,
194
PHY_PHYSP_CONTROL_DEFAULT
);
195
}
196
201
void
pch_gbe_phy_power_up
(
struct
pch_gbe_hw
*
hw
)
202
{
203
u16
mii_reg;
204
205
mii_reg = 0;
206
/* Just clear the power down bit to wake the phy back up */
207
/* according to the manual, the phy will retain its
208
* settings across a power-down/up cycle */
209
pch_gbe_phy_read_reg_miic
(hw,
PHY_CONTROL
, &mii_reg);
210
mii_reg &= ~
MII_CR_POWER_DOWN
;
211
pch_gbe_phy_write_reg_miic
(hw,
PHY_CONTROL
, mii_reg);
212
}
213
218
void
pch_gbe_phy_power_down
(
struct
pch_gbe_hw
*
hw
)
219
{
220
u16
mii_reg;
221
222
mii_reg = 0;
223
/* Power down the PHY so no link is implied when interface is down *
224
* The PHY cannot be powered down if any of the following is TRUE *
225
* (a) WoL is enabled
226
* (b) AMT is active
227
*/
228
pch_gbe_phy_read_reg_miic
(hw,
PHY_CONTROL
, &mii_reg);
229
mii_reg |=
MII_CR_POWER_DOWN
;
230
pch_gbe_phy_write_reg_miic
(hw,
PHY_CONTROL
, mii_reg);
231
mdelay
(1);
232
}
233
238
inline
void
pch_gbe_phy_set_rgmii
(
struct
pch_gbe_hw
*
hw
)
239
{
240
pch_gbe_phy_sw_reset
(hw);
241
}
242
247
void
pch_gbe_phy_init_setting
(
struct
pch_gbe_hw
*
hw
)
248
{
249
struct
pch_gbe_adapter
*
adapter
;
250
struct
ethtool_cmd
cmd = { .
cmd
=
ETHTOOL_GSET
};
251
int
ret
;
252
u16
mii_reg;
253
254
adapter =
container_of
(hw,
struct
pch_gbe_adapter
, hw);
255
ret =
mii_ethtool_gset
(&adapter->
mii
, &cmd);
256
if
(ret)
257
pr_err
(
"Error: mii_ethtool_gset\n"
);
258
259
ethtool_cmd_speed_set(&cmd, hw->
mac
.link_speed);
260
cmd.
duplex
= hw->
mac
.link_duplex;
261
cmd.
advertising
= hw->
phy
.autoneg_advertised;
262
cmd.
autoneg
= hw->
mac
.autoneg;
263
pch_gbe_phy_write_reg_miic
(hw,
MII_BMCR
,
BMCR_RESET
);
264
ret =
mii_ethtool_sset
(&adapter->
mii
, &cmd);
265
if
(ret)
266
pr_err
(
"Error: mii_ethtool_sset\n"
);
267
268
pch_gbe_phy_sw_reset
(hw);
269
270
pch_gbe_phy_read_reg_miic
(hw,
PHY_PHYSP_CONTROL
, &mii_reg);
271
mii_reg |=
PHYSP_CTRL_ASSERT_CRS_TX
;
272
pch_gbe_phy_write_reg_miic
(hw,
PHY_PHYSP_CONTROL
, mii_reg);
273
274
}
Generated on Thu Jan 10 2013 14:04:06 for Linux Kernel by
1.8.2