This source file includes following definitions.
- pch_gbe_phy_get_id
- pch_gbe_phy_read_reg_miic
- pch_gbe_phy_write_reg_miic
- pch_gbe_phy_sw_reset
- pch_gbe_phy_hw_reset
- pch_gbe_phy_power_up
- pch_gbe_phy_power_down
- pch_gbe_phy_set_rgmii
- pch_gbe_phy_tx_clk_delay
- pch_gbe_phy_init_setting
- pch_gbe_phy_disable_hibernate
1
2
3
4
5
6
7
8
9 #include "pch_gbe.h"
10 #include "pch_gbe_phy.h"
11
12 #define PHY_MAX_REG_ADDRESS 0x1F
13
14
15
16 #define PHY_CONTROL 0x00
17 #define PHY_STATUS 0x01
18 #define PHY_ID1 0x02
19 #define PHY_ID2 0x03
20 #define PHY_AUTONEG_ADV 0x04
21 #define PHY_LP_ABILITY 0x05
22 #define PHY_AUTONEG_EXP 0x06
23 #define PHY_NEXT_PAGE_TX 0x07
24 #define PHY_LP_NEXT_PAGE 0x08
25 #define PHY_1000T_CTRL 0x09
26 #define PHY_1000T_STATUS 0x0A
27 #define PHY_EXT_STATUS 0x0F
28 #define PHY_PHYSP_CONTROL 0x10
29 #define PHY_EXT_PHYSP_CONTROL 0x14
30 #define PHY_LED_CONTROL 0x18
31 #define PHY_EXT_PHYSP_STATUS 0x1B
32
33
34 #define MII_CR_SPEED_SELECT_MSB 0x0040
35 #define MII_CR_COLL_TEST_ENABLE 0x0080
36 #define MII_CR_FULL_DUPLEX 0x0100
37 #define MII_CR_RESTART_AUTO_NEG 0x0200
38 #define MII_CR_ISOLATE 0x0400
39 #define MII_CR_POWER_DOWN 0x0800
40 #define MII_CR_AUTO_NEG_EN 0x1000
41 #define MII_CR_SPEED_SELECT_LSB 0x2000
42 #define MII_CR_LOOPBACK 0x4000
43 #define MII_CR_RESET 0x8000
44 #define MII_CR_SPEED_1000 0x0040
45 #define MII_CR_SPEED_100 0x2000
46 #define MII_CR_SPEED_10 0x0000
47
48
49 #define MII_SR_EXTENDED_CAPS 0x0001
50 #define MII_SR_JABBER_DETECT 0x0002
51 #define MII_SR_LINK_STATUS 0x0004
52 #define MII_SR_AUTONEG_CAPS 0x0008
53 #define MII_SR_REMOTE_FAULT 0x0010
54 #define MII_SR_AUTONEG_COMPLETE 0x0020
55 #define MII_SR_PREAMBLE_SUPPRESS 0x0040
56 #define MII_SR_EXTENDED_STATUS 0x0100
57 #define MII_SR_100T2_HD_CAPS 0x0200
58 #define MII_SR_100T2_FD_CAPS 0x0400
59 #define MII_SR_10T_HD_CAPS 0x0800
60 #define MII_SR_10T_FD_CAPS 0x1000
61 #define MII_SR_100X_HD_CAPS 0x2000
62 #define MII_SR_100X_FD_CAPS 0x4000
63 #define MII_SR_100T4_CAPS 0x8000
64
65
66 #define PHY_AR803X_ID 0x00001374
67 #define PHY_AR8031_DBG_OFF 0x1D
68 #define PHY_AR8031_DBG_DAT 0x1E
69 #define PHY_AR8031_SERDES 0x05
70 #define PHY_AR8031_HIBERNATE 0x0B
71 #define PHY_AR8031_SERDES_TX_CLK_DLY 0x0100
72 #define PHY_AR8031_PS_HIB_EN 0x8000
73
74
75 #define PHY_REVISION_MASK 0x000F
76
77
78 #define PHYSP_CTRL_ASSERT_CRS_TX 0x0800
79
80
81
82 #define PHY_CONTROL_DEFAULT 0x1140
83 #define PHY_AUTONEG_ADV_DEFAULT 0x01e0
84 #define PHY_NEXT_PAGE_TX_DEFAULT 0x2001
85 #define PHY_1000T_CTRL_DEFAULT 0x0300
86 #define PHY_PHYSP_CONTROL_DEFAULT 0x01EE
87
88
89
90
91
92
93
94
95 s32 pch_gbe_phy_get_id(struct pch_gbe_hw *hw)
96 {
97 struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
98 struct pch_gbe_phy_info *phy = &hw->phy;
99 s32 ret;
100 u16 phy_id1;
101 u16 phy_id2;
102
103 ret = pch_gbe_phy_read_reg_miic(hw, PHY_ID1, &phy_id1);
104 if (ret)
105 return ret;
106 ret = pch_gbe_phy_read_reg_miic(hw, PHY_ID2, &phy_id2);
107 if (ret)
108 return ret;
109
110
111
112
113 phy->id = (u32)phy_id1;
114 phy->id = ((phy->id << 6) | ((phy_id2 & 0xFC00) >> 10));
115 phy->revision = (u32) (phy_id2 & 0x000F);
116 netdev_dbg(adapter->netdev,
117 "phy->id : 0x%08x phy->revision : 0x%08x\n",
118 phy->id, phy->revision);
119 return 0;
120 }
121
122
123
124
125
126
127
128
129
130
131 s32 pch_gbe_phy_read_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 *data)
132 {
133 struct pch_gbe_phy_info *phy = &hw->phy;
134
135 if (offset > PHY_MAX_REG_ADDRESS) {
136 struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
137
138 netdev_err(adapter->netdev, "PHY Address %d is out of range\n",
139 offset);
140 return -EINVAL;
141 }
142 *data = pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_READ,
143 offset, (u16)0);
144 return 0;
145 }
146
147
148
149
150
151
152
153
154
155
156 s32 pch_gbe_phy_write_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 data)
157 {
158 struct pch_gbe_phy_info *phy = &hw->phy;
159
160 if (offset > PHY_MAX_REG_ADDRESS) {
161 struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
162
163 netdev_err(adapter->netdev, "PHY Address %d is out of range\n",
164 offset);
165 return -EINVAL;
166 }
167 pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_WRITE,
168 offset, data);
169 return 0;
170 }
171
172
173
174
175
176 static void pch_gbe_phy_sw_reset(struct pch_gbe_hw *hw)
177 {
178 u16 phy_ctrl;
179
180 pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &phy_ctrl);
181 phy_ctrl |= MII_CR_RESET;
182 pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, phy_ctrl);
183 udelay(1);
184 }
185
186
187
188
189
190 void pch_gbe_phy_hw_reset(struct pch_gbe_hw *hw)
191 {
192 pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, PHY_CONTROL_DEFAULT);
193 pch_gbe_phy_write_reg_miic(hw, PHY_AUTONEG_ADV,
194 PHY_AUTONEG_ADV_DEFAULT);
195 pch_gbe_phy_write_reg_miic(hw, PHY_NEXT_PAGE_TX,
196 PHY_NEXT_PAGE_TX_DEFAULT);
197 pch_gbe_phy_write_reg_miic(hw, PHY_1000T_CTRL, PHY_1000T_CTRL_DEFAULT);
198 pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL,
199 PHY_PHYSP_CONTROL_DEFAULT);
200 }
201
202
203
204
205
206 void pch_gbe_phy_power_up(struct pch_gbe_hw *hw)
207 {
208 u16 mii_reg;
209
210 mii_reg = 0;
211
212
213
214 pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &mii_reg);
215 mii_reg &= ~MII_CR_POWER_DOWN;
216 pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, mii_reg);
217 }
218
219
220
221
222
223 void pch_gbe_phy_power_down(struct pch_gbe_hw *hw)
224 {
225 u16 mii_reg;
226
227 mii_reg = 0;
228
229
230
231
232
233 pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &mii_reg);
234 mii_reg |= MII_CR_POWER_DOWN;
235 pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, mii_reg);
236 mdelay(1);
237 }
238
239
240
241
242
243 void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw)
244 {
245 pch_gbe_phy_sw_reset(hw);
246 }
247
248
249
250
251
252
253
254
255 static int pch_gbe_phy_tx_clk_delay(struct pch_gbe_hw *hw)
256 {
257
258
259
260
261 struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
262 u16 mii_reg;
263 int ret = 0;
264
265 switch (hw->phy.id) {
266 case PHY_AR803X_ID:
267 netdev_dbg(adapter->netdev,
268 "Configuring AR803X PHY for 2ns TX clock delay\n");
269 pch_gbe_phy_read_reg_miic(hw, PHY_AR8031_DBG_OFF, &mii_reg);
270 ret = pch_gbe_phy_write_reg_miic(hw, PHY_AR8031_DBG_OFF,
271 PHY_AR8031_SERDES);
272 if (ret)
273 break;
274
275 pch_gbe_phy_read_reg_miic(hw, PHY_AR8031_DBG_DAT, &mii_reg);
276 mii_reg |= PHY_AR8031_SERDES_TX_CLK_DLY;
277 ret = pch_gbe_phy_write_reg_miic(hw, PHY_AR8031_DBG_DAT,
278 mii_reg);
279 break;
280 default:
281 netdev_err(adapter->netdev,
282 "Unknown PHY (%x), could not set TX clock delay\n",
283 hw->phy.id);
284 return -EINVAL;
285 }
286
287 if (ret)
288 netdev_err(adapter->netdev,
289 "Could not configure tx clock delay for PHY\n");
290 return ret;
291 }
292
293
294
295
296
297 void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw)
298 {
299 struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
300 struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
301 int ret;
302 u16 mii_reg;
303
304 ret = mii_ethtool_gset(&adapter->mii, &cmd);
305 if (ret)
306 netdev_err(adapter->netdev, "Error: mii_ethtool_gset\n");
307
308 ethtool_cmd_speed_set(&cmd, hw->mac.link_speed);
309 cmd.duplex = hw->mac.link_duplex;
310 cmd.advertising = hw->phy.autoneg_advertised;
311 cmd.autoneg = hw->mac.autoneg;
312 pch_gbe_phy_write_reg_miic(hw, MII_BMCR, BMCR_RESET);
313 ret = mii_ethtool_sset(&adapter->mii, &cmd);
314 if (ret)
315 netdev_err(adapter->netdev, "Error: mii_ethtool_sset\n");
316
317 pch_gbe_phy_sw_reset(hw);
318
319 pch_gbe_phy_read_reg_miic(hw, PHY_PHYSP_CONTROL, &mii_reg);
320 mii_reg |= PHYSP_CTRL_ASSERT_CRS_TX;
321 pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL, mii_reg);
322
323
324 if (adapter->pdata && adapter->pdata->phy_tx_clk_delay)
325 pch_gbe_phy_tx_clk_delay(hw);
326 }
327
328
329
330
331
332
333
334
335 int pch_gbe_phy_disable_hibernate(struct pch_gbe_hw *hw)
336 {
337 struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
338 u16 mii_reg;
339 int ret = 0;
340
341 switch (hw->phy.id) {
342 case PHY_AR803X_ID:
343 netdev_dbg(adapter->netdev,
344 "Disabling hibernation for AR803X PHY\n");
345 ret = pch_gbe_phy_write_reg_miic(hw, PHY_AR8031_DBG_OFF,
346 PHY_AR8031_HIBERNATE);
347 if (ret)
348 break;
349
350 pch_gbe_phy_read_reg_miic(hw, PHY_AR8031_DBG_DAT, &mii_reg);
351 mii_reg &= ~PHY_AR8031_PS_HIB_EN;
352 ret = pch_gbe_phy_write_reg_miic(hw, PHY_AR8031_DBG_DAT,
353 mii_reg);
354 break;
355 default:
356 netdev_err(adapter->netdev,
357 "Unknown PHY (%x), could not disable hibernation\n",
358 hw->phy.id);
359 return -EINVAL;
360 }
361
362 if (ret)
363 netdev_err(adapter->netdev,
364 "Could not disable PHY hibernation\n");
365 return ret;
366 }