]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/net/phy/mscc.c
8579a59a1336a9bbdc6b47fa25795fe72f7360af
[linux.git] / drivers / net / phy / mscc.c
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 "mscc_macsec.h"
22 #include "mscc_mac.h"
23 #include "mscc_fc_buffer.h"
24
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
34 };
35
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
43
44 #define MSCC_PHY_EXT_CNTL_STATUS          22
45 #define SMI_BROADCAST_WR_EN               0x0001
46
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)
51
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
72
73 #define MSCC_PHY_EXT_PHY_CNTL_2           24
74
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
79
80 #define MSCC_PHY_WOL_MAC_CONTROL          27
81 #define EDGE_RATE_CNTL_POS                5
82 #define EDGE_RATE_CNTL_MASK               0x00E0
83
84 #define MSCC_PHY_DEV_AUX_CNTL             28
85 #define HP_AUTO_MDIX_X_OVER_IND_MASK      0x2000
86
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))
91
92 #define MSCC_EXT_PAGE_CSR_CNTL_17         17
93 #define MSCC_EXT_PAGE_CSR_CNTL_18         18
94
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)
100
101 #define MSCC_EXT_PAGE_CSR_CNTL_20         20
102 #define MSCC_PHY_CSR_CNTL_20_TARGET(x)    (x)
103
104 #define PHY_MCB_TARGET                    0x07
105 #define PHY_MCB_S6G_WRITE                 BIT(31)
106 #define PHY_MCB_S6G_READ                  BIT(30)
107
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
118
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
127
128 #define MSCC_EXT_PAGE_MACSEC_17           17
129 #define MSCC_EXT_PAGE_MACSEC_18           18
130
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)
136
137 #define MSCC_EXT_PAGE_MACSEC_20           20
138 #define MSCC_PHY_MACSEC_20_TARGET(x)      (x)
139 enum macsec_bank {
140         FC_BUFFER   = 0x04,
141         HOST_MAC    = 0x05,
142         LINE_MAC    = 0x06,
143         IP_1588     = 0x0e,
144         MACSEC_INGR = 0x38,
145         MACSEC_EGR  = 0x3c,
146 };
147
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.
158  */
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 */
162
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)
166
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
171
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
177
178 #define MSCC_PHY_EXT_PHY_CNTL_4           23
179 #define PHY_CNTL_4_ADDR_POS               11
180
181 #define MSCC_PHY_VERIPHY_CNTL_2           25
182
183 #define MSCC_PHY_VERIPHY_CNTL_3           26
184
185 /* Extended Page 2 Registers */
186 #define MSCC_PHY_CU_PMD_TX_CNTL           16
187
188 #define MSCC_PHY_RGMII_CNTL               20
189 #define RGMII_RX_CLK_DELAY_MASK           0x0070
190 #define RGMII_RX_CLK_DELAY_POS            4
191
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
198
199 #define MSCC_PHY_WOL_MAC_CONTROL          27
200 #define SECURE_ON_ENABLE                  0x8000
201 #define SECURE_ON_PASSWD_LEN_4            0x4000
202
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
208
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
220
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
225
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))
235
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
260
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
265
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
272
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
279
280 /* Microsemi PHY ID's
281  *   Code assumes lowest nibble is 0
282  */
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
296
297 #define MSCC_VDDMAC_1500                  1500
298 #define MSCC_VDDMAC_1800                  1800
299 #define MSCC_VDDMAC_2500                  2500
300 #define MSCC_VDDMAC_3300                  3300
301
302 #define DOWNSHIFT_COUNT_MAX               5
303
304 #define MAX_LEDS                          4
305
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))
322
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))
337
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
341
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
345
346 #define VSC8584_REVB                            0x0001
347 #define MSCC_DEV_REV_MASK                       GENMASK(3, 0)
348
349 struct reg_val {
350         u16     reg;
351         u32     val;
352 };
353
354 struct vsc85xx_hw_stat {
355         const char *string;
356         u8 reg;
357         u16 page;
358         u16 mask;
359 };
360
361 static const struct vsc85xx_hw_stat vsc85xx_hw_stats[] = {
362         {
363                 .string = "phy_receive_errors",
364                 .reg    = MSCC_PHY_ERR_RX_CNT,
365                 .page   = MSCC_PHY_PAGE_STANDARD,
366                 .mask   = ERR_CNT_MASK,
367         }, {
368                 .string = "phy_false_carrier",
369                 .reg    = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
370                 .page   = MSCC_PHY_PAGE_STANDARD,
371                 .mask   = ERR_CNT_MASK,
372         }, {
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,
377         }, {
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,
382         }, {
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,
387         },
388 };
389
390 static const struct vsc85xx_hw_stat vsc8584_hw_stats[] = {
391         {
392                 .string = "phy_receive_errors",
393                 .reg    = MSCC_PHY_ERR_RX_CNT,
394                 .page   = MSCC_PHY_PAGE_STANDARD,
395                 .mask   = ERR_CNT_MASK,
396         }, {
397                 .string = "phy_false_carrier",
398                 .reg    = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
399                 .page   = MSCC_PHY_PAGE_STANDARD,
400                 .mask   = ERR_CNT_MASK,
401         }, {
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,
406         }, {
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,
411         }, {
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,
416         }, {
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,
421         }, {
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,
426         }, {
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,
431         }, {
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,
436         },
437 };
438
439 struct vsc8531_private {
440         int rate_magic;
441         u16 supp_led_modes;
442         u32 leds_mode[MAX_LEDS];
443         u8 nleds;
444         const struct vsc85xx_hw_stat *hw_stats;
445         u64 *stats;
446         int nstats;
447         bool pkg_init;
448         /* For multiple port PHYs; the MDIO address of the base PHY in the
449          * package.
450          */
451         unsigned int base_addr;
452 };
453
454 #ifdef CONFIG_OF_MDIO
455 struct vsc8531_edge_rate_table {
456         u32 vddmac;
457         u32 slowdown[8];
458 };
459
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} },
465 };
466 #endif /* CONFIG_OF_MDIO */
467
468 static int vsc85xx_phy_read_page(struct phy_device *phydev)
469 {
470         return __phy_read(phydev, MSCC_EXT_PAGE_ACCESS);
471 }
472
473 static int vsc85xx_phy_write_page(struct phy_device *phydev, int page)
474 {
475         return __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, page);
476 }
477
478 static int vsc85xx_get_sset_count(struct phy_device *phydev)
479 {
480         struct vsc8531_private *priv = phydev->priv;
481
482         if (!priv)
483                 return 0;
484
485         return priv->nstats;
486 }
487
488 static void vsc85xx_get_strings(struct phy_device *phydev, u8 *data)
489 {
490         struct vsc8531_private *priv = phydev->priv;
491         int i;
492
493         if (!priv)
494                 return;
495
496         for (i = 0; i < priv->nstats; i++)
497                 strlcpy(data + i * ETH_GSTRING_LEN, priv->hw_stats[i].string,
498                         ETH_GSTRING_LEN);
499 }
500
501 static u64 vsc85xx_get_stat(struct phy_device *phydev, int i)
502 {
503         struct vsc8531_private *priv = phydev->priv;
504         int val;
505
506         val = phy_read_paged(phydev, priv->hw_stats[i].page,
507                              priv->hw_stats[i].reg);
508         if (val < 0)
509                 return U64_MAX;
510
511         val = val & priv->hw_stats[i].mask;
512         priv->stats[i] += val;
513
514         return priv->stats[i];
515 }
516
517 static void vsc85xx_get_stats(struct phy_device *phydev,
518                               struct ethtool_stats *stats, u64 *data)
519 {
520         struct vsc8531_private *priv = phydev->priv;
521         int i;
522
523         if (!priv)
524                 return;
525
526         for (i = 0; i < priv->nstats; i++)
527                 data[i] = vsc85xx_get_stat(phydev, i);
528 }
529
530 static int vsc85xx_led_cntl_set(struct phy_device *phydev,
531                                 u8 led_num,
532                                 u8 mode)
533 {
534         int rc;
535         u16 reg_val;
536
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);
543
544         return rc;
545 }
546
547 static int vsc85xx_mdix_get(struct phy_device *phydev, u8 *mdix)
548 {
549         u16 reg_val;
550
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;
554         else
555                 *mdix = ETH_TP_MDI;
556
557         return 0;
558 }
559
560 static int vsc85xx_mdix_set(struct phy_device *phydev, u8 mdix)
561 {
562         int rc;
563         u16 reg_val;
564
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);
570         } else {
571                 reg_val &= ~(DISABLE_PAIR_SWAP_CORR_MASK |
572                              DISABLE_POLARITY_CORR_MASK  |
573                              DISABLE_HP_AUTO_MDIX_MASK);
574         }
575         rc = phy_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg_val);
576         if (rc)
577                 return rc;
578
579         reg_val = 0;
580
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;
585
586         rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
587                               MSCC_PHY_EXT_MODE_CNTL, FORCE_MDI_CROSSOVER_MASK,
588                               reg_val);
589         if (rc < 0)
590                 return rc;
591
592         return genphy_restart_aneg(phydev);
593 }
594
595 static int vsc85xx_downshift_get(struct phy_device *phydev, u8 *count)
596 {
597         int reg_val;
598
599         reg_val = phy_read_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
600                                  MSCC_PHY_ACTIPHY_CNTL);
601         if (reg_val < 0)
602                 return reg_val;
603
604         reg_val &= DOWNSHIFT_CNTL_MASK;
605         if (!(reg_val & DOWNSHIFT_EN))
606                 *count = DOWNSHIFT_DEV_DISABLE;
607         else
608                 *count = ((reg_val & ~DOWNSHIFT_EN) >> DOWNSHIFT_CNTL_POS) + 2;
609
610         return 0;
611 }
612
613 static int vsc85xx_downshift_set(struct phy_device *phydev, u8 count)
614 {
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");
620                 return -ERANGE;
621         } else if (count) {
622                 /* Downshift count is either 2,3,4 or 5 */
623                 count = (((count - 2) << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
624         }
625
626         return phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
627                                 MSCC_PHY_ACTIPHY_CNTL, DOWNSHIFT_CNTL_MASK,
628                                 count);
629 }
630
631 static int vsc85xx_wol_set(struct phy_device *phydev,
632                            struct ethtool_wolinfo *wol)
633 {
634         int rc;
635         u16 reg_val;
636         u8  i;
637         u16 pwd[3] = {0, 0, 0};
638         struct ethtool_wolinfo *wol_conf = wol;
639         u8 *mac_addr = phydev->attached_dev->dev_addr;
640
641         mutex_lock(&phydev->lock);
642         rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
643         if (rc < 0) {
644                 rc = phy_restore_page(phydev, rc, rc);
645                 goto out_unlock;
646         }
647
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 |
652                                  mac_addr[5 - i * 2];
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]);
656         } else {
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);
660         }
661
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]);
669         } else {
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);
673         }
674
675         reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
676         if (wol_conf->wolopts & WAKE_MAGICSECURE)
677                 reg_val |= SECURE_ON_ENABLE;
678         else
679                 reg_val &= ~SECURE_ON_ENABLE;
680         __phy_write(phydev, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
681
682         rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
683         if (rc < 0)
684                 goto out_unlock;
685
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);
691                 if (rc)
692                         goto out_unlock;
693         } else {
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);
698                 if (rc)
699                         goto out_unlock;
700         }
701         /* Clear WOL iterrupt status */
702         reg_val = phy_read(phydev, MII_VSC85XX_INT_STATUS);
703
704 out_unlock:
705         mutex_unlock(&phydev->lock);
706
707         return rc;
708 }
709
710 static void vsc85xx_wol_get(struct phy_device *phydev,
711                             struct ethtool_wolinfo *wol)
712 {
713         int rc;
714         u16 reg_val;
715         u8  i;
716         u16 pwd[3] = {0, 0, 0};
717         struct ethtool_wolinfo *wol_conf = wol;
718
719         mutex_lock(&phydev->lock);
720         rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
721         if (rc < 0)
722                 goto out_unlock;
723
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)
734                                                             >> 8;
735                 }
736         }
737
738 out_unlock:
739         phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
740         mutex_unlock(&phydev->lock);
741 }
742
743 #ifdef CONFIG_OF_MDIO
744 static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
745 {
746         u32 vdd, sd;
747         int i, j;
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);
751
752         if (!of_node)
753                 return -ENODEV;
754
755         if (of_property_read_u32(of_node, "vsc8531,vddmac", &vdd))
756                 vdd = MSCC_VDDMAC_3300;
757
758         if (of_property_read_u32(of_node, "vsc8531,edge-slowdown", &sd))
759                 sd = 0;
760
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);
766
767         return -EINVAL;
768 }
769
770 static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
771                                    char *led,
772                                    u32 default_mode)
773 {
774         struct vsc8531_private *priv = phydev->priv;
775         struct device *dev = &phydev->mdio.dev;
776         struct device_node *of_node = dev->of_node;
777         u32 led_mode;
778         int err;
779
780         if (!of_node)
781                 return -ENODEV;
782
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);
787                 return -EINVAL;
788         }
789
790         return led_mode;
791 }
792
793 #else
794 static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
795 {
796         return 0;
797 }
798
799 static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
800                                    char *led,
801                                    u8 default_mode)
802 {
803         return default_mode;
804 }
805 #endif /* CONFIG_OF_MDIO */
806
807 static int vsc85xx_dt_led_modes_get(struct phy_device *phydev,
808                                     u32 *default_mode)
809 {
810         struct vsc8531_private *priv = phydev->priv;
811         char led_dt_prop[28];
812         int i, ret;
813
814         for (i = 0; i < priv->nleds; i++) {
815                 ret = sprintf(led_dt_prop, "vsc8531,led-%d-mode", i);
816                 if (ret < 0)
817                         return ret;
818
819                 ret = vsc85xx_dt_led_mode_get(phydev, led_dt_prop,
820                                               default_mode[i]);
821                 if (ret < 0)
822                         return ret;
823                 priv->leds_mode[i] = ret;
824         }
825
826         return 0;
827 }
828
829 static int vsc85xx_edge_rate_cntl_set(struct phy_device *phydev, u8 edge_rate)
830 {
831         int rc;
832
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);
838
839         return rc;
840 }
841
842 static int vsc85xx_mac_if_set(struct phy_device *phydev,
843                               phy_interface_t interface)
844 {
845         int rc;
846         u16 reg_val;
847
848         mutex_lock(&phydev->lock);
849         reg_val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
850         reg_val &= ~(MAC_IF_SELECTION_MASK);
851         switch (interface) {
852         case PHY_INTERFACE_MODE_RGMII:
853                 reg_val |= (MAC_IF_SELECTION_RGMII << MAC_IF_SELECTION_POS);
854                 break;
855         case PHY_INTERFACE_MODE_RMII:
856                 reg_val |= (MAC_IF_SELECTION_RMII << MAC_IF_SELECTION_POS);
857                 break;
858         case PHY_INTERFACE_MODE_MII:
859         case PHY_INTERFACE_MODE_GMII:
860                 reg_val |= (MAC_IF_SELECTION_GMII << MAC_IF_SELECTION_POS);
861                 break;
862         default:
863                 rc = -EINVAL;
864                 goto out_unlock;
865         }
866         rc = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, reg_val);
867         if (rc)
868                 goto out_unlock;
869
870         rc = genphy_soft_reset(phydev);
871
872 out_unlock:
873         mutex_unlock(&phydev->lock);
874
875         return rc;
876 }
877
878 static int vsc85xx_default_config(struct phy_device *phydev)
879 {
880         int rc;
881         u16 reg_val;
882
883         phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
884         mutex_lock(&phydev->lock);
885
886         reg_val = RGMII_RX_CLK_DELAY_1_1_NS << RGMII_RX_CLK_DELAY_POS;
887
888         rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
889                               MSCC_PHY_RGMII_CNTL, RGMII_RX_CLK_DELAY_MASK,
890                               reg_val);
891
892         mutex_unlock(&phydev->lock);
893
894         return rc;
895 }
896
897 static int vsc85xx_get_tunable(struct phy_device *phydev,
898                                struct ethtool_tunable *tuna, void *data)
899 {
900         switch (tuna->id) {
901         case ETHTOOL_PHY_DOWNSHIFT:
902                 return vsc85xx_downshift_get(phydev, (u8 *)data);
903         default:
904                 return -EINVAL;
905         }
906 }
907
908 static int vsc85xx_set_tunable(struct phy_device *phydev,
909                                struct ethtool_tunable *tuna,
910                                const void *data)
911 {
912         switch (tuna->id) {
913         case ETHTOOL_PHY_DOWNSHIFT:
914                 return vsc85xx_downshift_set(phydev, *(u8 *)data);
915         default:
916                 return -EINVAL;
917         }
918 }
919
920 /* mdiobus lock should be locked when using this function */
921 static void vsc85xx_tr_write(struct phy_device *phydev, u16 addr, u32 val)
922 {
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));
926 }
927
928 static int vsc8531_pre_init_seq_set(struct phy_device *phydev)
929 {
930         int rc;
931         static const struct reg_val init_seq[] = {
932                 {0x0f90, 0x00688980},
933                 {0x0696, 0x00000003},
934                 {0x07fa, 0x0050100f},
935                 {0x1686, 0x00000004},
936         };
937         unsigned int i;
938         int oldpage;
939
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);
943         if (rc < 0)
944                 return rc;
945         rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
946                               MSCC_PHY_TEST_PAGE_24, 0, 0x0400);
947         if (rc < 0)
948                 return rc;
949         rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
950                               MSCC_PHY_TEST_PAGE_5, 0x0a00, 0x0e00);
951         if (rc < 0)
952                 return rc;
953         rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
954                               MSCC_PHY_TEST_PAGE_8, 0x8000, 0x8000);
955         if (rc < 0)
956                 return rc;
957
958         mutex_lock(&phydev->lock);
959         oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
960         if (oldpage < 0)
961                 goto out_unlock;
962
963         for (i = 0; i < ARRAY_SIZE(init_seq); i++)
964                 vsc85xx_tr_write(phydev, init_seq[i].reg, init_seq[i].val);
965
966 out_unlock:
967         oldpage = phy_restore_page(phydev, oldpage, oldpage);
968         mutex_unlock(&phydev->lock);
969
970         return oldpage;
971 }
972
973 static int vsc85xx_eee_init_seq_set(struct phy_device *phydev)
974 {
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},
994         };
995         unsigned int i;
996         int oldpage;
997
998         mutex_lock(&phydev->lock);
999         oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
1000         if (oldpage < 0)
1001                 goto out_unlock;
1002
1003         for (i = 0; i < ARRAY_SIZE(init_eee); i++)
1004                 vsc85xx_tr_write(phydev, init_eee[i].reg, init_eee[i].val);
1005
1006 out_unlock:
1007         oldpage = phy_restore_page(phydev, oldpage, oldpage);
1008         mutex_unlock(&phydev->lock);
1009
1010         return oldpage;
1011 }
1012
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)
1015 {
1016         struct vsc8531_private *priv = phydev->priv;
1017
1018         if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
1019                 dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
1020                 dump_stack();
1021         }
1022
1023         return __mdiobus_write(phydev->mdio.bus, priv->base_addr, regnum, val);
1024 }
1025
1026 /* phydev->bus->mdio_lock should be locked when using this function */
1027 static int phy_base_read(struct phy_device *phydev, u32 regnum)
1028 {
1029         struct vsc8531_private *priv = phydev->priv;
1030
1031         if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
1032                 dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
1033                 dump_stack();
1034         }
1035
1036         return __mdiobus_read(phydev->mdio.bus, priv->base_addr, regnum);
1037 }
1038
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)
1041 {
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));
1045 }
1046
1047 /* bus->mdio_lock should be locked when using this function */
1048 static int vsc8584_cmd(struct phy_device *phydev, u16 val)
1049 {
1050         unsigned long deadline;
1051         u16 reg_val;
1052
1053         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1054                        MSCC_PHY_PAGE_EXTENDED_GPIO);
1055
1056         phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NCOMPLETED | val);
1057
1058         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1059         do {
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));
1064
1065         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1066
1067         if (reg_val & PROC_CMD_FAILED)
1068                 return -EIO;
1069
1070         if (reg_val & PROC_CMD_NCOMPLETED)
1071                 return -ETIMEDOUT;
1072
1073         return 0;
1074 }
1075
1076 /* bus->mdio_lock should be locked when using this function */
1077 static int vsc8584_micro_deassert_reset(struct phy_device *phydev,
1078                                         bool patch_en)
1079 {
1080         u32 enable, release;
1081
1082         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1083                        MSCC_PHY_PAGE_EXTENDED_GPIO);
1084
1085         enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
1086         release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
1087                 MICRO_CLK_EN;
1088
1089         if (patch_en) {
1090                 enable |= MICRO_PATCH_EN;
1091                 release |= MICRO_PATCH_EN;
1092
1093                 /* Clear all patches */
1094                 phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
1095         }
1096
1097         /* Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
1098          * override and addr. auto-incr; operate at 125 MHz
1099          */
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);
1103
1104         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1105
1106         return 0;
1107 }
1108
1109 /* bus->mdio_lock should be locked when using this function */
1110 static int vsc8584_micro_assert_reset(struct phy_device *phydev)
1111 {
1112         int ret;
1113         u16 reg;
1114
1115         ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
1116         if (ret)
1117                 return ret;
1118
1119         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1120                        MSCC_PHY_PAGE_EXTENDED_GPIO);
1121
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);
1125
1126         phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(4), 0x005b);
1127         phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(4), 0x005b);
1128
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);
1132
1133         phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
1134
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);
1138
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 |
1141                        PROC_CMD_READ);
1142
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);
1146
1147         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1148
1149         return 0;
1150 }
1151
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,
1154                               u16 *crc)
1155 {
1156         int ret;
1157
1158         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
1159
1160         phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_2, start);
1161         phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_3, size);
1162
1163         /* Start Micro command */
1164         ret = vsc8584_cmd(phydev, PROC_CMD_CRC16);
1165         if (ret)
1166                 goto out;
1167
1168         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
1169
1170         *crc = phy_base_read(phydev, MSCC_PHY_VERIPHY_CNTL_2);
1171
1172 out:
1173         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1174
1175         return ret;
1176 }
1177
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)
1181 {
1182         int i, ret;
1183
1184         ret = vsc8584_micro_assert_reset(phydev);
1185         if (ret) {
1186                 dev_err(&phydev->mdio.dev,
1187                         "%s: failed to assert reset of micro\n", __func__);
1188                 return ret;
1189         }
1190
1191         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1192                        MSCC_PHY_PAGE_EXTENDED_GPIO);
1193
1194         /* Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
1195          * Disable the 8051 Micro clock
1196          */
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 |
1201                        INT_MEM_DATA(2));
1202         phy_base_write(phydev, MSCC_INT_MEM_ADDR, 0x0000);
1203
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]);
1207
1208         /* Clear internal memory access */
1209         phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
1210
1211         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1212
1213         return 0;
1214 }
1215
1216 /* bus->mdio_lock should be locked when using this function */
1217 static bool vsc8574_is_serdes_init(struct phy_device *phydev)
1218 {
1219         u16 reg;
1220         bool ret;
1221
1222         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1223                        MSCC_PHY_PAGE_EXTENDED_GPIO);
1224
1225         reg = phy_base_read(phydev, MSCC_TRAP_ROM_ADDR(1));
1226         if (reg != 0x3eb7) {
1227                 ret = false;
1228                 goto out;
1229         }
1230
1231         reg = phy_base_read(phydev, MSCC_PATCH_RAM_ADDR(1));
1232         if (reg != 0x4012) {
1233                 ret = false;
1234                 goto out;
1235         }
1236
1237         reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1238         if (reg != EN_PATCH_RAM_TRAP_ADDR(1)) {
1239                 ret = false;
1240                 goto out;
1241         }
1242
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)) {
1246                 ret = false;
1247                 goto out;
1248         }
1249
1250         ret = true;
1251 out:
1252         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1253
1254         return ret;
1255 }
1256
1257 /* bus->mdio_lock should be locked when using this function */
1258 static int vsc8574_config_pre_init(struct phy_device *phydev)
1259 {
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},
1307         };
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},
1323         };
1324         struct device *dev = &phydev->mdio.dev;
1325         const struct firmware *fw;
1326         unsigned int i;
1327         u16 crc, reg;
1328         bool serdes_init;
1329         int ret;
1330
1331         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1332
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);
1337
1338         phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
1339
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
1343          * values".
1344          */
1345         phy_base_write(phydev, MSCC_PHY_EXT_PHY_CNTL_2, 0x0040);
1346
1347         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1348
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);
1353
1354         reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1355         reg |= 0x8000;
1356         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1357
1358         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1359
1360         for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1361                 vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1362
1363         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
1364
1365         phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
1366
1367         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1368
1369         for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
1370                 vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
1371
1372         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1373
1374         reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1375         reg &= ~0x8000;
1376         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1377
1378         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1379
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);
1384
1385         ret = request_firmware(&fw, MSCC_VSC8574_REVB_INT8051_FW, dev);
1386         if (ret) {
1387                 dev_err(dev, "failed to load firmware %s, ret: %d\n",
1388                         MSCC_VSC8574_REVB_INT8051_FW, ret);
1389                 return ret;
1390         }
1391
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);
1396         if (ret)
1397                 goto out;
1398
1399         if (crc == MSCC_VSC8574_REVB_INT8051_FW_CRC) {
1400                 serdes_init = vsc8574_is_serdes_init(phydev);
1401
1402                 if (!serdes_init) {
1403                         ret = vsc8584_micro_assert_reset(phydev);
1404                         if (ret) {
1405                                 dev_err(dev,
1406                                         "%s: failed to assert reset of micro\n",
1407                                         __func__);
1408                                 goto out;
1409                         }
1410                 }
1411         } else {
1412                 dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
1413
1414                 serdes_init = false;
1415
1416                 if (vsc8584_patch_fw(phydev, fw))
1417                         dev_warn(dev,
1418                                  "failed to patch FW, expect non-optimal device\n");
1419         }
1420
1421         if (!serdes_init) {
1422                 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1423                                MSCC_PHY_PAGE_EXTENDED_GPIO);
1424
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));
1429
1430                 vsc8584_micro_deassert_reset(phydev, false);
1431
1432                 /* Add one byte to size for the one added by the patch_fw
1433                  * function
1434                  */
1435                 ret = vsc8584_get_fw_crc(phydev,
1436                                          MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
1437                                          fw->size + 1, &crc);
1438                 if (ret)
1439                         goto out;
1440
1441                 if (crc != MSCC_VSC8574_REVB_INT8051_FW_CRC)
1442                         dev_warn(dev,
1443                                  "FW CRC after patching is not the expected one, expect non-optimal device\n");
1444         }
1445
1446         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1447                        MSCC_PHY_PAGE_EXTENDED_GPIO);
1448
1449         ret = vsc8584_cmd(phydev, PROC_CMD_1588_DEFAULT_INIT |
1450                           PROC_CMD_PHY_INIT);
1451
1452 out:
1453         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1454
1455         release_firmware(fw);
1456
1457         return ret;
1458 }
1459
1460 /* bus->mdio_lock should be locked when using this function */
1461 static int vsc8584_config_pre_init(struct phy_device *phydev)
1462 {
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},
1486         };
1487         static const struct reg_val pre_init2[] = {
1488                 {0x0486, 0x0008a518},
1489                 {0x0488, 0x006dc696},
1490                 {0x048a, 0x00000912},
1491         };
1492         const struct firmware *fw;
1493         struct device *dev = &phydev->mdio.dev;
1494         unsigned int i;
1495         u16 crc, reg;
1496         int ret;
1497
1498         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1499
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);
1504
1505         phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
1506
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);
1510
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
1514          * values".
1515          */
1516         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_3);
1517
1518         phy_base_write(phydev, MSCC_PHY_SERDES_TX_CRC_ERR_CNT, 0x2000);
1519
1520         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1521
1522         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1f20);
1523
1524         reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1525         reg |= 0x8000;
1526         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1527
1528         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1529
1530         phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x2fa4));
1531
1532         reg = phy_base_read(phydev, MSCC_PHY_TR_MSB);
1533         reg &= ~0x007f;
1534         reg |= 0x0019;
1535         phy_base_write(phydev, MSCC_PHY_TR_MSB, reg);
1536
1537         phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x0fa4));
1538
1539         for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1540                 vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1541
1542         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
1543
1544         phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
1545
1546         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1547
1548         for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
1549                 vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
1550
1551         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1552
1553         reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1554         reg &= ~0x8000;
1555         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1556
1557         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1558
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);
1563
1564         ret = request_firmware(&fw, MSCC_VSC8584_REVB_INT8051_FW, dev);
1565         if (ret) {
1566                 dev_err(dev, "failed to load firmware %s, ret: %d\n",
1567                         MSCC_VSC8584_REVB_INT8051_FW, ret);
1568                 return ret;
1569         }
1570
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);
1575         if (ret)
1576                 goto out;
1577
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))
1581                         dev_warn(dev,
1582                                  "failed to patch FW, expect non-optimal device\n");
1583         }
1584
1585         vsc8584_micro_deassert_reset(phydev, false);
1586
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);
1591         if (ret)
1592                 goto out;
1593
1594         if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
1595                 dev_warn(dev,
1596                          "FW CRC after patching is not the expected one, expect non-optimal device\n");
1597
1598         ret = vsc8584_micro_assert_reset(phydev);
1599         if (ret)
1600                 goto out;
1601
1602         vsc8584_micro_deassert_reset(phydev, true);
1603
1604 out:
1605         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1606
1607         release_firmware(fw);
1608
1609         return ret;
1610 }
1611
1612 #if IS_ENABLED(CONFIG_MACSEC)
1613 static u32 vsc8584_macsec_phy_read(struct phy_device *phydev,
1614                                    enum macsec_bank bank, u32 reg)
1615 {
1616         u32 val, val_l = 0, val_h = 0;
1617         unsigned long deadline;
1618         int rc;
1619
1620         rc = phy_select_page(phydev, MSCC_PHY_PAGE_MACSEC);
1621         if (rc < 0)
1622                 goto failed;
1623
1624         __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_20,
1625                     MSCC_PHY_MACSEC_20_TARGET(bank >> 2));
1626
1627         if (bank >> 2 == 0x1)
1628                 /* non-MACsec access */
1629                 bank &= 0x3;
1630         else
1631                 bank = 0;
1632
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));
1637
1638         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1639         do {
1640                 val = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_19);
1641         } while (time_before(jiffies, deadline) && !(val & MSCC_PHY_MACSEC_19_CMD));
1642
1643         val_l = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_17);
1644         val_h = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_18);
1645
1646 failed:
1647         phy_restore_page(phydev, rc, rc);
1648
1649         return (val_h << 16) | val_l;
1650 }
1651
1652 static void vsc8584_macsec_phy_write(struct phy_device *phydev,
1653                                      enum macsec_bank bank, u32 reg, u32 val)
1654 {
1655         unsigned long deadline;
1656         int rc;
1657
1658         rc = phy_select_page(phydev, MSCC_PHY_PAGE_MACSEC);
1659         if (rc < 0)
1660                 goto failed;
1661
1662         __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_20,
1663                     MSCC_PHY_MACSEC_20_TARGET(bank >> 2));
1664
1665         if ((bank >> 2 == 0x1) || (bank >> 2 == 0x3))
1666                 bank &= 0x3;
1667         else
1668                 /* MACsec access */
1669                 bank = 0;
1670
1671         __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_17, (u16)val);
1672         __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_18, (u16)(val >> 16));
1673
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));
1677
1678         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1679         do {
1680                 val = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_19);
1681         } while (time_before(jiffies, deadline) && !(val & MSCC_PHY_MACSEC_19_CMD));
1682
1683 failed:
1684         phy_restore_page(phydev, rc, rc);
1685 }
1686
1687 static void vsc8584_macsec_classification(struct phy_device *phydev,
1688                                           enum macsec_bank bank)
1689 {
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);
1695 }
1696
1697 static void vsc8584_macsec_flow_default_action(struct phy_device *phydev,
1698                                                enum macsec_bank bank,
1699                                                bool block)
1700 {
1701         u32 port = (bank == MACSEC_INGR) ?
1702                     MSCC_MS_PORT_UNCONTROLLED : MSCC_MS_PORT_COMMON;
1703         u32 action = MSCC_MS_FLOW_BYPASS;
1704
1705         if (block)
1706                 action = MSCC_MS_FLOW_DROP;
1707
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) |
1713                                  /* MACsec tagged */
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) |
1717                                  /* Bad tag */
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) |
1721                                  /* Kay tag */
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) |
1730                                  /* MACsec tagged */
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) |
1734                                  /* Bad tag */
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) |
1738                                  /* Kay tag */
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));
1742 }
1743
1744 static void vsc8584_macsec_integrity_checks(struct phy_device *phydev,
1745                                             enum macsec_bank bank)
1746 {
1747         u32 val;
1748
1749         if (bank != MACSEC_INGR)
1750                 return;
1751
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,
1758                                  val);
1759
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);
1764 }
1765
1766 static void vsc8584_macsec_block_init(struct phy_device *phydev,
1767                                       enum macsec_bank bank)
1768 {
1769         u32 val;
1770         int i;
1771
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);
1775
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);
1779
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));
1785
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);
1790
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);
1794
1795         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_BLOCK_CTX_UPDATE, 0x3);
1796
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);
1800
1801         /* Set the MTU */
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);
1805
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);
1810
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);
1815
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));
1822         }
1823
1824         vsc8584_macsec_classification(phydev, bank);
1825         vsc8584_macsec_flow_default_action(phydev, bank, false);
1826         vsc8584_macsec_integrity_checks(phydev, bank);
1827
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));
1833 }
1834
1835 static void vsc8584_macsec_mac_init(struct phy_device *phydev,
1836                                     enum macsec_bank bank)
1837 {
1838         u32 val;
1839         int i;
1840
1841         /* Clear host & line stats */
1842         for (i = 0; i < 36; i++)
1843                 vsc8584_macsec_phy_write(phydev, bank, 0x1c + i, 0);
1844
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);
1852
1853         val = vsc8584_macsec_phy_read(phydev, bank,
1854                                       MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2);
1855         val |= 0xffff;
1856         vsc8584_macsec_phy_write(phydev, bank,
1857                                  MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2, val);
1858
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;
1864         else
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);
1871
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 |
1878                                  (bank == HOST_MAC ?
1879                                   MSCC_MAC_CFG_PKTINF_CFG_ENABLE_TX_PADDING : 0));
1880
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);
1884
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);
1889
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);
1895
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);
1899
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);
1905 }
1906
1907 /* Must be called with mdio_lock taken */
1908 static int vsc8584_macsec_init(struct phy_device *phydev)
1909 {
1910         u32 val;
1911
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);
1916
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));
1921
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);
1927
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));
1931
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);
1940
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);
1944
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);
1951
1952         return 0;
1953 }
1954 #endif /* CONFIG_MACSEC */
1955
1956 /* Check if one PHY has already done the init of the parts common to all PHYs
1957  * in the Quad PHY package.
1958  */
1959 static bool vsc8584_is_pkg_init(struct phy_device *phydev, bool reversed)
1960 {
1961         struct mdio_device **map = phydev->mdio.bus->mdio_map;
1962         struct vsc8531_private *vsc8531;
1963         struct phy_device *phy;
1964         int i, addr;
1965
1966         /* VSC8584 is a Quad PHY */
1967         for (i = 0; i < 4; i++) {
1968                 vsc8531 = phydev->priv;
1969
1970                 if (reversed)
1971                         addr = vsc8531->base_addr - i;
1972                 else
1973                         addr = vsc8531->base_addr + i;
1974
1975                 if (!map[addr])
1976                         continue;
1977
1978                 phy = container_of(map[addr], struct phy_device, mdio);
1979
1980                 if ((phy->phy_id & phydev->drv->phy_id_mask) !=
1981                     (phydev->drv->phy_id & phydev->drv->phy_id_mask))
1982                         continue;
1983
1984                 vsc8531 = phy->priv;
1985
1986                 if (vsc8531 && vsc8531->pkg_init)
1987                         return true;
1988         }
1989
1990         return false;
1991 }
1992
1993 static int vsc8584_config_init(struct phy_device *phydev)
1994 {
1995         struct vsc8531_private *vsc8531 = phydev->priv;
1996         u16 addr, val;
1997         int ret, i;
1998
1999         phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
2000
2001         mutex_lock(&phydev->mdio.bus->mdio_lock);
2002
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;
2008
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;
2013         else
2014                 vsc8531->base_addr = phydev->mdio.addr - addr;
2015
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.
2028          */
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.
2033                  */
2034                 WARN_ON(phydev->drv->phy_id_mask & 0xf);
2035
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);
2042                         break;
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);
2048                         break;
2049                 default:
2050                         ret = -EINVAL;
2051                         break;
2052                 }
2053
2054                 if (ret)
2055                         goto err;
2056         }
2057
2058         vsc8531->pkg_init = true;
2059
2060         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
2061                        MSCC_PHY_PAGE_EXTENDED_GPIO);
2062
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;
2067         else
2068                 val |= MAC_CFG_SGMII;
2069
2070         ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
2071         if (ret)
2072                 goto err;
2073
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;
2078         else
2079                 val |= PROC_CMD_SGMII_MAC;
2080
2081         ret = vsc8584_cmd(phydev, val);
2082         if (ret)
2083                 goto err;
2084
2085         usleep_range(10000, 20000);
2086
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);
2092         if (ret)
2093                 goto err;
2094
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);
2100         if (ret)
2101                 goto err;
2102
2103         mutex_unlock(&phydev->mdio.bus->mdio_lock);
2104
2105 #if IS_ENABLED(CONFIG_MACSEC)
2106         /* 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);
2113                 if (ret)
2114                         goto err;
2115         }
2116 #endif
2117
2118         phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2119
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);
2125
2126         ret = genphy_soft_reset(phydev);
2127         if (ret)
2128                 return ret;
2129
2130         for (i = 0; i < vsc8531->nleds; i++) {
2131                 ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
2132                 if (ret)
2133                         return ret;
2134         }
2135
2136         return 0;
2137
2138 err:
2139         mutex_unlock(&phydev->mdio.bus->mdio_lock);
2140         return ret;
2141 }
2142
2143 static int vsc85xx_config_init(struct phy_device *phydev)
2144 {
2145         int rc, i, phy_id;
2146         struct vsc8531_private *vsc8531 = phydev->priv;
2147
2148         rc = vsc85xx_default_config(phydev);
2149         if (rc)
2150                 return rc;
2151
2152         rc = vsc85xx_mac_if_set(phydev, phydev->interface);
2153         if (rc)
2154                 return rc;
2155
2156         rc = vsc85xx_edge_rate_cntl_set(phydev, vsc8531->rate_magic);
2157         if (rc)
2158                 return rc;
2159
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);
2164                 if (rc)
2165                         return rc;
2166         }
2167
2168         rc = vsc85xx_eee_init_seq_set(phydev);
2169         if (rc)
2170                 return rc;
2171
2172         for (i = 0; i < vsc8531->nleds; i++) {
2173                 rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
2174                 if (rc)
2175                         return rc;
2176         }
2177
2178         return 0;
2179 }
2180
2181 static int vsc8584_did_interrupt(struct phy_device *phydev)
2182 {
2183         int rc = 0;
2184
2185         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
2186                 rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2187
2188         return (rc < 0) ? 0 : rc & MII_VSC85XX_INT_MASK_MASK;
2189 }
2190
2191 static int vsc8514_config_pre_init(struct phy_device *phydev)
2192 {
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.
2196          */
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},
2218         };
2219         unsigned int i;
2220         u16 reg;
2221
2222         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2223
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);
2228
2229         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
2230
2231         reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
2232         reg |= BIT(15);
2233         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
2234
2235         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
2236
2237         for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
2238                 vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
2239
2240         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
2241
2242         reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
2243         reg &= ~BIT(15);
2244         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
2245
2246         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2247
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);
2251
2252         return 0;
2253 }
2254
2255 static u32 vsc85xx_csr_ctrl_phy_read(struct phy_device *phydev,
2256                                      u32 target, u32 reg)
2257 {
2258         unsigned long deadline;
2259         u32 val, val_l, val_h;
2260
2261         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
2262
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.
2268          */
2269
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));
2273
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));
2279
2280         /* Wait for register access*/
2281         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
2282         do {
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));
2287
2288         if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
2289                 return 0xffffffff;
2290
2291         /* Read the Least Significant Word (LSW) (17) */
2292         val_l = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_17);
2293
2294         /* Read the Most Significant Word (MSW) (18) */
2295         val_h = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_18);
2296
2297         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
2298                        MSCC_PHY_PAGE_STANDARD);
2299
2300         return (val_h << 16) | val_l;
2301 }
2302
2303 static int vsc85xx_csr_ctrl_phy_write(struct phy_device *phydev,
2304                                       u32 target, u32 reg, u32 val)
2305 {
2306         unsigned long deadline;
2307
2308         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
2309
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.
2315          */
2316
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));
2320
2321         /* Write the Least Significant Word (LSW) (17) */
2322         phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_17, (u16)val);
2323
2324         /* Write the Most Significant Word (MSW) (18) */
2325         phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_18, (u16)(val >> 16));
2326
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));
2332
2333         /* Wait for register access */
2334         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
2335         do {
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));
2340
2341         if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
2342                 return -ETIMEDOUT;
2343
2344         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
2345                        MSCC_PHY_PAGE_STANDARD);
2346
2347         return 0;
2348 }
2349
2350 static int __phy_write_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb,
2351                                u32 op)
2352 {
2353         unsigned long deadline;
2354         u32 val;
2355         int ret;
2356
2357         ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET, reg,
2358                                          op | (1 << mcb));
2359         if (ret)
2360                 return -EINVAL;
2361
2362         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
2363         do {
2364                 usleep_range(500, 1000);
2365                 val = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET, reg);
2366
2367                 if (val == 0xffffffff)
2368                         return -EIO;
2369
2370         } while (time_before(jiffies, deadline) && (val & op));
2371
2372         if (val & op)
2373                 return -ETIMEDOUT;
2374
2375         return 0;
2376 }
2377
2378 /* Trigger a read to the spcified MCB */
2379 static int phy_update_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
2380 {
2381         return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_READ);
2382 }
2383
2384 /* Trigger a write to the spcified MCB */
2385 static int phy_commit_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
2386 {
2387         return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_WRITE);
2388 }
2389
2390 static int vsc8514_config_init(struct phy_device *phydev)
2391 {
2392         struct vsc8531_private *vsc8531 = phydev->priv;
2393         unsigned long deadline;
2394         u16 val, addr;
2395         int ret, i;
2396         u32 reg;
2397
2398         phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
2399
2400         mutex_lock(&phydev->mdio.bus->mdio_lock);
2401
2402         __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
2403
2404         addr = __phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_4);
2405         addr >>= PHY_CNTL_4_ADDR_POS;
2406
2407         val = __phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL);
2408
2409         if (val & PHY_ADDR_REVERSED)
2410                 vsc8531->base_addr = phydev->mdio.addr + addr;
2411         else
2412                 vsc8531->base_addr = phydev->mdio.addr - addr;
2413
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.
2424          */
2425         if (!vsc8584_is_pkg_init(phydev, val & PHY_ADDR_REVERSED ? 1 : 0))
2426                 vsc8514_config_pre_init(phydev);
2427
2428         vsc8531->pkg_init = true;
2429
2430         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
2431                        MSCC_PHY_PAGE_EXTENDED_GPIO);
2432
2433         val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
2434
2435         val &= ~MAC_CFG_MASK;
2436         val |= MAC_CFG_QSGMII;
2437         ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
2438
2439         if (ret)
2440                 goto err;
2441
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);
2446         if (ret)
2447                 goto err;
2448
2449         /* 6g mcb */
2450         phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG, 0);
2451         /* lcpll mcb */
2452         phy_update_mcb_s6g(phydev, PHY_S6G_LCPLL_CFG, 0);
2453         /* pll5gcfg0 */
2454         ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2455                                          PHY_S6G_PLL5G_CFG0, 0x7036f145);
2456         if (ret)
2457                 goto err;
2458
2459         phy_commit_mcb_s6g(phydev, PHY_S6G_LCPLL_CFG, 0);
2460         /* pllcfg */
2461         ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2462                                          PHY_S6G_PLL_CFG,
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));
2466         if (ret)
2467                 goto err;
2468
2469         /* commoncfg */
2470         ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2471                                          PHY_S6G_COMMON_CFG,
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));
2477         if (ret)
2478                 goto err;
2479
2480         /* misccfg */
2481         ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2482                                          PHY_S6G_MISC_CFG, 1);
2483         if (ret)
2484                 goto err;
2485
2486         /* gpcfg */
2487         ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2488                                          PHY_S6G_GPC_CFG, 768);
2489         if (ret)
2490                 goto err;
2491
2492         phy_commit_mcb_s6g(phydev, PHY_S6G_DFT_CFG2, 0);
2493
2494         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
2495         do {
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);
2503                         return -EIO;
2504                 }
2505
2506         } while (time_before(jiffies, deadline) && (reg & BIT(12)));
2507
2508         if (reg & BIT(12)) {
2509                 mutex_unlock(&phydev->mdio.bus->mdio_lock);
2510                 return -ETIMEDOUT;
2511         }
2512
2513         /* misccfg */
2514         ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
2515                                          PHY_S6G_MISC_CFG, 0);
2516         if (ret)
2517                 goto err;
2518
2519         phy_commit_mcb_s6g(phydev, PHY_MCB_S6G_CFG, 0);
2520
2521         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
2522         do {
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);
2530                         return -EIO;
2531                 }
2532
2533         } while (time_before(jiffies, deadline) && !(reg & BIT(8)));
2534
2535         if (!(reg & BIT(8))) {
2536                 mutex_unlock(&phydev->mdio.bus->mdio_lock);
2537                 return -ETIMEDOUT;
2538         }
2539
2540         mutex_unlock(&phydev->mdio.bus->mdio_lock);
2541
2542         ret = phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2543
2544         if (ret)
2545                 return ret;
2546
2547         ret = phy_modify(phydev, MSCC_PHY_EXT_PHY_CNTL_1, MEDIA_OP_MODE_MASK,
2548                          MEDIA_OP_MODE_COPPER);
2549
2550         if (ret)
2551                 return ret;
2552
2553         ret = genphy_soft_reset(phydev);
2554
2555         if (ret)
2556                 return ret;
2557
2558         for (i = 0; i < vsc8531->nleds; i++) {
2559                 ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
2560                 if (ret)
2561                         return ret;
2562         }
2563
2564         return ret;
2565
2566 err:
2567         mutex_unlock(&phydev->mdio.bus->mdio_lock);
2568         return ret;
2569 }
2570
2571 static int vsc85xx_ack_interrupt(struct phy_device *phydev)
2572 {
2573         int rc = 0;
2574
2575         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
2576                 rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2577
2578         return (rc < 0) ? rc : 0;
2579 }
2580
2581 static int vsc85xx_config_intr(struct phy_device *phydev)
2582 {
2583         int rc;
2584
2585         if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
2586                 rc = phy_write(phydev, MII_VSC85XX_INT_MASK,
2587                                MII_VSC85XX_INT_MASK_MASK);
2588         } else {
2589                 rc = phy_write(phydev, MII_VSC85XX_INT_MASK, 0);
2590                 if (rc < 0)
2591                         return rc;
2592                 rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2593         }
2594
2595         return rc;
2596 }
2597
2598 static int vsc85xx_config_aneg(struct phy_device *phydev)
2599 {
2600         int rc;
2601
2602         rc = vsc85xx_mdix_set(phydev, phydev->mdix_ctrl);
2603         if (rc < 0)
2604                 return rc;
2605
2606         return genphy_config_aneg(phydev);
2607 }
2608
2609 static int vsc85xx_read_status(struct phy_device *phydev)
2610 {
2611         int rc;
2612
2613         rc = vsc85xx_mdix_get(phydev, &phydev->mdix);
2614         if (rc < 0)
2615                 return rc;
2616
2617         return genphy_read_status(phydev);
2618 }
2619
2620 static int vsc8514_probe(struct phy_device *phydev)
2621 {
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};
2626
2627         vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2628         if (!vsc8531)
2629                 return -ENOMEM;
2630
2631         phydev->priv = vsc8531;
2632
2633         vsc8531->nleds = 4;
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)
2640                 return -ENOMEM;
2641
2642         return vsc85xx_dt_led_modes_get(phydev, default_mode);
2643 }
2644
2645 static int vsc8574_probe(struct phy_device *phydev)
2646 {
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};
2651
2652         vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2653         if (!vsc8531)
2654                 return -ENOMEM;
2655
2656         phydev->priv = vsc8531;
2657
2658         vsc8531->nleds = 4;
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)
2665                 return -ENOMEM;
2666
2667         return vsc85xx_dt_led_modes_get(phydev, default_mode);
2668 }
2669
2670 static int vsc8584_probe(struct phy_device *phydev)
2671 {
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};
2676
2677         if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
2678                 dev_err(&phydev->mdio.dev, "Only VSC8584 revB is supported.\n");
2679                 return -ENOTSUPP;
2680         }
2681
2682         vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2683         if (!vsc8531)
2684                 return -ENOMEM;
2685
2686         phydev->priv = vsc8531;
2687
2688         vsc8531->nleds = 4;
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)
2695                 return -ENOMEM;
2696
2697         return vsc85xx_dt_led_modes_get(phydev, default_mode);
2698 }
2699
2700 static int vsc85xx_probe(struct phy_device *phydev)
2701 {
2702         struct vsc8531_private *vsc8531;
2703         int rate_magic;
2704         u32 default_mode[2] = {VSC8531_LINK_1000_ACTIVITY,
2705            VSC8531_LINK_100_ACTIVITY};
2706
2707         rate_magic = vsc85xx_edge_rate_magic_get(phydev);
2708         if (rate_magic < 0)
2709                 return rate_magic;
2710
2711         vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
2712         if (!vsc8531)
2713                 return -ENOMEM;
2714
2715         phydev->priv = vsc8531;
2716
2717         vsc8531->rate_magic = rate_magic;
2718         vsc8531->nleds = 2;
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)
2725                 return -ENOMEM;
2726
2727         return vsc85xx_dt_led_modes_get(phydev, default_mode);
2728 }
2729
2730 /* Microsemi VSC85xx PHYs */
2731 static struct phy_driver vsc85xx_driver[] = {
2732 {
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,
2757 },
2758 {
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,
2780 },
2781 {
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,
2804 },
2805 {
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,
2828 },
2829 {
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,
2852 },
2853 {
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,
2876 },
2877 {
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,
2901 },
2902 {
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,
2924 },
2925 {
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,
2950 },
2951 {
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,
2976 },
2977 {
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,
3000 },
3001 {
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,
3024 },
3025 {
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,
3048 }
3049
3050 };
3051
3052 module_phy_driver(vsc85xx_driver);
3053
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, },
3068         { }
3069 };
3070
3071 MODULE_DEVICE_TABLE(mdio, vsc85xx_tbl);
3072
3073 MODULE_DESCRIPTION("Microsemi VSC85xx PHY driver");
3074 MODULE_AUTHOR("Nagaraju Lakkaraju");
3075 MODULE_LICENSE("Dual MIT/GPL");