1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /*
3 * Driver for Microsemi VSC85xx PHYs
4 *
5 * Author: Nagaraju Lakkaraju
6 * License: Dual MIT/GPL
7 * Copyright (c) 2016 Microsemi Corporation
8 */
9
10 #include <linux/firmware.h>
11 #include <linux/jiffies.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/mdio.h>
15 #include <linux/mii.h>
16 #include <linux/phy.h>
17 #include <linux/of.h>
18 #include <linux/netdevice.h>
19 #include <dt-bindings/net/mscc-phy-vsc8531.h>
20
21 #include "../phylib.h"
22 #include "mscc_serdes.h"
23 #include "mscc.h"
24
25 struct vsc85xx_probe_config {
26 const struct vsc85xx_hw_stat *hw_stats;
27 size_t shared_size;
28 size_t nstats;
29 u16 supp_led_modes;
30 u8 nleds;
31 bool check_rate_magic;
32 bool use_package;
33 bool has_ptp;
34 };
35
36 static const u32 vsc85xx_default_led_modes_4[] = {
37 VSC8531_LINK_1000_ACTIVITY,
38 VSC8531_LINK_100_ACTIVITY,
39 VSC8531_LINK_ACTIVITY,
40 VSC8531_DUPLEX_COLLISION
41 };
42
43 static const struct vsc85xx_hw_stat vsc85xx_hw_stats[] = {
44 {
45 .string = "phy_receive_errors",
46 .reg = MSCC_PHY_ERR_RX_CNT,
47 .page = MSCC_PHY_PAGE_STANDARD,
48 .mask = ERR_CNT_MASK,
49 }, {
50 .string = "phy_false_carrier",
51 .reg = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
52 .page = MSCC_PHY_PAGE_STANDARD,
53 .mask = ERR_CNT_MASK,
54 }, {
55 .string = "phy_cu_media_link_disconnect",
56 .reg = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
57 .page = MSCC_PHY_PAGE_STANDARD,
58 .mask = ERR_CNT_MASK,
59 }, {
60 .string = "phy_cu_media_crc_good_count",
61 .reg = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
62 .page = MSCC_PHY_PAGE_EXTENDED,
63 .mask = VALID_CRC_CNT_CRC_MASK,
64 }, {
65 .string = "phy_cu_media_crc_error_count",
66 .reg = MSCC_PHY_EXT_PHY_CNTL_4,
67 .page = MSCC_PHY_PAGE_EXTENDED,
68 .mask = ERR_CNT_MASK,
69 },
70 };
71
72 static const struct vsc85xx_hw_stat vsc8584_hw_stats[] = {
73 {
74 .string = "phy_receive_errors",
75 .reg = MSCC_PHY_ERR_RX_CNT,
76 .page = MSCC_PHY_PAGE_STANDARD,
77 .mask = ERR_CNT_MASK,
78 }, {
79 .string = "phy_false_carrier",
80 .reg = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
81 .page = MSCC_PHY_PAGE_STANDARD,
82 .mask = ERR_CNT_MASK,
83 }, {
84 .string = "phy_cu_media_link_disconnect",
85 .reg = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
86 .page = MSCC_PHY_PAGE_STANDARD,
87 .mask = ERR_CNT_MASK,
88 }, {
89 .string = "phy_cu_media_crc_good_count",
90 .reg = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
91 .page = MSCC_PHY_PAGE_EXTENDED,
92 .mask = VALID_CRC_CNT_CRC_MASK,
93 }, {
94 .string = "phy_cu_media_crc_error_count",
95 .reg = MSCC_PHY_EXT_PHY_CNTL_4,
96 .page = MSCC_PHY_PAGE_EXTENDED,
97 .mask = ERR_CNT_MASK,
98 }, {
99 .string = "phy_serdes_tx_good_pkt_count",
100 .reg = MSCC_PHY_SERDES_TX_VALID_CNT,
101 .page = MSCC_PHY_PAGE_EXTENDED_3,
102 .mask = VALID_CRC_CNT_CRC_MASK,
103 }, {
104 .string = "phy_serdes_tx_bad_crc_count",
105 .reg = MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
106 .page = MSCC_PHY_PAGE_EXTENDED_3,
107 .mask = ERR_CNT_MASK,
108 }, {
109 .string = "phy_serdes_rx_good_pkt_count",
110 .reg = MSCC_PHY_SERDES_RX_VALID_CNT,
111 .page = MSCC_PHY_PAGE_EXTENDED_3,
112 .mask = VALID_CRC_CNT_CRC_MASK,
113 }, {
114 .string = "phy_serdes_rx_bad_crc_count",
115 .reg = MSCC_PHY_SERDES_RX_CRC_ERR_CNT,
116 .page = MSCC_PHY_PAGE_EXTENDED_3,
117 .mask = ERR_CNT_MASK,
118 },
119 };
120
121 #if IS_ENABLED(CONFIG_OF_MDIO)
122 static const struct vsc8531_edge_rate_table edge_table[] = {
123 {MSCC_VDDMAC_3300, { 0, 2, 4, 7, 10, 17, 29, 53} },
124 {MSCC_VDDMAC_2500, { 0, 3, 6, 10, 14, 23, 37, 63} },
125 {MSCC_VDDMAC_1800, { 0, 5, 9, 16, 23, 35, 52, 76} },
126 {MSCC_VDDMAC_1500, { 0, 6, 14, 21, 29, 42, 58, 77} },
127 };
128 #endif
129
130 static const int vsc85xx_internal_delay[] = {200, 800, 1100, 1700, 2000, 2300,
131 2600, 3400};
132
vsc85xx_phy_read_page(struct phy_device * phydev)133 static int vsc85xx_phy_read_page(struct phy_device *phydev)
134 {
135 return __phy_read(phydev, MSCC_EXT_PAGE_ACCESS);
136 }
137
vsc85xx_phy_write_page(struct phy_device * phydev,int page)138 static int vsc85xx_phy_write_page(struct phy_device *phydev, int page)
139 {
140 return __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, page);
141 }
142
vsc85xx_get_sset_count(struct phy_device * phydev)143 static int vsc85xx_get_sset_count(struct phy_device *phydev)
144 {
145 struct vsc8531_private *priv = phydev->priv;
146
147 if (!priv)
148 return 0;
149
150 return priv->nstats;
151 }
152
vsc85xx_get_strings(struct phy_device * phydev,u8 * data)153 static void vsc85xx_get_strings(struct phy_device *phydev, u8 *data)
154 {
155 struct vsc8531_private *priv = phydev->priv;
156 int i;
157
158 if (!priv)
159 return;
160
161 for (i = 0; i < priv->nstats; i++)
162 ethtool_puts(&data, priv->hw_stats[i].string);
163 }
164
vsc85xx_get_stat(struct phy_device * phydev,int i)165 static u64 vsc85xx_get_stat(struct phy_device *phydev, int i)
166 {
167 struct vsc8531_private *priv = phydev->priv;
168 int val;
169
170 val = phy_read_paged(phydev, priv->hw_stats[i].page,
171 priv->hw_stats[i].reg);
172 if (val < 0)
173 return U64_MAX;
174
175 val = val & priv->hw_stats[i].mask;
176 priv->stats[i] += val;
177
178 return priv->stats[i];
179 }
180
vsc85xx_get_stats(struct phy_device * phydev,struct ethtool_stats * stats,u64 * data)181 static void vsc85xx_get_stats(struct phy_device *phydev,
182 struct ethtool_stats *stats, u64 *data)
183 {
184 struct vsc8531_private *priv = phydev->priv;
185 int i;
186
187 if (!priv)
188 return;
189
190 for (i = 0; i < priv->nstats; i++)
191 data[i] = vsc85xx_get_stat(phydev, i);
192 }
193
vsc85xx_led_cntl_set(struct phy_device * phydev,u8 led_num,u8 mode)194 static int vsc85xx_led_cntl_set(struct phy_device *phydev,
195 u8 led_num,
196 u8 mode)
197 {
198 u16 mask = LED_MODE_SEL_MASK(led_num);
199 u16 val = LED_MODE_SEL(led_num, mode);
200
201 return phy_modify(phydev, MSCC_PHY_LED_MODE_SEL, mask, val);
202 }
203
vsc85xx_led_combine_disable_set(struct phy_device * phydev,u8 led_num,bool combine_disable)204 static int vsc85xx_led_combine_disable_set(struct phy_device *phydev,
205 u8 led_num, bool combine_disable)
206 {
207 u16 val = LED_COMBINE_DIS(led_num, combine_disable);
208 u16 mask = LED_COMBINE_DIS_MASK(led_num);
209
210 return phy_modify(phydev, MSCC_PHY_LED_BEHAVIOR, mask, val);
211 }
212
vsc85xx_mdix_get(struct phy_device * phydev,u8 * mdix)213 static int vsc85xx_mdix_get(struct phy_device *phydev, u8 *mdix)
214 {
215 u16 reg_val;
216
217 reg_val = phy_read(phydev, MSCC_PHY_DEV_AUX_CNTL);
218 if (reg_val & HP_AUTO_MDIX_X_OVER_IND_MASK)
219 *mdix = ETH_TP_MDI_X;
220 else
221 *mdix = ETH_TP_MDI;
222
223 return 0;
224 }
225
vsc85xx_mdix_set(struct phy_device * phydev,u8 mdix)226 static int vsc85xx_mdix_set(struct phy_device *phydev, u8 mdix)
227 {
228 int rc;
229 u16 reg_val;
230
231 reg_val = phy_read(phydev, MSCC_PHY_BYPASS_CONTROL);
232 if (mdix == ETH_TP_MDI || mdix == ETH_TP_MDI_X) {
233 reg_val |= (DISABLE_PAIR_SWAP_CORR_MASK |
234 DISABLE_POLARITY_CORR_MASK |
235 DISABLE_HP_AUTO_MDIX_MASK);
236 } else {
237 reg_val &= ~(DISABLE_PAIR_SWAP_CORR_MASK |
238 DISABLE_POLARITY_CORR_MASK |
239 DISABLE_HP_AUTO_MDIX_MASK);
240 }
241 rc = phy_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg_val);
242 if (rc)
243 return rc;
244
245 reg_val = 0;
246
247 if (mdix == ETH_TP_MDI)
248 reg_val = FORCE_MDI_CROSSOVER_MDI;
249 else if (mdix == ETH_TP_MDI_X)
250 reg_val = FORCE_MDI_CROSSOVER_MDIX;
251
252 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
253 MSCC_PHY_EXT_MODE_CNTL, FORCE_MDI_CROSSOVER_MASK,
254 reg_val);
255 if (rc < 0)
256 return rc;
257
258 return genphy_restart_aneg(phydev);
259 }
260
vsc85xx_downshift_get(struct phy_device * phydev,u8 * count)261 static int vsc85xx_downshift_get(struct phy_device *phydev, u8 *count)
262 {
263 int reg_val;
264
265 reg_val = phy_read_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
266 MSCC_PHY_ACTIPHY_CNTL);
267 if (reg_val < 0)
268 return reg_val;
269
270 reg_val &= DOWNSHIFT_CNTL_MASK;
271 if (!(reg_val & DOWNSHIFT_EN))
272 *count = DOWNSHIFT_DEV_DISABLE;
273 else
274 *count = ((reg_val & ~DOWNSHIFT_EN) >> DOWNSHIFT_CNTL_POS) + 2;
275
276 return 0;
277 }
278
vsc85xx_downshift_set(struct phy_device * phydev,u8 count)279 static int vsc85xx_downshift_set(struct phy_device *phydev, u8 count)
280 {
281 if (count == DOWNSHIFT_DEV_DEFAULT_COUNT) {
282 /* Default downshift count 3 (i.e. Bit3:2 = 0b01) */
283 count = ((1 << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
284 } else if (count > DOWNSHIFT_COUNT_MAX || count == 1) {
285 phydev_err(phydev, "Downshift count should be 2,3,4 or 5\n");
286 return -ERANGE;
287 } else if (count) {
288 /* Downshift count is either 2,3,4 or 5 */
289 count = (((count - 2) << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
290 }
291
292 return phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
293 MSCC_PHY_ACTIPHY_CNTL, DOWNSHIFT_CNTL_MASK,
294 count);
295 }
296
vsc85xx_wol_set(struct phy_device * phydev,struct ethtool_wolinfo * wol)297 static int vsc85xx_wol_set(struct phy_device *phydev,
298 struct ethtool_wolinfo *wol)
299 {
300 const u8 *mac_addr = phydev->attached_dev->dev_addr;
301 int rc;
302 u16 reg_val;
303 u8 i;
304 u16 pwd[3] = {0, 0, 0};
305 struct ethtool_wolinfo *wol_conf = wol;
306
307 rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
308 if (rc < 0)
309 return phy_restore_page(phydev, rc, rc);
310
311 if (wol->wolopts & WAKE_MAGIC) {
312 /* Store the device address for the magic packet */
313 for (i = 0; i < ARRAY_SIZE(pwd); i++)
314 pwd[i] = mac_addr[5 - (i * 2 + 1)] << 8 |
315 mac_addr[5 - i * 2];
316 __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, pwd[0]);
317 __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, pwd[1]);
318 __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, pwd[2]);
319 } else {
320 __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, 0);
321 __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, 0);
322 __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, 0);
323 }
324
325 if (wol_conf->wolopts & WAKE_MAGICSECURE) {
326 for (i = 0; i < ARRAY_SIZE(pwd); i++)
327 pwd[i] = wol_conf->sopass[5 - (i * 2 + 1)] << 8 |
328 wol_conf->sopass[5 - i * 2];
329 __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, pwd[0]);
330 __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, pwd[1]);
331 __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, pwd[2]);
332 } else {
333 __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, 0);
334 __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, 0);
335 __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, 0);
336 }
337
338 reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
339 if (wol_conf->wolopts & WAKE_MAGICSECURE)
340 reg_val |= SECURE_ON_ENABLE;
341 else
342 reg_val &= ~SECURE_ON_ENABLE;
343 __phy_write(phydev, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
344
345 rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
346 if (rc < 0)
347 return rc;
348
349 if (wol->wolopts & WAKE_MAGIC) {
350 /* Enable the WOL interrupt */
351 reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
352 reg_val |= MII_VSC85XX_INT_MASK_WOL;
353 rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
354 if (rc)
355 return rc;
356 } else {
357 /* Disable the WOL interrupt */
358 reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
359 reg_val &= (~MII_VSC85XX_INT_MASK_WOL);
360 rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
361 if (rc)
362 return rc;
363 }
364 /* Clear WOL iterrupt status */
365 reg_val = phy_read(phydev, MII_VSC85XX_INT_STATUS);
366
367 return 0;
368 }
369
vsc85xx_wol_get(struct phy_device * phydev,struct ethtool_wolinfo * wol)370 static void vsc85xx_wol_get(struct phy_device *phydev,
371 struct ethtool_wolinfo *wol)
372 {
373 int rc;
374 u16 reg_val;
375 u8 i;
376 u16 pwd[3] = {0, 0, 0};
377 struct ethtool_wolinfo *wol_conf = wol;
378
379 rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
380 if (rc < 0)
381 goto out_restore_page;
382
383 reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
384 if (reg_val & SECURE_ON_ENABLE)
385 wol_conf->wolopts |= WAKE_MAGICSECURE;
386 if (wol_conf->wolopts & WAKE_MAGICSECURE) {
387 pwd[0] = __phy_read(phydev, MSCC_PHY_WOL_LOWER_PASSWD);
388 pwd[1] = __phy_read(phydev, MSCC_PHY_WOL_MID_PASSWD);
389 pwd[2] = __phy_read(phydev, MSCC_PHY_WOL_UPPER_PASSWD);
390 for (i = 0; i < ARRAY_SIZE(pwd); i++) {
391 wol_conf->sopass[5 - i * 2] = pwd[i] & 0x00ff;
392 wol_conf->sopass[5 - (i * 2 + 1)] = (pwd[i] & 0xff00)
393 >> 8;
394 }
395 }
396
397 out_restore_page:
398 phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
399 }
400
401 #if IS_ENABLED(CONFIG_OF_MDIO)
vsc85xx_edge_rate_magic_get(struct phy_device * phydev)402 static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
403 {
404 u32 vdd, sd;
405 int i, j;
406 struct device *dev = &phydev->mdio.dev;
407 struct device_node *of_node = dev->of_node;
408 u8 sd_array_size = ARRAY_SIZE(edge_table[0].slowdown);
409
410 if (!of_node)
411 return -ENODEV;
412
413 if (of_property_read_u32(of_node, "vsc8531,vddmac", &vdd))
414 vdd = MSCC_VDDMAC_3300;
415
416 if (of_property_read_u32(of_node, "vsc8531,edge-slowdown", &sd))
417 sd = 0;
418
419 for (i = 0; i < ARRAY_SIZE(edge_table); i++)
420 if (edge_table[i].vddmac == vdd)
421 for (j = 0; j < sd_array_size; j++)
422 if (edge_table[i].slowdown[j] == sd)
423 return (sd_array_size - j - 1);
424
425 return -EINVAL;
426 }
427
vsc85xx_dt_led_mode_get(struct phy_device * phydev,char * led,u32 default_mode)428 static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
429 char *led,
430 u32 default_mode)
431 {
432 struct vsc8531_private *priv = phydev->priv;
433 struct device *dev = &phydev->mdio.dev;
434 struct device_node *of_node = dev->of_node;
435 u32 led_mode;
436 int err;
437
438 if (!of_node)
439 return -ENODEV;
440
441 led_mode = default_mode;
442 err = of_property_read_u32(of_node, led, &led_mode);
443 if (!err && !(BIT(led_mode) & priv->supp_led_modes)) {
444 phydev_err(phydev, "DT %s invalid\n", led);
445 return -EINVAL;
446 }
447
448 return led_mode;
449 }
450
451 #else
vsc85xx_edge_rate_magic_get(struct phy_device * phydev)452 static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
453 {
454 return 0;
455 }
456
vsc85xx_dt_led_mode_get(struct phy_device * phydev,char * led,u8 default_mode)457 static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
458 char *led,
459 u8 default_mode)
460 {
461 return default_mode;
462 }
463 #endif /* CONFIG_OF_MDIO */
464
vsc85xx_dt_led_modes_get(struct phy_device * phydev,const u32 * default_mode)465 static int vsc85xx_dt_led_modes_get(struct phy_device *phydev,
466 const u32 *default_mode)
467 {
468 struct vsc8531_private *priv = phydev->priv;
469 char led_dt_prop[28];
470 int i, ret;
471
472 for (i = 0; i < priv->nleds; i++) {
473 ret = sprintf(led_dt_prop, "vsc8531,led-%d-mode", i);
474 if (ret < 0)
475 return ret;
476
477 ret = vsc85xx_dt_led_mode_get(phydev, led_dt_prop,
478 default_mode[i]);
479 if (ret < 0)
480 return ret;
481 priv->leds_mode[i] = ret;
482 }
483
484 return 0;
485 }
486
vsc85xx_edge_rate_cntl_set(struct phy_device * phydev,u8 edge_rate)487 static int vsc85xx_edge_rate_cntl_set(struct phy_device *phydev, u8 edge_rate)
488 {
489 int rc;
490
491 mutex_lock(&phydev->lock);
492 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
493 MSCC_PHY_WOL_MAC_CONTROL, EDGE_RATE_CNTL_MASK,
494 edge_rate << EDGE_RATE_CNTL_POS);
495 mutex_unlock(&phydev->lock);
496
497 return rc;
498 }
499
vsc85xx_mac_if_set(struct phy_device * phydev,phy_interface_t interface)500 static int vsc85xx_mac_if_set(struct phy_device *phydev,
501 phy_interface_t interface)
502 {
503 int rc;
504 u16 reg_val;
505
506 mutex_lock(&phydev->lock);
507 reg_val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
508 reg_val &= ~(MAC_IF_SELECTION_MASK);
509 switch (interface) {
510 case PHY_INTERFACE_MODE_RGMII_TXID:
511 case PHY_INTERFACE_MODE_RGMII_RXID:
512 case PHY_INTERFACE_MODE_RGMII_ID:
513 case PHY_INTERFACE_MODE_RGMII:
514 reg_val |= (MAC_IF_SELECTION_RGMII << MAC_IF_SELECTION_POS);
515 break;
516 case PHY_INTERFACE_MODE_RMII:
517 reg_val |= (MAC_IF_SELECTION_RMII << MAC_IF_SELECTION_POS);
518 break;
519 case PHY_INTERFACE_MODE_MII:
520 case PHY_INTERFACE_MODE_GMII:
521 reg_val |= (MAC_IF_SELECTION_GMII << MAC_IF_SELECTION_POS);
522 break;
523 default:
524 rc = -EINVAL;
525 goto out_unlock;
526 }
527 rc = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, reg_val);
528 if (rc)
529 goto out_unlock;
530
531 rc = genphy_soft_reset(phydev);
532
533 out_unlock:
534 mutex_unlock(&phydev->lock);
535
536 return rc;
537 }
538
539 /* Set the RGMII RX and TX clock skews individually, according to the PHY
540 * interface type, to:
541 * * 0.2 ns (their default, and lowest, hardware value) if delays should
542 * not be enabled
543 * * 2.0 ns (which causes the data to be sampled at exactly half way between
544 * clock transitions at 1000 Mbps) if delays should be enabled
545 */
vsc85xx_update_rgmii_cntl(struct phy_device * phydev,u32 rgmii_cntl,u16 rgmii_rx_delay_mask,u16 rgmii_tx_delay_mask)546 static int vsc85xx_update_rgmii_cntl(struct phy_device *phydev, u32 rgmii_cntl,
547 u16 rgmii_rx_delay_mask,
548 u16 rgmii_tx_delay_mask)
549 {
550 u16 rgmii_rx_delay_pos = ffs(rgmii_rx_delay_mask) - 1;
551 u16 rgmii_tx_delay_pos = ffs(rgmii_tx_delay_mask) - 1;
552 int delay_size = ARRAY_SIZE(vsc85xx_internal_delay);
553 u16 reg_val = 0;
554 u16 mask = 0;
555 s32 rx_delay;
556 s32 tx_delay;
557 int rc = 0;
558
559 /* For traffic to pass, the VSC8502 family needs the RX_CLK disable bit
560 * to be unset for all PHY modes, so do that as part of the paged
561 * register modification.
562 * For some family members (like VSC8530/31/40/41) this bit is reserved
563 * and read-only, and the RX clock is enabled by default.
564 */
565 if (rgmii_cntl == VSC8502_RGMII_CNTL)
566 mask |= VSC8502_RGMII_RX_CLK_DISABLE;
567
568 if (phy_interface_is_rgmii(phydev))
569 mask |= rgmii_rx_delay_mask | rgmii_tx_delay_mask;
570
571 rx_delay = phy_get_internal_delay(phydev, vsc85xx_internal_delay,
572 delay_size, true);
573 if (rx_delay < 0) {
574 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
575 phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
576 rx_delay = RGMII_CLK_DELAY_2_0_NS;
577 else
578 rx_delay = RGMII_CLK_DELAY_0_2_NS;
579 }
580
581 tx_delay = phy_get_internal_delay(phydev, vsc85xx_internal_delay,
582 delay_size, false);
583 if (tx_delay < 0) {
584 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
585 phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
586 tx_delay = RGMII_CLK_DELAY_2_0_NS;
587 else
588 tx_delay = RGMII_CLK_DELAY_0_2_NS;
589 }
590
591 reg_val |= rx_delay << rgmii_rx_delay_pos;
592 reg_val |= tx_delay << rgmii_tx_delay_pos;
593
594 if (mask)
595 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
596 rgmii_cntl, mask, reg_val);
597
598 return rc;
599 }
600
vsc85xx_default_config(struct phy_device * phydev)601 static int vsc85xx_default_config(struct phy_device *phydev)
602 {
603 phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
604
605 return vsc85xx_update_rgmii_cntl(phydev, VSC8502_RGMII_CNTL,
606 VSC8502_RGMII_RX_DELAY_MASK,
607 VSC8502_RGMII_TX_DELAY_MASK);
608 }
609
vsc85xx_get_tunable(struct phy_device * phydev,struct ethtool_tunable * tuna,void * data)610 static int vsc85xx_get_tunable(struct phy_device *phydev,
611 struct ethtool_tunable *tuna, void *data)
612 {
613 switch (tuna->id) {
614 case ETHTOOL_PHY_DOWNSHIFT:
615 return vsc85xx_downshift_get(phydev, (u8 *)data);
616 default:
617 return -EINVAL;
618 }
619 }
620
vsc85xx_set_tunable(struct phy_device * phydev,struct ethtool_tunable * tuna,const void * data)621 static int vsc85xx_set_tunable(struct phy_device *phydev,
622 struct ethtool_tunable *tuna,
623 const void *data)
624 {
625 switch (tuna->id) {
626 case ETHTOOL_PHY_DOWNSHIFT:
627 return vsc85xx_downshift_set(phydev, *(u8 *)data);
628 default:
629 return -EINVAL;
630 }
631 }
632
633 /* mdiobus lock should be locked when using this function */
vsc85xx_tr_write(struct phy_device * phydev,u16 addr,u32 val)634 static void vsc85xx_tr_write(struct phy_device *phydev, u16 addr, u32 val)
635 {
636 __phy_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
637 __phy_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
638 __phy_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
639 }
640
vsc8531_pre_init_seq_set(struct phy_device * phydev)641 static int vsc8531_pre_init_seq_set(struct phy_device *phydev)
642 {
643 int rc;
644 static const struct reg_val init_seq[] = {
645 {0x0f90, 0x00688980},
646 {0x0696, 0x00000003},
647 {0x07fa, 0x0050100f},
648 {0x1686, 0x00000004},
649 };
650 unsigned int i;
651 int oldpage;
652
653 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_STANDARD,
654 MSCC_PHY_EXT_CNTL_STATUS, SMI_BROADCAST_WR_EN,
655 SMI_BROADCAST_WR_EN);
656 if (rc < 0)
657 return rc;
658 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
659 MSCC_PHY_TEST_PAGE_24, 0, 0x0400);
660 if (rc < 0)
661 return rc;
662 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
663 MSCC_PHY_TEST_PAGE_5, 0x0a00, 0x0e00);
664 if (rc < 0)
665 return rc;
666 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
667 MSCC_PHY_TEST_PAGE_8, TR_CLK_DISABLE, TR_CLK_DISABLE);
668 if (rc < 0)
669 return rc;
670
671 mutex_lock(&phydev->lock);
672 oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
673 if (oldpage < 0)
674 goto out_unlock;
675
676 for (i = 0; i < ARRAY_SIZE(init_seq); i++)
677 vsc85xx_tr_write(phydev, init_seq[i].reg, init_seq[i].val);
678
679 out_unlock:
680 oldpage = phy_restore_page(phydev, oldpage, oldpage);
681 mutex_unlock(&phydev->lock);
682
683 return oldpage;
684 }
685
vsc85xx_eee_init_seq_set(struct phy_device * phydev)686 static int vsc85xx_eee_init_seq_set(struct phy_device *phydev)
687 {
688 static const struct reg_val init_eee[] = {
689 {0x0f82, 0x0012b00a},
690 {0x1686, 0x00000004},
691 {0x168c, 0x00d2c46f},
692 {0x17a2, 0x00000620},
693 {0x16a0, 0x00eeffdd},
694 {0x16a6, 0x00071448},
695 {0x16a4, 0x0013132f},
696 {0x16a8, 0x00000000},
697 {0x0ffc, 0x00c0a028},
698 {0x0fe8, 0x0091b06c},
699 {0x0fea, 0x00041600},
700 {0x0f80, 0x00000af4},
701 {0x0fec, 0x00901809},
702 {0x0fee, 0x0000a6a1},
703 {0x0ffe, 0x00b01007},
704 {0x16b0, 0x00eeff00},
705 {0x16b2, 0x00007000},
706 {0x16b4, 0x00000814},
707 };
708 unsigned int i;
709 int oldpage;
710
711 mutex_lock(&phydev->lock);
712 oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
713 if (oldpage < 0)
714 goto out_unlock;
715
716 for (i = 0; i < ARRAY_SIZE(init_eee); i++)
717 vsc85xx_tr_write(phydev, init_eee[i].reg, init_eee[i].val);
718
719 out_unlock:
720 oldpage = phy_restore_page(phydev, oldpage, oldpage);
721 mutex_unlock(&phydev->lock);
722
723 return oldpage;
724 }
725
726 /* phydev->bus->mdio_lock should be locked when using this function */
phy_base_write(struct phy_device * phydev,u32 regnum,u16 val)727 int phy_base_write(struct phy_device *phydev, u32 regnum, u16 val)
728 {
729 if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
730 dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
731 dump_stack();
732 }
733
734 return __phy_package_write(phydev, VSC88XX_BASE_ADDR, regnum, val);
735 }
736
737 /* phydev->bus->mdio_lock should be locked when using this function */
phy_base_read(struct phy_device * phydev,u32 regnum)738 int phy_base_read(struct phy_device *phydev, u32 regnum)
739 {
740 if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
741 dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
742 dump_stack();
743 }
744
745 return __phy_package_read(phydev, VSC88XX_BASE_ADDR, regnum);
746 }
747
vsc85xx_csr_read(struct phy_device * phydev,enum csr_target target,u32 reg)748 u32 vsc85xx_csr_read(struct phy_device *phydev,
749 enum csr_target target, u32 reg)
750 {
751 unsigned long deadline;
752 u32 val, val_l, val_h;
753
754 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
755
756 /* CSR registers are grouped under different Target IDs.
757 * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
758 * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
759 * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
760 * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
761 */
762
763 /* Setup the Target ID */
764 phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
765 MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
766
767 if ((target >> 2 == 0x1) || (target >> 2 == 0x3))
768 /* non-MACsec access */
769 target &= 0x3;
770 else
771 target = 0;
772
773 /* Trigger CSR Action - Read into the CSR's */
774 phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
775 MSCC_PHY_CSR_CNTL_19_CMD | MSCC_PHY_CSR_CNTL_19_READ |
776 MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
777 MSCC_PHY_CSR_CNTL_19_TARGET(target));
778
779 /* Wait for register access*/
780 deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
781 do {
782 usleep_range(500, 1000);
783 val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
784 } while (time_before(jiffies, deadline) &&
785 !(val & MSCC_PHY_CSR_CNTL_19_CMD));
786
787 if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
788 return 0xffffffff;
789
790 /* Read the Least Significant Word (LSW) (17) */
791 val_l = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_17);
792
793 /* Read the Most Significant Word (MSW) (18) */
794 val_h = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_18);
795
796 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
797 MSCC_PHY_PAGE_STANDARD);
798
799 return (val_h << 16) | val_l;
800 }
801
vsc85xx_csr_write(struct phy_device * phydev,enum csr_target target,u32 reg,u32 val)802 int vsc85xx_csr_write(struct phy_device *phydev,
803 enum csr_target target, u32 reg, u32 val)
804 {
805 unsigned long deadline;
806
807 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
808
809 /* CSR registers are grouped under different Target IDs.
810 * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
811 * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
812 * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
813 * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
814 */
815
816 /* Setup the Target ID */
817 phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
818 MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
819
820 /* Write the Least Significant Word (LSW) (17) */
821 phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_17, (u16)val);
822
823 /* Write the Most Significant Word (MSW) (18) */
824 phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_18, (u16)(val >> 16));
825
826 if ((target >> 2 == 0x1) || (target >> 2 == 0x3))
827 /* non-MACsec access */
828 target &= 0x3;
829 else
830 target = 0;
831
832 /* Trigger CSR Action - Write into the CSR's */
833 phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
834 MSCC_PHY_CSR_CNTL_19_CMD |
835 MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
836 MSCC_PHY_CSR_CNTL_19_TARGET(target));
837
838 /* Wait for register access */
839 deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
840 do {
841 usleep_range(500, 1000);
842 val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
843 } while (time_before(jiffies, deadline) &&
844 !(val & MSCC_PHY_CSR_CNTL_19_CMD));
845
846 if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
847 return -ETIMEDOUT;
848
849 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
850 MSCC_PHY_PAGE_STANDARD);
851
852 return 0;
853 }
854
855 /* bus->mdio_lock should be locked when using this function */
vsc8584_csr_write(struct phy_device * phydev,u16 addr,u32 val)856 static void vsc8584_csr_write(struct phy_device *phydev, u16 addr, u32 val)
857 {
858 phy_base_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
859 phy_base_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
860 phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
861 }
862
863 /* bus->mdio_lock should be locked when using this function */
vsc8584_cmd(struct phy_device * phydev,u16 val)864 int vsc8584_cmd(struct phy_device *phydev, u16 val)
865 {
866 unsigned long deadline;
867 u16 reg_val;
868
869 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
870 MSCC_PHY_PAGE_EXTENDED_GPIO);
871
872 phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NCOMPLETED | val);
873
874 deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
875 do {
876 reg_val = phy_base_read(phydev, MSCC_PHY_PROC_CMD);
877 } while (time_before(jiffies, deadline) &&
878 (reg_val & PROC_CMD_NCOMPLETED) &&
879 !(reg_val & PROC_CMD_FAILED));
880
881 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
882
883 if (reg_val & PROC_CMD_FAILED)
884 return -EIO;
885
886 if (reg_val & PROC_CMD_NCOMPLETED)
887 return -ETIMEDOUT;
888
889 return 0;
890 }
891
892 /* bus->mdio_lock should be locked when using this function */
vsc8584_micro_deassert_reset(struct phy_device * phydev,bool patch_en)893 static int vsc8584_micro_deassert_reset(struct phy_device *phydev,
894 bool patch_en)
895 {
896 u32 enable, release;
897
898 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
899 MSCC_PHY_PAGE_EXTENDED_GPIO);
900
901 enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
902 release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
903 MICRO_CLK_EN;
904
905 if (patch_en) {
906 enable |= MICRO_PATCH_EN;
907 release |= MICRO_PATCH_EN;
908
909 /* Clear all patches */
910 phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
911 }
912
913 /* Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
914 * override and addr. auto-incr; operate at 125 MHz
915 */
916 phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, enable);
917 /* Release 8051 Micro SW reset */
918 phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, release);
919
920 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
921
922 return 0;
923 }
924
925 /* bus->mdio_lock should be locked when using this function */
vsc8584_micro_assert_reset(struct phy_device * phydev)926 static int vsc8584_micro_assert_reset(struct phy_device *phydev)
927 {
928 int ret;
929 u16 reg;
930
931 ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
932 if (ret)
933 return ret;
934
935 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
936 MSCC_PHY_PAGE_EXTENDED_GPIO);
937
938 reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
939 reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
940 phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
941
942 phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(4), 0x005b);
943 phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(4), 0x005b);
944
945 reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
946 reg |= EN_PATCH_RAM_TRAP_ADDR(4);
947 phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
948
949 phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
950
951 reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
952 reg &= ~MICRO_NSOFT_RESET;
953 phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, reg);
954
955 phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_MCB_ACCESS_MAC_CONF |
956 PROC_CMD_SGMII_PORT(0) | PROC_CMD_NO_MAC_CONF |
957 PROC_CMD_READ);
958
959 reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
960 reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
961 phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
962
963 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
964
965 return 0;
966 }
967
968 /* bus->mdio_lock should be locked when using this function */
vsc8584_get_fw_crc(struct phy_device * phydev,u16 start,u16 size,u16 * crc)969 static int vsc8584_get_fw_crc(struct phy_device *phydev, u16 start, u16 size,
970 u16 *crc)
971 {
972 int ret;
973
974 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
975
976 phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_2, start);
977 phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_3, size);
978
979 /* Start Micro command */
980 ret = vsc8584_cmd(phydev, PROC_CMD_CRC16);
981 if (ret)
982 goto out;
983
984 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
985
986 *crc = phy_base_read(phydev, MSCC_PHY_VERIPHY_CNTL_2);
987
988 out:
989 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
990
991 return ret;
992 }
993
994 /* bus->mdio_lock should be locked when using this function */
vsc8584_patch_fw(struct phy_device * phydev,const struct firmware * fw)995 static int vsc8584_patch_fw(struct phy_device *phydev,
996 const struct firmware *fw)
997 {
998 int i, ret;
999
1000 ret = vsc8584_micro_assert_reset(phydev);
1001 if (ret) {
1002 dev_err(&phydev->mdio.dev,
1003 "%s: failed to assert reset of micro\n", __func__);
1004 return ret;
1005 }
1006
1007 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1008 MSCC_PHY_PAGE_EXTENDED_GPIO);
1009
1010 /* Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
1011 * Disable the 8051 Micro clock
1012 */
1013 phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, RUN_FROM_INT_ROM |
1014 AUTOINC_ADDR | PATCH_RAM_CLK | MICRO_CLK_EN |
1015 MICRO_CLK_DIVIDE(2));
1016 phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM | INT_MEM_WRITE_EN |
1017 INT_MEM_DATA(2));
1018 phy_base_write(phydev, MSCC_INT_MEM_ADDR, 0x0000);
1019
1020 for (i = 0; i < fw->size; i++)
1021 phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM |
1022 INT_MEM_WRITE_EN | fw->data[i]);
1023
1024 /* Clear internal memory access */
1025 phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
1026
1027 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1028
1029 return 0;
1030 }
1031
1032 /* bus->mdio_lock should be locked when using this function */
vsc8574_is_serdes_init(struct phy_device * phydev)1033 static bool vsc8574_is_serdes_init(struct phy_device *phydev)
1034 {
1035 u16 reg;
1036 bool ret;
1037
1038 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1039 MSCC_PHY_PAGE_EXTENDED_GPIO);
1040
1041 reg = phy_base_read(phydev, MSCC_TRAP_ROM_ADDR(1));
1042 if (reg != 0x3eb7) {
1043 ret = false;
1044 goto out;
1045 }
1046
1047 reg = phy_base_read(phydev, MSCC_PATCH_RAM_ADDR(1));
1048 if (reg != 0x4012) {
1049 ret = false;
1050 goto out;
1051 }
1052
1053 reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1054 if (reg != EN_PATCH_RAM_TRAP_ADDR(1)) {
1055 ret = false;
1056 goto out;
1057 }
1058
1059 reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
1060 if ((MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
1061 MICRO_CLK_EN) != (reg & MSCC_DW8051_VLD_MASK)) {
1062 ret = false;
1063 goto out;
1064 }
1065
1066 ret = true;
1067 out:
1068 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1069
1070 return ret;
1071 }
1072
1073 /* bus->mdio_lock should be locked when using this function */
vsc8574_config_pre_init(struct phy_device * phydev)1074 static int vsc8574_config_pre_init(struct phy_device *phydev)
1075 {
1076 static const struct reg_val pre_init1[] = {
1077 {0x0fae, 0x000401bd},
1078 {0x0fac, 0x000f000f},
1079 {0x17a0, 0x00a0f147},
1080 {0x0fe4, 0x00052f54},
1081 {0x1792, 0x0027303d},
1082 {0x07fe, 0x00000704},
1083 {0x0fe0, 0x00060150},
1084 {0x0f82, 0x0012b00a},
1085 {0x0f80, 0x00000d74},
1086 {0x02e0, 0x00000012},
1087 {0x03a2, 0x00050208},
1088 {0x03b2, 0x00009186},
1089 {0x0fb0, 0x000e3700},
1090 {0x1688, 0x00049f81},
1091 {0x0fd2, 0x0000ffff},
1092 {0x168a, 0x00039fa2},
1093 {0x1690, 0x0020640b},
1094 {0x0258, 0x00002220},
1095 {0x025a, 0x00002a20},
1096 {0x025c, 0x00003060},
1097 {0x025e, 0x00003fa0},
1098 {0x03a6, 0x0000e0f0},
1099 {0x0f92, 0x00001489},
1100 {0x16a2, 0x00007000},
1101 {0x16a6, 0x00071448},
1102 {0x16a0, 0x00eeffdd},
1103 {0x0fe8, 0x0091b06c},
1104 {0x0fea, 0x00041600},
1105 {0x16b0, 0x00eeff00},
1106 {0x16b2, 0x00007000},
1107 {0x16b4, 0x00000814},
1108 {0x0f90, 0x00688980},
1109 {0x03a4, 0x0000d8f0},
1110 {0x0fc0, 0x00000400},
1111 {0x07fa, 0x0050100f},
1112 {0x0796, 0x00000003},
1113 {0x07f8, 0x00c3ff98},
1114 {0x0fa4, 0x0018292a},
1115 {0x168c, 0x00d2c46f},
1116 {0x17a2, 0x00000620},
1117 {0x16a4, 0x0013132f},
1118 {0x16a8, 0x00000000},
1119 {0x0ffc, 0x00c0a028},
1120 {0x0fec, 0x00901c09},
1121 {0x0fee, 0x0004a6a1},
1122 {0x0ffe, 0x00b01807},
1123 };
1124 static const struct reg_val pre_init2[] = {
1125 {0x0486, 0x0008a518},
1126 {0x0488, 0x006dc696},
1127 {0x048a, 0x00000912},
1128 {0x048e, 0x00000db6},
1129 {0x049c, 0x00596596},
1130 {0x049e, 0x00000514},
1131 {0x04a2, 0x00410280},
1132 {0x04a4, 0x00000000},
1133 {0x04a6, 0x00000000},
1134 {0x04a8, 0x00000000},
1135 {0x04aa, 0x00000000},
1136 {0x04ae, 0x007df7dd},
1137 {0x04b0, 0x006d95d4},
1138 {0x04b2, 0x00492410},
1139 };
1140 struct device *dev = &phydev->mdio.dev;
1141 const struct firmware *fw;
1142 unsigned int i;
1143 u16 crc, reg;
1144 bool serdes_init;
1145 int ret;
1146
1147 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1148
1149 /* all writes below are broadcasted to all PHYs in the same package */
1150 reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1151 reg |= SMI_BROADCAST_WR_EN;
1152 phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1153
1154 phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
1155
1156 /* The below register writes are tweaking analog and electrical
1157 * configuration that were determined through characterization by PHY
1158 * engineers. These don't mean anything more than "these are the best
1159 * values".
1160 */
1161 phy_base_write(phydev, MSCC_PHY_EXT_PHY_CNTL_2, 0x0040);
1162
1163 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1164
1165 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_20, 0x4320);
1166 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_24, 0x0c00);
1167 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_9, 0x18ca);
1168 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1b20);
1169
1170 reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1171 reg |= TR_CLK_DISABLE;
1172 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1173
1174 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1175
1176 for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1177 vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1178
1179 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
1180
1181 phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
1182
1183 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1184
1185 for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
1186 vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
1187
1188 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1189
1190 reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1191 reg &= ~TR_CLK_DISABLE;
1192 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1193
1194 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1195
1196 /* end of write broadcasting */
1197 reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1198 reg &= ~SMI_BROADCAST_WR_EN;
1199 phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1200
1201 ret = request_firmware(&fw, MSCC_VSC8574_REVB_INT8051_FW, dev);
1202 if (ret) {
1203 dev_err(dev, "failed to load firmware %s, ret: %d\n",
1204 MSCC_VSC8574_REVB_INT8051_FW, ret);
1205 return ret;
1206 }
1207
1208 /* Add one byte to size for the one added by the patch_fw function */
1209 ret = vsc8584_get_fw_crc(phydev,
1210 MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
1211 fw->size + 1, &crc);
1212 if (ret)
1213 goto out;
1214
1215 if (crc == MSCC_VSC8574_REVB_INT8051_FW_CRC) {
1216 serdes_init = vsc8574_is_serdes_init(phydev);
1217
1218 if (!serdes_init) {
1219 ret = vsc8584_micro_assert_reset(phydev);
1220 if (ret) {
1221 dev_err(dev,
1222 "%s: failed to assert reset of micro\n",
1223 __func__);
1224 goto out;
1225 }
1226 }
1227 } else {
1228 dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
1229
1230 serdes_init = false;
1231
1232 if (vsc8584_patch_fw(phydev, fw))
1233 dev_warn(dev,
1234 "failed to patch FW, expect non-optimal device\n");
1235 }
1236
1237 if (!serdes_init) {
1238 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1239 MSCC_PHY_PAGE_EXTENDED_GPIO);
1240
1241 phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), 0x3eb7);
1242 phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), 0x4012);
1243 phy_base_write(phydev, MSCC_INT_MEM_CNTL,
1244 EN_PATCH_RAM_TRAP_ADDR(1));
1245
1246 vsc8584_micro_deassert_reset(phydev, false);
1247
1248 /* Add one byte to size for the one added by the patch_fw
1249 * function
1250 */
1251 ret = vsc8584_get_fw_crc(phydev,
1252 MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
1253 fw->size + 1, &crc);
1254 if (ret)
1255 goto out;
1256
1257 if (crc != MSCC_VSC8574_REVB_INT8051_FW_CRC)
1258 dev_warn(dev,
1259 "FW CRC after patching is not the expected one, expect non-optimal device\n");
1260 }
1261
1262 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1263 MSCC_PHY_PAGE_EXTENDED_GPIO);
1264
1265 ret = vsc8584_cmd(phydev, PROC_CMD_1588_DEFAULT_INIT |
1266 PROC_CMD_PHY_INIT);
1267
1268 out:
1269 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1270
1271 release_firmware(fw);
1272
1273 return ret;
1274 }
1275
1276 /* Access LCPLL Cfg_2 */
vsc8584_pll5g_cfg2_wr(struct phy_device * phydev,bool disable_fsm)1277 static void vsc8584_pll5g_cfg2_wr(struct phy_device *phydev,
1278 bool disable_fsm)
1279 {
1280 u32 rd_dat;
1281
1282 rd_dat = vsc85xx_csr_read(phydev, MACRO_CTRL, PHY_S6G_PLL5G_CFG2);
1283 rd_dat &= ~BIT(PHY_S6G_CFG2_FSM_DIS);
1284 rd_dat |= (disable_fsm << PHY_S6G_CFG2_FSM_DIS);
1285 vsc85xx_csr_write(phydev, MACRO_CTRL, PHY_S6G_PLL5G_CFG2, rd_dat);
1286 }
1287
1288 /* trigger a read to the spcified MCB */
vsc8584_mcb_rd_trig(struct phy_device * phydev,u32 mcb_reg_addr,u8 mcb_slave_num)1289 static int vsc8584_mcb_rd_trig(struct phy_device *phydev,
1290 u32 mcb_reg_addr, u8 mcb_slave_num)
1291 {
1292 u32 rd_dat = 0;
1293
1294 /* read MCB */
1295 vsc85xx_csr_write(phydev, MACRO_CTRL, mcb_reg_addr,
1296 (0x40000000 | (1L << mcb_slave_num)));
1297
1298 return read_poll_timeout(vsc85xx_csr_read, rd_dat,
1299 !(rd_dat & 0x40000000),
1300 4000, 200000, 0,
1301 phydev, MACRO_CTRL, mcb_reg_addr);
1302 }
1303
1304 /* trigger a write to the spcified MCB */
vsc8584_mcb_wr_trig(struct phy_device * phydev,u32 mcb_reg_addr,u8 mcb_slave_num)1305 static int vsc8584_mcb_wr_trig(struct phy_device *phydev,
1306 u32 mcb_reg_addr,
1307 u8 mcb_slave_num)
1308 {
1309 u32 rd_dat = 0;
1310
1311 /* write back MCB */
1312 vsc85xx_csr_write(phydev, MACRO_CTRL, mcb_reg_addr,
1313 (0x80000000 | (1L << mcb_slave_num)));
1314
1315 return read_poll_timeout(vsc85xx_csr_read, rd_dat,
1316 !(rd_dat & 0x80000000),
1317 4000, 200000, 0,
1318 phydev, MACRO_CTRL, mcb_reg_addr);
1319 }
1320
1321 /* Sequence to Reset LCPLL for the VIPER and ELISE PHY */
vsc8584_pll5g_reset(struct phy_device * phydev)1322 static int vsc8584_pll5g_reset(struct phy_device *phydev)
1323 {
1324 bool dis_fsm;
1325 int ret = 0;
1326
1327 ret = vsc8584_mcb_rd_trig(phydev, 0x11, 0);
1328 if (ret < 0)
1329 goto done;
1330 dis_fsm = 1;
1331
1332 /* Reset LCPLL */
1333 vsc8584_pll5g_cfg2_wr(phydev, dis_fsm);
1334
1335 /* write back LCPLL MCB */
1336 ret = vsc8584_mcb_wr_trig(phydev, 0x11, 0);
1337 if (ret < 0)
1338 goto done;
1339
1340 /* 10 mSec sleep while LCPLL is hold in reset */
1341 usleep_range(10000, 20000);
1342
1343 /* read LCPLL MCB into CSRs */
1344 ret = vsc8584_mcb_rd_trig(phydev, 0x11, 0);
1345 if (ret < 0)
1346 goto done;
1347 dis_fsm = 0;
1348
1349 /* Release the Reset of LCPLL */
1350 vsc8584_pll5g_cfg2_wr(phydev, dis_fsm);
1351
1352 /* write back LCPLL MCB */
1353 ret = vsc8584_mcb_wr_trig(phydev, 0x11, 0);
1354 if (ret < 0)
1355 goto done;
1356
1357 usleep_range(110000, 200000);
1358 done:
1359 return ret;
1360 }
1361
1362 /* bus->mdio_lock should be locked when using this function */
vsc8584_config_pre_init(struct phy_device * phydev)1363 static int vsc8584_config_pre_init(struct phy_device *phydev)
1364 {
1365 static const struct reg_val pre_init1[] = {
1366 {0x07fa, 0x0050100f},
1367 {0x1688, 0x00049f81},
1368 {0x0f90, 0x00688980},
1369 {0x03a4, 0x0000d8f0},
1370 {0x0fc0, 0x00000400},
1371 {0x0f82, 0x0012b002},
1372 {0x1686, 0x00000004},
1373 {0x168c, 0x00d2c46f},
1374 {0x17a2, 0x00000620},
1375 {0x16a0, 0x00eeffdd},
1376 {0x16a6, 0x00071448},
1377 {0x16a4, 0x0013132f},
1378 {0x16a8, 0x00000000},
1379 {0x0ffc, 0x00c0a028},
1380 {0x0fe8, 0x0091b06c},
1381 {0x0fea, 0x00041600},
1382 {0x0f80, 0x00fffaff},
1383 {0x0fec, 0x00901809},
1384 {0x0ffe, 0x00b01007},
1385 {0x16b0, 0x00eeff00},
1386 {0x16b2, 0x00007000},
1387 {0x16b4, 0x00000814},
1388 };
1389 static const struct reg_val pre_init2[] = {
1390 {0x0486, 0x0008a518},
1391 {0x0488, 0x006dc696},
1392 {0x048a, 0x00000912},
1393 };
1394 const struct firmware *fw;
1395 struct device *dev = &phydev->mdio.dev;
1396 unsigned int i;
1397 u16 crc, reg;
1398 int ret;
1399
1400 ret = vsc8584_pll5g_reset(phydev);
1401 if (ret < 0) {
1402 dev_err(dev, "failed LCPLL reset, ret: %d\n", ret);
1403 return ret;
1404 }
1405
1406 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1407
1408 /* all writes below are broadcasted to all PHYs in the same package */
1409 reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1410 reg |= SMI_BROADCAST_WR_EN;
1411 phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1412
1413 phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
1414
1415 reg = phy_base_read(phydev, MSCC_PHY_BYPASS_CONTROL);
1416 reg |= PARALLEL_DET_IGNORE_ADVERTISED;
1417 phy_base_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg);
1418
1419 /* The below register writes are tweaking analog and electrical
1420 * configuration that were determined through characterization by PHY
1421 * engineers. These don't mean anything more than "these are the best
1422 * values".
1423 */
1424 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_3);
1425
1426 phy_base_write(phydev, MSCC_PHY_SERDES_TX_CRC_ERR_CNT, 0x2000);
1427
1428 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1429
1430 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1f20);
1431
1432 reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1433 reg |= TR_CLK_DISABLE;
1434 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1435
1436 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1437
1438 phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x2fa4));
1439
1440 reg = phy_base_read(phydev, MSCC_PHY_TR_MSB);
1441 reg &= ~0x007f;
1442 reg |= 0x0019;
1443 phy_base_write(phydev, MSCC_PHY_TR_MSB, reg);
1444
1445 phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x0fa4));
1446
1447 for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1448 vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1449
1450 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
1451
1452 phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
1453
1454 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1455
1456 for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
1457 vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
1458
1459 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1460
1461 reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1462 reg &= ~TR_CLK_DISABLE;
1463 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1464
1465 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1466
1467 /* end of write broadcasting */
1468 reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1469 reg &= ~SMI_BROADCAST_WR_EN;
1470 phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1471
1472 ret = request_firmware(&fw, MSCC_VSC8584_REVB_INT8051_FW, dev);
1473 if (ret) {
1474 dev_err(dev, "failed to load firmware %s, ret: %d\n",
1475 MSCC_VSC8584_REVB_INT8051_FW, ret);
1476 return ret;
1477 }
1478
1479 /* Add one byte to size for the one added by the patch_fw function */
1480 ret = vsc8584_get_fw_crc(phydev,
1481 MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
1482 fw->size + 1, &crc);
1483 if (ret)
1484 goto out;
1485
1486 if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
1487 dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
1488 if (vsc8584_patch_fw(phydev, fw))
1489 dev_warn(dev,
1490 "failed to patch FW, expect non-optimal device\n");
1491 }
1492
1493 vsc8584_micro_deassert_reset(phydev, false);
1494
1495 /* Add one byte to size for the one added by the patch_fw function */
1496 ret = vsc8584_get_fw_crc(phydev,
1497 MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
1498 fw->size + 1, &crc);
1499 if (ret)
1500 goto out;
1501
1502 if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
1503 dev_warn(dev,
1504 "FW CRC after patching is not the expected one, expect non-optimal device\n");
1505
1506 ret = vsc8584_micro_assert_reset(phydev);
1507 if (ret)
1508 goto out;
1509
1510 /* Write patch vector 0, to skip IB cal polling */
1511 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_GPIO);
1512 reg = MSCC_ROM_TRAP_SERDES_6G_CFG; /* ROM address to trap, for patch vector 0 */
1513 ret = phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), reg);
1514 if (ret)
1515 goto out;
1516
1517 reg = MSCC_RAM_TRAP_SERDES_6G_CFG; /* RAM address to jump to, when patch vector 0 enabled */
1518 ret = phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), reg);
1519 if (ret)
1520 goto out;
1521
1522 reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1523 reg |= PATCH_VEC_ZERO_EN; /* bit 8, enable patch vector 0 */
1524 ret = phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
1525 if (ret)
1526 goto out;
1527
1528 vsc8584_micro_deassert_reset(phydev, true);
1529
1530 out:
1531 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1532
1533 release_firmware(fw);
1534
1535 return ret;
1536 }
1537
vsc8584_get_base_addr(struct phy_device * phydev)1538 static void vsc8584_get_base_addr(struct phy_device *phydev)
1539 {
1540 struct vsc8531_private *vsc8531 = phydev->priv;
1541 u16 val, addr;
1542
1543 phy_lock_mdio_bus(phydev);
1544 __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
1545
1546 addr = __phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_4);
1547 addr >>= PHY_CNTL_4_ADDR_POS;
1548
1549 val = __phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL);
1550
1551 __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1552 phy_unlock_mdio_bus(phydev);
1553
1554 /* In the package, there are two pairs of PHYs (PHY0 + PHY2 and
1555 * PHY1 + PHY3). The first PHY of each pair (PHY0 and PHY1) is
1556 * the base PHY for timestamping operations.
1557 */
1558 vsc8531->ts_base_addr = phydev->mdio.addr;
1559 vsc8531->ts_base_phy = addr;
1560
1561 if (val & PHY_ADDR_REVERSED) {
1562 vsc8531->base_addr = phydev->mdio.addr + addr;
1563 if (addr > 1) {
1564 vsc8531->ts_base_addr += 2;
1565 vsc8531->ts_base_phy += 2;
1566 }
1567 } else {
1568 vsc8531->base_addr = phydev->mdio.addr - addr;
1569 if (addr > 1) {
1570 vsc8531->ts_base_addr -= 2;
1571 vsc8531->ts_base_phy -= 2;
1572 }
1573 }
1574
1575 vsc8531->addr = addr;
1576 }
1577
vsc85xx_coma_mode_release(struct phy_device * phydev)1578 static void vsc85xx_coma_mode_release(struct phy_device *phydev)
1579 {
1580 /* The coma mode (pin or reg) provides an optional feature that
1581 * may be used to control when the PHYs become active.
1582 * Alternatively the COMA_MODE pin may be connected low
1583 * so that the PHYs are fully active once out of reset.
1584 */
1585
1586 /* Enable output (mode=0) and write zero to it */
1587 vsc85xx_phy_write_page(phydev, MSCC_PHY_PAGE_EXTENDED_GPIO);
1588 __phy_modify(phydev, MSCC_PHY_GPIO_CONTROL_2,
1589 MSCC_PHY_COMA_MODE | MSCC_PHY_COMA_OUTPUT, 0);
1590 vsc85xx_phy_write_page(phydev, MSCC_PHY_PAGE_STANDARD);
1591 }
1592
vsc8584_config_host_serdes(struct phy_device * phydev)1593 static int vsc8584_config_host_serdes(struct phy_device *phydev)
1594 {
1595 struct vsc8531_private *vsc8531 = phydev->priv;
1596 int ret;
1597 u16 val;
1598
1599 ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1600 MSCC_PHY_PAGE_EXTENDED_GPIO);
1601 if (ret)
1602 return ret;
1603
1604 val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
1605 val &= ~MAC_CFG_MASK;
1606 if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
1607 val |= MAC_CFG_QSGMII;
1608 } else if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
1609 val |= MAC_CFG_SGMII;
1610 } else {
1611 ret = -EINVAL;
1612 return ret;
1613 }
1614
1615 ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
1616 if (ret)
1617 return ret;
1618
1619 ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1620 MSCC_PHY_PAGE_STANDARD);
1621 if (ret)
1622 return ret;
1623
1624 val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
1625 PROC_CMD_READ_MOD_WRITE_PORT;
1626 if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
1627 val |= PROC_CMD_QSGMII_MAC;
1628 else
1629 val |= PROC_CMD_SGMII_MAC;
1630
1631 ret = vsc8584_cmd(phydev, val);
1632 if (ret)
1633 return ret;
1634
1635 usleep_range(10000, 20000);
1636
1637 /* Disable SerDes for 100Base-FX */
1638 ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
1639 PROC_CMD_FIBER_PORT(vsc8531->addr) |
1640 PROC_CMD_FIBER_DISABLE |
1641 PROC_CMD_READ_MOD_WRITE_PORT |
1642 PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
1643 if (ret)
1644 return ret;
1645
1646 /* Disable SerDes for 1000Base-X */
1647 ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
1648 PROC_CMD_FIBER_PORT(vsc8531->addr) |
1649 PROC_CMD_FIBER_DISABLE |
1650 PROC_CMD_READ_MOD_WRITE_PORT |
1651 PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
1652 if (ret)
1653 return ret;
1654
1655 return vsc85xx_sd6g_config_v2(phydev);
1656 }
1657
vsc8574_config_host_serdes(struct phy_device * phydev)1658 static int vsc8574_config_host_serdes(struct phy_device *phydev)
1659 {
1660 struct vsc8531_private *vsc8531 = phydev->priv;
1661 int ret;
1662 u16 val;
1663
1664 ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1665 MSCC_PHY_PAGE_EXTENDED_GPIO);
1666 if (ret)
1667 return ret;
1668
1669 val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
1670 val &= ~MAC_CFG_MASK;
1671 if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
1672 val |= MAC_CFG_QSGMII;
1673 } else if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
1674 val |= MAC_CFG_SGMII;
1675 } else if (phy_interface_is_rgmii(phydev)) {
1676 val |= MAC_CFG_RGMII;
1677 } else {
1678 ret = -EINVAL;
1679 return ret;
1680 }
1681
1682 ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
1683 if (ret)
1684 return ret;
1685
1686 ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1687 MSCC_PHY_PAGE_STANDARD);
1688 if (ret)
1689 return ret;
1690
1691 if (!phy_interface_is_rgmii(phydev)) {
1692 val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
1693 PROC_CMD_READ_MOD_WRITE_PORT;
1694 if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
1695 val |= PROC_CMD_QSGMII_MAC;
1696 else
1697 val |= PROC_CMD_SGMII_MAC;
1698
1699 ret = vsc8584_cmd(phydev, val);
1700 if (ret)
1701 return ret;
1702
1703 usleep_range(10000, 20000);
1704 }
1705
1706 /* Disable SerDes for 100Base-FX */
1707 ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
1708 PROC_CMD_FIBER_PORT(vsc8531->addr) |
1709 PROC_CMD_FIBER_DISABLE |
1710 PROC_CMD_READ_MOD_WRITE_PORT |
1711 PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
1712 if (ret)
1713 return ret;
1714
1715 /* Disable SerDes for 1000Base-X */
1716 return vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
1717 PROC_CMD_FIBER_PORT(vsc8531->addr) |
1718 PROC_CMD_FIBER_DISABLE |
1719 PROC_CMD_READ_MOD_WRITE_PORT |
1720 PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
1721 }
1722
vsc8584_config_init(struct phy_device * phydev)1723 static int vsc8584_config_init(struct phy_device *phydev)
1724 {
1725 struct vsc8531_private *vsc8531 = phydev->priv;
1726 int ret, i;
1727 u16 val;
1728
1729 phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
1730
1731 phy_lock_mdio_bus(phydev);
1732
1733 /* Some parts of the init sequence are identical for every PHY in the
1734 * package. Some parts are modifying the GPIO register bank which is a
1735 * set of registers that are affecting all PHYs, a few resetting the
1736 * microprocessor common to all PHYs. The CRC check responsible of the
1737 * checking the firmware within the 8051 microprocessor can only be
1738 * accessed via the PHY whose internal address in the package is 0.
1739 * All PHYs' interrupts mask register has to be zeroed before enabling
1740 * any PHY's interrupt in this register.
1741 * For all these reasons, we need to do the init sequence once and only
1742 * once whatever is the first PHY in the package that is initialized and
1743 * do the correct init sequence for all PHYs that are package-critical
1744 * in this pre-init function.
1745 */
1746 if (phy_package_init_once(phydev)) {
1747 switch (phydev->phy_id & phydev->drv->phy_id_mask) {
1748 case PHY_ID_VSC8504:
1749 case PHY_ID_VSC8552:
1750 case PHY_ID_VSC8572:
1751 case PHY_ID_VSC8574:
1752 ret = vsc8574_config_pre_init(phydev);
1753 if (ret)
1754 goto err;
1755 ret = vsc8574_config_host_serdes(phydev);
1756 if (ret)
1757 goto err;
1758 break;
1759 case PHY_ID_VSC856X:
1760 case PHY_ID_VSC8575:
1761 case PHY_ID_VSC8582:
1762 case PHY_ID_VSC8584:
1763 ret = vsc8584_config_pre_init(phydev);
1764 if (ret)
1765 goto err;
1766 ret = vsc8584_config_host_serdes(phydev);
1767 if (ret)
1768 goto err;
1769 vsc85xx_coma_mode_release(phydev);
1770 break;
1771 default:
1772 ret = -EINVAL;
1773 break;
1774 }
1775
1776 if (ret)
1777 goto err;
1778 }
1779
1780 phy_unlock_mdio_bus(phydev);
1781
1782 ret = vsc8584_macsec_init(phydev);
1783 if (ret)
1784 return ret;
1785
1786 ret = vsc8584_ptp_init(phydev);
1787 if (ret)
1788 return ret;
1789
1790 val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
1791 val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
1792 val |= (MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS) |
1793 (VSC8584_MAC_IF_SELECTION_SGMII << VSC8584_MAC_IF_SELECTION_POS);
1794 ret = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, val);
1795 if (ret)
1796 return ret;
1797
1798 ret = vsc85xx_update_rgmii_cntl(phydev, VSC8572_RGMII_CNTL,
1799 VSC8572_RGMII_RX_DELAY_MASK,
1800 VSC8572_RGMII_TX_DELAY_MASK);
1801 if (ret)
1802 return ret;
1803
1804 ret = genphy_soft_reset(phydev);
1805 if (ret)
1806 return ret;
1807
1808 for (i = 0; i < vsc8531->nleds; i++) {
1809 ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
1810 if (ret)
1811 return ret;
1812 }
1813
1814 return 0;
1815
1816 err:
1817 phy_unlock_mdio_bus(phydev);
1818 return ret;
1819 }
1820
vsc8584_handle_interrupt(struct phy_device * phydev)1821 static irqreturn_t vsc8584_handle_interrupt(struct phy_device *phydev)
1822 {
1823 irqreturn_t ret;
1824 int irq_status;
1825
1826 irq_status = phy_read(phydev, MII_VSC85XX_INT_STATUS);
1827 if (irq_status < 0)
1828 return IRQ_NONE;
1829
1830 /* Timestamping IRQ does not set a bit in the global INT_STATUS, so
1831 * irq_status would be 0.
1832 */
1833 ret = vsc8584_handle_ts_interrupt(phydev);
1834 if (!(irq_status & MII_VSC85XX_INT_MASK_MASK))
1835 return ret;
1836
1837 if (irq_status & MII_VSC85XX_INT_MASK_EXT)
1838 vsc8584_handle_macsec_interrupt(phydev);
1839
1840 if (irq_status & MII_VSC85XX_INT_MASK_LINK_CHG)
1841 phy_trigger_machine(phydev);
1842
1843 return IRQ_HANDLED;
1844 }
1845
vsc85xx_config_init(struct phy_device * phydev)1846 static int vsc85xx_config_init(struct phy_device *phydev)
1847 {
1848 int rc, i, phy_id;
1849 struct vsc8531_private *vsc8531 = phydev->priv;
1850
1851 rc = vsc85xx_default_config(phydev);
1852 if (rc)
1853 return rc;
1854
1855 rc = vsc85xx_mac_if_set(phydev, phydev->interface);
1856 if (rc)
1857 return rc;
1858
1859 rc = vsc85xx_edge_rate_cntl_set(phydev, vsc8531->rate_magic);
1860 if (rc)
1861 return rc;
1862
1863 phy_id = phydev->drv->phy_id & phydev->drv->phy_id_mask;
1864 if (PHY_ID_VSC8531 == phy_id || PHY_ID_VSC8541 == phy_id ||
1865 PHY_ID_VSC8530 == phy_id || PHY_ID_VSC8540 == phy_id) {
1866 rc = vsc8531_pre_init_seq_set(phydev);
1867 if (rc)
1868 return rc;
1869 }
1870
1871 rc = vsc85xx_eee_init_seq_set(phydev);
1872 if (rc)
1873 return rc;
1874
1875 for (i = 0; i < vsc8531->nleds; i++) {
1876 rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
1877 if (rc)
1878 return rc;
1879 }
1880
1881 return 0;
1882 }
1883
__phy_write_mcb_s6g(struct phy_device * phydev,u32 reg,u8 mcb,u32 op)1884 static int __phy_write_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb,
1885 u32 op)
1886 {
1887 unsigned long deadline;
1888 u32 val;
1889 int ret;
1890
1891 ret = vsc85xx_csr_write(phydev, PHY_MCB_TARGET, reg,
1892 op | (1 << mcb));
1893 if (ret)
1894 return -EINVAL;
1895
1896 deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1897 do {
1898 usleep_range(500, 1000);
1899 val = vsc85xx_csr_read(phydev, PHY_MCB_TARGET, reg);
1900
1901 if (val == 0xffffffff)
1902 return -EIO;
1903
1904 } while (time_before(jiffies, deadline) && (val & op));
1905
1906 if (val & op)
1907 return -ETIMEDOUT;
1908
1909 return 0;
1910 }
1911
1912 /* Trigger a read to the specified MCB */
phy_update_mcb_s6g(struct phy_device * phydev,u32 reg,u8 mcb)1913 int phy_update_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
1914 {
1915 return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_READ);
1916 }
1917
1918 /* Trigger a write to the specified MCB */
phy_commit_mcb_s6g(struct phy_device * phydev,u32 reg,u8 mcb)1919 int phy_commit_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
1920 {
1921 return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_WRITE);
1922 }
1923
vsc8514_config_host_serdes(struct phy_device * phydev)1924 static int vsc8514_config_host_serdes(struct phy_device *phydev)
1925 {
1926 int ret;
1927 u16 val;
1928
1929 ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1930 MSCC_PHY_PAGE_EXTENDED_GPIO);
1931 if (ret)
1932 return ret;
1933
1934 val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
1935 val &= ~MAC_CFG_MASK;
1936 val |= MAC_CFG_QSGMII;
1937 ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
1938 if (ret)
1939 return ret;
1940
1941 ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1942 MSCC_PHY_PAGE_STANDARD);
1943 if (ret)
1944 return ret;
1945
1946 ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
1947 if (ret)
1948 return ret;
1949
1950 ret = vsc8584_cmd(phydev,
1951 PROC_CMD_MCB_ACCESS_MAC_CONF |
1952 PROC_CMD_RST_CONF_PORT |
1953 PROC_CMD_READ_MOD_WRITE_PORT | PROC_CMD_QSGMII_MAC);
1954 if (ret) {
1955 dev_err(&phydev->mdio.dev, "%s: QSGMII error: %d\n",
1956 __func__, ret);
1957 return ret;
1958 }
1959
1960 /* Apply 6G SerDes FOJI Algorithm
1961 * Initial condition requirement:
1962 * 1. hold 8051 in reset
1963 * 2. disable patch vector 0, in order to allow IB cal poll during FoJi
1964 * 3. deassert 8051 reset after change patch vector status
1965 * 4. proceed with FoJi (vsc85xx_sd6g_config_v2)
1966 */
1967 vsc8584_micro_assert_reset(phydev);
1968 val = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1969 /* clear bit 8, to disable patch vector 0 */
1970 val &= ~PATCH_VEC_ZERO_EN;
1971 ret = phy_base_write(phydev, MSCC_INT_MEM_CNTL, val);
1972 /* Enable 8051 clock, don't set patch present, disable PRAM clock override */
1973 vsc8584_micro_deassert_reset(phydev, false);
1974
1975 return vsc85xx_sd6g_config_v2(phydev);
1976 }
1977
vsc8514_config_pre_init(struct phy_device * phydev)1978 static int vsc8514_config_pre_init(struct phy_device *phydev)
1979 {
1980 /* These are the settings to override the silicon default
1981 * values to handle hardware performance of PHY. They
1982 * are set at Power-On state and remain until PHY Reset.
1983 */
1984 static const struct reg_val pre_init1[] = {
1985 {0x0f90, 0x00688980},
1986 {0x0786, 0x00000003},
1987 {0x07fa, 0x0050100f},
1988 {0x0f82, 0x0012b002},
1989 {0x1686, 0x00000004},
1990 {0x168c, 0x00d2c46f},
1991 {0x17a2, 0x00000620},
1992 {0x16a0, 0x00eeffdd},
1993 {0x16a6, 0x00071448},
1994 {0x16a4, 0x0013132f},
1995 {0x16a8, 0x00000000},
1996 {0x0ffc, 0x00c0a028},
1997 {0x0fe8, 0x0091b06c},
1998 {0x0fea, 0x00041600},
1999 {0x0f80, 0x00fffaff},
2000 {0x0fec, 0x00901809},
2001 {0x0ffe, 0x00b01007},
2002 {0x16b0, 0x00eeff00},
2003 {0x16b2, 0x00007000},
2004 {0x16b4, 0x00000814},
2005 };
2006 struct device *dev = &phydev->mdio.dev;
2007 unsigned int i;
2008 u16 reg;
2009 int ret;
2010
2011 ret = vsc8584_pll5g_reset(phydev);
2012 if (ret < 0) {
2013 dev_err(dev, "failed LCPLL reset, ret: %d\n", ret);
2014 return ret;
2015 }
2016
2017 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2018
2019 /* all writes below are broadcasted to all PHYs in the same package */
2020 reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
2021 reg |= SMI_BROADCAST_WR_EN;
2022 phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
2023
2024 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
2025
2026 reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
2027 reg |= BIT(15);
2028 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
2029
2030 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
2031
2032 for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
2033 vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
2034
2035 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
2036
2037 reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
2038 reg &= ~BIT(15);
2039 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
2040
2041 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2042
2043 reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
2044 reg &= ~SMI_BROADCAST_WR_EN;
2045 phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
2046
2047 /* Add pre-patching commands to:
2048 * 1. enable 8051 clock, operate 8051 clock at 125 MHz
2049 * instead of HW default 62.5MHz
2050 * 2. write patch vector 0, to skip IB cal polling executed
2051 * as part of the 0x80E0 ROM command
2052 */
2053 vsc8584_micro_deassert_reset(phydev, false);
2054
2055 vsc8584_micro_assert_reset(phydev);
2056 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
2057 MSCC_PHY_PAGE_EXTENDED_GPIO);
2058 /* ROM address to trap, for patch vector 0 */
2059 reg = MSCC_ROM_TRAP_SERDES_6G_CFG;
2060 ret = phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), reg);
2061 if (ret)
2062 goto err;
2063 /* RAM address to jump to, when patch vector 0 enabled */
2064 reg = MSCC_RAM_TRAP_SERDES_6G_CFG;
2065 ret = phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), reg);
2066 if (ret)
2067 goto err;
2068 reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
2069 reg |= PATCH_VEC_ZERO_EN; /* bit 8, enable patch vector 0 */
2070 ret = phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
2071 if (ret)
2072 goto err;
2073
2074 /* Enable 8051 clock, don't set patch present
2075 * yet, disable PRAM clock override
2076 */
2077 vsc8584_micro_deassert_reset(phydev, false);
2078 return ret;
2079 err:
2080 /* restore 8051 and bail w error */
2081 vsc8584_micro_deassert_reset(phydev, false);
2082 return ret;
2083 }
2084
vsc8514_config_init(struct phy_device * phydev)2085 static int vsc8514_config_init(struct phy_device *phydev)
2086 {
2087 struct vsc8531_private *vsc8531 = phydev->priv;
2088 int ret, i;
2089
2090 phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
2091
2092 phy_lock_mdio_bus(phydev);
2093
2094 /* Some parts of the init sequence are identical for every PHY in the
2095 * package. Some parts are modifying the GPIO register bank which is a
2096 * set of registers that are affecting all PHYs, a few resetting the
2097 * microprocessor common to all PHYs.
2098 * All PHYs' interrupts mask register has to be zeroed before enabling
2099 * any PHY's interrupt in this register.
2100 * For all these reasons, we need to do the init sequence once and only
2101 * once whatever is the first PHY in the package that is initialized and
2102 * do the correct init sequence for all PHYs that are package-critical
2103 * in this pre-init function.
2104 */
2105 if (phy_package_init_once(phydev)) {
2106 ret = vsc8514_config_pre_init(phydev);
2107 if (ret)
2108 goto err;
2109 ret = vsc8514_config_host_serdes(phydev);
2110 if (ret)
2111 goto err;
2112 vsc85xx_coma_mode_release(phydev);
2113 }
2114
2115 phy_unlock_mdio_bus(phydev);
2116
2117 ret = phy_modify(phydev, MSCC_PHY_EXT_PHY_CNTL_1, MEDIA_OP_MODE_MASK,
2118 MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS);
2119
2120 if (ret)
2121 return ret;
2122
2123 ret = genphy_soft_reset(phydev);
2124
2125 if (ret)
2126 return ret;
2127
2128 for (i = 0; i < vsc8531->nleds; i++) {
2129 ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
2130 if (ret)
2131 return ret;
2132 }
2133
2134 return ret;
2135
2136 err:
2137 phy_unlock_mdio_bus(phydev);
2138 return ret;
2139 }
2140
vsc85xx_ack_interrupt(struct phy_device * phydev)2141 static int vsc85xx_ack_interrupt(struct phy_device *phydev)
2142 {
2143 int rc = 0;
2144
2145 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
2146 rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2147
2148 return (rc < 0) ? rc : 0;
2149 }
2150
vsc85xx_config_intr(struct phy_device * phydev)2151 static int vsc85xx_config_intr(struct phy_device *phydev)
2152 {
2153 int rc;
2154
2155 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
2156 rc = vsc85xx_ack_interrupt(phydev);
2157 if (rc)
2158 return rc;
2159
2160 vsc8584_config_macsec_intr(phydev);
2161 vsc8584_config_ts_intr(phydev);
2162
2163 rc = phy_write(phydev, MII_VSC85XX_INT_MASK,
2164 MII_VSC85XX_INT_MASK_MASK);
2165 } else {
2166 rc = phy_write(phydev, MII_VSC85XX_INT_MASK, 0);
2167 if (rc < 0)
2168 return rc;
2169 rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2170 if (rc < 0)
2171 return rc;
2172
2173 rc = vsc85xx_ack_interrupt(phydev);
2174 }
2175
2176 return rc;
2177 }
2178
vsc85xx_handle_interrupt(struct phy_device * phydev)2179 static irqreturn_t vsc85xx_handle_interrupt(struct phy_device *phydev)
2180 {
2181 int irq_status;
2182
2183 irq_status = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2184 if (irq_status < 0) {
2185 phy_error(phydev);
2186 return IRQ_NONE;
2187 }
2188
2189 if (!(irq_status & MII_VSC85XX_INT_MASK_MASK))
2190 return IRQ_NONE;
2191
2192 phy_trigger_machine(phydev);
2193
2194 return IRQ_HANDLED;
2195 }
2196
vsc85xx_config_aneg(struct phy_device * phydev)2197 static int vsc85xx_config_aneg(struct phy_device *phydev)
2198 {
2199 int rc;
2200
2201 rc = vsc85xx_mdix_set(phydev, phydev->mdix_ctrl);
2202 if (rc < 0)
2203 return rc;
2204
2205 return genphy_config_aneg(phydev);
2206 }
2207
vsc85xx_read_status(struct phy_device * phydev)2208 static int vsc85xx_read_status(struct phy_device *phydev)
2209 {
2210 int rc;
2211
2212 rc = vsc85xx_mdix_get(phydev, &phydev->mdix);
2213 if (rc < 0)
2214 return rc;
2215
2216 return genphy_read_status(phydev);
2217 }
2218
vsc85xx_inband_caps(struct phy_device * phydev,phy_interface_t interface)2219 static unsigned int vsc85xx_inband_caps(struct phy_device *phydev,
2220 phy_interface_t interface)
2221 {
2222 if (interface != PHY_INTERFACE_MODE_SGMII &&
2223 interface != PHY_INTERFACE_MODE_QSGMII)
2224 return 0;
2225
2226 return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
2227 }
2228
vsc85xx_config_inband(struct phy_device * phydev,unsigned int modes)2229 static int vsc85xx_config_inband(struct phy_device *phydev, unsigned int modes)
2230 {
2231 u16 reg_val = 0;
2232
2233 if (modes == LINK_INBAND_ENABLE)
2234 reg_val = MSCC_PHY_SERDES_ANEG;
2235
2236 return phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_3,
2237 MSCC_PHY_SERDES_PCS_CTRL, MSCC_PHY_SERDES_ANEG,
2238 reg_val);
2239 }
2240
vsc85xx_probe_common(struct phy_device * phydev,const struct vsc85xx_probe_config * cfg,const u32 * default_led_mode)2241 static int vsc85xx_probe_common(struct phy_device *phydev,
2242 const struct vsc85xx_probe_config *cfg,
2243 const u32 *default_led_mode)
2244 {
2245 struct vsc8531_private *vsc8531;
2246 struct device_node *np;
2247 int ret;
2248
2249 vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2250 if (!vsc8531)
2251 return -ENOMEM;
2252
2253 phydev->priv = vsc8531;
2254
2255 /* Check rate magic if needed (only for non-package PHYs) */
2256 if (cfg->check_rate_magic) {
2257 ret = vsc85xx_edge_rate_magic_get(phydev);
2258 if (ret < 0)
2259 return ret;
2260
2261 vsc8531->rate_magic = ret;
2262 }
2263
2264 /* Set up package if needed */
2265 if (cfg->use_package) {
2266 vsc8584_get_base_addr(phydev);
2267 ret = devm_phy_package_join(&phydev->mdio.dev, phydev,
2268 vsc8531->base_addr,
2269 cfg->shared_size);
2270 if (ret)
2271 return ret;
2272 }
2273
2274 /* Configure LED settings */
2275 vsc8531->nleds = cfg->nleds;
2276 vsc8531->supp_led_modes = cfg->supp_led_modes;
2277
2278 /* Configure hardware stats */
2279 vsc8531->hw_stats = cfg->hw_stats;
2280 vsc8531->nstats = cfg->nstats;
2281 vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2282 sizeof(u64), GFP_KERNEL);
2283 if (!vsc8531->stats)
2284 return -ENOMEM;
2285
2286 /* PTP setup for VSC8584 */
2287 if (cfg->has_ptp) {
2288 if (phy_package_probe_once(phydev)) {
2289 ret = vsc8584_ptp_probe_once(phydev);
2290 if (ret)
2291 return ret;
2292 }
2293
2294 ret = vsc8584_ptp_probe(phydev);
2295 if (ret)
2296 return ret;
2297 }
2298
2299 /*
2300 * Check for LED configuration in device tree if available
2301 * or fall back to default `vsc8531,led-x-mode` DT properties.
2302 */
2303 np = of_get_child_by_name(phydev->mdio.dev.of_node, "leds");
2304 if (np) {
2305 of_node_put(np);
2306
2307 /* Force to defaults */
2308 for (unsigned int i = 0; i < vsc8531->nleds; i++)
2309 vsc8531->leds_mode[i] = default_led_mode[i];
2310
2311 return 0;
2312 }
2313
2314 /* Parse LED modes from device tree */
2315 return vsc85xx_dt_led_modes_get(phydev, default_led_mode);
2316 }
2317
vsc85xx_led_brightness_set(struct phy_device * phydev,u8 index,enum led_brightness value)2318 static int vsc85xx_led_brightness_set(struct phy_device *phydev,
2319 u8 index, enum led_brightness value)
2320 {
2321 struct vsc8531_private *vsc8531 = phydev->priv;
2322
2323 if (index >= vsc8531->nleds)
2324 return -EINVAL;
2325
2326 return vsc85xx_led_cntl_set(phydev, index, value == LED_OFF ?
2327 VSC8531_FORCE_LED_OFF : VSC8531_FORCE_LED_ON);
2328 }
2329
vsc85xx_led_hw_is_supported(struct phy_device * phydev,u8 index,unsigned long rules)2330 static int vsc85xx_led_hw_is_supported(struct phy_device *phydev, u8 index,
2331 unsigned long rules)
2332 {
2333 static const unsigned long supported = BIT(TRIGGER_NETDEV_LINK_1000) |
2334 BIT(TRIGGER_NETDEV_LINK_100) |
2335 BIT(TRIGGER_NETDEV_LINK_10) |
2336 BIT(TRIGGER_NETDEV_LINK) |
2337 BIT(TRIGGER_NETDEV_RX) |
2338 BIT(TRIGGER_NETDEV_TX);
2339 struct vsc8531_private *vsc8531 = phydev->priv;
2340
2341 if (index >= vsc8531->nleds)
2342 return -EINVAL;
2343
2344 if (rules & ~supported)
2345 return -EOPNOTSUPP;
2346
2347 return 0;
2348 }
2349
vsc85xx_led_hw_control_get(struct phy_device * phydev,u8 index,unsigned long * rules)2350 static int vsc85xx_led_hw_control_get(struct phy_device *phydev, u8 index,
2351 unsigned long *rules)
2352 {
2353 struct vsc8531_private *vsc8531 = phydev->priv;
2354 u8 mode, behavior;
2355 int rc;
2356
2357 if (index >= vsc8531->nleds)
2358 return -EINVAL;
2359
2360 rc = phy_read(phydev, MSCC_PHY_LED_MODE_SEL);
2361 if (rc < 0)
2362 return rc;
2363 mode = (rc & LED_MODE_SEL_MASK(index)) >> LED_MODE_SEL_POS(index);
2364
2365 rc = phy_read(phydev, MSCC_PHY_LED_BEHAVIOR);
2366 if (rc < 0)
2367 return rc;
2368 behavior = (rc & LED_COMBINE_DIS_MASK(index)) >> index;
2369
2370 switch (mode) {
2371 case VSC8531_LINK_ACTIVITY:
2372 case VSC8531_ACTIVITY:
2373 *rules = BIT(TRIGGER_NETDEV_LINK);
2374 break;
2375
2376 case VSC8531_LINK_1000_ACTIVITY:
2377 *rules = BIT(TRIGGER_NETDEV_LINK_1000) |
2378 BIT(TRIGGER_NETDEV_LINK);
2379 break;
2380
2381 case VSC8531_LINK_100_ACTIVITY:
2382 *rules = BIT(TRIGGER_NETDEV_LINK_100) |
2383 BIT(TRIGGER_NETDEV_LINK);
2384 break;
2385
2386 case VSC8531_LINK_10_ACTIVITY:
2387 *rules = BIT(TRIGGER_NETDEV_LINK_10) |
2388 BIT(TRIGGER_NETDEV_LINK);
2389 break;
2390
2391 case VSC8531_LINK_100_1000_ACTIVITY:
2392 *rules = BIT(TRIGGER_NETDEV_LINK_1000) |
2393 BIT(TRIGGER_NETDEV_LINK_100) |
2394 BIT(TRIGGER_NETDEV_LINK);
2395 break;
2396
2397 case VSC8531_LINK_10_1000_ACTIVITY:
2398 *rules = BIT(TRIGGER_NETDEV_LINK_1000) |
2399 BIT(TRIGGER_NETDEV_LINK_10) |
2400 BIT(TRIGGER_NETDEV_LINK);
2401 break;
2402
2403 case VSC8531_LINK_10_100_ACTIVITY:
2404 *rules = BIT(TRIGGER_NETDEV_LINK_100) |
2405 BIT(TRIGGER_NETDEV_LINK_10) |
2406 BIT(TRIGGER_NETDEV_LINK);
2407 break;
2408
2409 default:
2410 *rules = 0;
2411 break;
2412 }
2413
2414 if (!behavior && *rules)
2415 *rules |= BIT(TRIGGER_NETDEV_RX) | BIT(TRIGGER_NETDEV_TX);
2416
2417 return 0;
2418 }
2419
vsc85xx_led_hw_control_set(struct phy_device * phydev,u8 index,unsigned long rules)2420 static int vsc85xx_led_hw_control_set(struct phy_device *phydev, u8 index,
2421 unsigned long rules)
2422 {
2423 struct vsc8531_private *vsc8531 = phydev->priv;
2424 u8 mode = VSC8531_FORCE_LED_ON;
2425 bool combine_disable = false;
2426 bool has_rx, has_tx;
2427 int ret;
2428
2429 if (index >= vsc8531->nleds)
2430 return -EINVAL;
2431
2432 if (rules & BIT(TRIGGER_NETDEV_LINK))
2433 mode = VSC8531_LINK_ACTIVITY;
2434
2435 if (rules & BIT(TRIGGER_NETDEV_LINK_10))
2436 mode = VSC8531_LINK_10_ACTIVITY;
2437
2438 if (rules & BIT(TRIGGER_NETDEV_LINK_100))
2439 mode = VSC8531_LINK_100_ACTIVITY;
2440
2441 if (rules & BIT(TRIGGER_NETDEV_LINK_1000))
2442 mode = VSC8531_LINK_1000_ACTIVITY;
2443
2444 if (rules & BIT(TRIGGER_NETDEV_LINK_100) &&
2445 rules & BIT(TRIGGER_NETDEV_LINK_1000))
2446 mode = VSC8531_LINK_100_1000_ACTIVITY;
2447
2448 if (rules & BIT(TRIGGER_NETDEV_LINK_10) &&
2449 rules & BIT(TRIGGER_NETDEV_LINK_1000))
2450 mode = VSC8531_LINK_10_1000_ACTIVITY;
2451
2452 if (rules & BIT(TRIGGER_NETDEV_LINK_10) &&
2453 rules & BIT(TRIGGER_NETDEV_LINK_100))
2454 mode = VSC8531_LINK_10_100_ACTIVITY;
2455
2456 /*
2457 * The VSC85xx PHYs provides an option to control LED behavior. By
2458 * default, the LEDx combine function is enabled, meaning the LED
2459 * will be on when there is link/activity or duplex/collision. If
2460 * the combine function is disabled, the LED will be on only for
2461 * link or duplex.
2462 *
2463 * To control this behavior, we check the selected rules. If both
2464 * RX and TX activity are not selected, the LED combine function
2465 * is disabled; otherwise, it remains enabled.
2466 */
2467 has_rx = !!(rules & BIT(TRIGGER_NETDEV_RX));
2468 has_tx = !!(rules & BIT(TRIGGER_NETDEV_TX));
2469 if (!has_rx && !has_tx)
2470 combine_disable = true;
2471
2472 ret = vsc85xx_led_combine_disable_set(phydev, index, combine_disable);
2473 if (ret < 0)
2474 return ret;
2475
2476 return vsc85xx_led_cntl_set(phydev, index, mode);
2477 }
2478
vsc8514_probe(struct phy_device * phydev)2479 static int vsc8514_probe(struct phy_device *phydev)
2480 {
2481 static const struct vsc85xx_probe_config vsc8514_cfg = {
2482 .nleds = 4,
2483 .supp_led_modes = VSC85XX_SUPP_LED_MODES,
2484 .hw_stats = vsc85xx_hw_stats,
2485 .nstats = ARRAY_SIZE(vsc85xx_hw_stats),
2486 .use_package = true,
2487 .shared_size = 0,
2488 .has_ptp = false,
2489 .check_rate_magic = false,
2490 };
2491
2492 return vsc85xx_probe_common(phydev, &vsc8514_cfg, vsc85xx_default_led_modes_4);
2493 }
2494
vsc8574_probe(struct phy_device * phydev)2495 static int vsc8574_probe(struct phy_device *phydev)
2496 {
2497 static const struct vsc85xx_probe_config vsc8574_cfg = {
2498 .nleds = 4,
2499 .supp_led_modes = VSC8584_SUPP_LED_MODES,
2500 .hw_stats = vsc8584_hw_stats,
2501 .nstats = ARRAY_SIZE(vsc8584_hw_stats),
2502 .use_package = true,
2503 .shared_size = 0,
2504 .has_ptp = false,
2505 .check_rate_magic = false,
2506 };
2507
2508 return vsc85xx_probe_common(phydev, &vsc8574_cfg, vsc85xx_default_led_modes_4);
2509 }
2510
vsc8584_probe(struct phy_device * phydev)2511 static int vsc8584_probe(struct phy_device *phydev)
2512 {
2513 static const struct vsc85xx_probe_config vsc8584_cfg = {
2514 .nleds = 4,
2515 .supp_led_modes = VSC8584_SUPP_LED_MODES,
2516 .hw_stats = vsc8584_hw_stats,
2517 .nstats = ARRAY_SIZE(vsc8584_hw_stats),
2518 .use_package = true,
2519 .shared_size = sizeof(struct vsc85xx_shared_private),
2520 .has_ptp = true,
2521 .check_rate_magic = false,
2522 };
2523
2524 return vsc85xx_probe_common(phydev, &vsc8584_cfg, vsc85xx_default_led_modes_4);
2525 }
2526
vsc85xx_probe(struct phy_device * phydev)2527 static int vsc85xx_probe(struct phy_device *phydev)
2528 {
2529 static const struct vsc85xx_probe_config vsc85xx_cfg = {
2530 .nleds = 2,
2531 .supp_led_modes = VSC85XX_SUPP_LED_MODES,
2532 .hw_stats = vsc85xx_hw_stats,
2533 .nstats = ARRAY_SIZE(vsc85xx_hw_stats),
2534 .use_package = false,
2535 .has_ptp = false,
2536 .check_rate_magic = true,
2537 };
2538
2539 return vsc85xx_probe_common(phydev, &vsc85xx_cfg, vsc85xx_default_led_modes_4);
2540 }
2541
vsc85xx_remove(struct phy_device * phydev)2542 static void vsc85xx_remove(struct phy_device *phydev)
2543 {
2544 vsc8584_ptp_deinit(phydev);
2545 }
2546
2547 /* Microsemi VSC85xx PHYs */
2548 static struct phy_driver vsc85xx_driver[] = {
2549 {
2550 .phy_id = PHY_ID_VSC8501,
2551 .name = "Microsemi GE VSC8501 SyncE",
2552 .phy_id_mask = 0xfffffff0,
2553 /* PHY_BASIC_FEATURES */
2554 .soft_reset = &genphy_soft_reset,
2555 .config_init = &vsc85xx_config_init,
2556 .config_aneg = &vsc85xx_config_aneg,
2557 .read_status = &vsc85xx_read_status,
2558 .handle_interrupt = vsc85xx_handle_interrupt,
2559 .config_intr = &vsc85xx_config_intr,
2560 .suspend = &genphy_suspend,
2561 .resume = &genphy_resume,
2562 .probe = &vsc85xx_probe,
2563 .set_wol = &vsc85xx_wol_set,
2564 .get_wol = &vsc85xx_wol_get,
2565 .get_tunable = &vsc85xx_get_tunable,
2566 .set_tunable = &vsc85xx_set_tunable,
2567 .read_page = &vsc85xx_phy_read_page,
2568 .write_page = &vsc85xx_phy_write_page,
2569 .get_sset_count = &vsc85xx_get_sset_count,
2570 .get_strings = &vsc85xx_get_strings,
2571 .get_stats = &vsc85xx_get_stats,
2572 .led_brightness_set = vsc85xx_led_brightness_set,
2573 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2574 .led_hw_control_get = vsc85xx_led_hw_control_get,
2575 .led_hw_control_set = vsc85xx_led_hw_control_set,
2576 },
2577 {
2578 .phy_id = PHY_ID_VSC8502,
2579 .name = "Microsemi GE VSC8502 SyncE",
2580 .phy_id_mask = 0xfffffff0,
2581 /* PHY_BASIC_FEATURES */
2582 .soft_reset = &genphy_soft_reset,
2583 .config_init = &vsc85xx_config_init,
2584 .config_aneg = &vsc85xx_config_aneg,
2585 .read_status = &vsc85xx_read_status,
2586 .handle_interrupt = vsc85xx_handle_interrupt,
2587 .config_intr = &vsc85xx_config_intr,
2588 .suspend = &genphy_suspend,
2589 .resume = &genphy_resume,
2590 .probe = &vsc85xx_probe,
2591 .set_wol = &vsc85xx_wol_set,
2592 .get_wol = &vsc85xx_wol_get,
2593 .get_tunable = &vsc85xx_get_tunable,
2594 .set_tunable = &vsc85xx_set_tunable,
2595 .read_page = &vsc85xx_phy_read_page,
2596 .write_page = &vsc85xx_phy_write_page,
2597 .get_sset_count = &vsc85xx_get_sset_count,
2598 .get_strings = &vsc85xx_get_strings,
2599 .get_stats = &vsc85xx_get_stats,
2600 .led_brightness_set = vsc85xx_led_brightness_set,
2601 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2602 .led_hw_control_get = vsc85xx_led_hw_control_get,
2603 .led_hw_control_set = vsc85xx_led_hw_control_set,
2604 },
2605 {
2606 .phy_id = PHY_ID_VSC8504,
2607 .name = "Microsemi GE VSC8504 SyncE",
2608 .phy_id_mask = 0xfffffff0,
2609 /* PHY_GBIT_FEATURES */
2610 .soft_reset = &genphy_soft_reset,
2611 .config_init = &vsc8584_config_init,
2612 .config_aneg = &vsc85xx_config_aneg,
2613 .aneg_done = &genphy_aneg_done,
2614 .read_status = &vsc85xx_read_status,
2615 .handle_interrupt = vsc85xx_handle_interrupt,
2616 .config_intr = &vsc85xx_config_intr,
2617 .suspend = &genphy_suspend,
2618 .resume = &genphy_resume,
2619 .probe = &vsc8574_probe,
2620 .set_wol = &vsc85xx_wol_set,
2621 .get_wol = &vsc85xx_wol_get,
2622 .get_tunable = &vsc85xx_get_tunable,
2623 .set_tunable = &vsc85xx_set_tunable,
2624 .read_page = &vsc85xx_phy_read_page,
2625 .write_page = &vsc85xx_phy_write_page,
2626 .get_sset_count = &vsc85xx_get_sset_count,
2627 .get_strings = &vsc85xx_get_strings,
2628 .get_stats = &vsc85xx_get_stats,
2629 .inband_caps = vsc85xx_inband_caps,
2630 .config_inband = vsc85xx_config_inband,
2631 .led_brightness_set = vsc85xx_led_brightness_set,
2632 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2633 .led_hw_control_get = vsc85xx_led_hw_control_get,
2634 .led_hw_control_set = vsc85xx_led_hw_control_set,
2635 },
2636 {
2637 .phy_id = PHY_ID_VSC8514,
2638 .name = "Microsemi GE VSC8514 SyncE",
2639 .phy_id_mask = 0xfffffff0,
2640 .soft_reset = &genphy_soft_reset,
2641 .config_init = &vsc8514_config_init,
2642 .config_aneg = &vsc85xx_config_aneg,
2643 .read_status = &vsc85xx_read_status,
2644 .handle_interrupt = vsc85xx_handle_interrupt,
2645 .config_intr = &vsc85xx_config_intr,
2646 .suspend = &genphy_suspend,
2647 .resume = &genphy_resume,
2648 .probe = &vsc8514_probe,
2649 .set_wol = &vsc85xx_wol_set,
2650 .get_wol = &vsc85xx_wol_get,
2651 .get_tunable = &vsc85xx_get_tunable,
2652 .set_tunable = &vsc85xx_set_tunable,
2653 .read_page = &vsc85xx_phy_read_page,
2654 .write_page = &vsc85xx_phy_write_page,
2655 .get_sset_count = &vsc85xx_get_sset_count,
2656 .get_strings = &vsc85xx_get_strings,
2657 .get_stats = &vsc85xx_get_stats,
2658 .inband_caps = vsc85xx_inband_caps,
2659 .config_inband = vsc85xx_config_inband,
2660 .led_brightness_set = vsc85xx_led_brightness_set,
2661 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2662 .led_hw_control_get = vsc85xx_led_hw_control_get,
2663 .led_hw_control_set = vsc85xx_led_hw_control_set,
2664 },
2665 {
2666 .phy_id = PHY_ID_VSC8530,
2667 .name = "Microsemi FE VSC8530",
2668 .phy_id_mask = 0xfffffff0,
2669 /* PHY_BASIC_FEATURES */
2670 .soft_reset = &genphy_soft_reset,
2671 .config_init = &vsc85xx_config_init,
2672 .config_aneg = &vsc85xx_config_aneg,
2673 .read_status = &vsc85xx_read_status,
2674 .handle_interrupt = vsc85xx_handle_interrupt,
2675 .config_intr = &vsc85xx_config_intr,
2676 .suspend = &genphy_suspend,
2677 .resume = &genphy_resume,
2678 .probe = &vsc85xx_probe,
2679 .set_wol = &vsc85xx_wol_set,
2680 .get_wol = &vsc85xx_wol_get,
2681 .get_tunable = &vsc85xx_get_tunable,
2682 .set_tunable = &vsc85xx_set_tunable,
2683 .read_page = &vsc85xx_phy_read_page,
2684 .write_page = &vsc85xx_phy_write_page,
2685 .get_sset_count = &vsc85xx_get_sset_count,
2686 .get_strings = &vsc85xx_get_strings,
2687 .get_stats = &vsc85xx_get_stats,
2688 .led_brightness_set = vsc85xx_led_brightness_set,
2689 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2690 .led_hw_control_get = vsc85xx_led_hw_control_get,
2691 .led_hw_control_set = vsc85xx_led_hw_control_set,
2692 },
2693 {
2694 .phy_id = PHY_ID_VSC8531,
2695 .name = "Microsemi VSC8531",
2696 .phy_id_mask = 0xfffffff0,
2697 /* PHY_GBIT_FEATURES */
2698 .soft_reset = &genphy_soft_reset,
2699 .config_init = &vsc85xx_config_init,
2700 .config_aneg = &vsc85xx_config_aneg,
2701 .read_status = &vsc85xx_read_status,
2702 .handle_interrupt = vsc85xx_handle_interrupt,
2703 .config_intr = &vsc85xx_config_intr,
2704 .suspend = &genphy_suspend,
2705 .resume = &genphy_resume,
2706 .probe = &vsc85xx_probe,
2707 .set_wol = &vsc85xx_wol_set,
2708 .get_wol = &vsc85xx_wol_get,
2709 .get_tunable = &vsc85xx_get_tunable,
2710 .set_tunable = &vsc85xx_set_tunable,
2711 .read_page = &vsc85xx_phy_read_page,
2712 .write_page = &vsc85xx_phy_write_page,
2713 .get_sset_count = &vsc85xx_get_sset_count,
2714 .get_strings = &vsc85xx_get_strings,
2715 .get_stats = &vsc85xx_get_stats,
2716 .led_brightness_set = vsc85xx_led_brightness_set,
2717 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2718 .led_hw_control_get = vsc85xx_led_hw_control_get,
2719 .led_hw_control_set = vsc85xx_led_hw_control_set,
2720 },
2721 {
2722 .phy_id = PHY_ID_VSC8540,
2723 .name = "Microsemi FE VSC8540 SyncE",
2724 .phy_id_mask = 0xfffffff0,
2725 /* PHY_BASIC_FEATURES */
2726 .soft_reset = &genphy_soft_reset,
2727 .config_init = &vsc85xx_config_init,
2728 .config_aneg = &vsc85xx_config_aneg,
2729 .read_status = &vsc85xx_read_status,
2730 .handle_interrupt = vsc85xx_handle_interrupt,
2731 .config_intr = &vsc85xx_config_intr,
2732 .suspend = &genphy_suspend,
2733 .resume = &genphy_resume,
2734 .probe = &vsc85xx_probe,
2735 .set_wol = &vsc85xx_wol_set,
2736 .get_wol = &vsc85xx_wol_get,
2737 .get_tunable = &vsc85xx_get_tunable,
2738 .set_tunable = &vsc85xx_set_tunable,
2739 .read_page = &vsc85xx_phy_read_page,
2740 .write_page = &vsc85xx_phy_write_page,
2741 .get_sset_count = &vsc85xx_get_sset_count,
2742 .get_strings = &vsc85xx_get_strings,
2743 .get_stats = &vsc85xx_get_stats,
2744 .led_brightness_set = vsc85xx_led_brightness_set,
2745 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2746 .led_hw_control_get = vsc85xx_led_hw_control_get,
2747 .led_hw_control_set = vsc85xx_led_hw_control_set,
2748 },
2749 {
2750 .phy_id = PHY_ID_VSC8541,
2751 .name = "Microsemi VSC8541 SyncE",
2752 .phy_id_mask = 0xfffffff0,
2753 /* PHY_GBIT_FEATURES */
2754 .soft_reset = &genphy_soft_reset,
2755 .config_init = &vsc85xx_config_init,
2756 .config_aneg = &vsc85xx_config_aneg,
2757 .read_status = &vsc85xx_read_status,
2758 .handle_interrupt = vsc85xx_handle_interrupt,
2759 .config_intr = &vsc85xx_config_intr,
2760 .suspend = &genphy_suspend,
2761 .resume = &genphy_resume,
2762 .probe = &vsc85xx_probe,
2763 .set_wol = &vsc85xx_wol_set,
2764 .get_wol = &vsc85xx_wol_get,
2765 .get_tunable = &vsc85xx_get_tunable,
2766 .set_tunable = &vsc85xx_set_tunable,
2767 .read_page = &vsc85xx_phy_read_page,
2768 .write_page = &vsc85xx_phy_write_page,
2769 .get_sset_count = &vsc85xx_get_sset_count,
2770 .get_strings = &vsc85xx_get_strings,
2771 .get_stats = &vsc85xx_get_stats,
2772 .led_brightness_set = vsc85xx_led_brightness_set,
2773 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2774 .led_hw_control_get = vsc85xx_led_hw_control_get,
2775 .led_hw_control_set = vsc85xx_led_hw_control_set,
2776 },
2777 {
2778 .phy_id = PHY_ID_VSC8552,
2779 .name = "Microsemi GE VSC8552 SyncE",
2780 .phy_id_mask = 0xfffffff0,
2781 /* PHY_GBIT_FEATURES */
2782 .soft_reset = &genphy_soft_reset,
2783 .config_init = &vsc8584_config_init,
2784 .config_aneg = &vsc85xx_config_aneg,
2785 .read_status = &vsc85xx_read_status,
2786 .handle_interrupt = vsc85xx_handle_interrupt,
2787 .config_intr = &vsc85xx_config_intr,
2788 .suspend = &genphy_suspend,
2789 .resume = &genphy_resume,
2790 .probe = &vsc8574_probe,
2791 .set_wol = &vsc85xx_wol_set,
2792 .get_wol = &vsc85xx_wol_get,
2793 .get_tunable = &vsc85xx_get_tunable,
2794 .set_tunable = &vsc85xx_set_tunable,
2795 .read_page = &vsc85xx_phy_read_page,
2796 .write_page = &vsc85xx_phy_write_page,
2797 .get_sset_count = &vsc85xx_get_sset_count,
2798 .get_strings = &vsc85xx_get_strings,
2799 .get_stats = &vsc85xx_get_stats,
2800 .inband_caps = vsc85xx_inband_caps,
2801 .config_inband = vsc85xx_config_inband,
2802 .led_brightness_set = vsc85xx_led_brightness_set,
2803 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2804 .led_hw_control_get = vsc85xx_led_hw_control_get,
2805 .led_hw_control_set = vsc85xx_led_hw_control_set,
2806 },
2807 {
2808 PHY_ID_MATCH_EXACT(PHY_ID_VSC856X),
2809 .name = "Microsemi GE VSC856X SyncE",
2810 /* PHY_GBIT_FEATURES */
2811 .soft_reset = &genphy_soft_reset,
2812 .config_init = &vsc8584_config_init,
2813 .config_aneg = &vsc85xx_config_aneg,
2814 .read_status = &vsc85xx_read_status,
2815 .handle_interrupt = vsc85xx_handle_interrupt,
2816 .config_intr = &vsc85xx_config_intr,
2817 .suspend = &genphy_suspend,
2818 .resume = &genphy_resume,
2819 .probe = &vsc8584_probe,
2820 .get_tunable = &vsc85xx_get_tunable,
2821 .set_tunable = &vsc85xx_set_tunable,
2822 .read_page = &vsc85xx_phy_read_page,
2823 .write_page = &vsc85xx_phy_write_page,
2824 .get_sset_count = &vsc85xx_get_sset_count,
2825 .get_strings = &vsc85xx_get_strings,
2826 .get_stats = &vsc85xx_get_stats,
2827 .inband_caps = vsc85xx_inband_caps,
2828 .config_inband = vsc85xx_config_inband,
2829 .led_brightness_set = vsc85xx_led_brightness_set,
2830 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2831 .led_hw_control_get = vsc85xx_led_hw_control_get,
2832 .led_hw_control_set = vsc85xx_led_hw_control_set,
2833 },
2834 {
2835 .phy_id = PHY_ID_VSC8572,
2836 .name = "Microsemi GE VSC8572 SyncE",
2837 .phy_id_mask = 0xfffffff0,
2838 /* PHY_GBIT_FEATURES */
2839 .soft_reset = &genphy_soft_reset,
2840 .config_init = &vsc8584_config_init,
2841 .config_aneg = &vsc85xx_config_aneg,
2842 .aneg_done = &genphy_aneg_done,
2843 .read_status = &vsc85xx_read_status,
2844 .handle_interrupt = &vsc8584_handle_interrupt,
2845 .config_intr = &vsc85xx_config_intr,
2846 .suspend = &genphy_suspend,
2847 .resume = &genphy_resume,
2848 .remove = &vsc85xx_remove,
2849 .probe = &vsc8584_probe,
2850 .set_wol = &vsc85xx_wol_set,
2851 .get_wol = &vsc85xx_wol_get,
2852 .get_tunable = &vsc85xx_get_tunable,
2853 .set_tunable = &vsc85xx_set_tunable,
2854 .read_page = &vsc85xx_phy_read_page,
2855 .write_page = &vsc85xx_phy_write_page,
2856 .get_sset_count = &vsc85xx_get_sset_count,
2857 .get_strings = &vsc85xx_get_strings,
2858 .get_stats = &vsc85xx_get_stats,
2859 .inband_caps = vsc85xx_inband_caps,
2860 .config_inband = vsc85xx_config_inband,
2861 .led_brightness_set = vsc85xx_led_brightness_set,
2862 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2863 .led_hw_control_get = vsc85xx_led_hw_control_get,
2864 .led_hw_control_set = vsc85xx_led_hw_control_set,
2865 },
2866 {
2867 .phy_id = PHY_ID_VSC8574,
2868 .name = "Microsemi GE VSC8574 SyncE",
2869 .phy_id_mask = 0xfffffff0,
2870 /* PHY_GBIT_FEATURES */
2871 .soft_reset = &genphy_soft_reset,
2872 .config_init = &vsc8584_config_init,
2873 .config_aneg = &vsc85xx_config_aneg,
2874 .aneg_done = &genphy_aneg_done,
2875 .read_status = &vsc85xx_read_status,
2876 .handle_interrupt = vsc8584_handle_interrupt,
2877 .config_intr = &vsc85xx_config_intr,
2878 .suspend = &genphy_suspend,
2879 .resume = &genphy_resume,
2880 .remove = &vsc85xx_remove,
2881 .probe = &vsc8584_probe,
2882 .set_wol = &vsc85xx_wol_set,
2883 .get_wol = &vsc85xx_wol_get,
2884 .get_tunable = &vsc85xx_get_tunable,
2885 .set_tunable = &vsc85xx_set_tunable,
2886 .read_page = &vsc85xx_phy_read_page,
2887 .write_page = &vsc85xx_phy_write_page,
2888 .get_sset_count = &vsc85xx_get_sset_count,
2889 .get_strings = &vsc85xx_get_strings,
2890 .get_stats = &vsc85xx_get_stats,
2891 .inband_caps = vsc85xx_inband_caps,
2892 .config_inband = vsc85xx_config_inband,
2893 .led_brightness_set = vsc85xx_led_brightness_set,
2894 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2895 .led_hw_control_get = vsc85xx_led_hw_control_get,
2896 .led_hw_control_set = vsc85xx_led_hw_control_set,
2897 },
2898 {
2899 PHY_ID_MATCH_EXACT(PHY_ID_VSC8575),
2900 .name = "Microsemi GE VSC8575 SyncE",
2901 /* PHY_GBIT_FEATURES */
2902 .soft_reset = &genphy_soft_reset,
2903 .config_init = &vsc8584_config_init,
2904 .config_aneg = &vsc85xx_config_aneg,
2905 .aneg_done = &genphy_aneg_done,
2906 .read_status = &vsc85xx_read_status,
2907 .handle_interrupt = &vsc8584_handle_interrupt,
2908 .config_intr = &vsc85xx_config_intr,
2909 .suspend = &genphy_suspend,
2910 .resume = &genphy_resume,
2911 .remove = &vsc85xx_remove,
2912 .probe = &vsc8584_probe,
2913 .get_tunable = &vsc85xx_get_tunable,
2914 .set_tunable = &vsc85xx_set_tunable,
2915 .read_page = &vsc85xx_phy_read_page,
2916 .write_page = &vsc85xx_phy_write_page,
2917 .get_sset_count = &vsc85xx_get_sset_count,
2918 .get_strings = &vsc85xx_get_strings,
2919 .get_stats = &vsc85xx_get_stats,
2920 .inband_caps = vsc85xx_inband_caps,
2921 .config_inband = vsc85xx_config_inband,
2922 .led_brightness_set = vsc85xx_led_brightness_set,
2923 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2924 .led_hw_control_get = vsc85xx_led_hw_control_get,
2925 .led_hw_control_set = vsc85xx_led_hw_control_set,
2926 },
2927 {
2928 PHY_ID_MATCH_EXACT(PHY_ID_VSC8582),
2929 .name = "Microsemi GE VSC8582 SyncE",
2930 /* PHY_GBIT_FEATURES */
2931 .soft_reset = &genphy_soft_reset,
2932 .config_init = &vsc8584_config_init,
2933 .config_aneg = &vsc85xx_config_aneg,
2934 .aneg_done = &genphy_aneg_done,
2935 .read_status = &vsc85xx_read_status,
2936 .handle_interrupt = &vsc8584_handle_interrupt,
2937 .config_intr = &vsc85xx_config_intr,
2938 .suspend = &genphy_suspend,
2939 .resume = &genphy_resume,
2940 .remove = &vsc85xx_remove,
2941 .probe = &vsc8584_probe,
2942 .get_tunable = &vsc85xx_get_tunable,
2943 .set_tunable = &vsc85xx_set_tunable,
2944 .read_page = &vsc85xx_phy_read_page,
2945 .write_page = &vsc85xx_phy_write_page,
2946 .get_sset_count = &vsc85xx_get_sset_count,
2947 .get_strings = &vsc85xx_get_strings,
2948 .get_stats = &vsc85xx_get_stats,
2949 .inband_caps = vsc85xx_inband_caps,
2950 .config_inband = vsc85xx_config_inband,
2951 .led_brightness_set = vsc85xx_led_brightness_set,
2952 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2953 .led_hw_control_get = vsc85xx_led_hw_control_get,
2954 .led_hw_control_set = vsc85xx_led_hw_control_set,
2955 },
2956 {
2957 PHY_ID_MATCH_EXACT(PHY_ID_VSC8584),
2958 .name = "Microsemi GE VSC8584 SyncE",
2959 /* PHY_GBIT_FEATURES */
2960 .soft_reset = &genphy_soft_reset,
2961 .config_init = &vsc8584_config_init,
2962 .config_aneg = &vsc85xx_config_aneg,
2963 .aneg_done = &genphy_aneg_done,
2964 .read_status = &vsc85xx_read_status,
2965 .handle_interrupt = &vsc8584_handle_interrupt,
2966 .config_intr = &vsc85xx_config_intr,
2967 .suspend = &genphy_suspend,
2968 .resume = &genphy_resume,
2969 .remove = &vsc85xx_remove,
2970 .probe = &vsc8584_probe,
2971 .get_tunable = &vsc85xx_get_tunable,
2972 .set_tunable = &vsc85xx_set_tunable,
2973 .read_page = &vsc85xx_phy_read_page,
2974 .write_page = &vsc85xx_phy_write_page,
2975 .get_sset_count = &vsc85xx_get_sset_count,
2976 .get_strings = &vsc85xx_get_strings,
2977 .get_stats = &vsc85xx_get_stats,
2978 .link_change_notify = &vsc85xx_link_change_notify,
2979 .inband_caps = vsc85xx_inband_caps,
2980 .config_inband = vsc85xx_config_inband,
2981 .led_brightness_set = vsc85xx_led_brightness_set,
2982 .led_hw_is_supported = vsc85xx_led_hw_is_supported,
2983 .led_hw_control_get = vsc85xx_led_hw_control_get,
2984 .led_hw_control_set = vsc85xx_led_hw_control_set,
2985 }
2986
2987 };
2988
2989 module_phy_driver(vsc85xx_driver);
2990
2991 static const struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
2992 { PHY_ID_MATCH_VENDOR(PHY_VENDOR_MSCC) },
2993 { }
2994 };
2995
2996 MODULE_DEVICE_TABLE(mdio, vsc85xx_tbl);
2997
2998 MODULE_DESCRIPTION("Microsemi VSC85xx PHY driver");
2999 MODULE_AUTHOR("Nagaraju Lakkaraju");
3000 MODULE_LICENSE("Dual MIT/GPL");
3001
3002 MODULE_FIRMWARE(MSCC_VSC8584_REVB_INT8051_FW);
3003 MODULE_FIRMWARE(MSCC_VSC8574_REVB_INT8051_FW);
3004