1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Clause 45 PHY support |
4 | */ |
5 | #include <linux/ethtool.h> |
6 | #include <linux/export.h> |
7 | #include <linux/mdio.h> |
8 | #include <linux/mii.h> |
9 | #include <linux/phy.h> |
10 | |
11 | #include "mdio-open-alliance.h" |
12 | |
13 | /** |
14 | * genphy_c45_baset1_able - checks if the PMA has BASE-T1 extended abilities |
15 | * @phydev: target phy_device struct |
16 | */ |
17 | static bool genphy_c45_baset1_able(struct phy_device *phydev) |
18 | { |
19 | int val; |
20 | |
21 | if (phydev->pma_extable == -ENODATA) { |
22 | val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_EXTABLE); |
23 | if (val < 0) |
24 | return false; |
25 | |
26 | phydev->pma_extable = val; |
27 | } |
28 | |
29 | return !!(phydev->pma_extable & MDIO_PMA_EXTABLE_BT1); |
30 | } |
31 | |
32 | /** |
33 | * genphy_c45_pma_can_sleep - checks if the PMA have sleep support |
34 | * @phydev: target phy_device struct |
35 | */ |
36 | static bool genphy_c45_pma_can_sleep(struct phy_device *phydev) |
37 | { |
38 | int stat1; |
39 | |
40 | stat1 = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_STAT1); |
41 | if (stat1 < 0) |
42 | return false; |
43 | |
44 | return !!(stat1 & MDIO_STAT1_LPOWERABLE); |
45 | } |
46 | |
47 | /** |
48 | * genphy_c45_pma_resume - wakes up the PMA module |
49 | * @phydev: target phy_device struct |
50 | */ |
51 | int genphy_c45_pma_resume(struct phy_device *phydev) |
52 | { |
53 | if (!genphy_c45_pma_can_sleep(phydev)) |
54 | return -EOPNOTSUPP; |
55 | |
56 | return phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1, |
57 | MDIO_CTRL1_LPOWER); |
58 | } |
59 | EXPORT_SYMBOL_GPL(genphy_c45_pma_resume); |
60 | |
61 | /** |
62 | * genphy_c45_pma_suspend - suspends the PMA module |
63 | * @phydev: target phy_device struct |
64 | */ |
65 | int genphy_c45_pma_suspend(struct phy_device *phydev) |
66 | { |
67 | if (!genphy_c45_pma_can_sleep(phydev)) |
68 | return -EOPNOTSUPP; |
69 | |
70 | return phy_set_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1, |
71 | MDIO_CTRL1_LPOWER); |
72 | } |
73 | EXPORT_SYMBOL_GPL(genphy_c45_pma_suspend); |
74 | |
75 | /** |
76 | * genphy_c45_pma_baset1_setup_master_slave - configures forced master/slave |
77 | * role of BaseT1 devices. |
78 | * @phydev: target phy_device struct |
79 | */ |
80 | int genphy_c45_pma_baset1_setup_master_slave(struct phy_device *phydev) |
81 | { |
82 | int ctl = 0; |
83 | |
84 | switch (phydev->master_slave_set) { |
85 | case MASTER_SLAVE_CFG_MASTER_PREFERRED: |
86 | case MASTER_SLAVE_CFG_MASTER_FORCE: |
87 | ctl = MDIO_PMA_PMD_BT1_CTRL_CFG_MST; |
88 | break; |
89 | case MASTER_SLAVE_CFG_SLAVE_FORCE: |
90 | case MASTER_SLAVE_CFG_SLAVE_PREFERRED: |
91 | break; |
92 | case MASTER_SLAVE_CFG_UNKNOWN: |
93 | case MASTER_SLAVE_CFG_UNSUPPORTED: |
94 | return 0; |
95 | default: |
96 | phydev_warn(phydev, "Unsupported Master/Slave mode\n" ); |
97 | return -EOPNOTSUPP; |
98 | } |
99 | |
100 | return phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_PMD_BT1_CTRL, |
101 | MDIO_PMA_PMD_BT1_CTRL_CFG_MST, set: ctl); |
102 | } |
103 | EXPORT_SYMBOL_GPL(genphy_c45_pma_baset1_setup_master_slave); |
104 | |
105 | /** |
106 | * genphy_c45_pma_setup_forced - configures a forced speed |
107 | * @phydev: target phy_device struct |
108 | */ |
109 | int genphy_c45_pma_setup_forced(struct phy_device *phydev) |
110 | { |
111 | int bt1_ctrl, ctrl1, ctrl2, ret; |
112 | |
113 | /* Half duplex is not supported */ |
114 | if (phydev->duplex != DUPLEX_FULL) |
115 | return -EINVAL; |
116 | |
117 | ctrl1 = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1); |
118 | if (ctrl1 < 0) |
119 | return ctrl1; |
120 | |
121 | ctrl2 = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL2); |
122 | if (ctrl2 < 0) |
123 | return ctrl2; |
124 | |
125 | ctrl1 &= ~MDIO_CTRL1_SPEEDSEL; |
126 | /* |
127 | * PMA/PMD type selection is 1.7.5:0 not 1.7.3:0. See 45.2.1.6.1 |
128 | * in 802.3-2012 and 802.3-2015. |
129 | */ |
130 | ctrl2 &= ~(MDIO_PMA_CTRL2_TYPE | 0x30); |
131 | |
132 | switch (phydev->speed) { |
133 | case SPEED_10: |
134 | if (genphy_c45_baset1_able(phydev)) |
135 | ctrl2 |= MDIO_PMA_CTRL2_BASET1; |
136 | else |
137 | ctrl2 |= MDIO_PMA_CTRL2_10BT; |
138 | break; |
139 | case SPEED_100: |
140 | ctrl1 |= MDIO_PMA_CTRL1_SPEED100; |
141 | ctrl2 |= MDIO_PMA_CTRL2_100BTX; |
142 | break; |
143 | case SPEED_1000: |
144 | ctrl1 |= MDIO_PMA_CTRL1_SPEED1000; |
145 | /* Assume 1000base-T */ |
146 | ctrl2 |= MDIO_PMA_CTRL2_1000BT; |
147 | break; |
148 | case SPEED_2500: |
149 | ctrl1 |= MDIO_CTRL1_SPEED2_5G; |
150 | /* Assume 2.5Gbase-T */ |
151 | ctrl2 |= MDIO_PMA_CTRL2_2_5GBT; |
152 | break; |
153 | case SPEED_5000: |
154 | ctrl1 |= MDIO_CTRL1_SPEED5G; |
155 | /* Assume 5Gbase-T */ |
156 | ctrl2 |= MDIO_PMA_CTRL2_5GBT; |
157 | break; |
158 | case SPEED_10000: |
159 | ctrl1 |= MDIO_CTRL1_SPEED10G; |
160 | /* Assume 10Gbase-T */ |
161 | ctrl2 |= MDIO_PMA_CTRL2_10GBT; |
162 | break; |
163 | default: |
164 | return -EINVAL; |
165 | } |
166 | |
167 | ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1, val: ctrl1); |
168 | if (ret < 0) |
169 | return ret; |
170 | |
171 | ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL2, val: ctrl2); |
172 | if (ret < 0) |
173 | return ret; |
174 | |
175 | if (genphy_c45_baset1_able(phydev)) { |
176 | ret = genphy_c45_pma_baset1_setup_master_slave(phydev); |
177 | if (ret < 0) |
178 | return ret; |
179 | |
180 | bt1_ctrl = 0; |
181 | if (phydev->speed == SPEED_1000) |
182 | bt1_ctrl = MDIO_PMA_PMD_BT1_CTRL_STRAP_B1000; |
183 | |
184 | ret = phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_PMD_BT1_CTRL, |
185 | MDIO_PMA_PMD_BT1_CTRL_STRAP, set: bt1_ctrl); |
186 | if (ret < 0) |
187 | return ret; |
188 | } |
189 | |
190 | return genphy_c45_an_disable_aneg(phydev); |
191 | } |
192 | EXPORT_SYMBOL_GPL(genphy_c45_pma_setup_forced); |
193 | |
194 | /* Sets master/slave preference and supported technologies. |
195 | * The preference is set in the BIT(4) of BASE-T1 AN |
196 | * advertisement register 7.515 and whether the status |
197 | * is forced or not, it is set in the BIT(12) of BASE-T1 |
198 | * AN advertisement register 7.514. |
199 | * Sets 10BASE-T1L Ability BIT(14) in BASE-T1 autonegotiation |
200 | * advertisement register [31:16] if supported. |
201 | */ |
202 | static int genphy_c45_baset1_an_config_aneg(struct phy_device *phydev) |
203 | { |
204 | u16 adv_l_mask, adv_l = 0; |
205 | u16 adv_m_mask, adv_m = 0; |
206 | int changed = 0; |
207 | int ret; |
208 | |
209 | adv_l_mask = MDIO_AN_T1_ADV_L_FORCE_MS | MDIO_AN_T1_ADV_L_PAUSE_CAP | |
210 | MDIO_AN_T1_ADV_L_PAUSE_ASYM; |
211 | adv_m_mask = MDIO_AN_T1_ADV_M_MST | MDIO_AN_T1_ADV_M_B10L; |
212 | |
213 | switch (phydev->master_slave_set) { |
214 | case MASTER_SLAVE_CFG_MASTER_FORCE: |
215 | adv_m |= MDIO_AN_T1_ADV_M_MST; |
216 | fallthrough; |
217 | case MASTER_SLAVE_CFG_SLAVE_FORCE: |
218 | adv_l |= MDIO_AN_T1_ADV_L_FORCE_MS; |
219 | break; |
220 | case MASTER_SLAVE_CFG_MASTER_PREFERRED: |
221 | adv_m |= MDIO_AN_T1_ADV_M_MST; |
222 | fallthrough; |
223 | case MASTER_SLAVE_CFG_SLAVE_PREFERRED: |
224 | break; |
225 | case MASTER_SLAVE_CFG_UNKNOWN: |
226 | case MASTER_SLAVE_CFG_UNSUPPORTED: |
227 | /* if master/slave role is not specified, do not overwrite it */ |
228 | adv_l_mask &= ~MDIO_AN_T1_ADV_L_FORCE_MS; |
229 | adv_m_mask &= ~MDIO_AN_T1_ADV_M_MST; |
230 | break; |
231 | default: |
232 | phydev_warn(phydev, "Unsupported Master/Slave mode\n" ); |
233 | return -EOPNOTSUPP; |
234 | } |
235 | |
236 | adv_l |= linkmode_adv_to_mii_t1_adv_l_t(advertising: phydev->advertising); |
237 | |
238 | ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_T1_ADV_L, |
239 | mask: adv_l_mask, set: adv_l); |
240 | if (ret < 0) |
241 | return ret; |
242 | if (ret > 0) |
243 | changed = 1; |
244 | |
245 | adv_m |= linkmode_adv_to_mii_t1_adv_m_t(advertising: phydev->advertising); |
246 | |
247 | ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_T1_ADV_M, |
248 | mask: adv_m_mask, set: adv_m); |
249 | if (ret < 0) |
250 | return ret; |
251 | if (ret > 0) |
252 | changed = 1; |
253 | |
254 | return changed; |
255 | } |
256 | |
257 | /** |
258 | * genphy_c45_an_config_aneg - configure advertisement registers |
259 | * @phydev: target phy_device struct |
260 | * |
261 | * Configure advertisement registers based on modes set in phydev->advertising |
262 | * |
263 | * Returns negative errno code on failure, 0 if advertisement didn't change, |
264 | * or 1 if advertised modes changed. |
265 | */ |
266 | int genphy_c45_an_config_aneg(struct phy_device *phydev) |
267 | { |
268 | int changed = 0, ret; |
269 | u32 adv; |
270 | |
271 | linkmode_and(dst: phydev->advertising, a: phydev->advertising, |
272 | b: phydev->supported); |
273 | |
274 | ret = genphy_c45_an_config_eee_aneg(phydev); |
275 | if (ret < 0) |
276 | return ret; |
277 | else if (ret) |
278 | changed = true; |
279 | |
280 | if (genphy_c45_baset1_able(phydev)) |
281 | return genphy_c45_baset1_an_config_aneg(phydev); |
282 | |
283 | adv = linkmode_adv_to_mii_adv_t(advertising: phydev->advertising); |
284 | |
285 | ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE, |
286 | ADVERTISE_ALL | ADVERTISE_100BASE4 | |
287 | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM, |
288 | set: adv); |
289 | if (ret < 0) |
290 | return ret; |
291 | if (ret > 0) |
292 | changed = 1; |
293 | |
294 | adv = linkmode_adv_to_mii_10gbt_adv_t(advertising: phydev->advertising); |
295 | |
296 | ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, |
297 | MDIO_AN_10GBT_CTRL_ADV10G | |
298 | MDIO_AN_10GBT_CTRL_ADV5G | |
299 | MDIO_AN_10GBT_CTRL_ADV2_5G, set: adv); |
300 | if (ret < 0) |
301 | return ret; |
302 | if (ret > 0) |
303 | changed = 1; |
304 | |
305 | return changed; |
306 | } |
307 | EXPORT_SYMBOL_GPL(genphy_c45_an_config_aneg); |
308 | |
309 | /** |
310 | * genphy_c45_an_disable_aneg - disable auto-negotiation |
311 | * @phydev: target phy_device struct |
312 | * |
313 | * Disable auto-negotiation in the Clause 45 PHY. The link parameters |
314 | * are controlled through the PMA/PMD MMD registers. |
315 | * |
316 | * Returns zero on success, negative errno code on failure. |
317 | */ |
318 | int genphy_c45_an_disable_aneg(struct phy_device *phydev) |
319 | { |
320 | u16 reg = MDIO_CTRL1; |
321 | |
322 | if (genphy_c45_baset1_able(phydev)) |
323 | reg = MDIO_AN_T1_CTRL; |
324 | |
325 | return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, regnum: reg, |
326 | MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART); |
327 | } |
328 | EXPORT_SYMBOL_GPL(genphy_c45_an_disable_aneg); |
329 | |
330 | /** |
331 | * genphy_c45_restart_aneg - Enable and restart auto-negotiation |
332 | * @phydev: target phy_device struct |
333 | * |
334 | * This assumes that the auto-negotiation MMD is present. |
335 | * |
336 | * Enable and restart auto-negotiation. |
337 | */ |
338 | int genphy_c45_restart_aneg(struct phy_device *phydev) |
339 | { |
340 | u16 reg = MDIO_CTRL1; |
341 | |
342 | if (genphy_c45_baset1_able(phydev)) |
343 | reg = MDIO_AN_T1_CTRL; |
344 | |
345 | return phy_set_bits_mmd(phydev, MDIO_MMD_AN, regnum: reg, |
346 | MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART); |
347 | } |
348 | EXPORT_SYMBOL_GPL(genphy_c45_restart_aneg); |
349 | |
350 | /** |
351 | * genphy_c45_check_and_restart_aneg - Enable and restart auto-negotiation |
352 | * @phydev: target phy_device struct |
353 | * @restart: whether aneg restart is requested |
354 | * |
355 | * This assumes that the auto-negotiation MMD is present. |
356 | * |
357 | * Check, and restart auto-negotiation if needed. |
358 | */ |
359 | int genphy_c45_check_and_restart_aneg(struct phy_device *phydev, bool restart) |
360 | { |
361 | u16 reg = MDIO_CTRL1; |
362 | int ret; |
363 | |
364 | if (genphy_c45_baset1_able(phydev)) |
365 | reg = MDIO_AN_T1_CTRL; |
366 | |
367 | if (!restart) { |
368 | /* Configure and restart aneg if it wasn't set before */ |
369 | ret = phy_read_mmd(phydev, MDIO_MMD_AN, regnum: reg); |
370 | if (ret < 0) |
371 | return ret; |
372 | |
373 | if (!(ret & MDIO_AN_CTRL1_ENABLE)) |
374 | restart = true; |
375 | } |
376 | |
377 | if (restart) |
378 | return genphy_c45_restart_aneg(phydev); |
379 | |
380 | return 0; |
381 | } |
382 | EXPORT_SYMBOL_GPL(genphy_c45_check_and_restart_aneg); |
383 | |
384 | /** |
385 | * genphy_c45_aneg_done - return auto-negotiation complete status |
386 | * @phydev: target phy_device struct |
387 | * |
388 | * This assumes that the auto-negotiation MMD is present. |
389 | * |
390 | * Reads the status register from the auto-negotiation MMD, returning: |
391 | * - positive if auto-negotiation is complete |
392 | * - negative errno code on error |
393 | * - zero otherwise |
394 | */ |
395 | int genphy_c45_aneg_done(struct phy_device *phydev) |
396 | { |
397 | int reg = MDIO_STAT1; |
398 | int val; |
399 | |
400 | if (genphy_c45_baset1_able(phydev)) |
401 | reg = MDIO_AN_T1_STAT; |
402 | |
403 | val = phy_read_mmd(phydev, MDIO_MMD_AN, regnum: reg); |
404 | |
405 | return val < 0 ? val : val & MDIO_AN_STAT1_COMPLETE ? 1 : 0; |
406 | } |
407 | EXPORT_SYMBOL_GPL(genphy_c45_aneg_done); |
408 | |
409 | /** |
410 | * genphy_c45_read_link - read the overall link status from the MMDs |
411 | * @phydev: target phy_device struct |
412 | * |
413 | * Read the link status from the specified MMDs, and if they all indicate |
414 | * that the link is up, set phydev->link to 1. If an error is encountered, |
415 | * a negative errno will be returned, otherwise zero. |
416 | */ |
417 | int genphy_c45_read_link(struct phy_device *phydev) |
418 | { |
419 | u32 mmd_mask = MDIO_DEVS_PMAPMD; |
420 | int val, devad; |
421 | bool link = true; |
422 | |
423 | if (phydev->c45_ids.mmds_present & MDIO_DEVS_AN) { |
424 | val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1); |
425 | if (val < 0) |
426 | return val; |
427 | |
428 | /* Autoneg is being started, therefore disregard current |
429 | * link status and report link as down. |
430 | */ |
431 | if (val & MDIO_AN_CTRL1_RESTART) { |
432 | phydev->link = 0; |
433 | return 0; |
434 | } |
435 | } |
436 | |
437 | while (mmd_mask && link) { |
438 | devad = __ffs(mmd_mask); |
439 | mmd_mask &= ~BIT(devad); |
440 | |
441 | /* The link state is latched low so that momentary link |
442 | * drops can be detected. Do not double-read the status |
443 | * in polling mode to detect such short link drops except |
444 | * the link was already down. |
445 | */ |
446 | if (!phy_polling_mode(phydev) || !phydev->link) { |
447 | val = phy_read_mmd(phydev, devad, MDIO_STAT1); |
448 | if (val < 0) |
449 | return val; |
450 | else if (val & MDIO_STAT1_LSTATUS) |
451 | continue; |
452 | } |
453 | |
454 | val = phy_read_mmd(phydev, devad, MDIO_STAT1); |
455 | if (val < 0) |
456 | return val; |
457 | |
458 | if (!(val & MDIO_STAT1_LSTATUS)) |
459 | link = false; |
460 | } |
461 | |
462 | phydev->link = link; |
463 | |
464 | return 0; |
465 | } |
466 | EXPORT_SYMBOL_GPL(genphy_c45_read_link); |
467 | |
468 | /* Read the Clause 45 defined BASE-T1 AN (7.513) status register to check |
469 | * if autoneg is complete. If so read the BASE-T1 Autonegotiation |
470 | * Advertisement registers filling in the link partner advertisement, |
471 | * pause and asym_pause members in phydev. |
472 | */ |
473 | static int genphy_c45_baset1_read_lpa(struct phy_device *phydev) |
474 | { |
475 | int val; |
476 | |
477 | val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_T1_STAT); |
478 | if (val < 0) |
479 | return val; |
480 | |
481 | if (!(val & MDIO_AN_STAT1_COMPLETE)) { |
482 | linkmode_clear_bit(nr: ETHTOOL_LINK_MODE_Autoneg_BIT, addr: phydev->lp_advertising); |
483 | mii_t1_adv_l_mod_linkmode_t(advertising: phydev->lp_advertising, lpa: 0); |
484 | mii_t1_adv_m_mod_linkmode_t(advertising: phydev->lp_advertising, lpa: 0); |
485 | |
486 | phydev->pause = 0; |
487 | phydev->asym_pause = 0; |
488 | |
489 | return 0; |
490 | } |
491 | |
492 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_Autoneg_BIT, addr: phydev->lp_advertising, set: 1); |
493 | |
494 | val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_T1_LP_L); |
495 | if (val < 0) |
496 | return val; |
497 | |
498 | mii_t1_adv_l_mod_linkmode_t(advertising: phydev->lp_advertising, lpa: val); |
499 | phydev->pause = val & MDIO_AN_T1_ADV_L_PAUSE_CAP ? 1 : 0; |
500 | phydev->asym_pause = val & MDIO_AN_T1_ADV_L_PAUSE_ASYM ? 1 : 0; |
501 | |
502 | val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_T1_LP_M); |
503 | if (val < 0) |
504 | return val; |
505 | |
506 | mii_t1_adv_m_mod_linkmode_t(advertising: phydev->lp_advertising, lpa: val); |
507 | |
508 | return 0; |
509 | } |
510 | |
511 | /** |
512 | * genphy_c45_read_lpa - read the link partner advertisement and pause |
513 | * @phydev: target phy_device struct |
514 | * |
515 | * Read the Clause 45 defined base (7.19) and 10G (7.33) status registers, |
516 | * filling in the link partner advertisement, pause and asym_pause members |
517 | * in @phydev. This assumes that the auto-negotiation MMD is present, and |
518 | * the backplane bit (7.48.0) is clear. Clause 45 PHY drivers are expected |
519 | * to fill in the remainder of the link partner advert from vendor registers. |
520 | */ |
521 | int genphy_c45_read_lpa(struct phy_device *phydev) |
522 | { |
523 | int val; |
524 | |
525 | if (genphy_c45_baset1_able(phydev)) |
526 | return genphy_c45_baset1_read_lpa(phydev); |
527 | |
528 | val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1); |
529 | if (val < 0) |
530 | return val; |
531 | |
532 | if (!(val & MDIO_AN_STAT1_COMPLETE)) { |
533 | linkmode_clear_bit(nr: ETHTOOL_LINK_MODE_Autoneg_BIT, |
534 | addr: phydev->lp_advertising); |
535 | mii_10gbt_stat_mod_linkmode_lpa_t(advertising: phydev->lp_advertising, lpa: 0); |
536 | mii_adv_mod_linkmode_adv_t(advertising: phydev->lp_advertising, adv: 0); |
537 | phydev->pause = 0; |
538 | phydev->asym_pause = 0; |
539 | |
540 | return 0; |
541 | } |
542 | |
543 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_Autoneg_BIT, addr: phydev->lp_advertising, |
544 | set: val & MDIO_AN_STAT1_LPABLE); |
545 | |
546 | /* Read the link partner's base page advertisement */ |
547 | val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_LPA); |
548 | if (val < 0) |
549 | return val; |
550 | |
551 | mii_adv_mod_linkmode_adv_t(advertising: phydev->lp_advertising, adv: val); |
552 | phydev->pause = val & LPA_PAUSE_CAP ? 1 : 0; |
553 | phydev->asym_pause = val & LPA_PAUSE_ASYM ? 1 : 0; |
554 | |
555 | /* Read the link partner's 10G advertisement */ |
556 | val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); |
557 | if (val < 0) |
558 | return val; |
559 | |
560 | mii_10gbt_stat_mod_linkmode_lpa_t(advertising: phydev->lp_advertising, lpa: val); |
561 | |
562 | return 0; |
563 | } |
564 | EXPORT_SYMBOL_GPL(genphy_c45_read_lpa); |
565 | |
566 | /** |
567 | * genphy_c45_pma_baset1_read_master_slave - read forced master/slave |
568 | * configuration |
569 | * @phydev: target phy_device struct |
570 | */ |
571 | int genphy_c45_pma_baset1_read_master_slave(struct phy_device *phydev) |
572 | { |
573 | int val; |
574 | |
575 | phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN; |
576 | phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN; |
577 | |
578 | val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_PMD_BT1_CTRL); |
579 | if (val < 0) |
580 | return val; |
581 | |
582 | if (val & MDIO_PMA_PMD_BT1_CTRL_CFG_MST) { |
583 | phydev->master_slave_get = MASTER_SLAVE_CFG_MASTER_FORCE; |
584 | phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER; |
585 | } else { |
586 | phydev->master_slave_get = MASTER_SLAVE_CFG_SLAVE_FORCE; |
587 | phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE; |
588 | } |
589 | |
590 | return 0; |
591 | } |
592 | EXPORT_SYMBOL_GPL(genphy_c45_pma_baset1_read_master_slave); |
593 | |
594 | /** |
595 | * genphy_c45_read_pma - read link speed etc from PMA |
596 | * @phydev: target phy_device struct |
597 | */ |
598 | int genphy_c45_read_pma(struct phy_device *phydev) |
599 | { |
600 | int val; |
601 | |
602 | linkmode_zero(dst: phydev->lp_advertising); |
603 | |
604 | val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1); |
605 | if (val < 0) |
606 | return val; |
607 | |
608 | switch (val & MDIO_CTRL1_SPEEDSEL) { |
609 | case 0: |
610 | phydev->speed = SPEED_10; |
611 | break; |
612 | case MDIO_PMA_CTRL1_SPEED100: |
613 | phydev->speed = SPEED_100; |
614 | break; |
615 | case MDIO_PMA_CTRL1_SPEED1000: |
616 | phydev->speed = SPEED_1000; |
617 | break; |
618 | case MDIO_CTRL1_SPEED2_5G: |
619 | phydev->speed = SPEED_2500; |
620 | break; |
621 | case MDIO_CTRL1_SPEED5G: |
622 | phydev->speed = SPEED_5000; |
623 | break; |
624 | case MDIO_CTRL1_SPEED10G: |
625 | phydev->speed = SPEED_10000; |
626 | break; |
627 | default: |
628 | phydev->speed = SPEED_UNKNOWN; |
629 | break; |
630 | } |
631 | |
632 | phydev->duplex = DUPLEX_FULL; |
633 | |
634 | if (genphy_c45_baset1_able(phydev)) { |
635 | val = genphy_c45_pma_baset1_read_master_slave(phydev); |
636 | if (val < 0) |
637 | return val; |
638 | } |
639 | |
640 | return 0; |
641 | } |
642 | EXPORT_SYMBOL_GPL(genphy_c45_read_pma); |
643 | |
644 | /** |
645 | * genphy_c45_read_mdix - read mdix status from PMA |
646 | * @phydev: target phy_device struct |
647 | */ |
648 | int genphy_c45_read_mdix(struct phy_device *phydev) |
649 | { |
650 | int val; |
651 | |
652 | if (phydev->speed == SPEED_10000) { |
653 | val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, |
654 | MDIO_PMA_10GBT_SWAPPOL); |
655 | if (val < 0) |
656 | return val; |
657 | |
658 | switch (val) { |
659 | case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX: |
660 | phydev->mdix = ETH_TP_MDI; |
661 | break; |
662 | |
663 | case 0: |
664 | phydev->mdix = ETH_TP_MDI_X; |
665 | break; |
666 | |
667 | default: |
668 | phydev->mdix = ETH_TP_MDI_INVALID; |
669 | break; |
670 | } |
671 | } |
672 | |
673 | return 0; |
674 | } |
675 | EXPORT_SYMBOL_GPL(genphy_c45_read_mdix); |
676 | |
677 | /** |
678 | * genphy_c45_write_eee_adv - write advertised EEE link modes |
679 | * @phydev: target phy_device struct |
680 | * @adv: the linkmode advertisement settings |
681 | */ |
682 | int genphy_c45_write_eee_adv(struct phy_device *phydev, unsigned long *adv) |
683 | { |
684 | int val, changed = 0; |
685 | |
686 | if (linkmode_intersects(src1: phydev->supported_eee, PHY_EEE_CAP1_FEATURES)) { |
687 | val = linkmode_to_mii_eee_cap1_t(adv); |
688 | |
689 | /* In eee_broken_modes are stored MDIO_AN_EEE_ADV specific raw |
690 | * register values. |
691 | */ |
692 | val &= ~phydev->eee_broken_modes; |
693 | |
694 | /* IEEE 802.3-2018 45.2.7.13 EEE advertisement 1 |
695 | * (Register 7.60) |
696 | */ |
697 | val = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, |
698 | MDIO_AN_EEE_ADV, |
699 | MDIO_EEE_100TX | MDIO_EEE_1000T | |
700 | MDIO_EEE_10GT | MDIO_EEE_1000KX | |
701 | MDIO_EEE_10GKX4 | MDIO_EEE_10GKR, |
702 | set: val); |
703 | if (val < 0) |
704 | return val; |
705 | if (val > 0) |
706 | changed = 1; |
707 | } |
708 | |
709 | if (linkmode_test_bit(nr: ETHTOOL_LINK_MODE_10baseT1L_Full_BIT, |
710 | addr: phydev->supported_eee)) { |
711 | val = linkmode_adv_to_mii_10base_t1_t(adv); |
712 | /* IEEE 802.3cg-2019 45.2.7.25 10BASE-T1 AN control register |
713 | * (Register 7.526) |
714 | */ |
715 | val = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, |
716 | MDIO_AN_10BT1_AN_CTRL, |
717 | MDIO_AN_10BT1_AN_CTRL_ADV_EEE_T1L, |
718 | set: val); |
719 | if (val < 0) |
720 | return val; |
721 | if (val > 0) |
722 | changed = 1; |
723 | } |
724 | |
725 | return changed; |
726 | } |
727 | |
728 | /** |
729 | * genphy_c45_read_eee_adv - read advertised EEE link modes |
730 | * @phydev: target phy_device struct |
731 | * @adv: the linkmode advertisement status |
732 | */ |
733 | int genphy_c45_read_eee_adv(struct phy_device *phydev, unsigned long *adv) |
734 | { |
735 | int val; |
736 | |
737 | if (linkmode_intersects(src1: phydev->supported_eee, PHY_EEE_CAP1_FEATURES)) { |
738 | /* IEEE 802.3-2018 45.2.7.13 EEE advertisement 1 |
739 | * (Register 7.60) |
740 | */ |
741 | val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV); |
742 | if (val < 0) |
743 | return val; |
744 | |
745 | mii_eee_cap1_mod_linkmode_t(adv, val); |
746 | } |
747 | |
748 | if (linkmode_test_bit(nr: ETHTOOL_LINK_MODE_10baseT1L_Full_BIT, |
749 | addr: phydev->supported_eee)) { |
750 | /* IEEE 802.3cg-2019 45.2.7.25 10BASE-T1 AN control register |
751 | * (Register 7.526) |
752 | */ |
753 | val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10BT1_AN_CTRL); |
754 | if (val < 0) |
755 | return val; |
756 | |
757 | mii_10base_t1_adv_mod_linkmode_t(adv, val); |
758 | } |
759 | |
760 | return 0; |
761 | } |
762 | |
763 | /** |
764 | * genphy_c45_read_eee_lpa - read advertised LP EEE link modes |
765 | * @phydev: target phy_device struct |
766 | * @lpa: the linkmode LP advertisement status |
767 | */ |
768 | static int genphy_c45_read_eee_lpa(struct phy_device *phydev, |
769 | unsigned long *lpa) |
770 | { |
771 | int val; |
772 | |
773 | if (linkmode_intersects(src1: phydev->supported_eee, PHY_EEE_CAP1_FEATURES)) { |
774 | /* IEEE 802.3-2018 45.2.7.14 EEE link partner ability 1 |
775 | * (Register 7.61) |
776 | */ |
777 | val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE); |
778 | if (val < 0) |
779 | return val; |
780 | |
781 | mii_eee_cap1_mod_linkmode_t(adv: lpa, val); |
782 | } |
783 | |
784 | if (linkmode_test_bit(nr: ETHTOOL_LINK_MODE_10baseT1L_Full_BIT, |
785 | addr: phydev->supported_eee)) { |
786 | /* IEEE 802.3cg-2019 45.2.7.26 10BASE-T1 AN status register |
787 | * (Register 7.527) |
788 | */ |
789 | val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10BT1_AN_STAT); |
790 | if (val < 0) |
791 | return val; |
792 | |
793 | mii_10base_t1_adv_mod_linkmode_t(adv: lpa, val); |
794 | } |
795 | |
796 | return 0; |
797 | } |
798 | |
799 | /** |
800 | * genphy_c45_read_eee_cap1 - read supported EEE link modes from register 3.20 |
801 | * @phydev: target phy_device struct |
802 | */ |
803 | static int genphy_c45_read_eee_cap1(struct phy_device *phydev) |
804 | { |
805 | int val; |
806 | |
807 | /* IEEE 802.3-2018 45.2.3.10 EEE control and capability 1 |
808 | * (Register 3.20) |
809 | */ |
810 | val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); |
811 | if (val < 0) |
812 | return val; |
813 | |
814 | /* The 802.3 2018 standard says the top 2 bits are reserved and should |
815 | * read as 0. Also, it seems unlikely anybody will build a PHY which |
816 | * supports 100GBASE-R deep sleep all the way down to 100BASE-TX EEE. |
817 | * If MDIO_PCS_EEE_ABLE is 0xffff assume EEE is not supported. |
818 | */ |
819 | if (val == 0xffff) |
820 | return 0; |
821 | |
822 | mii_eee_cap1_mod_linkmode_t(adv: phydev->supported_eee, val); |
823 | |
824 | /* Some buggy devices indicate EEE link modes in MDIO_PCS_EEE_ABLE |
825 | * which they don't support as indicated by BMSR, ESTATUS etc. |
826 | */ |
827 | linkmode_and(dst: phydev->supported_eee, a: phydev->supported_eee, |
828 | b: phydev->supported); |
829 | |
830 | return 0; |
831 | } |
832 | |
833 | /** |
834 | * genphy_c45_read_eee_abilities - read supported EEE link modes |
835 | * @phydev: target phy_device struct |
836 | */ |
837 | int genphy_c45_read_eee_abilities(struct phy_device *phydev) |
838 | { |
839 | int val; |
840 | |
841 | /* There is not indicator whether optional register |
842 | * "EEE control and capability 1" (3.20) is supported. Read it only |
843 | * on devices with appropriate linkmodes. |
844 | */ |
845 | if (linkmode_intersects(src1: phydev->supported, PHY_EEE_CAP1_FEATURES)) { |
846 | val = genphy_c45_read_eee_cap1(phydev); |
847 | if (val) |
848 | return val; |
849 | } |
850 | |
851 | if (linkmode_test_bit(nr: ETHTOOL_LINK_MODE_10baseT1L_Full_BIT, |
852 | addr: phydev->supported)) { |
853 | /* IEEE 802.3cg-2019 45.2.1.186b 10BASE-T1L PMA status register |
854 | * (Register 1.2295) |
855 | */ |
856 | val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10T1L_STAT); |
857 | if (val < 0) |
858 | return val; |
859 | |
860 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_10baseT1L_Full_BIT, |
861 | addr: phydev->supported_eee, |
862 | set: val & MDIO_PMA_10T1L_STAT_EEE); |
863 | } |
864 | |
865 | return 0; |
866 | } |
867 | EXPORT_SYMBOL_GPL(genphy_c45_read_eee_abilities); |
868 | |
869 | /** |
870 | * genphy_c45_an_config_eee_aneg - configure EEE advertisement |
871 | * @phydev: target phy_device struct |
872 | */ |
873 | int genphy_c45_an_config_eee_aneg(struct phy_device *phydev) |
874 | { |
875 | if (!phydev->eee_enabled) { |
876 | __ETHTOOL_DECLARE_LINK_MODE_MASK(adv) = {}; |
877 | |
878 | return genphy_c45_write_eee_adv(phydev, adv); |
879 | } |
880 | |
881 | return genphy_c45_write_eee_adv(phydev, adv: phydev->advertising_eee); |
882 | } |
883 | |
884 | /** |
885 | * genphy_c45_pma_baset1_read_abilities - read supported baset1 link modes from PMA |
886 | * @phydev: target phy_device struct |
887 | * |
888 | * Read the supported link modes from the extended BASE-T1 ability register |
889 | */ |
890 | int genphy_c45_pma_baset1_read_abilities(struct phy_device *phydev) |
891 | { |
892 | int val; |
893 | |
894 | val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_PMD_BT1); |
895 | if (val < 0) |
896 | return val; |
897 | |
898 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_10baseT1L_Full_BIT, |
899 | addr: phydev->supported, |
900 | set: val & MDIO_PMA_PMD_BT1_B10L_ABLE); |
901 | |
902 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_100baseT1_Full_BIT, |
903 | addr: phydev->supported, |
904 | set: val & MDIO_PMA_PMD_BT1_B100_ABLE); |
905 | |
906 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_1000baseT1_Full_BIT, |
907 | addr: phydev->supported, |
908 | set: val & MDIO_PMA_PMD_BT1_B1000_ABLE); |
909 | |
910 | val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_T1_STAT); |
911 | if (val < 0) |
912 | return val; |
913 | |
914 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_Autoneg_BIT, |
915 | addr: phydev->supported, |
916 | set: val & MDIO_AN_STAT1_ABLE); |
917 | |
918 | return 0; |
919 | } |
920 | EXPORT_SYMBOL_GPL(genphy_c45_pma_baset1_read_abilities); |
921 | |
922 | /** |
923 | * genphy_c45_pma_read_abilities - read supported link modes from PMA |
924 | * @phydev: target phy_device struct |
925 | * |
926 | * Read the supported link modes from the PMA Status 2 (1.8) register. If bit |
927 | * 1.8.9 is set, the list of supported modes is build using the values in the |
928 | * PMA Extended Abilities (1.11) register, indicating 1000BASET an 10G related |
929 | * modes. If bit 1.11.14 is set, then the list is also extended with the modes |
930 | * in the 2.5G/5G PMA Extended register (1.21), indicating if 2.5GBASET and |
931 | * 5GBASET are supported. |
932 | */ |
933 | int genphy_c45_pma_read_abilities(struct phy_device *phydev) |
934 | { |
935 | int val; |
936 | |
937 | linkmode_clear_bit(nr: ETHTOOL_LINK_MODE_Autoneg_BIT, addr: phydev->supported); |
938 | if (phydev->c45_ids.mmds_present & MDIO_DEVS_AN) { |
939 | val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1); |
940 | if (val < 0) |
941 | return val; |
942 | |
943 | if (val & MDIO_AN_STAT1_ABLE) |
944 | linkmode_set_bit(nr: ETHTOOL_LINK_MODE_Autoneg_BIT, |
945 | addr: phydev->supported); |
946 | } |
947 | |
948 | val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_STAT2); |
949 | if (val < 0) |
950 | return val; |
951 | |
952 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, |
953 | addr: phydev->supported, |
954 | set: val & MDIO_PMA_STAT2_10GBSR); |
955 | |
956 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, |
957 | addr: phydev->supported, |
958 | set: val & MDIO_PMA_STAT2_10GBLR); |
959 | |
960 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_10000baseER_Full_BIT, |
961 | addr: phydev->supported, |
962 | set: val & MDIO_PMA_STAT2_10GBER); |
963 | |
964 | if (val & MDIO_PMA_STAT2_EXTABLE) { |
965 | val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_EXTABLE); |
966 | if (val < 0) |
967 | return val; |
968 | |
969 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT, |
970 | addr: phydev->supported, |
971 | set: val & MDIO_PMA_EXTABLE_10GBLRM); |
972 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_10000baseT_Full_BIT, |
973 | addr: phydev->supported, |
974 | set: val & MDIO_PMA_EXTABLE_10GBT); |
975 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, |
976 | addr: phydev->supported, |
977 | set: val & MDIO_PMA_EXTABLE_10GBKX4); |
978 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, |
979 | addr: phydev->supported, |
980 | set: val & MDIO_PMA_EXTABLE_10GBKR); |
981 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_1000baseT_Full_BIT, |
982 | addr: phydev->supported, |
983 | set: val & MDIO_PMA_EXTABLE_1000BT); |
984 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, |
985 | addr: phydev->supported, |
986 | set: val & MDIO_PMA_EXTABLE_1000BKX); |
987 | |
988 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_100baseT_Full_BIT, |
989 | addr: phydev->supported, |
990 | set: val & MDIO_PMA_EXTABLE_100BTX); |
991 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_100baseT_Half_BIT, |
992 | addr: phydev->supported, |
993 | set: val & MDIO_PMA_EXTABLE_100BTX); |
994 | |
995 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_10baseT_Full_BIT, |
996 | addr: phydev->supported, |
997 | set: val & MDIO_PMA_EXTABLE_10BT); |
998 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_10baseT_Half_BIT, |
999 | addr: phydev->supported, |
1000 | set: val & MDIO_PMA_EXTABLE_10BT); |
1001 | |
1002 | if (val & MDIO_PMA_EXTABLE_NBT) { |
1003 | val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, |
1004 | MDIO_PMA_NG_EXTABLE); |
1005 | if (val < 0) |
1006 | return val; |
1007 | |
1008 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_2500baseT_Full_BIT, |
1009 | addr: phydev->supported, |
1010 | set: val & MDIO_PMA_NG_EXTABLE_2_5GBT); |
1011 | |
1012 | linkmode_mod_bit(nr: ETHTOOL_LINK_MODE_5000baseT_Full_BIT, |
1013 | addr: phydev->supported, |
1014 | set: val & MDIO_PMA_NG_EXTABLE_5GBT); |
1015 | } |
1016 | |
1017 | if (val & MDIO_PMA_EXTABLE_BT1) { |
1018 | val = genphy_c45_pma_baset1_read_abilities(phydev); |
1019 | if (val < 0) |
1020 | return val; |
1021 | } |
1022 | } |
1023 | |
1024 | /* This is optional functionality. If not supported, we may get an error |
1025 | * which should be ignored. |
1026 | */ |
1027 | genphy_c45_read_eee_abilities(phydev); |
1028 | |
1029 | return 0; |
1030 | } |
1031 | EXPORT_SYMBOL_GPL(genphy_c45_pma_read_abilities); |
1032 | |
1033 | /* Read master/slave preference from registers. |
1034 | * The preference is read from the BIT(4) of BASE-T1 AN |
1035 | * advertisement register 7.515 and whether the preference |
1036 | * is forced or not, it is read from BASE-T1 AN advertisement |
1037 | * register 7.514. |
1038 | */ |
1039 | int genphy_c45_baset1_read_status(struct phy_device *phydev) |
1040 | { |
1041 | int ret; |
1042 | int cfg; |
1043 | |
1044 | phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN; |
1045 | phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN; |
1046 | |
1047 | ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_T1_ADV_L); |
1048 | if (ret < 0) |
1049 | return ret; |
1050 | |
1051 | cfg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_T1_ADV_M); |
1052 | if (cfg < 0) |
1053 | return cfg; |
1054 | |
1055 | if (ret & MDIO_AN_T1_ADV_L_FORCE_MS) { |
1056 | if (cfg & MDIO_AN_T1_ADV_M_MST) |
1057 | phydev->master_slave_get = MASTER_SLAVE_CFG_MASTER_FORCE; |
1058 | else |
1059 | phydev->master_slave_get = MASTER_SLAVE_CFG_SLAVE_FORCE; |
1060 | } else { |
1061 | if (cfg & MDIO_AN_T1_ADV_M_MST) |
1062 | phydev->master_slave_get = MASTER_SLAVE_CFG_MASTER_PREFERRED; |
1063 | else |
1064 | phydev->master_slave_get = MASTER_SLAVE_CFG_SLAVE_PREFERRED; |
1065 | } |
1066 | |
1067 | return 0; |
1068 | } |
1069 | EXPORT_SYMBOL_GPL(genphy_c45_baset1_read_status); |
1070 | |
1071 | /** |
1072 | * genphy_c45_read_status - read PHY status |
1073 | * @phydev: target phy_device struct |
1074 | * |
1075 | * Reads status from PHY and sets phy_device members accordingly. |
1076 | */ |
1077 | int genphy_c45_read_status(struct phy_device *phydev) |
1078 | { |
1079 | int ret; |
1080 | |
1081 | ret = genphy_c45_read_link(phydev); |
1082 | if (ret) |
1083 | return ret; |
1084 | |
1085 | phydev->speed = SPEED_UNKNOWN; |
1086 | phydev->duplex = DUPLEX_UNKNOWN; |
1087 | phydev->pause = 0; |
1088 | phydev->asym_pause = 0; |
1089 | |
1090 | if (phydev->autoneg == AUTONEG_ENABLE) { |
1091 | ret = genphy_c45_read_lpa(phydev); |
1092 | if (ret) |
1093 | return ret; |
1094 | |
1095 | if (genphy_c45_baset1_able(phydev)) { |
1096 | ret = genphy_c45_baset1_read_status(phydev); |
1097 | if (ret < 0) |
1098 | return ret; |
1099 | } |
1100 | |
1101 | phy_resolve_aneg_linkmode(phydev); |
1102 | } else { |
1103 | ret = genphy_c45_read_pma(phydev); |
1104 | } |
1105 | |
1106 | return ret; |
1107 | } |
1108 | EXPORT_SYMBOL_GPL(genphy_c45_read_status); |
1109 | |
1110 | /** |
1111 | * genphy_c45_config_aneg - restart auto-negotiation or forced setup |
1112 | * @phydev: target phy_device struct |
1113 | * |
1114 | * Description: If auto-negotiation is enabled, we configure the |
1115 | * advertising, and then restart auto-negotiation. If it is not |
1116 | * enabled, then we force a configuration. |
1117 | */ |
1118 | int genphy_c45_config_aneg(struct phy_device *phydev) |
1119 | { |
1120 | bool changed = false; |
1121 | int ret; |
1122 | |
1123 | if (phydev->autoneg == AUTONEG_DISABLE) |
1124 | return genphy_c45_pma_setup_forced(phydev); |
1125 | |
1126 | ret = genphy_c45_an_config_aneg(phydev); |
1127 | if (ret < 0) |
1128 | return ret; |
1129 | if (ret > 0) |
1130 | changed = true; |
1131 | |
1132 | return genphy_c45_check_and_restart_aneg(phydev, changed); |
1133 | } |
1134 | EXPORT_SYMBOL_GPL(genphy_c45_config_aneg); |
1135 | |
1136 | /* The gen10g_* functions are the old Clause 45 stub */ |
1137 | |
1138 | int gen10g_config_aneg(struct phy_device *phydev) |
1139 | { |
1140 | return 0; |
1141 | } |
1142 | EXPORT_SYMBOL_GPL(gen10g_config_aneg); |
1143 | |
1144 | int genphy_c45_loopback(struct phy_device *phydev, bool enable) |
1145 | { |
1146 | return phy_modify_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, |
1147 | MDIO_PCS_CTRL1_LOOPBACK, |
1148 | set: enable ? MDIO_PCS_CTRL1_LOOPBACK : 0); |
1149 | } |
1150 | EXPORT_SYMBOL_GPL(genphy_c45_loopback); |
1151 | |
1152 | /** |
1153 | * genphy_c45_fast_retrain - configure fast retrain registers |
1154 | * @phydev: target phy_device struct |
1155 | * @enable: enable fast retrain or not |
1156 | * |
1157 | * Description: If fast-retrain is enabled, we configure PHY as |
1158 | * advertising fast retrain capable and THP Bypass Request, then |
1159 | * enable fast retrain. If it is not enabled, we configure fast |
1160 | * retrain disabled. |
1161 | */ |
1162 | int genphy_c45_fast_retrain(struct phy_device *phydev, bool enable) |
1163 | { |
1164 | int ret; |
1165 | |
1166 | if (!enable) |
1167 | return phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FSRT_CSR, |
1168 | MDIO_PMA_10GBR_FSRT_ENABLE); |
1169 | |
1170 | if (linkmode_test_bit(nr: ETHTOOL_LINK_MODE_2500baseT_Full_BIT, addr: phydev->supported)) { |
1171 | ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, |
1172 | MDIO_AN_10GBT_CTRL_ADVFSRT2_5G); |
1173 | if (ret) |
1174 | return ret; |
1175 | |
1176 | ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN, MDIO_AN_CTRL2, |
1177 | MDIO_AN_THP_BP2_5GT); |
1178 | if (ret) |
1179 | return ret; |
1180 | } |
1181 | |
1182 | return phy_set_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FSRT_CSR, |
1183 | MDIO_PMA_10GBR_FSRT_ENABLE); |
1184 | } |
1185 | EXPORT_SYMBOL_GPL(genphy_c45_fast_retrain); |
1186 | |
1187 | /** |
1188 | * genphy_c45_plca_get_cfg - get PLCA configuration from standard registers |
1189 | * @phydev: target phy_device struct |
1190 | * @plca_cfg: output structure to store the PLCA configuration |
1191 | * |
1192 | * Description: if the PHY complies to the Open Alliance TC14 10BASE-T1S PLCA |
1193 | * Management Registers specifications, this function can be used to retrieve |
1194 | * the current PLCA configuration from the standard registers in MMD 31. |
1195 | */ |
1196 | int genphy_c45_plca_get_cfg(struct phy_device *phydev, |
1197 | struct phy_plca_cfg *plca_cfg) |
1198 | { |
1199 | int ret; |
1200 | |
1201 | ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, MDIO_OATC14_PLCA_IDVER); |
1202 | if (ret < 0) |
1203 | return ret; |
1204 | |
1205 | if ((ret & MDIO_OATC14_PLCA_IDM) != OATC14_IDM) |
1206 | return -ENODEV; |
1207 | |
1208 | plca_cfg->version = ret & ~MDIO_OATC14_PLCA_IDM; |
1209 | |
1210 | ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, MDIO_OATC14_PLCA_CTRL0); |
1211 | if (ret < 0) |
1212 | return ret; |
1213 | |
1214 | plca_cfg->enabled = !!(ret & MDIO_OATC14_PLCA_EN); |
1215 | |
1216 | ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, MDIO_OATC14_PLCA_CTRL1); |
1217 | if (ret < 0) |
1218 | return ret; |
1219 | |
1220 | plca_cfg->node_cnt = (ret & MDIO_OATC14_PLCA_NCNT) >> 8; |
1221 | plca_cfg->node_id = (ret & MDIO_OATC14_PLCA_ID); |
1222 | |
1223 | ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, MDIO_OATC14_PLCA_TOTMR); |
1224 | if (ret < 0) |
1225 | return ret; |
1226 | |
1227 | plca_cfg->to_tmr = ret & MDIO_OATC14_PLCA_TOT; |
1228 | |
1229 | ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, MDIO_OATC14_PLCA_BURST); |
1230 | if (ret < 0) |
1231 | return ret; |
1232 | |
1233 | plca_cfg->burst_cnt = (ret & MDIO_OATC14_PLCA_MAXBC) >> 8; |
1234 | plca_cfg->burst_tmr = (ret & MDIO_OATC14_PLCA_BTMR); |
1235 | |
1236 | return 0; |
1237 | } |
1238 | EXPORT_SYMBOL_GPL(genphy_c45_plca_get_cfg); |
1239 | |
1240 | /** |
1241 | * genphy_c45_plca_set_cfg - set PLCA configuration using standard registers |
1242 | * @phydev: target phy_device struct |
1243 | * @plca_cfg: structure containing the PLCA configuration. Fields set to -1 are |
1244 | * not to be changed. |
1245 | * |
1246 | * Description: if the PHY complies to the Open Alliance TC14 10BASE-T1S PLCA |
1247 | * Management Registers specifications, this function can be used to modify |
1248 | * the PLCA configuration using the standard registers in MMD 31. |
1249 | */ |
1250 | int genphy_c45_plca_set_cfg(struct phy_device *phydev, |
1251 | const struct phy_plca_cfg *plca_cfg) |
1252 | { |
1253 | u16 val = 0; |
1254 | int ret; |
1255 | |
1256 | // PLCA IDVER is read-only |
1257 | if (plca_cfg->version >= 0) |
1258 | return -EINVAL; |
1259 | |
1260 | // first of all, disable PLCA if required |
1261 | if (plca_cfg->enabled == 0) { |
1262 | ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, |
1263 | MDIO_OATC14_PLCA_CTRL0, |
1264 | MDIO_OATC14_PLCA_EN); |
1265 | |
1266 | if (ret < 0) |
1267 | return ret; |
1268 | } |
1269 | |
1270 | // check if we need to set the PLCA node count, node ID, or both |
1271 | if (plca_cfg->node_cnt >= 0 || plca_cfg->node_id >= 0) { |
1272 | /* if one between node count and node ID is -not- to be |
1273 | * changed, read the register to later perform merge/purge of |
1274 | * the configuration as appropriate |
1275 | */ |
1276 | if (plca_cfg->node_cnt < 0 || plca_cfg->node_id < 0) { |
1277 | ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, |
1278 | MDIO_OATC14_PLCA_CTRL1); |
1279 | |
1280 | if (ret < 0) |
1281 | return ret; |
1282 | |
1283 | val = ret; |
1284 | } |
1285 | |
1286 | if (plca_cfg->node_cnt >= 0) |
1287 | val = (val & ~MDIO_OATC14_PLCA_NCNT) | |
1288 | (plca_cfg->node_cnt << 8); |
1289 | |
1290 | if (plca_cfg->node_id >= 0) |
1291 | val = (val & ~MDIO_OATC14_PLCA_ID) | |
1292 | (plca_cfg->node_id); |
1293 | |
1294 | ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, |
1295 | MDIO_OATC14_PLCA_CTRL1, val); |
1296 | |
1297 | if (ret < 0) |
1298 | return ret; |
1299 | } |
1300 | |
1301 | if (plca_cfg->to_tmr >= 0) { |
1302 | ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, |
1303 | MDIO_OATC14_PLCA_TOTMR, |
1304 | val: plca_cfg->to_tmr); |
1305 | |
1306 | if (ret < 0) |
1307 | return ret; |
1308 | } |
1309 | |
1310 | // check if we need to set the PLCA burst count, burst timer, or both |
1311 | if (plca_cfg->burst_cnt >= 0 || plca_cfg->burst_tmr >= 0) { |
1312 | /* if one between burst count and burst timer is -not- to be |
1313 | * changed, read the register to later perform merge/purge of |
1314 | * the configuration as appropriate |
1315 | */ |
1316 | if (plca_cfg->burst_cnt < 0 || plca_cfg->burst_tmr < 0) { |
1317 | ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, |
1318 | MDIO_OATC14_PLCA_BURST); |
1319 | |
1320 | if (ret < 0) |
1321 | return ret; |
1322 | |
1323 | val = ret; |
1324 | } |
1325 | |
1326 | if (plca_cfg->burst_cnt >= 0) |
1327 | val = (val & ~MDIO_OATC14_PLCA_MAXBC) | |
1328 | (plca_cfg->burst_cnt << 8); |
1329 | |
1330 | if (plca_cfg->burst_tmr >= 0) |
1331 | val = (val & ~MDIO_OATC14_PLCA_BTMR) | |
1332 | (plca_cfg->burst_tmr); |
1333 | |
1334 | ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, |
1335 | MDIO_OATC14_PLCA_BURST, val); |
1336 | |
1337 | if (ret < 0) |
1338 | return ret; |
1339 | } |
1340 | |
1341 | // if we need to enable PLCA, do it at the end |
1342 | if (plca_cfg->enabled > 0) { |
1343 | ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, |
1344 | MDIO_OATC14_PLCA_CTRL0, |
1345 | MDIO_OATC14_PLCA_EN); |
1346 | |
1347 | if (ret < 0) |
1348 | return ret; |
1349 | } |
1350 | |
1351 | return 0; |
1352 | } |
1353 | EXPORT_SYMBOL_GPL(genphy_c45_plca_set_cfg); |
1354 | |
1355 | /** |
1356 | * genphy_c45_plca_get_status - get PLCA status from standard registers |
1357 | * @phydev: target phy_device struct |
1358 | * @plca_st: output structure to store the PLCA status |
1359 | * |
1360 | * Description: if the PHY complies to the Open Alliance TC14 10BASE-T1S PLCA |
1361 | * Management Registers specifications, this function can be used to retrieve |
1362 | * the current PLCA status information from the standard registers in MMD 31. |
1363 | */ |
1364 | int genphy_c45_plca_get_status(struct phy_device *phydev, |
1365 | struct phy_plca_status *plca_st) |
1366 | { |
1367 | int ret; |
1368 | |
1369 | ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, MDIO_OATC14_PLCA_STATUS); |
1370 | if (ret < 0) |
1371 | return ret; |
1372 | |
1373 | plca_st->pst = !!(ret & MDIO_OATC14_PLCA_PST); |
1374 | return 0; |
1375 | } |
1376 | EXPORT_SYMBOL_GPL(genphy_c45_plca_get_status); |
1377 | |
1378 | /** |
1379 | * genphy_c45_eee_is_active - get EEE status |
1380 | * @phydev: target phy_device struct |
1381 | * @adv: variable to store advertised linkmodes |
1382 | * @lp: variable to store LP advertised linkmodes |
1383 | * @is_enabled: variable to store EEE enabled/disabled configuration value |
1384 | * |
1385 | * Description: this function will read local and link partner PHY |
1386 | * advertisements. Compare them return current EEE state. |
1387 | */ |
1388 | int genphy_c45_eee_is_active(struct phy_device *phydev, unsigned long *adv, |
1389 | unsigned long *lp, bool *is_enabled) |
1390 | { |
1391 | __ETHTOOL_DECLARE_LINK_MODE_MASK(tmp_adv) = {}; |
1392 | __ETHTOOL_DECLARE_LINK_MODE_MASK(tmp_lp) = {}; |
1393 | __ETHTOOL_DECLARE_LINK_MODE_MASK(common); |
1394 | bool eee_enabled, eee_active; |
1395 | int ret; |
1396 | |
1397 | ret = genphy_c45_read_eee_adv(phydev, adv: tmp_adv); |
1398 | if (ret) |
1399 | return ret; |
1400 | |
1401 | ret = genphy_c45_read_eee_lpa(phydev, lpa: tmp_lp); |
1402 | if (ret) |
1403 | return ret; |
1404 | |
1405 | eee_enabled = !linkmode_empty(src: tmp_adv); |
1406 | linkmode_and(dst: common, a: tmp_adv, b: tmp_lp); |
1407 | if (eee_enabled && !linkmode_empty(src: common)) |
1408 | eee_active = phy_check_valid(speed: phydev->speed, duplex: phydev->duplex, |
1409 | features: common); |
1410 | else |
1411 | eee_active = false; |
1412 | |
1413 | if (adv) |
1414 | linkmode_copy(dst: adv, src: tmp_adv); |
1415 | if (lp) |
1416 | linkmode_copy(dst: lp, src: tmp_lp); |
1417 | if (is_enabled) |
1418 | *is_enabled = eee_enabled; |
1419 | |
1420 | return eee_active; |
1421 | } |
1422 | EXPORT_SYMBOL(genphy_c45_eee_is_active); |
1423 | |
1424 | /** |
1425 | * genphy_c45_ethtool_get_eee - get EEE supported and status |
1426 | * @phydev: target phy_device struct |
1427 | * @data: ethtool_eee data |
1428 | * |
1429 | * Description: it reports the Supported/Advertisement/LP Advertisement |
1430 | * capabilities. |
1431 | */ |
1432 | int genphy_c45_ethtool_get_eee(struct phy_device *phydev, |
1433 | struct ethtool_eee *data) |
1434 | { |
1435 | __ETHTOOL_DECLARE_LINK_MODE_MASK(adv) = {}; |
1436 | __ETHTOOL_DECLARE_LINK_MODE_MASK(lp) = {}; |
1437 | bool overflow = false, is_enabled; |
1438 | int ret; |
1439 | |
1440 | ret = genphy_c45_eee_is_active(phydev, adv, lp, &is_enabled); |
1441 | if (ret < 0) |
1442 | return ret; |
1443 | |
1444 | data->eee_enabled = is_enabled; |
1445 | data->eee_active = ret; |
1446 | |
1447 | if (!ethtool_convert_link_mode_to_legacy_u32(legacy_u32: &data->supported, |
1448 | src: phydev->supported_eee)) |
1449 | overflow = true; |
1450 | if (!ethtool_convert_link_mode_to_legacy_u32(legacy_u32: &data->advertised, src: adv)) |
1451 | overflow = true; |
1452 | if (!ethtool_convert_link_mode_to_legacy_u32(legacy_u32: &data->lp_advertised, src: lp)) |
1453 | overflow = true; |
1454 | |
1455 | if (overflow) |
1456 | phydev_warn(phydev, "Not all supported or advertised EEE link modes were passed to the user space\n" ); |
1457 | |
1458 | return 0; |
1459 | } |
1460 | EXPORT_SYMBOL(genphy_c45_ethtool_get_eee); |
1461 | |
1462 | /** |
1463 | * genphy_c45_ethtool_set_eee - set EEE supported and status |
1464 | * @phydev: target phy_device struct |
1465 | * @data: ethtool_eee data |
1466 | * |
1467 | * Description: sets the Supported/Advertisement/LP Advertisement |
1468 | * capabilities. If eee_enabled is false, no links modes are |
1469 | * advertised, but the previously advertised link modes are |
1470 | * retained. This allows EEE to be enabled/disabled in a |
1471 | * non-destructive way. |
1472 | */ |
1473 | int genphy_c45_ethtool_set_eee(struct phy_device *phydev, |
1474 | struct ethtool_eee *data) |
1475 | { |
1476 | int ret; |
1477 | |
1478 | if (data->eee_enabled) { |
1479 | if (data->advertised) { |
1480 | __ETHTOOL_DECLARE_LINK_MODE_MASK(adv); |
1481 | |
1482 | ethtool_convert_legacy_u32_to_link_mode(dst: adv, |
1483 | legacy_u32: data->advertised); |
1484 | linkmode_andnot(dst: adv, src1: adv, src2: phydev->supported_eee); |
1485 | if (!linkmode_empty(src: adv)) { |
1486 | phydev_warn(phydev, "At least some EEE link modes are not supported.\n" ); |
1487 | return -EINVAL; |
1488 | } |
1489 | |
1490 | ethtool_convert_legacy_u32_to_link_mode(dst: phydev->advertising_eee, |
1491 | legacy_u32: data->advertised); |
1492 | } else { |
1493 | linkmode_copy(dst: phydev->advertising_eee, |
1494 | src: phydev->supported_eee); |
1495 | } |
1496 | |
1497 | phydev->eee_enabled = true; |
1498 | } else { |
1499 | phydev->eee_enabled = false; |
1500 | } |
1501 | |
1502 | ret = genphy_c45_an_config_eee_aneg(phydev); |
1503 | if (ret < 0) |
1504 | return ret; |
1505 | if (ret > 0) |
1506 | return phy_restart_aneg(phydev); |
1507 | |
1508 | return 0; |
1509 | } |
1510 | EXPORT_SYMBOL(genphy_c45_ethtool_set_eee); |
1511 | |
1512 | struct phy_driver genphy_c45_driver = { |
1513 | .phy_id = 0xffffffff, |
1514 | .phy_id_mask = 0xffffffff, |
1515 | .name = "Generic Clause 45 PHY" , |
1516 | .read_status = genphy_c45_read_status, |
1517 | }; |
1518 | |