1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
3 * Driver for Microsemi VSC85xx PHYs
5 * Author: Nagaraju Lakkaraju
6 * License: Dual MIT/GPL
7 * Copyright (c) 2016 Microsemi Corporation
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>
18 #include <linux/netdevice.h>
19 #include <dt-bindings/net/mscc-phy-vsc8531.h>
21 #include "mscc_macsec.h"
23 #include "mscc_fc_buffer.h"
25 enum rgmii_rx_clock_delay {
26 RGMII_RX_CLK_DELAY_0_2_NS = 0,
27 RGMII_RX_CLK_DELAY_0_8_NS = 1,
28 RGMII_RX_CLK_DELAY_1_1_NS = 2,
29 RGMII_RX_CLK_DELAY_1_7_NS = 3,
30 RGMII_RX_CLK_DELAY_2_0_NS = 4,
31 RGMII_RX_CLK_DELAY_2_3_NS = 5,
32 RGMII_RX_CLK_DELAY_2_6_NS = 6,
33 RGMII_RX_CLK_DELAY_3_4_NS = 7
36 /* Microsemi VSC85xx PHY registers */
37 /* IEEE 802. Std Registers */
38 #define MSCC_PHY_BYPASS_CONTROL 18
39 #define DISABLE_HP_AUTO_MDIX_MASK 0x0080
40 #define DISABLE_PAIR_SWAP_CORR_MASK 0x0020
41 #define DISABLE_POLARITY_CORR_MASK 0x0010
42 #define PARALLEL_DET_IGNORE_ADVERTISED 0x0008
44 #define MSCC_PHY_EXT_CNTL_STATUS 22
45 #define SMI_BROADCAST_WR_EN 0x0001
47 #define MSCC_PHY_ERR_RX_CNT 19
48 #define MSCC_PHY_ERR_FALSE_CARRIER_CNT 20
49 #define MSCC_PHY_ERR_LINK_DISCONNECT_CNT 21
50 #define ERR_CNT_MASK GENMASK(7, 0)
52 #define MSCC_PHY_EXT_PHY_CNTL_1 23
53 #define MAC_IF_SELECTION_MASK 0x1800
54 #define MAC_IF_SELECTION_GMII 0
55 #define MAC_IF_SELECTION_RMII 1
56 #define MAC_IF_SELECTION_RGMII 2
57 #define MAC_IF_SELECTION_POS 11
58 #define VSC8584_MAC_IF_SELECTION_MASK 0x1000
59 #define VSC8584_MAC_IF_SELECTION_SGMII 0
60 #define VSC8584_MAC_IF_SELECTION_1000BASEX 1
61 #define VSC8584_MAC_IF_SELECTION_POS 12
62 #define FAR_END_LOOPBACK_MODE_MASK 0x0008
63 #define MEDIA_OP_MODE_MASK 0x0700
64 #define MEDIA_OP_MODE_COPPER 0
65 #define MEDIA_OP_MODE_SERDES 1
66 #define MEDIA_OP_MODE_1000BASEX 2
67 #define MEDIA_OP_MODE_100BASEFX 3
68 #define MEDIA_OP_MODE_AMS_COPPER_SERDES 5
69 #define MEDIA_OP_MODE_AMS_COPPER_1000BASEX 6
70 #define MEDIA_OP_MODE_AMS_COPPER_100BASEFX 7
71 #define MEDIA_OP_MODE_POS 8
73 #define MSCC_PHY_EXT_PHY_CNTL_2 24
75 #define MII_VSC85XX_INT_MASK 25
76 #define MII_VSC85XX_INT_MASK_MASK 0xa000
77 #define MII_VSC85XX_INT_MASK_WOL 0x0040
78 #define MII_VSC85XX_INT_STATUS 26
80 #define MSCC_PHY_WOL_MAC_CONTROL 27
81 #define EDGE_RATE_CNTL_POS 5
82 #define EDGE_RATE_CNTL_MASK 0x00E0
84 #define MSCC_PHY_DEV_AUX_CNTL 28
85 #define HP_AUTO_MDIX_X_OVER_IND_MASK 0x2000
87 #define MSCC_PHY_LED_MODE_SEL 29
88 #define LED_MODE_SEL_POS(x) ((x) * 4)
89 #define LED_MODE_SEL_MASK(x) (GENMASK(3, 0) << LED_MODE_SEL_POS(x))
90 #define LED_MODE_SEL(x, mode) (((mode) << LED_MODE_SEL_POS(x)) & LED_MODE_SEL_MASK(x))
92 #define MSCC_EXT_PAGE_CSR_CNTL_17 17
93 #define MSCC_EXT_PAGE_CSR_CNTL_18 18
95 #define MSCC_EXT_PAGE_CSR_CNTL_19 19
96 #define MSCC_PHY_CSR_CNTL_19_REG_ADDR(x) (x)
97 #define MSCC_PHY_CSR_CNTL_19_TARGET(x) ((x) << 12)
98 #define MSCC_PHY_CSR_CNTL_19_READ BIT(14)
99 #define MSCC_PHY_CSR_CNTL_19_CMD BIT(15)
101 #define MSCC_EXT_PAGE_CSR_CNTL_20 20
102 #define MSCC_PHY_CSR_CNTL_20_TARGET(x) (x)
104 #define PHY_MCB_TARGET 0x07
105 #define PHY_MCB_S6G_WRITE BIT(31)
106 #define PHY_MCB_S6G_READ BIT(30)
108 #define PHY_S6G_PLL5G_CFG0 0x06
109 #define PHY_S6G_LCPLL_CFG 0x11
110 #define PHY_S6G_PLL_CFG 0x2b
111 #define PHY_S6G_COMMON_CFG 0x2c
112 #define PHY_S6G_GPC_CFG 0x2e
113 #define PHY_S6G_MISC_CFG 0x3b
114 #define PHY_MCB_S6G_CFG 0x3f
115 #define PHY_S6G_DFT_CFG2 0x3e
116 #define PHY_S6G_PLL_STATUS 0x31
117 #define PHY_S6G_IB_STATUS0 0x2f
119 #define PHY_S6G_SYS_RST_POS 31
120 #define PHY_S6G_ENA_LANE_POS 18
121 #define PHY_S6G_ENA_LOOP_POS 8
122 #define PHY_S6G_QRATE_POS 6
123 #define PHY_S6G_IF_MODE_POS 4
124 #define PHY_S6G_PLL_ENA_OFFS_POS 21
125 #define PHY_S6G_PLL_FSM_CTRL_DATA_POS 8
126 #define PHY_S6G_PLL_FSM_ENA_POS 7
128 #define MSCC_EXT_PAGE_MACSEC_17 17
129 #define MSCC_EXT_PAGE_MACSEC_18 18
131 #define MSCC_EXT_PAGE_MACSEC_19 19
132 #define MSCC_PHY_MACSEC_19_REG_ADDR(x) (x)
133 #define MSCC_PHY_MACSEC_19_TARGET(x) ((x) << 12)
134 #define MSCC_PHY_MACSEC_19_READ BIT(14)
135 #define MSCC_PHY_MACSEC_19_CMD BIT(15)
137 #define MSCC_EXT_PAGE_MACSEC_20 20
138 #define MSCC_PHY_MACSEC_20_TARGET(x) (x)
148 #define MSCC_EXT_PAGE_ACCESS 31
149 #define MSCC_PHY_PAGE_STANDARD 0x0000 /* Standard registers */
150 #define MSCC_PHY_PAGE_EXTENDED 0x0001 /* Extended registers */
151 #define MSCC_PHY_PAGE_EXTENDED_2 0x0002 /* Extended reg - page 2 */
152 #define MSCC_PHY_PAGE_EXTENDED_3 0x0003 /* Extended reg - page 3 */
153 #define MSCC_PHY_PAGE_EXTENDED_4 0x0004 /* Extended reg - page 4 */
154 #define MSCC_PHY_PAGE_CSR_CNTL MSCC_PHY_PAGE_EXTENDED_4
155 #define MSCC_PHY_PAGE_MACSEC MSCC_PHY_PAGE_EXTENDED_4
156 /* Extended reg - GPIO; this is a bank of registers that are shared for all PHYs
157 * in the same package.
159 #define MSCC_PHY_PAGE_EXTENDED_GPIO 0x0010 /* Extended reg - GPIO */
160 #define MSCC_PHY_PAGE_TEST 0x2a30 /* Test reg */
161 #define MSCC_PHY_PAGE_TR 0x52b5 /* Token ring registers */
163 /* Extended Page 1 Registers */
164 #define MSCC_PHY_CU_MEDIA_CRC_VALID_CNT 18
165 #define VALID_CRC_CNT_CRC_MASK GENMASK(13, 0)
167 #define MSCC_PHY_EXT_MODE_CNTL 19
168 #define FORCE_MDI_CROSSOVER_MASK 0x000C
169 #define FORCE_MDI_CROSSOVER_MDIX 0x000C
170 #define FORCE_MDI_CROSSOVER_MDI 0x0008
172 #define MSCC_PHY_ACTIPHY_CNTL 20
173 #define PHY_ADDR_REVERSED 0x0200
174 #define DOWNSHIFT_CNTL_MASK 0x001C
175 #define DOWNSHIFT_EN 0x0010
176 #define DOWNSHIFT_CNTL_POS 2
178 #define MSCC_PHY_EXT_PHY_CNTL_4 23
179 #define PHY_CNTL_4_ADDR_POS 11
181 #define MSCC_PHY_VERIPHY_CNTL_2 25
183 #define MSCC_PHY_VERIPHY_CNTL_3 26
185 /* Extended Page 2 Registers */
186 #define MSCC_PHY_CU_PMD_TX_CNTL 16
188 #define MSCC_PHY_RGMII_CNTL 20
189 #define RGMII_RX_CLK_DELAY_MASK 0x0070
190 #define RGMII_RX_CLK_DELAY_POS 4
192 #define MSCC_PHY_WOL_LOWER_MAC_ADDR 21
193 #define MSCC_PHY_WOL_MID_MAC_ADDR 22
194 #define MSCC_PHY_WOL_UPPER_MAC_ADDR 23
195 #define MSCC_PHY_WOL_LOWER_PASSWD 24
196 #define MSCC_PHY_WOL_MID_PASSWD 25
197 #define MSCC_PHY_WOL_UPPER_PASSWD 26
199 #define MSCC_PHY_WOL_MAC_CONTROL 27
200 #define SECURE_ON_ENABLE 0x8000
201 #define SECURE_ON_PASSWD_LEN_4 0x4000
203 /* Extended Page 3 Registers */
204 #define MSCC_PHY_SERDES_TX_VALID_CNT 21
205 #define MSCC_PHY_SERDES_TX_CRC_ERR_CNT 22
206 #define MSCC_PHY_SERDES_RX_VALID_CNT 28
207 #define MSCC_PHY_SERDES_RX_CRC_ERR_CNT 29
209 /* Extended page GPIO Registers */
210 #define MSCC_DW8051_CNTL_STATUS 0
211 #define MICRO_NSOFT_RESET 0x8000
212 #define RUN_FROM_INT_ROM 0x4000
213 #define AUTOINC_ADDR 0x2000
214 #define PATCH_RAM_CLK 0x1000
215 #define MICRO_PATCH_EN 0x0080
216 #define DW8051_CLK_EN 0x0010
217 #define MICRO_CLK_EN 0x0008
218 #define MICRO_CLK_DIVIDE(x) ((x) >> 1)
219 #define MSCC_DW8051_VLD_MASK 0xf1ff
221 /* x Address in range 1-4 */
222 #define MSCC_TRAP_ROM_ADDR(x) ((x) * 2 + 1)
223 #define MSCC_PATCH_RAM_ADDR(x) (((x) + 1) * 2)
224 #define MSCC_INT_MEM_ADDR 11
226 #define MSCC_INT_MEM_CNTL 12
227 #define READ_SFR 0x6000
228 #define READ_PRAM 0x4000
229 #define READ_ROM 0x2000
230 #define READ_RAM 0x0000
231 #define INT_MEM_WRITE_EN 0x1000
232 #define EN_PATCH_RAM_TRAP_ADDR(x) (0x0100 << ((x) - 1))
233 #define INT_MEM_DATA_M 0x00ff
234 #define INT_MEM_DATA(x) (INT_MEM_DATA_M & (x))
236 #define MSCC_PHY_PROC_CMD 18
237 #define PROC_CMD_NCOMPLETED 0x8000
238 #define PROC_CMD_FAILED 0x4000
239 #define PROC_CMD_SGMII_PORT(x) ((x) << 8)
240 #define PROC_CMD_FIBER_PORT(x) (0x0100 << (x) % 4)
241 #define PROC_CMD_QSGMII_PORT 0x0c00
242 #define PROC_CMD_RST_CONF_PORT 0x0080
243 #define PROC_CMD_RECONF_PORT 0x0000
244 #define PROC_CMD_READ_MOD_WRITE_PORT 0x0040
245 #define PROC_CMD_WRITE 0x0040
246 #define PROC_CMD_READ 0x0000
247 #define PROC_CMD_FIBER_DISABLE 0x0020
248 #define PROC_CMD_FIBER_100BASE_FX 0x0010
249 #define PROC_CMD_FIBER_1000BASE_X 0x0000
250 #define PROC_CMD_SGMII_MAC 0x0030
251 #define PROC_CMD_QSGMII_MAC 0x0020
252 #define PROC_CMD_NO_MAC_CONF 0x0000
253 #define PROC_CMD_1588_DEFAULT_INIT 0x0010
254 #define PROC_CMD_NOP 0x000f
255 #define PROC_CMD_PHY_INIT 0x000a
256 #define PROC_CMD_CRC16 0x0008
257 #define PROC_CMD_FIBER_MEDIA_CONF 0x0001
258 #define PROC_CMD_MCB_ACCESS_MAC_CONF 0x0000
259 #define PROC_CMD_NCOMPLETED_TIMEOUT_MS 500
261 #define MSCC_PHY_MAC_CFG_FASTLINK 19
262 #define MAC_CFG_MASK 0xc000
263 #define MAC_CFG_SGMII 0x0000
264 #define MAC_CFG_QSGMII 0x4000
266 /* Test page Registers */
267 #define MSCC_PHY_TEST_PAGE_5 5
268 #define MSCC_PHY_TEST_PAGE_8 8
269 #define MSCC_PHY_TEST_PAGE_9 9
270 #define MSCC_PHY_TEST_PAGE_20 20
271 #define MSCC_PHY_TEST_PAGE_24 24
273 /* Token ring page Registers */
274 #define MSCC_PHY_TR_CNTL 16
275 #define TR_WRITE 0x8000
276 #define TR_ADDR(x) (0x7fff & (x))
277 #define MSCC_PHY_TR_LSB 17
278 #define MSCC_PHY_TR_MSB 18
280 /* Microsemi PHY ID's
281 * Code assumes lowest nibble is 0
283 #define PHY_ID_VSC8504 0x000704c0
284 #define PHY_ID_VSC8514 0x00070670
285 #define PHY_ID_VSC8530 0x00070560
286 #define PHY_ID_VSC8531 0x00070570
287 #define PHY_ID_VSC8540 0x00070760
288 #define PHY_ID_VSC8541 0x00070770
289 #define PHY_ID_VSC8552 0x000704e0
290 #define PHY_ID_VSC856X 0x000707e0
291 #define PHY_ID_VSC8572 0x000704d0
292 #define PHY_ID_VSC8574 0x000704a0
293 #define PHY_ID_VSC8575 0x000707d0
294 #define PHY_ID_VSC8582 0x000707b0
295 #define PHY_ID_VSC8584 0x000707c0
297 #define MSCC_VDDMAC_1500 1500
298 #define MSCC_VDDMAC_1800 1800
299 #define MSCC_VDDMAC_2500 2500
300 #define MSCC_VDDMAC_3300 3300
302 #define DOWNSHIFT_COUNT_MAX 5
306 #define VSC8584_SUPP_LED_MODES (BIT(VSC8531_LINK_ACTIVITY) | \
307 BIT(VSC8531_LINK_1000_ACTIVITY) | \
308 BIT(VSC8531_LINK_100_ACTIVITY) | \
309 BIT(VSC8531_LINK_10_ACTIVITY) | \
310 BIT(VSC8531_LINK_100_1000_ACTIVITY) | \
311 BIT(VSC8531_LINK_10_1000_ACTIVITY) | \
312 BIT(VSC8531_LINK_10_100_ACTIVITY) | \
313 BIT(VSC8584_LINK_100FX_1000X_ACTIVITY) | \
314 BIT(VSC8531_DUPLEX_COLLISION) | \
315 BIT(VSC8531_COLLISION) | \
316 BIT(VSC8531_ACTIVITY) | \
317 BIT(VSC8584_100FX_1000X_ACTIVITY) | \
318 BIT(VSC8531_AUTONEG_FAULT) | \
319 BIT(VSC8531_SERIAL_MODE) | \
320 BIT(VSC8531_FORCE_LED_OFF) | \
321 BIT(VSC8531_FORCE_LED_ON))
323 #define VSC85XX_SUPP_LED_MODES (BIT(VSC8531_LINK_ACTIVITY) | \
324 BIT(VSC8531_LINK_1000_ACTIVITY) | \
325 BIT(VSC8531_LINK_100_ACTIVITY) | \
326 BIT(VSC8531_LINK_10_ACTIVITY) | \
327 BIT(VSC8531_LINK_100_1000_ACTIVITY) | \
328 BIT(VSC8531_LINK_10_1000_ACTIVITY) | \
329 BIT(VSC8531_LINK_10_100_ACTIVITY) | \
330 BIT(VSC8531_DUPLEX_COLLISION) | \
331 BIT(VSC8531_COLLISION) | \
332 BIT(VSC8531_ACTIVITY) | \
333 BIT(VSC8531_AUTONEG_FAULT) | \
334 BIT(VSC8531_SERIAL_MODE) | \
335 BIT(VSC8531_FORCE_LED_OFF) | \
336 BIT(VSC8531_FORCE_LED_ON))
338 #define MSCC_VSC8584_REVB_INT8051_FW "mscc_vsc8584_revb_int8051_fb48.bin"
339 #define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800
340 #define MSCC_VSC8584_REVB_INT8051_FW_CRC 0xfb48
342 #define MSCC_VSC8574_REVB_INT8051_FW "mscc_vsc8574_revb_int8051_29e8.bin"
343 #define MSCC_VSC8574_REVB_INT8051_FW_START_ADDR 0x4000
344 #define MSCC_VSC8574_REVB_INT8051_FW_CRC 0x29e8
346 #define VSC8584_REVB 0x0001
347 #define MSCC_DEV_REV_MASK GENMASK(3, 0)
354 struct vsc85xx_hw_stat {
361 static const struct vsc85xx_hw_stat vsc85xx_hw_stats[] = {
363 .string = "phy_receive_errors",
364 .reg = MSCC_PHY_ERR_RX_CNT,
365 .page = MSCC_PHY_PAGE_STANDARD,
366 .mask = ERR_CNT_MASK,
368 .string = "phy_false_carrier",
369 .reg = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
370 .page = MSCC_PHY_PAGE_STANDARD,
371 .mask = ERR_CNT_MASK,
373 .string = "phy_cu_media_link_disconnect",
374 .reg = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
375 .page = MSCC_PHY_PAGE_STANDARD,
376 .mask = ERR_CNT_MASK,
378 .string = "phy_cu_media_crc_good_count",
379 .reg = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
380 .page = MSCC_PHY_PAGE_EXTENDED,
381 .mask = VALID_CRC_CNT_CRC_MASK,
383 .string = "phy_cu_media_crc_error_count",
384 .reg = MSCC_PHY_EXT_PHY_CNTL_4,
385 .page = MSCC_PHY_PAGE_EXTENDED,
386 .mask = ERR_CNT_MASK,
390 static const struct vsc85xx_hw_stat vsc8584_hw_stats[] = {
392 .string = "phy_receive_errors",
393 .reg = MSCC_PHY_ERR_RX_CNT,
394 .page = MSCC_PHY_PAGE_STANDARD,
395 .mask = ERR_CNT_MASK,
397 .string = "phy_false_carrier",
398 .reg = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
399 .page = MSCC_PHY_PAGE_STANDARD,
400 .mask = ERR_CNT_MASK,
402 .string = "phy_cu_media_link_disconnect",
403 .reg = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
404 .page = MSCC_PHY_PAGE_STANDARD,
405 .mask = ERR_CNT_MASK,
407 .string = "phy_cu_media_crc_good_count",
408 .reg = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
409 .page = MSCC_PHY_PAGE_EXTENDED,
410 .mask = VALID_CRC_CNT_CRC_MASK,
412 .string = "phy_cu_media_crc_error_count",
413 .reg = MSCC_PHY_EXT_PHY_CNTL_4,
414 .page = MSCC_PHY_PAGE_EXTENDED,
415 .mask = ERR_CNT_MASK,
417 .string = "phy_serdes_tx_good_pkt_count",
418 .reg = MSCC_PHY_SERDES_TX_VALID_CNT,
419 .page = MSCC_PHY_PAGE_EXTENDED_3,
420 .mask = VALID_CRC_CNT_CRC_MASK,
422 .string = "phy_serdes_tx_bad_crc_count",
423 .reg = MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
424 .page = MSCC_PHY_PAGE_EXTENDED_3,
425 .mask = ERR_CNT_MASK,
427 .string = "phy_serdes_rx_good_pkt_count",
428 .reg = MSCC_PHY_SERDES_RX_VALID_CNT,
429 .page = MSCC_PHY_PAGE_EXTENDED_3,
430 .mask = VALID_CRC_CNT_CRC_MASK,
432 .string = "phy_serdes_rx_bad_crc_count",
433 .reg = MSCC_PHY_SERDES_RX_CRC_ERR_CNT,
434 .page = MSCC_PHY_PAGE_EXTENDED_3,
435 .mask = ERR_CNT_MASK,
439 struct vsc8531_private {
442 u32 leds_mode[MAX_LEDS];
444 const struct vsc85xx_hw_stat *hw_stats;
448 /* For multiple port PHYs; the MDIO address of the base PHY in the
451 unsigned int base_addr;
454 #ifdef CONFIG_OF_MDIO
455 struct vsc8531_edge_rate_table {
460 static const struct vsc8531_edge_rate_table edge_table[] = {
461 {MSCC_VDDMAC_3300, { 0, 2, 4, 7, 10, 17, 29, 53} },
462 {MSCC_VDDMAC_2500, { 0, 3, 6, 10, 14, 23, 37, 63} },
463 {MSCC_VDDMAC_1800, { 0, 5, 9, 16, 23, 35, 52, 76} },
464 {MSCC_VDDMAC_1500, { 0, 6, 14, 21, 29, 42, 58, 77} },
466 #endif /* CONFIG_OF_MDIO */
468 static int vsc85xx_phy_read_page(struct phy_device *phydev)
470 return __phy_read(phydev, MSCC_EXT_PAGE_ACCESS);
473 static int vsc85xx_phy_write_page(struct phy_device *phydev, int page)
475 return __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, page);
478 static int vsc85xx_get_sset_count(struct phy_device *phydev)
480 struct vsc8531_private *priv = phydev->priv;
488 static void vsc85xx_get_strings(struct phy_device *phydev, u8 *data)
490 struct vsc8531_private *priv = phydev->priv;
496 for (i = 0; i < priv->nstats; i++)
497 strlcpy(data + i * ETH_GSTRING_LEN, priv->hw_stats[i].string,
501 static u64 vsc85xx_get_stat(struct phy_device *phydev, int i)
503 struct vsc8531_private *priv = phydev->priv;
506 val = phy_read_paged(phydev, priv->hw_stats[i].page,
507 priv->hw_stats[i].reg);
511 val = val & priv->hw_stats[i].mask;
512 priv->stats[i] += val;
514 return priv->stats[i];
517 static void vsc85xx_get_stats(struct phy_device *phydev,
518 struct ethtool_stats *stats, u64 *data)
520 struct vsc8531_private *priv = phydev->priv;
526 for (i = 0; i < priv->nstats; i++)
527 data[i] = vsc85xx_get_stat(phydev, i);
530 static int vsc85xx_led_cntl_set(struct phy_device *phydev,
537 mutex_lock(&phydev->lock);
538 reg_val = phy_read(phydev, MSCC_PHY_LED_MODE_SEL);
539 reg_val &= ~LED_MODE_SEL_MASK(led_num);
540 reg_val |= LED_MODE_SEL(led_num, (u16)mode);
541 rc = phy_write(phydev, MSCC_PHY_LED_MODE_SEL, reg_val);
542 mutex_unlock(&phydev->lock);
547 static int vsc85xx_mdix_get(struct phy_device *phydev, u8 *mdix)
551 reg_val = phy_read(phydev, MSCC_PHY_DEV_AUX_CNTL);
552 if (reg_val & HP_AUTO_MDIX_X_OVER_IND_MASK)
553 *mdix = ETH_TP_MDI_X;
560 static int vsc85xx_mdix_set(struct phy_device *phydev, u8 mdix)
565 reg_val = phy_read(phydev, MSCC_PHY_BYPASS_CONTROL);
566 if (mdix == ETH_TP_MDI || mdix == ETH_TP_MDI_X) {
567 reg_val |= (DISABLE_PAIR_SWAP_CORR_MASK |
568 DISABLE_POLARITY_CORR_MASK |
569 DISABLE_HP_AUTO_MDIX_MASK);
571 reg_val &= ~(DISABLE_PAIR_SWAP_CORR_MASK |
572 DISABLE_POLARITY_CORR_MASK |
573 DISABLE_HP_AUTO_MDIX_MASK);
575 rc = phy_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg_val);
581 if (mdix == ETH_TP_MDI)
582 reg_val = FORCE_MDI_CROSSOVER_MDI;
583 else if (mdix == ETH_TP_MDI_X)
584 reg_val = FORCE_MDI_CROSSOVER_MDIX;
586 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
587 MSCC_PHY_EXT_MODE_CNTL, FORCE_MDI_CROSSOVER_MASK,
592 return genphy_restart_aneg(phydev);
595 static int vsc85xx_downshift_get(struct phy_device *phydev, u8 *count)
599 reg_val = phy_read_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
600 MSCC_PHY_ACTIPHY_CNTL);
604 reg_val &= DOWNSHIFT_CNTL_MASK;
605 if (!(reg_val & DOWNSHIFT_EN))
606 *count = DOWNSHIFT_DEV_DISABLE;
608 *count = ((reg_val & ~DOWNSHIFT_EN) >> DOWNSHIFT_CNTL_POS) + 2;
613 static int vsc85xx_downshift_set(struct phy_device *phydev, u8 count)
615 if (count == DOWNSHIFT_DEV_DEFAULT_COUNT) {
616 /* Default downshift count 3 (i.e. Bit3:2 = 0b01) */
617 count = ((1 << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
618 } else if (count > DOWNSHIFT_COUNT_MAX || count == 1) {
619 phydev_err(phydev, "Downshift count should be 2,3,4 or 5\n");
622 /* Downshift count is either 2,3,4 or 5 */
623 count = (((count - 2) << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
626 return phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
627 MSCC_PHY_ACTIPHY_CNTL, DOWNSHIFT_CNTL_MASK,
631 static int vsc85xx_wol_set(struct phy_device *phydev,
632 struct ethtool_wolinfo *wol)
637 u16 pwd[3] = {0, 0, 0};
638 struct ethtool_wolinfo *wol_conf = wol;
639 u8 *mac_addr = phydev->attached_dev->dev_addr;
641 mutex_lock(&phydev->lock);
642 rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
644 rc = phy_restore_page(phydev, rc, rc);
648 if (wol->wolopts & WAKE_MAGIC) {
649 /* Store the device address for the magic packet */
650 for (i = 0; i < ARRAY_SIZE(pwd); i++)
651 pwd[i] = mac_addr[5 - (i * 2 + 1)] << 8 |
653 __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, pwd[0]);
654 __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, pwd[1]);
655 __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, pwd[2]);
657 __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, 0);
658 __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, 0);
659 __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, 0);
662 if (wol_conf->wolopts & WAKE_MAGICSECURE) {
663 for (i = 0; i < ARRAY_SIZE(pwd); i++)
664 pwd[i] = wol_conf->sopass[5 - (i * 2 + 1)] << 8 |
665 wol_conf->sopass[5 - i * 2];
666 __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, pwd[0]);
667 __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, pwd[1]);
668 __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, pwd[2]);
670 __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, 0);
671 __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, 0);
672 __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, 0);
675 reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
676 if (wol_conf->wolopts & WAKE_MAGICSECURE)
677 reg_val |= SECURE_ON_ENABLE;
679 reg_val &= ~SECURE_ON_ENABLE;
680 __phy_write(phydev, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
682 rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
686 if (wol->wolopts & WAKE_MAGIC) {
687 /* Enable the WOL interrupt */
688 reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
689 reg_val |= MII_VSC85XX_INT_MASK_WOL;
690 rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
694 /* Disable the WOL interrupt */
695 reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
696 reg_val &= (~MII_VSC85XX_INT_MASK_WOL);
697 rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
701 /* Clear WOL iterrupt status */
702 reg_val = phy_read(phydev, MII_VSC85XX_INT_STATUS);
705 mutex_unlock(&phydev->lock);
710 static void vsc85xx_wol_get(struct phy_device *phydev,
711 struct ethtool_wolinfo *wol)
716 u16 pwd[3] = {0, 0, 0};
717 struct ethtool_wolinfo *wol_conf = wol;
719 mutex_lock(&phydev->lock);
720 rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
724 reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
725 if (reg_val & SECURE_ON_ENABLE)
726 wol_conf->wolopts |= WAKE_MAGICSECURE;
727 if (wol_conf->wolopts & WAKE_MAGICSECURE) {
728 pwd[0] = __phy_read(phydev, MSCC_PHY_WOL_LOWER_PASSWD);
729 pwd[1] = __phy_read(phydev, MSCC_PHY_WOL_MID_PASSWD);
730 pwd[2] = __phy_read(phydev, MSCC_PHY_WOL_UPPER_PASSWD);
731 for (i = 0; i < ARRAY_SIZE(pwd); i++) {
732 wol_conf->sopass[5 - i * 2] = pwd[i] & 0x00ff;
733 wol_conf->sopass[5 - (i * 2 + 1)] = (pwd[i] & 0xff00)
739 phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
740 mutex_unlock(&phydev->lock);
743 #ifdef CONFIG_OF_MDIO
744 static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
748 struct device *dev = &phydev->mdio.dev;
749 struct device_node *of_node = dev->of_node;
750 u8 sd_array_size = ARRAY_SIZE(edge_table[0].slowdown);
755 if (of_property_read_u32(of_node, "vsc8531,vddmac", &vdd))
756 vdd = MSCC_VDDMAC_3300;
758 if (of_property_read_u32(of_node, "vsc8531,edge-slowdown", &sd))
761 for (i = 0; i < ARRAY_SIZE(edge_table); i++)
762 if (edge_table[i].vddmac == vdd)
763 for (j = 0; j < sd_array_size; j++)
764 if (edge_table[i].slowdown[j] == sd)
765 return (sd_array_size - j - 1);
770 static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
774 struct vsc8531_private *priv = phydev->priv;
775 struct device *dev = &phydev->mdio.dev;
776 struct device_node *of_node = dev->of_node;
783 led_mode = default_mode;
784 err = of_property_read_u32(of_node, led, &led_mode);
785 if (!err && !(BIT(led_mode) & priv->supp_led_modes)) {
786 phydev_err(phydev, "DT %s invalid\n", led);
794 static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
799 static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
805 #endif /* CONFIG_OF_MDIO */
807 static int vsc85xx_dt_led_modes_get(struct phy_device *phydev,
810 struct vsc8531_private *priv = phydev->priv;
811 char led_dt_prop[28];
814 for (i = 0; i < priv->nleds; i++) {
815 ret = sprintf(led_dt_prop, "vsc8531,led-%d-mode", i);
819 ret = vsc85xx_dt_led_mode_get(phydev, led_dt_prop,
823 priv->leds_mode[i] = ret;
829 static int vsc85xx_edge_rate_cntl_set(struct phy_device *phydev, u8 edge_rate)
833 mutex_lock(&phydev->lock);
834 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
835 MSCC_PHY_WOL_MAC_CONTROL, EDGE_RATE_CNTL_MASK,
836 edge_rate << EDGE_RATE_CNTL_POS);
837 mutex_unlock(&phydev->lock);
842 static int vsc85xx_mac_if_set(struct phy_device *phydev,
843 phy_interface_t interface)
848 mutex_lock(&phydev->lock);
849 reg_val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
850 reg_val &= ~(MAC_IF_SELECTION_MASK);
852 case PHY_INTERFACE_MODE_RGMII:
853 reg_val |= (MAC_IF_SELECTION_RGMII << MAC_IF_SELECTION_POS);
855 case PHY_INTERFACE_MODE_RMII:
856 reg_val |= (MAC_IF_SELECTION_RMII << MAC_IF_SELECTION_POS);
858 case PHY_INTERFACE_MODE_MII:
859 case PHY_INTERFACE_MODE_GMII:
860 reg_val |= (MAC_IF_SELECTION_GMII << MAC_IF_SELECTION_POS);
866 rc = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, reg_val);
870 rc = genphy_soft_reset(phydev);
873 mutex_unlock(&phydev->lock);
878 static int vsc85xx_default_config(struct phy_device *phydev)
883 phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
884 mutex_lock(&phydev->lock);
886 reg_val = RGMII_RX_CLK_DELAY_1_1_NS << RGMII_RX_CLK_DELAY_POS;
888 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
889 MSCC_PHY_RGMII_CNTL, RGMII_RX_CLK_DELAY_MASK,
892 mutex_unlock(&phydev->lock);
897 static int vsc85xx_get_tunable(struct phy_device *phydev,
898 struct ethtool_tunable *tuna, void *data)
901 case ETHTOOL_PHY_DOWNSHIFT:
902 return vsc85xx_downshift_get(phydev, (u8 *)data);
908 static int vsc85xx_set_tunable(struct phy_device *phydev,
909 struct ethtool_tunable *tuna,
913 case ETHTOOL_PHY_DOWNSHIFT:
914 return vsc85xx_downshift_set(phydev, *(u8 *)data);
920 /* mdiobus lock should be locked when using this function */
921 static void vsc85xx_tr_write(struct phy_device *phydev, u16 addr, u32 val)
923 __phy_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
924 __phy_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
925 __phy_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
928 static int vsc8531_pre_init_seq_set(struct phy_device *phydev)
931 static const struct reg_val init_seq[] = {
932 {0x0f90, 0x00688980},
933 {0x0696, 0x00000003},
934 {0x07fa, 0x0050100f},
935 {0x1686, 0x00000004},
940 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_STANDARD,
941 MSCC_PHY_EXT_CNTL_STATUS, SMI_BROADCAST_WR_EN,
942 SMI_BROADCAST_WR_EN);
945 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
946 MSCC_PHY_TEST_PAGE_24, 0, 0x0400);
949 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
950 MSCC_PHY_TEST_PAGE_5, 0x0a00, 0x0e00);
953 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
954 MSCC_PHY_TEST_PAGE_8, 0x8000, 0x8000);
958 mutex_lock(&phydev->lock);
959 oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
963 for (i = 0; i < ARRAY_SIZE(init_seq); i++)
964 vsc85xx_tr_write(phydev, init_seq[i].reg, init_seq[i].val);
967 oldpage = phy_restore_page(phydev, oldpage, oldpage);
968 mutex_unlock(&phydev->lock);
973 static int vsc85xx_eee_init_seq_set(struct phy_device *phydev)
975 static const struct reg_val init_eee[] = {
976 {0x0f82, 0x0012b00a},
977 {0x1686, 0x00000004},
978 {0x168c, 0x00d2c46f},
979 {0x17a2, 0x00000620},
980 {0x16a0, 0x00eeffdd},
981 {0x16a6, 0x00071448},
982 {0x16a4, 0x0013132f},
983 {0x16a8, 0x00000000},
984 {0x0ffc, 0x00c0a028},
985 {0x0fe8, 0x0091b06c},
986 {0x0fea, 0x00041600},
987 {0x0f80, 0x00000af4},
988 {0x0fec, 0x00901809},
989 {0x0fee, 0x0000a6a1},
990 {0x0ffe, 0x00b01007},
991 {0x16b0, 0x00eeff00},
992 {0x16b2, 0x00007000},
993 {0x16b4, 0x00000814},
998 mutex_lock(&phydev->lock);
999 oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
1003 for (i = 0; i < ARRAY_SIZE(init_eee); i++)
1004 vsc85xx_tr_write(phydev, init_eee[i].reg, init_eee[i].val);
1007 oldpage = phy_restore_page(phydev, oldpage, oldpage);
1008 mutex_unlock(&phydev->lock);
1013 /* phydev->bus->mdio_lock should be locked when using this function */
1014 static int phy_base_write(struct phy_device *phydev, u32 regnum, u16 val)
1016 struct vsc8531_private *priv = phydev->priv;
1018 if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
1019 dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
1023 return __mdiobus_write(phydev->mdio.bus, priv->base_addr, regnum, val);
1026 /* phydev->bus->mdio_lock should be locked when using this function */
1027 static int phy_base_read(struct phy_device *phydev, u32 regnum)
1029 struct vsc8531_private *priv = phydev->priv;
1031 if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
1032 dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
1036 return __mdiobus_read(phydev->mdio.bus, priv->base_addr, regnum);
1039 /* bus->mdio_lock should be locked when using this function */
1040 static void vsc8584_csr_write(struct phy_device *phydev, u16 addr, u32 val)
1042 phy_base_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
1043 phy_base_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
1044 phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
1047 /* bus->mdio_lock should be locked when using this function */
1048 static int vsc8584_cmd(struct phy_device *phydev, u16 val)
1050 unsigned long deadline;
1053 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1054 MSCC_PHY_PAGE_EXTENDED_GPIO);
1056 phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NCOMPLETED | val);
1058 deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1060 reg_val = phy_base_read(phydev, MSCC_PHY_PROC_CMD);
1061 } while (time_before(jiffies, deadline) &&
1062 (reg_val & PROC_CMD_NCOMPLETED) &&
1063 !(reg_val & PROC_CMD_FAILED));
1065 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1067 if (reg_val & PROC_CMD_FAILED)
1070 if (reg_val & PROC_CMD_NCOMPLETED)
1076 /* bus->mdio_lock should be locked when using this function */
1077 static int vsc8584_micro_deassert_reset(struct phy_device *phydev,
1080 u32 enable, release;
1082 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1083 MSCC_PHY_PAGE_EXTENDED_GPIO);
1085 enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
1086 release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
1090 enable |= MICRO_PATCH_EN;
1091 release |= MICRO_PATCH_EN;
1093 /* Clear all patches */
1094 phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
1097 /* Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
1098 * override and addr. auto-incr; operate at 125 MHz
1100 phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, enable);
1101 /* Release 8051 Micro SW reset */
1102 phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, release);
1104 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1109 /* bus->mdio_lock should be locked when using this function */
1110 static int vsc8584_micro_assert_reset(struct phy_device *phydev)
1115 ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
1119 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1120 MSCC_PHY_PAGE_EXTENDED_GPIO);
1122 reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1123 reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
1124 phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
1126 phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(4), 0x005b);
1127 phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(4), 0x005b);
1129 reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1130 reg |= EN_PATCH_RAM_TRAP_ADDR(4);
1131 phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
1133 phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
1135 reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
1136 reg &= ~MICRO_NSOFT_RESET;
1137 phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, reg);
1139 phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_MCB_ACCESS_MAC_CONF |
1140 PROC_CMD_SGMII_PORT(0) | PROC_CMD_NO_MAC_CONF |
1143 reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1144 reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
1145 phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
1147 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1152 /* bus->mdio_lock should be locked when using this function */
1153 static int vsc8584_get_fw_crc(struct phy_device *phydev, u16 start, u16 size,
1158 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
1160 phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_2, start);
1161 phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_3, size);
1163 /* Start Micro command */
1164 ret = vsc8584_cmd(phydev, PROC_CMD_CRC16);
1168 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
1170 *crc = phy_base_read(phydev, MSCC_PHY_VERIPHY_CNTL_2);
1173 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1178 /* bus->mdio_lock should be locked when using this function */
1179 static int vsc8584_patch_fw(struct phy_device *phydev,
1180 const struct firmware *fw)
1184 ret = vsc8584_micro_assert_reset(phydev);
1186 dev_err(&phydev->mdio.dev,
1187 "%s: failed to assert reset of micro\n", __func__);
1191 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1192 MSCC_PHY_PAGE_EXTENDED_GPIO);
1194 /* Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
1195 * Disable the 8051 Micro clock
1197 phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, RUN_FROM_INT_ROM |
1198 AUTOINC_ADDR | PATCH_RAM_CLK | MICRO_CLK_EN |
1199 MICRO_CLK_DIVIDE(2));
1200 phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM | INT_MEM_WRITE_EN |
1202 phy_base_write(phydev, MSCC_INT_MEM_ADDR, 0x0000);
1204 for (i = 0; i < fw->size; i++)
1205 phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM |
1206 INT_MEM_WRITE_EN | fw->data[i]);
1208 /* Clear internal memory access */
1209 phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
1211 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1216 /* bus->mdio_lock should be locked when using this function */
1217 static bool vsc8574_is_serdes_init(struct phy_device *phydev)
1222 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1223 MSCC_PHY_PAGE_EXTENDED_GPIO);
1225 reg = phy_base_read(phydev, MSCC_TRAP_ROM_ADDR(1));
1226 if (reg != 0x3eb7) {
1231 reg = phy_base_read(phydev, MSCC_PATCH_RAM_ADDR(1));
1232 if (reg != 0x4012) {
1237 reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1238 if (reg != EN_PATCH_RAM_TRAP_ADDR(1)) {
1243 reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
1244 if ((MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
1245 MICRO_CLK_EN) != (reg & MSCC_DW8051_VLD_MASK)) {
1252 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1257 /* bus->mdio_lock should be locked when using this function */
1258 static int vsc8574_config_pre_init(struct phy_device *phydev)
1260 static const struct reg_val pre_init1[] = {
1261 {0x0fae, 0x000401bd},
1262 {0x0fac, 0x000f000f},
1263 {0x17a0, 0x00a0f147},
1264 {0x0fe4, 0x00052f54},
1265 {0x1792, 0x0027303d},
1266 {0x07fe, 0x00000704},
1267 {0x0fe0, 0x00060150},
1268 {0x0f82, 0x0012b00a},
1269 {0x0f80, 0x00000d74},
1270 {0x02e0, 0x00000012},
1271 {0x03a2, 0x00050208},
1272 {0x03b2, 0x00009186},
1273 {0x0fb0, 0x000e3700},
1274 {0x1688, 0x00049f81},
1275 {0x0fd2, 0x0000ffff},
1276 {0x168a, 0x00039fa2},
1277 {0x1690, 0x0020640b},
1278 {0x0258, 0x00002220},
1279 {0x025a, 0x00002a20},
1280 {0x025c, 0x00003060},
1281 {0x025e, 0x00003fa0},
1282 {0x03a6, 0x0000e0f0},
1283 {0x0f92, 0x00001489},
1284 {0x16a2, 0x00007000},
1285 {0x16a6, 0x00071448},
1286 {0x16a0, 0x00eeffdd},
1287 {0x0fe8, 0x0091b06c},
1288 {0x0fea, 0x00041600},
1289 {0x16b0, 0x00eeff00},
1290 {0x16b2, 0x00007000},
1291 {0x16b4, 0x00000814},
1292 {0x0f90, 0x00688980},
1293 {0x03a4, 0x0000d8f0},
1294 {0x0fc0, 0x00000400},
1295 {0x07fa, 0x0050100f},
1296 {0x0796, 0x00000003},
1297 {0x07f8, 0x00c3ff98},
1298 {0x0fa4, 0x0018292a},
1299 {0x168c, 0x00d2c46f},
1300 {0x17a2, 0x00000620},
1301 {0x16a4, 0x0013132f},
1302 {0x16a8, 0x00000000},
1303 {0x0ffc, 0x00c0a028},
1304 {0x0fec, 0x00901c09},
1305 {0x0fee, 0x0004a6a1},
1306 {0x0ffe, 0x00b01807},
1308 static const struct reg_val pre_init2[] = {
1309 {0x0486, 0x0008a518},
1310 {0x0488, 0x006dc696},
1311 {0x048a, 0x00000912},
1312 {0x048e, 0x00000db6},
1313 {0x049c, 0x00596596},
1314 {0x049e, 0x00000514},
1315 {0x04a2, 0x00410280},
1316 {0x04a4, 0x00000000},
1317 {0x04a6, 0x00000000},
1318 {0x04a8, 0x00000000},
1319 {0x04aa, 0x00000000},
1320 {0x04ae, 0x007df7dd},
1321 {0x04b0, 0x006d95d4},
1322 {0x04b2, 0x00492410},
1324 struct device *dev = &phydev->mdio.dev;
1325 const struct firmware *fw;
1331 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1333 /* all writes below are broadcasted to all PHYs in the same package */
1334 reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1335 reg |= SMI_BROADCAST_WR_EN;
1336 phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1338 phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
1340 /* The below register writes are tweaking analog and electrical
1341 * configuration that were determined through characterization by PHY
1342 * engineers. These don't mean anything more than "these are the best
1345 phy_base_write(phydev, MSCC_PHY_EXT_PHY_CNTL_2, 0x0040);
1347 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1349 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_20, 0x4320);
1350 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_24, 0x0c00);
1351 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_9, 0x18ca);
1352 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1b20);
1354 reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1356 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1358 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1360 for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1361 vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1363 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
1365 phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
1367 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1369 for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
1370 vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
1372 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1374 reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1376 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1378 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1380 /* end of write broadcasting */
1381 reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1382 reg &= ~SMI_BROADCAST_WR_EN;
1383 phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1385 ret = request_firmware(&fw, MSCC_VSC8574_REVB_INT8051_FW, dev);
1387 dev_err(dev, "failed to load firmware %s, ret: %d\n",
1388 MSCC_VSC8574_REVB_INT8051_FW, ret);
1392 /* Add one byte to size for the one added by the patch_fw function */
1393 ret = vsc8584_get_fw_crc(phydev,
1394 MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
1395 fw->size + 1, &crc);
1399 if (crc == MSCC_VSC8574_REVB_INT8051_FW_CRC) {
1400 serdes_init = vsc8574_is_serdes_init(phydev);
1403 ret = vsc8584_micro_assert_reset(phydev);
1406 "%s: failed to assert reset of micro\n",
1412 dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
1414 serdes_init = false;
1416 if (vsc8584_patch_fw(phydev, fw))
1418 "failed to patch FW, expect non-optimal device\n");
1422 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1423 MSCC_PHY_PAGE_EXTENDED_GPIO);
1425 phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), 0x3eb7);
1426 phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), 0x4012);
1427 phy_base_write(phydev, MSCC_INT_MEM_CNTL,
1428 EN_PATCH_RAM_TRAP_ADDR(1));
1430 vsc8584_micro_deassert_reset(phydev, false);
1432 /* Add one byte to size for the one added by the patch_fw
1435 ret = vsc8584_get_fw_crc(phydev,
1436 MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
1437 fw->size + 1, &crc);
1441 if (crc != MSCC_VSC8574_REVB_INT8051_FW_CRC)
1443 "FW CRC after patching is not the expected one, expect non-optimal device\n");
1446 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1447 MSCC_PHY_PAGE_EXTENDED_GPIO);
1449 ret = vsc8584_cmd(phydev, PROC_CMD_1588_DEFAULT_INIT |
1453 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1455 release_firmware(fw);
1460 /* bus->mdio_lock should be locked when using this function */
1461 static int vsc8584_config_pre_init(struct phy_device *phydev)
1463 static const struct reg_val pre_init1[] = {
1464 {0x07fa, 0x0050100f},
1465 {0x1688, 0x00049f81},
1466 {0x0f90, 0x00688980},
1467 {0x03a4, 0x0000d8f0},
1468 {0x0fc0, 0x00000400},
1469 {0x0f82, 0x0012b002},
1470 {0x1686, 0x00000004},
1471 {0x168c, 0x00d2c46f},
1472 {0x17a2, 0x00000620},
1473 {0x16a0, 0x00eeffdd},
1474 {0x16a6, 0x00071448},
1475 {0x16a4, 0x0013132f},
1476 {0x16a8, 0x00000000},
1477 {0x0ffc, 0x00c0a028},
1478 {0x0fe8, 0x0091b06c},
1479 {0x0fea, 0x00041600},
1480 {0x0f80, 0x00fffaff},
1481 {0x0fec, 0x00901809},
1482 {0x0ffe, 0x00b01007},
1483 {0x16b0, 0x00eeff00},
1484 {0x16b2, 0x00007000},
1485 {0x16b4, 0x00000814},
1487 static const struct reg_val pre_init2[] = {
1488 {0x0486, 0x0008a518},
1489 {0x0488, 0x006dc696},
1490 {0x048a, 0x00000912},
1492 const struct firmware *fw;
1493 struct device *dev = &phydev->mdio.dev;
1498 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1500 /* all writes below are broadcasted to all PHYs in the same package */
1501 reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1502 reg |= SMI_BROADCAST_WR_EN;
1503 phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1505 phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
1507 reg = phy_base_read(phydev, MSCC_PHY_BYPASS_CONTROL);
1508 reg |= PARALLEL_DET_IGNORE_ADVERTISED;
1509 phy_base_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg);
1511 /* The below register writes are tweaking analog and electrical
1512 * configuration that were determined through characterization by PHY
1513 * engineers. These don't mean anything more than "these are the best
1516 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_3);
1518 phy_base_write(phydev, MSCC_PHY_SERDES_TX_CRC_ERR_CNT, 0x2000);
1520 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1522 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1f20);
1524 reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1526 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1528 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1530 phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x2fa4));
1532 reg = phy_base_read(phydev, MSCC_PHY_TR_MSB);
1535 phy_base_write(phydev, MSCC_PHY_TR_MSB, reg);
1537 phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x0fa4));
1539 for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1540 vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1542 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
1544 phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
1546 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1548 for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
1549 vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
1551 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1553 reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1555 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1557 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1559 /* end of write broadcasting */
1560 reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1561 reg &= ~SMI_BROADCAST_WR_EN;
1562 phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1564 ret = request_firmware(&fw, MSCC_VSC8584_REVB_INT8051_FW, dev);
1566 dev_err(dev, "failed to load firmware %s, ret: %d\n",
1567 MSCC_VSC8584_REVB_INT8051_FW, ret);
1571 /* Add one byte to size for the one added by the patch_fw function */
1572 ret = vsc8584_get_fw_crc(phydev,
1573 MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
1574 fw->size + 1, &crc);
1578 if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
1579 dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
1580 if (vsc8584_patch_fw(phydev, fw))
1582 "failed to patch FW, expect non-optimal device\n");
1585 vsc8584_micro_deassert_reset(phydev, false);
1587 /* Add one byte to size for the one added by the patch_fw function */
1588 ret = vsc8584_get_fw_crc(phydev,
1589 MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
1590 fw->size + 1, &crc);
1594 if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
1596 "FW CRC after patching is not the expected one, expect non-optimal device\n");
1598 ret = vsc8584_micro_assert_reset(phydev);
1602 vsc8584_micro_deassert_reset(phydev, true);
1605 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1607 release_firmware(fw);
1612 #if IS_ENABLED(CONFIG_MACSEC)
1613 static u32 vsc8584_macsec_phy_read(struct phy_device *phydev,
1614 enum macsec_bank bank, u32 reg)
1616 u32 val, val_l = 0, val_h = 0;
1617 unsigned long deadline;
1620 rc = phy_select_page(phydev, MSCC_PHY_PAGE_MACSEC);
1624 __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_20,
1625 MSCC_PHY_MACSEC_20_TARGET(bank >> 2));
1627 if (bank >> 2 == 0x1)
1628 /* non-MACsec access */
1633 __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_19,
1634 MSCC_PHY_MACSEC_19_CMD | MSCC_PHY_MACSEC_19_READ |
1635 MSCC_PHY_MACSEC_19_REG_ADDR(reg) |
1636 MSCC_PHY_MACSEC_19_TARGET(bank));
1638 deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1640 val = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_19);
1641 } while (time_before(jiffies, deadline) && !(val & MSCC_PHY_MACSEC_19_CMD));
1643 val_l = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_17);
1644 val_h = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_18);
1647 phy_restore_page(phydev, rc, rc);
1649 return (val_h << 16) | val_l;
1652 static void vsc8584_macsec_phy_write(struct phy_device *phydev,
1653 enum macsec_bank bank, u32 reg, u32 val)
1655 unsigned long deadline;
1658 rc = phy_select_page(phydev, MSCC_PHY_PAGE_MACSEC);
1662 __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_20,
1663 MSCC_PHY_MACSEC_20_TARGET(bank >> 2));
1665 if ((bank >> 2 == 0x1) || (bank >> 2 == 0x3))
1671 __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_17, (u16)val);
1672 __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_18, (u16)(val >> 16));
1674 __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_19,
1675 MSCC_PHY_MACSEC_19_CMD | MSCC_PHY_MACSEC_19_REG_ADDR(reg) |
1676 MSCC_PHY_MACSEC_19_TARGET(bank));
1678 deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1680 val = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_19);
1681 } while (time_before(jiffies, deadline) && !(val & MSCC_PHY_MACSEC_19_CMD));
1684 phy_restore_page(phydev, rc, rc);
1687 static void vsc8584_macsec_classification(struct phy_device *phydev,
1688 enum macsec_bank bank)
1690 /* enable VLAN tag parsing */
1691 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_CP_TAG,
1692 MSCC_MS_SAM_CP_TAG_PARSE_STAG |
1693 MSCC_MS_SAM_CP_TAG_PARSE_QTAG |
1694 MSCC_MS_SAM_CP_TAG_PARSE_QINQ);
1697 static void vsc8584_macsec_flow_default_action(struct phy_device *phydev,
1698 enum macsec_bank bank,
1701 u32 port = (bank == MACSEC_INGR) ?
1702 MSCC_MS_PORT_UNCONTROLLED : MSCC_MS_PORT_COMMON;
1703 u32 action = MSCC_MS_FLOW_BYPASS;
1706 action = MSCC_MS_FLOW_DROP;
1708 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_NM_FLOW_NCP,
1709 /* MACsec untagged */
1710 MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_FLOW_TYPE(action) |
1711 MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1712 MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_DEST_PORT(port) |
1714 MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_FLOW_TYPE(action) |
1715 MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1716 MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_DEST_PORT(port) |
1718 MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_FLOW_TYPE(action) |
1719 MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1720 MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_DEST_PORT(port) |
1722 MSCC_MS_SAM_NM_FLOW_NCP_KAY_FLOW_TYPE(action) |
1723 MSCC_MS_SAM_NM_FLOW_NCP_KAY_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1724 MSCC_MS_SAM_NM_FLOW_NCP_KAY_DEST_PORT(port));
1725 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_NM_FLOW_CP,
1726 /* MACsec untagged */
1727 MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_FLOW_TYPE(action) |
1728 MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1729 MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_DEST_PORT(port) |
1731 MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_FLOW_TYPE(action) |
1732 MSCC_MS_SAM_NM_FLOW_CP_TAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1733 MSCC_MS_SAM_NM_FLOW_CP_TAGGED_DEST_PORT(port) |
1735 MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_FLOW_TYPE(action) |
1736 MSCC_MS_SAM_NM_FLOW_CP_BADTAG_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1737 MSCC_MS_SAM_NM_FLOW_CP_BADTAG_DEST_PORT(port) |
1739 MSCC_MS_SAM_NM_FLOW_NCP_KAY_FLOW_TYPE(action) |
1740 MSCC_MS_SAM_NM_FLOW_CP_KAY_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1741 MSCC_MS_SAM_NM_FLOW_CP_KAY_DEST_PORT(port));
1744 static void vsc8584_macsec_integrity_checks(struct phy_device *phydev,
1745 enum macsec_bank bank)
1749 if (bank != MACSEC_INGR)
1752 /* Set default rules to pass unmatched frames */
1753 val = vsc8584_macsec_phy_read(phydev, bank,
1754 MSCC_MS_PARAMS2_IG_CC_CONTROL);
1755 val |= MSCC_MS_PARAMS2_IG_CC_CONTROL_NON_MATCH_CTRL_ACT |
1756 MSCC_MS_PARAMS2_IG_CC_CONTROL_NON_MATCH_ACT;
1757 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PARAMS2_IG_CC_CONTROL,
1760 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PARAMS2_IG_CP_TAG,
1761 MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_STAG |
1762 MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_QTAG |
1763 MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_QINQ);
1766 static void vsc8584_macsec_block_init(struct phy_device *phydev,
1767 enum macsec_bank bank)
1772 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
1773 MSCC_MS_ENA_CFG_SW_RST |
1774 MSCC_MS_ENA_CFG_MACSEC_BYPASS_ENA);
1776 /* Set the MACsec block out of s/w reset and enable clocks */
1777 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
1778 MSCC_MS_ENA_CFG_CLK_ENA);
1780 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_STATUS_CONTEXT_CTRL,
1781 bank == MACSEC_INGR ? 0xe5880214 : 0xe5880218);
1782 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_MISC_CONTROL,
1783 MSCC_MS_MISC_CONTROL_MC_LATENCY_FIX(bank == MACSEC_INGR ? 57 : 40) |
1784 MSCC_MS_MISC_CONTROL_XFORM_REC_SIZE(bank == MACSEC_INGR ? 1 : 2));
1786 /* Clear the counters */
1787 val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_COUNT_CONTROL);
1788 val |= MSCC_MS_COUNT_CONTROL_AUTO_CNTR_RESET;
1789 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_COUNT_CONTROL, val);
1791 /* Enable octet increment mode */
1792 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PP_CTRL,
1793 MSCC_MS_PP_CTRL_MACSEC_OCTET_INCR_MODE);
1795 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_BLOCK_CTX_UPDATE, 0x3);
1797 val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_COUNT_CONTROL);
1798 val |= MSCC_MS_COUNT_CONTROL_RESET_ALL;
1799 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_COUNT_CONTROL, val);
1802 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_NON_VLAN_MTU_CHECK,
1803 MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMPARE(32761) |
1804 MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMP_DROP);
1806 for (i = 0; i < 8; i++)
1807 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_VLAN_MTU_CHECK(i),
1808 MSCC_MS_VLAN_MTU_CHECK_MTU_COMPARE(32761) |
1809 MSCC_MS_VLAN_MTU_CHECK_MTU_COMP_DROP);
1811 if (bank == MACSEC_EGR) {
1812 val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_INTR_CTRL_STATUS);
1813 val &= ~MSCC_MS_INTR_CTRL_STATUS_INTR_ENABLE_M;
1814 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_INTR_CTRL_STATUS, val);
1816 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_FC_CFG,
1817 MSCC_MS_FC_CFG_FCBUF_ENA |
1818 MSCC_MS_FC_CFG_LOW_THRESH(0x1) |
1819 MSCC_MS_FC_CFG_HIGH_THRESH(0x4) |
1820 MSCC_MS_FC_CFG_LOW_BYTES_VAL(0x4) |
1821 MSCC_MS_FC_CFG_HIGH_BYTES_VAL(0x6));
1824 vsc8584_macsec_classification(phydev, bank);
1825 vsc8584_macsec_flow_default_action(phydev, bank, false);
1826 vsc8584_macsec_integrity_checks(phydev, bank);
1828 /* Enable the MACsec block */
1829 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
1830 MSCC_MS_ENA_CFG_CLK_ENA |
1831 MSCC_MS_ENA_CFG_MACSEC_ENA |
1832 MSCC_MS_ENA_CFG_MACSEC_SPEED_MODE(0x5));
1835 static void vsc8584_macsec_mac_init(struct phy_device *phydev,
1836 enum macsec_bank bank)
1841 /* Clear host & line stats */
1842 for (i = 0; i < 36; i++)
1843 vsc8584_macsec_phy_write(phydev, bank, 0x1c + i, 0);
1845 val = vsc8584_macsec_phy_read(phydev, bank,
1846 MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL);
1847 val &= ~MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE_M;
1848 val |= MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE(2) |
1849 MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_VALUE(0xffff);
1850 vsc8584_macsec_phy_write(phydev, bank,
1851 MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL, val);
1853 val = vsc8584_macsec_phy_read(phydev, bank,
1854 MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2);
1856 vsc8584_macsec_phy_write(phydev, bank,
1857 MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2, val);
1859 val = vsc8584_macsec_phy_read(phydev, bank,
1860 MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL);
1861 if (bank == HOST_MAC)
1862 val |= MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_TIMER_ENA |
1863 MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_FRAME_DROP_ENA;
1865 val |= MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_REACT_ENA |
1866 MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_FRAME_DROP_ENA |
1867 MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_MODE |
1868 MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_EARLY_PAUSE_DETECT_ENA;
1869 vsc8584_macsec_phy_write(phydev, bank,
1870 MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL, val);
1872 vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_PKTINF_CFG,
1873 MSCC_MAC_CFG_PKTINF_CFG_STRIP_FCS_ENA |
1874 MSCC_MAC_CFG_PKTINF_CFG_INSERT_FCS_ENA |
1875 MSCC_MAC_CFG_PKTINF_CFG_LPI_RELAY_ENA |
1876 MSCC_MAC_CFG_PKTINF_CFG_STRIP_PREAMBLE_ENA |
1877 MSCC_MAC_CFG_PKTINF_CFG_INSERT_PREAMBLE_ENA |
1879 MSCC_MAC_CFG_PKTINF_CFG_ENABLE_TX_PADDING : 0));
1881 val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_MODE_CFG);
1882 val &= ~MSCC_MAC_CFG_MODE_CFG_DISABLE_DIC;
1883 vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_MODE_CFG, val);
1885 val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_MAXLEN_CFG);
1886 val &= ~MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN_M;
1887 val |= MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN(10240);
1888 vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_MAXLEN_CFG, val);
1890 vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_ADV_CHK_CFG,
1891 MSCC_MAC_CFG_ADV_CHK_CFG_SFD_CHK_ENA |
1892 MSCC_MAC_CFG_ADV_CHK_CFG_PRM_CHK_ENA |
1893 MSCC_MAC_CFG_ADV_CHK_CFG_OOR_ERR_ENA |
1894 MSCC_MAC_CFG_ADV_CHK_CFG_INR_ERR_ENA);
1896 val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_LFS_CFG);
1897 val &= ~MSCC_MAC_CFG_LFS_CFG_LFS_MODE_ENA;
1898 vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_LFS_CFG, val);
1900 vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_ENA_CFG,
1901 MSCC_MAC_CFG_ENA_CFG_RX_CLK_ENA |
1902 MSCC_MAC_CFG_ENA_CFG_TX_CLK_ENA |
1903 MSCC_MAC_CFG_ENA_CFG_RX_ENA |
1904 MSCC_MAC_CFG_ENA_CFG_TX_ENA);
1907 /* Must be called with mdio_lock taken */
1908 static int vsc8584_macsec_init(struct phy_device *phydev)
1912 vsc8584_macsec_block_init(phydev, MACSEC_INGR);
1913 vsc8584_macsec_block_init(phydev, MACSEC_EGR);
1914 vsc8584_macsec_mac_init(phydev, HOST_MAC);
1915 vsc8584_macsec_mac_init(phydev, LINE_MAC);
1917 vsc8584_macsec_phy_write(phydev, FC_BUFFER,
1918 MSCC_FCBUF_FC_READ_THRESH_CFG,
1919 MSCC_FCBUF_FC_READ_THRESH_CFG_TX_THRESH(4) |
1920 MSCC_FCBUF_FC_READ_THRESH_CFG_RX_THRESH(5));
1922 val = vsc8584_macsec_phy_read(phydev, FC_BUFFER, MSCC_FCBUF_MODE_CFG);
1923 val |= MSCC_FCBUF_MODE_CFG_PAUSE_GEN_ENA |
1924 MSCC_FCBUF_MODE_CFG_RX_PPM_RATE_ADAPT_ENA |
1925 MSCC_FCBUF_MODE_CFG_TX_PPM_RATE_ADAPT_ENA;
1926 vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_MODE_CFG, val);
1928 vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG,
1929 MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_THRESH(8) |
1930 MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_OFFSET(9));
1932 val = vsc8584_macsec_phy_read(phydev, FC_BUFFER,
1933 MSCC_FCBUF_TX_DATA_QUEUE_CFG);
1934 val &= ~(MSCC_FCBUF_TX_DATA_QUEUE_CFG_START_M |
1935 MSCC_FCBUF_TX_DATA_QUEUE_CFG_END_M);
1936 val |= MSCC_FCBUF_TX_DATA_QUEUE_CFG_START(0) |
1937 MSCC_FCBUF_TX_DATA_QUEUE_CFG_END(5119);
1938 vsc8584_macsec_phy_write(phydev, FC_BUFFER,
1939 MSCC_FCBUF_TX_DATA_QUEUE_CFG, val);
1941 val = vsc8584_macsec_phy_read(phydev, FC_BUFFER, MSCC_FCBUF_ENA_CFG);
1942 val |= MSCC_FCBUF_ENA_CFG_TX_ENA | MSCC_FCBUF_ENA_CFG_RX_ENA;
1943 vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_ENA_CFG, val);
1945 val = vsc8584_macsec_phy_read(phydev, IP_1588,
1946 MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL);
1947 val &= ~MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE_M;
1948 val |= MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE(4);
1949 vsc8584_macsec_phy_write(phydev, IP_1588,
1950 MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL, val);
1954 #endif /* CONFIG_MACSEC */
1956 /* Check if one PHY has already done the init of the parts common to all PHYs
1957 * in the Quad PHY package.
1959 static bool vsc8584_is_pkg_init(struct phy_device *phydev, bool reversed)
1961 struct mdio_device **map = phydev->mdio.bus->mdio_map;
1962 struct vsc8531_private *vsc8531;
1963 struct phy_device *phy;
1966 /* VSC8584 is a Quad PHY */
1967 for (i = 0; i < 4; i++) {
1968 vsc8531 = phydev->priv;
1971 addr = vsc8531->base_addr - i;
1973 addr = vsc8531->base_addr + i;
1978 phy = container_of(map[addr], struct phy_device, mdio);
1980 if ((phy->phy_id & phydev->drv->phy_id_mask) !=
1981 (phydev->drv->phy_id & phydev->drv->phy_id_mask))
1984 vsc8531 = phy->priv;
1986 if (vsc8531 && vsc8531->pkg_init)
1993 static int vsc8584_config_init(struct phy_device *phydev)
1995 struct vsc8531_private *vsc8531 = phydev->priv;
1999 phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
2001 mutex_lock(&phydev->mdio.bus->mdio_lock);
2003 __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
2004 MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
2005 addr = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
2006 MSCC_PHY_EXT_PHY_CNTL_4);
2007 addr >>= PHY_CNTL_4_ADDR_POS;
2009 val = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
2010 MSCC_PHY_ACTIPHY_CNTL);
2011 if (val & PHY_ADDR_REVERSED)
2012 vsc8531->base_addr = phydev->mdio.addr + addr;
2014 vsc8531->base_addr = phydev->mdio.addr - addr;
2016 /* Some parts of the init sequence are identical for every PHY in the
2017 * package. Some parts are modifying the GPIO register bank which is a
2018 * set of registers that are affecting all PHYs, a few resetting the
2019 * microprocessor common to all PHYs. The CRC check responsible of the
2020 * checking the firmware within the 8051 microprocessor can only be
2021 * accessed via the PHY whose internal address in the package is 0.
2022 * All PHYs' interrupts mask register has to be zeroed before enabling
2023 * any PHY's interrupt in this register.
2024 * For all these reasons, we need to do the init sequence once and only
2025 * once whatever is the first PHY in the package that is initialized and
2026 * do the correct init sequence for all PHYs that are package-critical
2027 * in this pre-init function.
2029 if (!vsc8584_is_pkg_init(phydev, val & PHY_ADDR_REVERSED ? 1 : 0)) {
2030 /* The following switch statement assumes that the lowest
2031 * nibble of the phy_id_mask is always 0. This works because
2032 * the lowest nibble of the PHY_ID's below are also 0.
2034 WARN_ON(phydev->drv->phy_id_mask & 0xf);
2036 switch (phydev->phy_id & phydev->drv->phy_id_mask) {
2037 case PHY_ID_VSC8504:
2038 case PHY_ID_VSC8552:
2039 case PHY_ID_VSC8572:
2040 case PHY_ID_VSC8574:
2041 ret = vsc8574_config_pre_init(phydev);
2043 case PHY_ID_VSC856X:
2044 case PHY_ID_VSC8575:
2045 case PHY_ID_VSC8582:
2046 case PHY_ID_VSC8584:
2047 ret = vsc8584_config_pre_init(phydev);
2058 vsc8531->pkg_init = true;
2060 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
2061 MSCC_PHY_PAGE_EXTENDED_GPIO);
2063 val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
2064 val &= ~MAC_CFG_MASK;
2065 if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
2066 val |= MAC_CFG_QSGMII;
2068 val |= MAC_CFG_SGMII;
2070 ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
2074 val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
2075 PROC_CMD_READ_MOD_WRITE_PORT;
2076 if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
2077 val |= PROC_CMD_QSGMII_MAC;
2079 val |= PROC_CMD_SGMII_MAC;
2081 ret = vsc8584_cmd(phydev, val);
2085 usleep_range(10000, 20000);
2087 /* Disable SerDes for 100Base-FX */
2088 ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
2089 PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
2090 PROC_CMD_READ_MOD_WRITE_PORT |
2091 PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
2095 /* Disable SerDes for 1000Base-X */
2096 ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
2097 PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
2098 PROC_CMD_READ_MOD_WRITE_PORT |
2099 PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
2103 mutex_unlock(&phydev->mdio.bus->mdio_lock);
2105 #if IS_ENABLED(CONFIG_MACSEC)
2107 switch (phydev->phy_id & phydev->drv->phy_id_mask) {
2108 case PHY_ID_VSC856X:
2109 case PHY_ID_VSC8575:
2110 case PHY_ID_VSC8582:
2111 case PHY_ID_VSC8584:
2112 ret = vsc8584_macsec_init(phydev);
2118 phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2120 val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
2121 val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
2122 val |= MEDIA_OP_MODE_COPPER | (VSC8584_MAC_IF_SELECTION_SGMII <<
2123 VSC8584_MAC_IF_SELECTION_POS);
2124 ret = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, val);
2126 ret = genphy_soft_reset(phydev);
2130 for (i = 0; i < vsc8531->nleds; i++) {
2131 ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
2139 mutex_unlock(&phydev->mdio.bus->mdio_lock);
2143 static int vsc85xx_config_init(struct phy_device *phydev)
2146 struct vsc8531_private *vsc8531 = phydev->priv;
2148 rc = vsc85xx_default_config(phydev);
2152 rc = vsc85xx_mac_if_set(phydev, phydev->interface);
2156 rc = vsc85xx_edge_rate_cntl_set(phydev, vsc8531->rate_magic);
2160 phy_id = phydev->drv->phy_id & phydev->drv->phy_id_mask;
2161 if (PHY_ID_VSC8531 == phy_id || PHY_ID_VSC8541 == phy_id ||
2162 PHY_ID_VSC8530 == phy_id || PHY_ID_VSC8540 == phy_id) {
2163 rc = vsc8531_pre_init_seq_set(phydev);
2168 rc = vsc85xx_eee_init_seq_set(phydev);
2172 for (i = 0; i < vsc8531->nleds; i++) {
2173 rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
2181 static int vsc8584_did_interrupt(struct phy_device *phydev)
2185 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
2186 rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2188 return (rc < 0) ? 0 : rc & MII_VSC85XX_INT_MASK_MASK;
2191 static int vsc8514_config_pre_init(struct phy_device *phydev)
2193 /* These are the settings to override the silicon default
2194 * values to handle hardware performance of PHY. They
2195 * are set at Power-On state and remain until PHY Reset.
2197 static const struct reg_val pre_init1[] = {
2198 {0x0f90, 0x00688980},
2199 {0x0786, 0x00000003},
2200 {0x07fa, 0x0050100f},
2201 {0x0f82, 0x0012b002},
2202 {0x1686, 0x00000004},
2203 {0x168c, 0x00d2c46f},
2204 {0x17a2, 0x00000620},
2205 {0x16a0, 0x00eeffdd},
2206 {0x16a6, 0x00071448},
2207 {0x16a4, 0x0013132f},
2208 {0x16a8, 0x00000000},
2209 {0x0ffc, 0x00c0a028},
2210 {0x0fe8, 0x0091b06c},
2211 {0x0fea, 0x00041600},
2212 {0x0f80, 0x00fffaff},
2213 {0x0fec, 0x00901809},
2214 {0x0ffe, 0x00b01007},
2215 {0x16b0, 0x00eeff00},
2216 {0x16b2, 0x00007000},
2217 {0x16b4, 0x00000814},
2222 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2224 /* all writes below are broadcasted to all PHYs in the same package */
2225 reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
2226 reg |= SMI_BROADCAST_WR_EN;
2227 phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
2229 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
2231 reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
2233 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
2235 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
2237 for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
2238 vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
2240 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
2242 reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
2244 phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
2246 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2248 reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
2249 reg &= ~SMI_BROADCAST_WR_EN;
2250 phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
2255 static u32 vsc85xx_csr_ctrl_phy_read(struct phy_device *phydev,
2256 u32 target, u32 reg)
2258 unsigned long deadline;
2259 u32 val, val_l, val_h;
2261 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
2263 /* CSR registers are grouped under different Target IDs.
2264 * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
2265 * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
2266 * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
2267 * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
2270 /* Setup the Target ID */
2271 phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
2272 MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
2274 /* Trigger CSR Action - Read into the CSR's */
2275 phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
2276 MSCC_PHY_CSR_CNTL_19_CMD | MSCC_PHY_CSR_CNTL_19_READ |
2277 MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
2278 MSCC_PHY_CSR_CNTL_19_TARGET(target & 0x3));
2280 /* Wait for register access*/
2281 deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
2283 usleep_range(500, 1000);
2284 val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
2285 } while (time_before(jiffies, deadline) &&
2286 !(val & MSCC_PHY_CSR_CNTL_19_CMD));
2288 if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
2291 /* Read the Least Significant Word (LSW) (17) */
2292 val_l = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_17);
2294 /* Read the Most Significant Word (MSW) (18) */
2295 val_h = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_18);
2297 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
2298 MSCC_PHY_PAGE_STANDARD);
2300 return (val_h << 16) | val_l;
2303 static int vsc85xx_csr_ctrl_phy_write(struct phy_device *phydev,
2304 u32 target, u32 reg, u32 val)
2306 unsigned long deadline;
2308 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
2310 /* CSR registers are grouped under different Target IDs.
2311 * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
2312 * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
2313 * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
2314 * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
2317 /* Setup the Target ID */
2318 phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
2319 MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
2321 /* Write the Least Significant Word (LSW) (17) */
2322 phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_17, (u16)val);
2324 /* Write the Most Significant Word (MSW) (18) */
2325 phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_18, (u16)(val >> 16));
2327 /* Trigger CSR Action - Write into the CSR's */
2328 phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
2329 MSCC_PHY_CSR_CNTL_19_CMD |
2330 MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
2331 MSCC_PHY_CSR_CNTL_19_TARGET(target & 0x3));
2333 /* Wait for register access */
2334 deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
2336 usleep_range(500, 1000);
2337 val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
2338 } while (time_before(jiffies, deadline) &&
2339 !(val & MSCC_PHY_CSR_CNTL_19_CMD));
2341 if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
2344 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
2345 MSCC_PHY_PAGE_STANDARD);
2350 static int __phy_write_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb,
2353 unsigned long deadline;
2357 ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET, reg,
2362 deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
2364 usleep_range(500, 1000);
2365 val = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET, reg);
2367 if (val == 0xffffffff)
2370 } while (time_before(jiffies, deadline) && (val & op));
2378 /* Trigger a read to the spcified MCB */
2379 static int phy_update_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
2381 return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_READ);
2384 /* Trigger a write to the spcified MCB */
2385 static int phy_commit_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
2387 return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_WRITE);
2390 static int vsc8514_config_init(struct phy_device *phydev)
2392 struct vsc8531_private *vsc8531 = phydev->priv;
2393 unsigned long deadline;
2398 phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
2400 mutex_lock(&phydev->mdio.bus->mdio_lock);
2402 __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
2404 addr = __phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_4);
2405 addr >>= PHY_CNTL_4_ADDR_POS;
2407 val = __phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL);
2409 if (val & PHY_ADDR_REVERSED)
2410 vsc8531->base_addr = phydev->mdio.addr + addr;
2412 vsc8531->base_addr = phydev->mdio.addr - addr;
2414 /* Some parts of the init sequence are identical for every PHY in the
2415 * package. Some parts are modifying the GPIO register bank which is a
2416 * set of registers that are affecting all PHYs, a few resetting the
2417 * microprocessor common to all PHYs.
2418 * All PHYs' interrupts mask register has to be zeroed before enabling
2419 * any PHY's interrupt in this register.
2420 * For all these reasons, we need to do the init sequence once and only
2421 * once whatever is the first PHY in the package that is initialized and
2422 * do the correct init sequence for all PHYs that are package-critical
2423 * in this pre-init function.
2425 if (!vsc8584_is_pkg_init(phydev, val & PHY_ADDR_REVERSED ? 1 : 0))
2426 vsc8514_config_pre_init(phydev);
2428 vsc8531->pkg_init = true;
2430 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
2431 MSCC_PHY_PAGE_EXTENDED_GPIO);
2433 val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
2435 val &= ~MAC_CFG_MASK;
2436 val |= MAC_CFG_QSGMII;
2437 ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
2442 ret = vsc8584_cmd(phydev,
2443 PROC_CMD_MCB_ACCESS_MAC_CONF |
2444 PROC_CMD_RST_CONF_PORT |
2445 PROC_CMD_READ_MOD_WRITE_PORT | PROC_CMD_QSGMII_MAC);
2450 phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG, 0);
2452 phy_update_mcb_s6g(phydev, PHY_S6G_LCPLL_CFG, 0);
2454 ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2455 PHY_S6G_PLL5G_CFG0, 0x7036f145);
2459 phy_commit_mcb_s6g(phydev, PHY_S6G_LCPLL_CFG, 0);
2461 ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2463 (3 << PHY_S6G_PLL_ENA_OFFS_POS) |
2464 (120 << PHY_S6G_PLL_FSM_CTRL_DATA_POS)
2465 | (0 << PHY_S6G_PLL_FSM_ENA_POS));
2470 ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2472 (0 << PHY_S6G_SYS_RST_POS) |
2473 (0 << PHY_S6G_ENA_LANE_POS) |
2474 (0 << PHY_S6G_ENA_LOOP_POS) |
2475 (0 << PHY_S6G_QRATE_POS) |
2476 (3 << PHY_S6G_IF_MODE_POS));
2481 ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2482 PHY_S6G_MISC_CFG, 1);
2487 ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2488 PHY_S6G_GPC_CFG, 768);
2492 phy_commit_mcb_s6g(phydev, PHY_S6G_DFT_CFG2, 0);
2494 deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
2496 usleep_range(500, 1000);
2497 phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG,
2498 0); /* read 6G MCB into CSRs */
2499 reg = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET,
2500 PHY_S6G_PLL_STATUS);
2501 if (reg == 0xffffffff) {
2502 mutex_unlock(&phydev->mdio.bus->mdio_lock);
2506 } while (time_before(jiffies, deadline) && (reg & BIT(12)));
2508 if (reg & BIT(12)) {
2509 mutex_unlock(&phydev->mdio.bus->mdio_lock);
2514 ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2515 PHY_S6G_MISC_CFG, 0);
2519 phy_commit_mcb_s6g(phydev, PHY_MCB_S6G_CFG, 0);
2521 deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
2523 usleep_range(500, 1000);
2524 phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG,
2525 0); /* read 6G MCB into CSRs */
2526 reg = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET,
2527 PHY_S6G_IB_STATUS0);
2528 if (reg == 0xffffffff) {
2529 mutex_unlock(&phydev->mdio.bus->mdio_lock);
2533 } while (time_before(jiffies, deadline) && !(reg & BIT(8)));
2535 if (!(reg & BIT(8))) {
2536 mutex_unlock(&phydev->mdio.bus->mdio_lock);
2540 mutex_unlock(&phydev->mdio.bus->mdio_lock);
2542 ret = phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2547 ret = phy_modify(phydev, MSCC_PHY_EXT_PHY_CNTL_1, MEDIA_OP_MODE_MASK,
2548 MEDIA_OP_MODE_COPPER);
2553 ret = genphy_soft_reset(phydev);
2558 for (i = 0; i < vsc8531->nleds; i++) {
2559 ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
2567 mutex_unlock(&phydev->mdio.bus->mdio_lock);
2571 static int vsc85xx_ack_interrupt(struct phy_device *phydev)
2575 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
2576 rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2578 return (rc < 0) ? rc : 0;
2581 static int vsc85xx_config_intr(struct phy_device *phydev)
2585 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
2586 rc = phy_write(phydev, MII_VSC85XX_INT_MASK,
2587 MII_VSC85XX_INT_MASK_MASK);
2589 rc = phy_write(phydev, MII_VSC85XX_INT_MASK, 0);
2592 rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2598 static int vsc85xx_config_aneg(struct phy_device *phydev)
2602 rc = vsc85xx_mdix_set(phydev, phydev->mdix_ctrl);
2606 return genphy_config_aneg(phydev);
2609 static int vsc85xx_read_status(struct phy_device *phydev)
2613 rc = vsc85xx_mdix_get(phydev, &phydev->mdix);
2617 return genphy_read_status(phydev);
2620 static int vsc8514_probe(struct phy_device *phydev)
2622 struct vsc8531_private *vsc8531;
2623 u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
2624 VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
2625 VSC8531_DUPLEX_COLLISION};
2627 vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2631 phydev->priv = vsc8531;
2634 vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
2635 vsc8531->hw_stats = vsc85xx_hw_stats;
2636 vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
2637 vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2638 sizeof(u64), GFP_KERNEL);
2639 if (!vsc8531->stats)
2642 return vsc85xx_dt_led_modes_get(phydev, default_mode);
2645 static int vsc8574_probe(struct phy_device *phydev)
2647 struct vsc8531_private *vsc8531;
2648 u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
2649 VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
2650 VSC8531_DUPLEX_COLLISION};
2652 vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2656 phydev->priv = vsc8531;
2659 vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
2660 vsc8531->hw_stats = vsc8584_hw_stats;
2661 vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
2662 vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2663 sizeof(u64), GFP_KERNEL);
2664 if (!vsc8531->stats)
2667 return vsc85xx_dt_led_modes_get(phydev, default_mode);
2670 static int vsc8584_probe(struct phy_device *phydev)
2672 struct vsc8531_private *vsc8531;
2673 u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
2674 VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
2675 VSC8531_DUPLEX_COLLISION};
2677 if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
2678 dev_err(&phydev->mdio.dev, "Only VSC8584 revB is supported.\n");
2682 vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2686 phydev->priv = vsc8531;
2689 vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
2690 vsc8531->hw_stats = vsc8584_hw_stats;
2691 vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
2692 vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2693 sizeof(u64), GFP_KERNEL);
2694 if (!vsc8531->stats)
2697 return vsc85xx_dt_led_modes_get(phydev, default_mode);
2700 static int vsc85xx_probe(struct phy_device *phydev)
2702 struct vsc8531_private *vsc8531;
2704 u32 default_mode[2] = {VSC8531_LINK_1000_ACTIVITY,
2705 VSC8531_LINK_100_ACTIVITY};
2707 rate_magic = vsc85xx_edge_rate_magic_get(phydev);
2711 vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2715 phydev->priv = vsc8531;
2717 vsc8531->rate_magic = rate_magic;
2719 vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
2720 vsc8531->hw_stats = vsc85xx_hw_stats;
2721 vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
2722 vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
2723 sizeof(u64), GFP_KERNEL);
2724 if (!vsc8531->stats)
2727 return vsc85xx_dt_led_modes_get(phydev, default_mode);
2730 /* Microsemi VSC85xx PHYs */
2731 static struct phy_driver vsc85xx_driver[] = {
2733 .phy_id = PHY_ID_VSC8504,
2734 .name = "Microsemi GE VSC8504 SyncE",
2735 .phy_id_mask = 0xfffffff0,
2736 /* PHY_GBIT_FEATURES */
2737 .soft_reset = &genphy_soft_reset,
2738 .config_init = &vsc8584_config_init,
2739 .config_aneg = &vsc85xx_config_aneg,
2740 .aneg_done = &genphy_aneg_done,
2741 .read_status = &vsc85xx_read_status,
2742 .ack_interrupt = &vsc85xx_ack_interrupt,
2743 .config_intr = &vsc85xx_config_intr,
2744 .did_interrupt = &vsc8584_did_interrupt,
2745 .suspend = &genphy_suspend,
2746 .resume = &genphy_resume,
2747 .probe = &vsc8574_probe,
2748 .set_wol = &vsc85xx_wol_set,
2749 .get_wol = &vsc85xx_wol_get,
2750 .get_tunable = &vsc85xx_get_tunable,
2751 .set_tunable = &vsc85xx_set_tunable,
2752 .read_page = &vsc85xx_phy_read_page,
2753 .write_page = &vsc85xx_phy_write_page,
2754 .get_sset_count = &vsc85xx_get_sset_count,
2755 .get_strings = &vsc85xx_get_strings,
2756 .get_stats = &vsc85xx_get_stats,
2759 .phy_id = PHY_ID_VSC8514,
2760 .name = "Microsemi GE VSC8514 SyncE",
2761 .phy_id_mask = 0xfffffff0,
2762 .soft_reset = &genphy_soft_reset,
2763 .config_init = &vsc8514_config_init,
2764 .config_aneg = &vsc85xx_config_aneg,
2765 .read_status = &vsc85xx_read_status,
2766 .ack_interrupt = &vsc85xx_ack_interrupt,
2767 .config_intr = &vsc85xx_config_intr,
2768 .suspend = &genphy_suspend,
2769 .resume = &genphy_resume,
2770 .probe = &vsc8514_probe,
2771 .set_wol = &vsc85xx_wol_set,
2772 .get_wol = &vsc85xx_wol_get,
2773 .get_tunable = &vsc85xx_get_tunable,
2774 .set_tunable = &vsc85xx_set_tunable,
2775 .read_page = &vsc85xx_phy_read_page,
2776 .write_page = &vsc85xx_phy_write_page,
2777 .get_sset_count = &vsc85xx_get_sset_count,
2778 .get_strings = &vsc85xx_get_strings,
2779 .get_stats = &vsc85xx_get_stats,
2782 .phy_id = PHY_ID_VSC8530,
2783 .name = "Microsemi FE VSC8530",
2784 .phy_id_mask = 0xfffffff0,
2785 /* PHY_BASIC_FEATURES */
2786 .soft_reset = &genphy_soft_reset,
2787 .config_init = &vsc85xx_config_init,
2788 .config_aneg = &vsc85xx_config_aneg,
2789 .read_status = &vsc85xx_read_status,
2790 .ack_interrupt = &vsc85xx_ack_interrupt,
2791 .config_intr = &vsc85xx_config_intr,
2792 .suspend = &genphy_suspend,
2793 .resume = &genphy_resume,
2794 .probe = &vsc85xx_probe,
2795 .set_wol = &vsc85xx_wol_set,
2796 .get_wol = &vsc85xx_wol_get,
2797 .get_tunable = &vsc85xx_get_tunable,
2798 .set_tunable = &vsc85xx_set_tunable,
2799 .read_page = &vsc85xx_phy_read_page,
2800 .write_page = &vsc85xx_phy_write_page,
2801 .get_sset_count = &vsc85xx_get_sset_count,
2802 .get_strings = &vsc85xx_get_strings,
2803 .get_stats = &vsc85xx_get_stats,
2806 .phy_id = PHY_ID_VSC8531,
2807 .name = "Microsemi VSC8531",
2808 .phy_id_mask = 0xfffffff0,
2809 /* PHY_GBIT_FEATURES */
2810 .soft_reset = &genphy_soft_reset,
2811 .config_init = &vsc85xx_config_init,
2812 .config_aneg = &vsc85xx_config_aneg,
2813 .read_status = &vsc85xx_read_status,
2814 .ack_interrupt = &vsc85xx_ack_interrupt,
2815 .config_intr = &vsc85xx_config_intr,
2816 .suspend = &genphy_suspend,
2817 .resume = &genphy_resume,
2818 .probe = &vsc85xx_probe,
2819 .set_wol = &vsc85xx_wol_set,
2820 .get_wol = &vsc85xx_wol_get,
2821 .get_tunable = &vsc85xx_get_tunable,
2822 .set_tunable = &vsc85xx_set_tunable,
2823 .read_page = &vsc85xx_phy_read_page,
2824 .write_page = &vsc85xx_phy_write_page,
2825 .get_sset_count = &vsc85xx_get_sset_count,
2826 .get_strings = &vsc85xx_get_strings,
2827 .get_stats = &vsc85xx_get_stats,
2830 .phy_id = PHY_ID_VSC8540,
2831 .name = "Microsemi FE VSC8540 SyncE",
2832 .phy_id_mask = 0xfffffff0,
2833 /* PHY_BASIC_FEATURES */
2834 .soft_reset = &genphy_soft_reset,
2835 .config_init = &vsc85xx_config_init,
2836 .config_aneg = &vsc85xx_config_aneg,
2837 .read_status = &vsc85xx_read_status,
2838 .ack_interrupt = &vsc85xx_ack_interrupt,
2839 .config_intr = &vsc85xx_config_intr,
2840 .suspend = &genphy_suspend,
2841 .resume = &genphy_resume,
2842 .probe = &vsc85xx_probe,
2843 .set_wol = &vsc85xx_wol_set,
2844 .get_wol = &vsc85xx_wol_get,
2845 .get_tunable = &vsc85xx_get_tunable,
2846 .set_tunable = &vsc85xx_set_tunable,
2847 .read_page = &vsc85xx_phy_read_page,
2848 .write_page = &vsc85xx_phy_write_page,
2849 .get_sset_count = &vsc85xx_get_sset_count,
2850 .get_strings = &vsc85xx_get_strings,
2851 .get_stats = &vsc85xx_get_stats,
2854 .phy_id = PHY_ID_VSC8541,
2855 .name = "Microsemi VSC8541 SyncE",
2856 .phy_id_mask = 0xfffffff0,
2857 /* PHY_GBIT_FEATURES */
2858 .soft_reset = &genphy_soft_reset,
2859 .config_init = &vsc85xx_config_init,
2860 .config_aneg = &vsc85xx_config_aneg,
2861 .read_status = &vsc85xx_read_status,
2862 .ack_interrupt = &vsc85xx_ack_interrupt,
2863 .config_intr = &vsc85xx_config_intr,
2864 .suspend = &genphy_suspend,
2865 .resume = &genphy_resume,
2866 .probe = &vsc85xx_probe,
2867 .set_wol = &vsc85xx_wol_set,
2868 .get_wol = &vsc85xx_wol_get,
2869 .get_tunable = &vsc85xx_get_tunable,
2870 .set_tunable = &vsc85xx_set_tunable,
2871 .read_page = &vsc85xx_phy_read_page,
2872 .write_page = &vsc85xx_phy_write_page,
2873 .get_sset_count = &vsc85xx_get_sset_count,
2874 .get_strings = &vsc85xx_get_strings,
2875 .get_stats = &vsc85xx_get_stats,
2878 .phy_id = PHY_ID_VSC8552,
2879 .name = "Microsemi GE VSC8552 SyncE",
2880 .phy_id_mask = 0xfffffff0,
2881 /* PHY_GBIT_FEATURES */
2882 .soft_reset = &genphy_soft_reset,
2883 .config_init = &vsc8584_config_init,
2884 .config_aneg = &vsc85xx_config_aneg,
2885 .read_status = &vsc85xx_read_status,
2886 .ack_interrupt = &vsc85xx_ack_interrupt,
2887 .config_intr = &vsc85xx_config_intr,
2888 .did_interrupt = &vsc8584_did_interrupt,
2889 .suspend = &genphy_suspend,
2890 .resume = &genphy_resume,
2891 .probe = &vsc8574_probe,
2892 .set_wol = &vsc85xx_wol_set,
2893 .get_wol = &vsc85xx_wol_get,
2894 .get_tunable = &vsc85xx_get_tunable,
2895 .set_tunable = &vsc85xx_set_tunable,
2896 .read_page = &vsc85xx_phy_read_page,
2897 .write_page = &vsc85xx_phy_write_page,
2898 .get_sset_count = &vsc85xx_get_sset_count,
2899 .get_strings = &vsc85xx_get_strings,
2900 .get_stats = &vsc85xx_get_stats,
2903 .phy_id = PHY_ID_VSC856X,
2904 .name = "Microsemi GE VSC856X SyncE",
2905 .phy_id_mask = 0xfffffff0,
2906 /* PHY_GBIT_FEATURES */
2907 .soft_reset = &genphy_soft_reset,
2908 .config_init = &vsc8584_config_init,
2909 .config_aneg = &vsc85xx_config_aneg,
2910 .read_status = &vsc85xx_read_status,
2911 .ack_interrupt = &vsc85xx_ack_interrupt,
2912 .config_intr = &vsc85xx_config_intr,
2913 .did_interrupt = &vsc8584_did_interrupt,
2914 .suspend = &genphy_suspend,
2915 .resume = &genphy_resume,
2916 .probe = &vsc8584_probe,
2917 .get_tunable = &vsc85xx_get_tunable,
2918 .set_tunable = &vsc85xx_set_tunable,
2919 .read_page = &vsc85xx_phy_read_page,
2920 .write_page = &vsc85xx_phy_write_page,
2921 .get_sset_count = &vsc85xx_get_sset_count,
2922 .get_strings = &vsc85xx_get_strings,
2923 .get_stats = &vsc85xx_get_stats,
2926 .phy_id = PHY_ID_VSC8572,
2927 .name = "Microsemi GE VSC8572 SyncE",
2928 .phy_id_mask = 0xfffffff0,
2929 /* PHY_GBIT_FEATURES */
2930 .soft_reset = &genphy_soft_reset,
2931 .config_init = &vsc8584_config_init,
2932 .config_aneg = &vsc85xx_config_aneg,
2933 .aneg_done = &genphy_aneg_done,
2934 .read_status = &vsc85xx_read_status,
2935 .ack_interrupt = &vsc85xx_ack_interrupt,
2936 .config_intr = &vsc85xx_config_intr,
2937 .did_interrupt = &vsc8584_did_interrupt,
2938 .suspend = &genphy_suspend,
2939 .resume = &genphy_resume,
2940 .probe = &vsc8574_probe,
2941 .set_wol = &vsc85xx_wol_set,
2942 .get_wol = &vsc85xx_wol_get,
2943 .get_tunable = &vsc85xx_get_tunable,
2944 .set_tunable = &vsc85xx_set_tunable,
2945 .read_page = &vsc85xx_phy_read_page,
2946 .write_page = &vsc85xx_phy_write_page,
2947 .get_sset_count = &vsc85xx_get_sset_count,
2948 .get_strings = &vsc85xx_get_strings,
2949 .get_stats = &vsc85xx_get_stats,
2952 .phy_id = PHY_ID_VSC8574,
2953 .name = "Microsemi GE VSC8574 SyncE",
2954 .phy_id_mask = 0xfffffff0,
2955 /* PHY_GBIT_FEATURES */
2956 .soft_reset = &genphy_soft_reset,
2957 .config_init = &vsc8584_config_init,
2958 .config_aneg = &vsc85xx_config_aneg,
2959 .aneg_done = &genphy_aneg_done,
2960 .read_status = &vsc85xx_read_status,
2961 .ack_interrupt = &vsc85xx_ack_interrupt,
2962 .config_intr = &vsc85xx_config_intr,
2963 .did_interrupt = &vsc8584_did_interrupt,
2964 .suspend = &genphy_suspend,
2965 .resume = &genphy_resume,
2966 .probe = &vsc8574_probe,
2967 .set_wol = &vsc85xx_wol_set,
2968 .get_wol = &vsc85xx_wol_get,
2969 .get_tunable = &vsc85xx_get_tunable,
2970 .set_tunable = &vsc85xx_set_tunable,
2971 .read_page = &vsc85xx_phy_read_page,
2972 .write_page = &vsc85xx_phy_write_page,
2973 .get_sset_count = &vsc85xx_get_sset_count,
2974 .get_strings = &vsc85xx_get_strings,
2975 .get_stats = &vsc85xx_get_stats,
2978 .phy_id = PHY_ID_VSC8575,
2979 .name = "Microsemi GE VSC8575 SyncE",
2980 .phy_id_mask = 0xfffffff0,
2981 /* PHY_GBIT_FEATURES */
2982 .soft_reset = &genphy_soft_reset,
2983 .config_init = &vsc8584_config_init,
2984 .config_aneg = &vsc85xx_config_aneg,
2985 .aneg_done = &genphy_aneg_done,
2986 .read_status = &vsc85xx_read_status,
2987 .ack_interrupt = &vsc85xx_ack_interrupt,
2988 .config_intr = &vsc85xx_config_intr,
2989 .did_interrupt = &vsc8584_did_interrupt,
2990 .suspend = &genphy_suspend,
2991 .resume = &genphy_resume,
2992 .probe = &vsc8584_probe,
2993 .get_tunable = &vsc85xx_get_tunable,
2994 .set_tunable = &vsc85xx_set_tunable,
2995 .read_page = &vsc85xx_phy_read_page,
2996 .write_page = &vsc85xx_phy_write_page,
2997 .get_sset_count = &vsc85xx_get_sset_count,
2998 .get_strings = &vsc85xx_get_strings,
2999 .get_stats = &vsc85xx_get_stats,
3002 .phy_id = PHY_ID_VSC8582,
3003 .name = "Microsemi GE VSC8582 SyncE",
3004 .phy_id_mask = 0xfffffff0,
3005 /* PHY_GBIT_FEATURES */
3006 .soft_reset = &genphy_soft_reset,
3007 .config_init = &vsc8584_config_init,
3008 .config_aneg = &vsc85xx_config_aneg,
3009 .aneg_done = &genphy_aneg_done,
3010 .read_status = &vsc85xx_read_status,
3011 .ack_interrupt = &vsc85xx_ack_interrupt,
3012 .config_intr = &vsc85xx_config_intr,
3013 .did_interrupt = &vsc8584_did_interrupt,
3014 .suspend = &genphy_suspend,
3015 .resume = &genphy_resume,
3016 .probe = &vsc8584_probe,
3017 .get_tunable = &vsc85xx_get_tunable,
3018 .set_tunable = &vsc85xx_set_tunable,
3019 .read_page = &vsc85xx_phy_read_page,
3020 .write_page = &vsc85xx_phy_write_page,
3021 .get_sset_count = &vsc85xx_get_sset_count,
3022 .get_strings = &vsc85xx_get_strings,
3023 .get_stats = &vsc85xx_get_stats,
3026 .phy_id = PHY_ID_VSC8584,
3027 .name = "Microsemi GE VSC8584 SyncE",
3028 .phy_id_mask = 0xfffffff0,
3029 /* PHY_GBIT_FEATURES */
3030 .soft_reset = &genphy_soft_reset,
3031 .config_init = &vsc8584_config_init,
3032 .config_aneg = &vsc85xx_config_aneg,
3033 .aneg_done = &genphy_aneg_done,
3034 .read_status = &vsc85xx_read_status,
3035 .ack_interrupt = &vsc85xx_ack_interrupt,
3036 .config_intr = &vsc85xx_config_intr,
3037 .did_interrupt = &vsc8584_did_interrupt,
3038 .suspend = &genphy_suspend,
3039 .resume = &genphy_resume,
3040 .probe = &vsc8584_probe,
3041 .get_tunable = &vsc85xx_get_tunable,
3042 .set_tunable = &vsc85xx_set_tunable,
3043 .read_page = &vsc85xx_phy_read_page,
3044 .write_page = &vsc85xx_phy_write_page,
3045 .get_sset_count = &vsc85xx_get_sset_count,
3046 .get_strings = &vsc85xx_get_strings,
3047 .get_stats = &vsc85xx_get_stats,
3052 module_phy_driver(vsc85xx_driver);
3054 static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
3055 { PHY_ID_VSC8504, 0xfffffff0, },
3056 { PHY_ID_VSC8514, 0xfffffff0, },
3057 { PHY_ID_VSC8530, 0xfffffff0, },
3058 { PHY_ID_VSC8531, 0xfffffff0, },
3059 { PHY_ID_VSC8540, 0xfffffff0, },
3060 { PHY_ID_VSC8541, 0xfffffff0, },
3061 { PHY_ID_VSC8552, 0xfffffff0, },
3062 { PHY_ID_VSC856X, 0xfffffff0, },
3063 { PHY_ID_VSC8572, 0xfffffff0, },
3064 { PHY_ID_VSC8574, 0xfffffff0, },
3065 { PHY_ID_VSC8575, 0xfffffff0, },
3066 { PHY_ID_VSC8582, 0xfffffff0, },
3067 { PHY_ID_VSC8584, 0xfffffff0, },
3071 MODULE_DEVICE_TABLE(mdio, vsc85xx_tbl);
3073 MODULE_DESCRIPTION("Microsemi VSC85xx PHY driver");
3074 MODULE_AUTHOR("Nagaraju Lakkaraju");
3075 MODULE_LICENSE("Dual MIT/GPL");