b2eac7ee02880685d329684fdc9876a176076914
[platform/kernel/linux-starfive.git] / drivers / net / phy / mscc / 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 <linux/scatterlist.h>
22 #include <crypto/skcipher.h>
23
24 #if IS_ENABLED(CONFIG_MACSEC)
25 #include <net/macsec.h>
26 #endif
27
28 #include "mscc_macsec.h"
29 #include "mscc_mac.h"
30 #include "mscc_fc_buffer.h"
31
32 enum rgmii_rx_clock_delay {
33         RGMII_RX_CLK_DELAY_0_2_NS = 0,
34         RGMII_RX_CLK_DELAY_0_8_NS = 1,
35         RGMII_RX_CLK_DELAY_1_1_NS = 2,
36         RGMII_RX_CLK_DELAY_1_7_NS = 3,
37         RGMII_RX_CLK_DELAY_2_0_NS = 4,
38         RGMII_RX_CLK_DELAY_2_3_NS = 5,
39         RGMII_RX_CLK_DELAY_2_6_NS = 6,
40         RGMII_RX_CLK_DELAY_3_4_NS = 7
41 };
42
43 /* Microsemi VSC85xx PHY registers */
44 /* IEEE 802. Std Registers */
45 #define MSCC_PHY_BYPASS_CONTROL           18
46 #define DISABLE_HP_AUTO_MDIX_MASK         0x0080
47 #define DISABLE_PAIR_SWAP_CORR_MASK       0x0020
48 #define DISABLE_POLARITY_CORR_MASK        0x0010
49 #define PARALLEL_DET_IGNORE_ADVERTISED    0x0008
50
51 #define MSCC_PHY_EXT_CNTL_STATUS          22
52 #define SMI_BROADCAST_WR_EN               0x0001
53
54 #define MSCC_PHY_ERR_RX_CNT               19
55 #define MSCC_PHY_ERR_FALSE_CARRIER_CNT    20
56 #define MSCC_PHY_ERR_LINK_DISCONNECT_CNT  21
57 #define ERR_CNT_MASK                      GENMASK(7, 0)
58
59 #define MSCC_PHY_EXT_PHY_CNTL_1           23
60 #define MAC_IF_SELECTION_MASK             0x1800
61 #define MAC_IF_SELECTION_GMII             0
62 #define MAC_IF_SELECTION_RMII             1
63 #define MAC_IF_SELECTION_RGMII            2
64 #define MAC_IF_SELECTION_POS              11
65 #define VSC8584_MAC_IF_SELECTION_MASK     0x1000
66 #define VSC8584_MAC_IF_SELECTION_SGMII    0
67 #define VSC8584_MAC_IF_SELECTION_1000BASEX 1
68 #define VSC8584_MAC_IF_SELECTION_POS      12
69 #define FAR_END_LOOPBACK_MODE_MASK        0x0008
70 #define MEDIA_OP_MODE_MASK                0x0700
71 #define MEDIA_OP_MODE_COPPER              0
72 #define MEDIA_OP_MODE_SERDES              1
73 #define MEDIA_OP_MODE_1000BASEX           2
74 #define MEDIA_OP_MODE_100BASEFX           3
75 #define MEDIA_OP_MODE_AMS_COPPER_SERDES   5
76 #define MEDIA_OP_MODE_AMS_COPPER_1000BASEX      6
77 #define MEDIA_OP_MODE_AMS_COPPER_100BASEFX      7
78 #define MEDIA_OP_MODE_POS                 8
79
80 #define MSCC_PHY_EXT_PHY_CNTL_2           24
81
82 #define MII_VSC85XX_INT_MASK              25
83 #define MII_VSC85XX_INT_MASK_MDINT        BIT(15)
84 #define MII_VSC85XX_INT_MASK_LINK_CHG     BIT(13)
85 #define MII_VSC85XX_INT_MASK_WOL          BIT(6)
86 #define MII_VSC85XX_INT_MASK_EXT          BIT(5)
87 #define MII_VSC85XX_INT_STATUS            26
88
89 #define MII_VSC85XX_INT_MASK_MASK         (MII_VSC85XX_INT_MASK_MDINT    | \
90                                            MII_VSC85XX_INT_MASK_LINK_CHG | \
91                                            MII_VSC85XX_INT_MASK_EXT)
92
93 #define MSCC_PHY_WOL_MAC_CONTROL          27
94 #define EDGE_RATE_CNTL_POS                5
95 #define EDGE_RATE_CNTL_MASK               0x00E0
96
97 #define MSCC_PHY_DEV_AUX_CNTL             28
98 #define HP_AUTO_MDIX_X_OVER_IND_MASK      0x2000
99
100 #define MSCC_PHY_LED_MODE_SEL             29
101 #define LED_MODE_SEL_POS(x)               ((x) * 4)
102 #define LED_MODE_SEL_MASK(x)              (GENMASK(3, 0) << LED_MODE_SEL_POS(x))
103 #define LED_MODE_SEL(x, mode)             (((mode) << LED_MODE_SEL_POS(x)) & LED_MODE_SEL_MASK(x))
104
105 #define MSCC_EXT_PAGE_CSR_CNTL_17         17
106 #define MSCC_EXT_PAGE_CSR_CNTL_18         18
107
108 #define MSCC_EXT_PAGE_CSR_CNTL_19         19
109 #define MSCC_PHY_CSR_CNTL_19_REG_ADDR(x)  (x)
110 #define MSCC_PHY_CSR_CNTL_19_TARGET(x)    ((x) << 12)
111 #define MSCC_PHY_CSR_CNTL_19_READ         BIT(14)
112 #define MSCC_PHY_CSR_CNTL_19_CMD          BIT(15)
113
114 #define MSCC_EXT_PAGE_CSR_CNTL_20         20
115 #define MSCC_PHY_CSR_CNTL_20_TARGET(x)    (x)
116
117 #define PHY_MCB_TARGET                    0x07
118 #define PHY_MCB_S6G_WRITE                 BIT(31)
119 #define PHY_MCB_S6G_READ                  BIT(30)
120
121 #define PHY_S6G_PLL5G_CFG0                0x06
122 #define PHY_S6G_LCPLL_CFG                 0x11
123 #define PHY_S6G_PLL_CFG                   0x2b
124 #define PHY_S6G_COMMON_CFG                0x2c
125 #define PHY_S6G_GPC_CFG                   0x2e
126 #define PHY_S6G_MISC_CFG                  0x3b
127 #define PHY_MCB_S6G_CFG                   0x3f
128 #define PHY_S6G_DFT_CFG2                  0x3e
129 #define PHY_S6G_PLL_STATUS                0x31
130 #define PHY_S6G_IB_STATUS0                0x2f
131
132 #define PHY_S6G_SYS_RST_POS               31
133 #define PHY_S6G_ENA_LANE_POS              18
134 #define PHY_S6G_ENA_LOOP_POS              8
135 #define PHY_S6G_QRATE_POS                 6
136 #define PHY_S6G_IF_MODE_POS               4
137 #define PHY_S6G_PLL_ENA_OFFS_POS          21
138 #define PHY_S6G_PLL_FSM_CTRL_DATA_POS     8
139 #define PHY_S6G_PLL_FSM_ENA_POS           7
140
141 #define MSCC_EXT_PAGE_MACSEC_17           17
142 #define MSCC_EXT_PAGE_MACSEC_18           18
143
144 #define MSCC_EXT_PAGE_MACSEC_19           19
145 #define MSCC_PHY_MACSEC_19_REG_ADDR(x)    (x)
146 #define MSCC_PHY_MACSEC_19_TARGET(x)      ((x) << 12)
147 #define MSCC_PHY_MACSEC_19_READ           BIT(14)
148 #define MSCC_PHY_MACSEC_19_CMD            BIT(15)
149
150 #define MSCC_EXT_PAGE_MACSEC_20           20
151 #define MSCC_PHY_MACSEC_20_TARGET(x)      (x)
152 enum macsec_bank {
153         FC_BUFFER   = 0x04,
154         HOST_MAC    = 0x05,
155         LINE_MAC    = 0x06,
156         IP_1588     = 0x0e,
157         MACSEC_INGR = 0x38,
158         MACSEC_EGR  = 0x3c,
159 };
160
161 #define MSCC_EXT_PAGE_ACCESS              31
162 #define MSCC_PHY_PAGE_STANDARD            0x0000 /* Standard registers */
163 #define MSCC_PHY_PAGE_EXTENDED            0x0001 /* Extended registers */
164 #define MSCC_PHY_PAGE_EXTENDED_2          0x0002 /* Extended reg - page 2 */
165 #define MSCC_PHY_PAGE_EXTENDED_3          0x0003 /* Extended reg - page 3 */
166 #define MSCC_PHY_PAGE_EXTENDED_4          0x0004 /* Extended reg - page 4 */
167 #define MSCC_PHY_PAGE_CSR_CNTL            MSCC_PHY_PAGE_EXTENDED_4
168 #define MSCC_PHY_PAGE_MACSEC              MSCC_PHY_PAGE_EXTENDED_4
169 /* Extended reg - GPIO; this is a bank of registers that are shared for all PHYs
170  * in the same package.
171  */
172 #define MSCC_PHY_PAGE_EXTENDED_GPIO       0x0010 /* Extended reg - GPIO */
173 #define MSCC_PHY_PAGE_TEST                0x2a30 /* Test reg */
174 #define MSCC_PHY_PAGE_TR                  0x52b5 /* Token ring registers */
175
176 /* Extended Page 1 Registers */
177 #define MSCC_PHY_CU_MEDIA_CRC_VALID_CNT   18
178 #define VALID_CRC_CNT_CRC_MASK            GENMASK(13, 0)
179
180 #define MSCC_PHY_EXT_MODE_CNTL            19
181 #define FORCE_MDI_CROSSOVER_MASK          0x000C
182 #define FORCE_MDI_CROSSOVER_MDIX          0x000C
183 #define FORCE_MDI_CROSSOVER_MDI           0x0008
184
185 #define MSCC_PHY_ACTIPHY_CNTL             20
186 #define PHY_ADDR_REVERSED                 0x0200
187 #define DOWNSHIFT_CNTL_MASK               0x001C
188 #define DOWNSHIFT_EN                      0x0010
189 #define DOWNSHIFT_CNTL_POS                2
190
191 #define MSCC_PHY_EXT_PHY_CNTL_4           23
192 #define PHY_CNTL_4_ADDR_POS               11
193
194 #define MSCC_PHY_VERIPHY_CNTL_2           25
195
196 #define MSCC_PHY_VERIPHY_CNTL_3           26
197
198 /* Extended Page 2 Registers */
199 #define MSCC_PHY_CU_PMD_TX_CNTL           16
200
201 #define MSCC_PHY_RGMII_CNTL               20
202 #define RGMII_RX_CLK_DELAY_MASK           0x0070
203 #define RGMII_RX_CLK_DELAY_POS            4
204
205 #define MSCC_PHY_WOL_LOWER_MAC_ADDR       21
206 #define MSCC_PHY_WOL_MID_MAC_ADDR         22
207 #define MSCC_PHY_WOL_UPPER_MAC_ADDR       23
208 #define MSCC_PHY_WOL_LOWER_PASSWD         24
209 #define MSCC_PHY_WOL_MID_PASSWD           25
210 #define MSCC_PHY_WOL_UPPER_PASSWD         26
211
212 #define MSCC_PHY_WOL_MAC_CONTROL          27
213 #define SECURE_ON_ENABLE                  0x8000
214 #define SECURE_ON_PASSWD_LEN_4            0x4000
215
216 #define MSCC_PHY_EXTENDED_INT             28
217 #define MSCC_PHY_EXTENDED_INT_MS_EGR      BIT(9)
218
219 /* Extended Page 3 Registers */
220 #define MSCC_PHY_SERDES_TX_VALID_CNT      21
221 #define MSCC_PHY_SERDES_TX_CRC_ERR_CNT    22
222 #define MSCC_PHY_SERDES_RX_VALID_CNT      28
223 #define MSCC_PHY_SERDES_RX_CRC_ERR_CNT    29
224
225 /* Extended page GPIO Registers */
226 #define MSCC_DW8051_CNTL_STATUS           0
227 #define MICRO_NSOFT_RESET                 0x8000
228 #define RUN_FROM_INT_ROM                  0x4000
229 #define AUTOINC_ADDR                      0x2000
230 #define PATCH_RAM_CLK                     0x1000
231 #define MICRO_PATCH_EN                    0x0080
232 #define DW8051_CLK_EN                     0x0010
233 #define MICRO_CLK_EN                      0x0008
234 #define MICRO_CLK_DIVIDE(x)               ((x) >> 1)
235 #define MSCC_DW8051_VLD_MASK              0xf1ff
236
237 /* x Address in range 1-4 */
238 #define MSCC_TRAP_ROM_ADDR(x)             ((x) * 2 + 1)
239 #define MSCC_PATCH_RAM_ADDR(x)            (((x) + 1) * 2)
240 #define MSCC_INT_MEM_ADDR                 11
241
242 #define MSCC_INT_MEM_CNTL                 12
243 #define READ_SFR                          0x6000
244 #define READ_PRAM                         0x4000
245 #define READ_ROM                          0x2000
246 #define READ_RAM                          0x0000
247 #define INT_MEM_WRITE_EN                  0x1000
248 #define EN_PATCH_RAM_TRAP_ADDR(x)         (0x0100 << ((x) - 1))
249 #define INT_MEM_DATA_M                    0x00ff
250 #define INT_MEM_DATA(x)                   (INT_MEM_DATA_M & (x))
251
252 #define MSCC_PHY_PROC_CMD                 18
253 #define PROC_CMD_NCOMPLETED               0x8000
254 #define PROC_CMD_FAILED                   0x4000
255 #define PROC_CMD_SGMII_PORT(x)            ((x) << 8)
256 #define PROC_CMD_FIBER_PORT(x)            (0x0100 << (x) % 4)
257 #define PROC_CMD_QSGMII_PORT              0x0c00
258 #define PROC_CMD_RST_CONF_PORT            0x0080
259 #define PROC_CMD_RECONF_PORT              0x0000
260 #define PROC_CMD_READ_MOD_WRITE_PORT      0x0040
261 #define PROC_CMD_WRITE                    0x0040
262 #define PROC_CMD_READ                     0x0000
263 #define PROC_CMD_FIBER_DISABLE            0x0020
264 #define PROC_CMD_FIBER_100BASE_FX         0x0010
265 #define PROC_CMD_FIBER_1000BASE_X         0x0000
266 #define PROC_CMD_SGMII_MAC                0x0030
267 #define PROC_CMD_QSGMII_MAC               0x0020
268 #define PROC_CMD_NO_MAC_CONF              0x0000
269 #define PROC_CMD_1588_DEFAULT_INIT        0x0010
270 #define PROC_CMD_NOP                      0x000f
271 #define PROC_CMD_PHY_INIT                 0x000a
272 #define PROC_CMD_CRC16                    0x0008
273 #define PROC_CMD_FIBER_MEDIA_CONF         0x0001
274 #define PROC_CMD_MCB_ACCESS_MAC_CONF      0x0000
275 #define PROC_CMD_NCOMPLETED_TIMEOUT_MS    500
276
277 #define MSCC_PHY_MAC_CFG_FASTLINK         19
278 #define MAC_CFG_MASK                      0xc000
279 #define MAC_CFG_SGMII                     0x0000
280 #define MAC_CFG_QSGMII                    0x4000
281
282 /* Test page Registers */
283 #define MSCC_PHY_TEST_PAGE_5              5
284 #define MSCC_PHY_TEST_PAGE_8              8
285 #define MSCC_PHY_TEST_PAGE_9              9
286 #define MSCC_PHY_TEST_PAGE_20             20
287 #define MSCC_PHY_TEST_PAGE_24             24
288
289 /* Token ring page Registers */
290 #define MSCC_PHY_TR_CNTL                  16
291 #define TR_WRITE                          0x8000
292 #define TR_ADDR(x)                        (0x7fff & (x))
293 #define MSCC_PHY_TR_LSB                   17
294 #define MSCC_PHY_TR_MSB                   18
295
296 /* Microsemi PHY ID's
297  *   Code assumes lowest nibble is 0
298  */
299 #define PHY_ID_VSC8504                    0x000704c0
300 #define PHY_ID_VSC8514                    0x00070670
301 #define PHY_ID_VSC8530                    0x00070560
302 #define PHY_ID_VSC8531                    0x00070570
303 #define PHY_ID_VSC8540                    0x00070760
304 #define PHY_ID_VSC8541                    0x00070770
305 #define PHY_ID_VSC8552                    0x000704e0
306 #define PHY_ID_VSC856X                    0x000707e0
307 #define PHY_ID_VSC8572                    0x000704d0
308 #define PHY_ID_VSC8574                    0x000704a0
309 #define PHY_ID_VSC8575                    0x000707d0
310 #define PHY_ID_VSC8582                    0x000707b0
311 #define PHY_ID_VSC8584                    0x000707c0
312
313 #define MSCC_VDDMAC_1500                  1500
314 #define MSCC_VDDMAC_1800                  1800
315 #define MSCC_VDDMAC_2500                  2500
316 #define MSCC_VDDMAC_3300                  3300
317
318 #define DOWNSHIFT_COUNT_MAX               5
319
320 #define MAX_LEDS                          4
321
322 #define VSC8584_SUPP_LED_MODES (BIT(VSC8531_LINK_ACTIVITY) | \
323                                 BIT(VSC8531_LINK_1000_ACTIVITY) | \
324                                 BIT(VSC8531_LINK_100_ACTIVITY) | \
325                                 BIT(VSC8531_LINK_10_ACTIVITY) | \
326                                 BIT(VSC8531_LINK_100_1000_ACTIVITY) | \
327                                 BIT(VSC8531_LINK_10_1000_ACTIVITY) | \
328                                 BIT(VSC8531_LINK_10_100_ACTIVITY) | \
329                                 BIT(VSC8584_LINK_100FX_1000X_ACTIVITY) | \
330                                 BIT(VSC8531_DUPLEX_COLLISION) | \
331                                 BIT(VSC8531_COLLISION) | \
332                                 BIT(VSC8531_ACTIVITY) | \
333                                 BIT(VSC8584_100FX_1000X_ACTIVITY) | \
334                                 BIT(VSC8531_AUTONEG_FAULT) | \
335                                 BIT(VSC8531_SERIAL_MODE) | \
336                                 BIT(VSC8531_FORCE_LED_OFF) | \
337                                 BIT(VSC8531_FORCE_LED_ON))
338
339 #define VSC85XX_SUPP_LED_MODES (BIT(VSC8531_LINK_ACTIVITY) | \
340                                 BIT(VSC8531_LINK_1000_ACTIVITY) | \
341                                 BIT(VSC8531_LINK_100_ACTIVITY) | \
342                                 BIT(VSC8531_LINK_10_ACTIVITY) | \
343                                 BIT(VSC8531_LINK_100_1000_ACTIVITY) | \
344                                 BIT(VSC8531_LINK_10_1000_ACTIVITY) | \
345                                 BIT(VSC8531_LINK_10_100_ACTIVITY) | \
346                                 BIT(VSC8531_DUPLEX_COLLISION) | \
347                                 BIT(VSC8531_COLLISION) | \
348                                 BIT(VSC8531_ACTIVITY) | \
349                                 BIT(VSC8531_AUTONEG_FAULT) | \
350                                 BIT(VSC8531_SERIAL_MODE) | \
351                                 BIT(VSC8531_FORCE_LED_OFF) | \
352                                 BIT(VSC8531_FORCE_LED_ON))
353
354 #define MSCC_VSC8584_REVB_INT8051_FW            "microchip/mscc_vsc8584_revb_int8051_fb48.bin"
355 #define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800
356 #define MSCC_VSC8584_REVB_INT8051_FW_CRC        0xfb48
357
358 #define MSCC_VSC8574_REVB_INT8051_FW            "microchip/mscc_vsc8574_revb_int8051_29e8.bin"
359 #define MSCC_VSC8574_REVB_INT8051_FW_START_ADDR 0x4000
360 #define MSCC_VSC8574_REVB_INT8051_FW_CRC        0x29e8
361
362 #define VSC8584_REVB                            0x0001
363 #define MSCC_DEV_REV_MASK                       GENMASK(3, 0)
364
365 struct reg_val {
366         u16     reg;
367         u32     val;
368 };
369
370 struct vsc85xx_hw_stat {
371         const char *string;
372         u8 reg;
373         u16 page;
374         u16 mask;
375 };
376
377 static const struct vsc85xx_hw_stat vsc85xx_hw_stats[] = {
378         {
379                 .string = "phy_receive_errors",
380                 .reg    = MSCC_PHY_ERR_RX_CNT,
381                 .page   = MSCC_PHY_PAGE_STANDARD,
382                 .mask   = ERR_CNT_MASK,
383         }, {
384                 .string = "phy_false_carrier",
385                 .reg    = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
386                 .page   = MSCC_PHY_PAGE_STANDARD,
387                 .mask   = ERR_CNT_MASK,
388         }, {
389                 .string = "phy_cu_media_link_disconnect",
390                 .reg    = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
391                 .page   = MSCC_PHY_PAGE_STANDARD,
392                 .mask   = ERR_CNT_MASK,
393         }, {
394                 .string = "phy_cu_media_crc_good_count",
395                 .reg    = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
396                 .page   = MSCC_PHY_PAGE_EXTENDED,
397                 .mask   = VALID_CRC_CNT_CRC_MASK,
398         }, {
399                 .string = "phy_cu_media_crc_error_count",
400                 .reg    = MSCC_PHY_EXT_PHY_CNTL_4,
401                 .page   = MSCC_PHY_PAGE_EXTENDED,
402                 .mask   = ERR_CNT_MASK,
403         },
404 };
405
406 static const struct vsc85xx_hw_stat vsc8584_hw_stats[] = {
407         {
408                 .string = "phy_receive_errors",
409                 .reg    = MSCC_PHY_ERR_RX_CNT,
410                 .page   = MSCC_PHY_PAGE_STANDARD,
411                 .mask   = ERR_CNT_MASK,
412         }, {
413                 .string = "phy_false_carrier",
414                 .reg    = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
415                 .page   = MSCC_PHY_PAGE_STANDARD,
416                 .mask   = ERR_CNT_MASK,
417         }, {
418                 .string = "phy_cu_media_link_disconnect",
419                 .reg    = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
420                 .page   = MSCC_PHY_PAGE_STANDARD,
421                 .mask   = ERR_CNT_MASK,
422         }, {
423                 .string = "phy_cu_media_crc_good_count",
424                 .reg    = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
425                 .page   = MSCC_PHY_PAGE_EXTENDED,
426                 .mask   = VALID_CRC_CNT_CRC_MASK,
427         }, {
428                 .string = "phy_cu_media_crc_error_count",
429                 .reg    = MSCC_PHY_EXT_PHY_CNTL_4,
430                 .page   = MSCC_PHY_PAGE_EXTENDED,
431                 .mask   = ERR_CNT_MASK,
432         }, {
433                 .string = "phy_serdes_tx_good_pkt_count",
434                 .reg    = MSCC_PHY_SERDES_TX_VALID_CNT,
435                 .page   = MSCC_PHY_PAGE_EXTENDED_3,
436                 .mask   = VALID_CRC_CNT_CRC_MASK,
437         }, {
438                 .string = "phy_serdes_tx_bad_crc_count",
439                 .reg    = MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
440                 .page   = MSCC_PHY_PAGE_EXTENDED_3,
441                 .mask   = ERR_CNT_MASK,
442         }, {
443                 .string = "phy_serdes_rx_good_pkt_count",
444                 .reg    = MSCC_PHY_SERDES_RX_VALID_CNT,
445                 .page   = MSCC_PHY_PAGE_EXTENDED_3,
446                 .mask   = VALID_CRC_CNT_CRC_MASK,
447         }, {
448                 .string = "phy_serdes_rx_bad_crc_count",
449                 .reg    = MSCC_PHY_SERDES_RX_CRC_ERR_CNT,
450                 .page   = MSCC_PHY_PAGE_EXTENDED_3,
451                 .mask   = ERR_CNT_MASK,
452         },
453 };
454
455 #if IS_ENABLED(CONFIG_MACSEC)
456 struct macsec_flow {
457         struct list_head list;
458         enum mscc_macsec_destination_ports port;
459         enum macsec_bank bank;
460         u32 index;
461         int assoc_num;
462         bool has_transformation;
463
464         /* Highest takes precedence [0..15] */
465         u8 priority;
466
467         u8 key[MACSEC_KEYID_LEN];
468
469         union {
470                 struct macsec_rx_sa *rx_sa;
471                 struct macsec_tx_sa *tx_sa;
472         };
473
474         /* Matching */
475         struct {
476                 u8 sci:1;
477                 u8 tagged:1;
478                 u8 untagged:1;
479                 u8 etype:1;
480         } match;
481
482         u16 etype;
483
484         /* Action */
485         struct {
486                 u8 bypass:1;
487                 u8 drop:1;
488         } action;
489
490 };
491 #endif
492
493 struct vsc8531_private {
494         int rate_magic;
495         u16 supp_led_modes;
496         u32 leds_mode[MAX_LEDS];
497         u8 nleds;
498         const struct vsc85xx_hw_stat *hw_stats;
499         u64 *stats;
500         int nstats;
501         bool pkg_init;
502         /* For multiple port PHYs; the MDIO address of the base PHY in the
503          * package.
504          */
505         unsigned int base_addr;
506
507 #if IS_ENABLED(CONFIG_MACSEC)
508         /* MACsec fields:
509          * - One SecY per device (enforced at the s/w implementation level)
510          * - macsec_flows: list of h/w flows
511          * - ingr_flows: bitmap of ingress flows
512          * - egr_flows: bitmap of egress flows
513          */
514         struct macsec_secy *secy;
515         struct list_head macsec_flows;
516         unsigned long ingr_flows;
517         unsigned long egr_flows;
518 #endif
519 };
520
521 #ifdef CONFIG_OF_MDIO
522 struct vsc8531_edge_rate_table {
523         u32 vddmac;
524         u32 slowdown[8];
525 };
526
527 static const struct vsc8531_edge_rate_table edge_table[] = {
528         {MSCC_VDDMAC_3300, { 0, 2,  4,  7, 10, 17, 29, 53} },
529         {MSCC_VDDMAC_2500, { 0, 3,  6, 10, 14, 23, 37, 63} },
530         {MSCC_VDDMAC_1800, { 0, 5,  9, 16, 23, 35, 52, 76} },
531         {MSCC_VDDMAC_1500, { 0, 6, 14, 21, 29, 42, 58, 77} },
532 };
533 #endif /* CONFIG_OF_MDIO */
534
535 static int vsc85xx_phy_read_page(struct phy_device *phydev)
536 {
537         return __phy_read(phydev, MSCC_EXT_PAGE_ACCESS);
538 }
539
540 static int vsc85xx_phy_write_page(struct phy_device *phydev, int page)
541 {
542         return __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, page);
543 }
544
545 static int vsc85xx_get_sset_count(struct phy_device *phydev)
546 {
547         struct vsc8531_private *priv = phydev->priv;
548
549         if (!priv)
550                 return 0;
551
552         return priv->nstats;
553 }
554
555 static void vsc85xx_get_strings(struct phy_device *phydev, u8 *data)
556 {
557         struct vsc8531_private *priv = phydev->priv;
558         int i;
559
560         if (!priv)
561                 return;
562
563         for (i = 0; i < priv->nstats; i++)
564                 strlcpy(data + i * ETH_GSTRING_LEN, priv->hw_stats[i].string,
565                         ETH_GSTRING_LEN);
566 }
567
568 static u64 vsc85xx_get_stat(struct phy_device *phydev, int i)
569 {
570         struct vsc8531_private *priv = phydev->priv;
571         int val;
572
573         val = phy_read_paged(phydev, priv->hw_stats[i].page,
574                              priv->hw_stats[i].reg);
575         if (val < 0)
576                 return U64_MAX;
577
578         val = val & priv->hw_stats[i].mask;
579         priv->stats[i] += val;
580
581         return priv->stats[i];
582 }
583
584 static void vsc85xx_get_stats(struct phy_device *phydev,
585                               struct ethtool_stats *stats, u64 *data)
586 {
587         struct vsc8531_private *priv = phydev->priv;
588         int i;
589
590         if (!priv)
591                 return;
592
593         for (i = 0; i < priv->nstats; i++)
594                 data[i] = vsc85xx_get_stat(phydev, i);
595 }
596
597 static int vsc85xx_led_cntl_set(struct phy_device *phydev,
598                                 u8 led_num,
599                                 u8 mode)
600 {
601         int rc;
602         u16 reg_val;
603
604         mutex_lock(&phydev->lock);
605         reg_val = phy_read(phydev, MSCC_PHY_LED_MODE_SEL);
606         reg_val &= ~LED_MODE_SEL_MASK(led_num);
607         reg_val |= LED_MODE_SEL(led_num, (u16)mode);
608         rc = phy_write(phydev, MSCC_PHY_LED_MODE_SEL, reg_val);
609         mutex_unlock(&phydev->lock);
610
611         return rc;
612 }
613
614 static int vsc85xx_mdix_get(struct phy_device *phydev, u8 *mdix)
615 {
616         u16 reg_val;
617
618         reg_val = phy_read(phydev, MSCC_PHY_DEV_AUX_CNTL);
619         if (reg_val & HP_AUTO_MDIX_X_OVER_IND_MASK)
620                 *mdix = ETH_TP_MDI_X;
621         else
622                 *mdix = ETH_TP_MDI;
623
624         return 0;
625 }
626
627 static int vsc85xx_mdix_set(struct phy_device *phydev, u8 mdix)
628 {
629         int rc;
630         u16 reg_val;
631
632         reg_val = phy_read(phydev, MSCC_PHY_BYPASS_CONTROL);
633         if (mdix == ETH_TP_MDI || mdix == ETH_TP_MDI_X) {
634                 reg_val |= (DISABLE_PAIR_SWAP_CORR_MASK |
635                             DISABLE_POLARITY_CORR_MASK  |
636                             DISABLE_HP_AUTO_MDIX_MASK);
637         } else {
638                 reg_val &= ~(DISABLE_PAIR_SWAP_CORR_MASK |
639                              DISABLE_POLARITY_CORR_MASK  |
640                              DISABLE_HP_AUTO_MDIX_MASK);
641         }
642         rc = phy_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg_val);
643         if (rc)
644                 return rc;
645
646         reg_val = 0;
647
648         if (mdix == ETH_TP_MDI)
649                 reg_val = FORCE_MDI_CROSSOVER_MDI;
650         else if (mdix == ETH_TP_MDI_X)
651                 reg_val = FORCE_MDI_CROSSOVER_MDIX;
652
653         rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
654                               MSCC_PHY_EXT_MODE_CNTL, FORCE_MDI_CROSSOVER_MASK,
655                               reg_val);
656         if (rc < 0)
657                 return rc;
658
659         return genphy_restart_aneg(phydev);
660 }
661
662 static int vsc85xx_downshift_get(struct phy_device *phydev, u8 *count)
663 {
664         int reg_val;
665
666         reg_val = phy_read_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
667                                  MSCC_PHY_ACTIPHY_CNTL);
668         if (reg_val < 0)
669                 return reg_val;
670
671         reg_val &= DOWNSHIFT_CNTL_MASK;
672         if (!(reg_val & DOWNSHIFT_EN))
673                 *count = DOWNSHIFT_DEV_DISABLE;
674         else
675                 *count = ((reg_val & ~DOWNSHIFT_EN) >> DOWNSHIFT_CNTL_POS) + 2;
676
677         return 0;
678 }
679
680 static int vsc85xx_downshift_set(struct phy_device *phydev, u8 count)
681 {
682         if (count == DOWNSHIFT_DEV_DEFAULT_COUNT) {
683                 /* Default downshift count 3 (i.e. Bit3:2 = 0b01) */
684                 count = ((1 << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
685         } else if (count > DOWNSHIFT_COUNT_MAX || count == 1) {
686                 phydev_err(phydev, "Downshift count should be 2,3,4 or 5\n");
687                 return -ERANGE;
688         } else if (count) {
689                 /* Downshift count is either 2,3,4 or 5 */
690                 count = (((count - 2) << DOWNSHIFT_CNTL_POS) | DOWNSHIFT_EN);
691         }
692
693         return phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED,
694                                 MSCC_PHY_ACTIPHY_CNTL, DOWNSHIFT_CNTL_MASK,
695                                 count);
696 }
697
698 static int vsc85xx_wol_set(struct phy_device *phydev,
699                            struct ethtool_wolinfo *wol)
700 {
701         int rc;
702         u16 reg_val;
703         u8  i;
704         u16 pwd[3] = {0, 0, 0};
705         struct ethtool_wolinfo *wol_conf = wol;
706         u8 *mac_addr = phydev->attached_dev->dev_addr;
707
708         mutex_lock(&phydev->lock);
709         rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
710         if (rc < 0) {
711                 rc = phy_restore_page(phydev, rc, rc);
712                 goto out_unlock;
713         }
714
715         if (wol->wolopts & WAKE_MAGIC) {
716                 /* Store the device address for the magic packet */
717                 for (i = 0; i < ARRAY_SIZE(pwd); i++)
718                         pwd[i] = mac_addr[5 - (i * 2 + 1)] << 8 |
719                                  mac_addr[5 - i * 2];
720                 __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, pwd[0]);
721                 __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, pwd[1]);
722                 __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, pwd[2]);
723         } else {
724                 __phy_write(phydev, MSCC_PHY_WOL_LOWER_MAC_ADDR, 0);
725                 __phy_write(phydev, MSCC_PHY_WOL_MID_MAC_ADDR, 0);
726                 __phy_write(phydev, MSCC_PHY_WOL_UPPER_MAC_ADDR, 0);
727         }
728
729         if (wol_conf->wolopts & WAKE_MAGICSECURE) {
730                 for (i = 0; i < ARRAY_SIZE(pwd); i++)
731                         pwd[i] = wol_conf->sopass[5 - (i * 2 + 1)] << 8 |
732                                  wol_conf->sopass[5 - i * 2];
733                 __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, pwd[0]);
734                 __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, pwd[1]);
735                 __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, pwd[2]);
736         } else {
737                 __phy_write(phydev, MSCC_PHY_WOL_LOWER_PASSWD, 0);
738                 __phy_write(phydev, MSCC_PHY_WOL_MID_PASSWD, 0);
739                 __phy_write(phydev, MSCC_PHY_WOL_UPPER_PASSWD, 0);
740         }
741
742         reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
743         if (wol_conf->wolopts & WAKE_MAGICSECURE)
744                 reg_val |= SECURE_ON_ENABLE;
745         else
746                 reg_val &= ~SECURE_ON_ENABLE;
747         __phy_write(phydev, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
748
749         rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
750         if (rc < 0)
751                 goto out_unlock;
752
753         if (wol->wolopts & WAKE_MAGIC) {
754                 /* Enable the WOL interrupt */
755                 reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
756                 reg_val |= MII_VSC85XX_INT_MASK_WOL;
757                 rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
758                 if (rc)
759                         goto out_unlock;
760         } else {
761                 /* Disable the WOL interrupt */
762                 reg_val = phy_read(phydev, MII_VSC85XX_INT_MASK);
763                 reg_val &= (~MII_VSC85XX_INT_MASK_WOL);
764                 rc = phy_write(phydev, MII_VSC85XX_INT_MASK, reg_val);
765                 if (rc)
766                         goto out_unlock;
767         }
768         /* Clear WOL iterrupt status */
769         reg_val = phy_read(phydev, MII_VSC85XX_INT_STATUS);
770
771 out_unlock:
772         mutex_unlock(&phydev->lock);
773
774         return rc;
775 }
776
777 static void vsc85xx_wol_get(struct phy_device *phydev,
778                             struct ethtool_wolinfo *wol)
779 {
780         int rc;
781         u16 reg_val;
782         u8  i;
783         u16 pwd[3] = {0, 0, 0};
784         struct ethtool_wolinfo *wol_conf = wol;
785
786         mutex_lock(&phydev->lock);
787         rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
788         if (rc < 0)
789                 goto out_unlock;
790
791         reg_val = __phy_read(phydev, MSCC_PHY_WOL_MAC_CONTROL);
792         if (reg_val & SECURE_ON_ENABLE)
793                 wol_conf->wolopts |= WAKE_MAGICSECURE;
794         if (wol_conf->wolopts & WAKE_MAGICSECURE) {
795                 pwd[0] = __phy_read(phydev, MSCC_PHY_WOL_LOWER_PASSWD);
796                 pwd[1] = __phy_read(phydev, MSCC_PHY_WOL_MID_PASSWD);
797                 pwd[2] = __phy_read(phydev, MSCC_PHY_WOL_UPPER_PASSWD);
798                 for (i = 0; i < ARRAY_SIZE(pwd); i++) {
799                         wol_conf->sopass[5 - i * 2] = pwd[i] & 0x00ff;
800                         wol_conf->sopass[5 - (i * 2 + 1)] = (pwd[i] & 0xff00)
801                                                             >> 8;
802                 }
803         }
804
805 out_unlock:
806         phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
807         mutex_unlock(&phydev->lock);
808 }
809
810 #ifdef CONFIG_OF_MDIO
811 static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
812 {
813         u32 vdd, sd;
814         int i, j;
815         struct device *dev = &phydev->mdio.dev;
816         struct device_node *of_node = dev->of_node;
817         u8 sd_array_size = ARRAY_SIZE(edge_table[0].slowdown);
818
819         if (!of_node)
820                 return -ENODEV;
821
822         if (of_property_read_u32(of_node, "vsc8531,vddmac", &vdd))
823                 vdd = MSCC_VDDMAC_3300;
824
825         if (of_property_read_u32(of_node, "vsc8531,edge-slowdown", &sd))
826                 sd = 0;
827
828         for (i = 0; i < ARRAY_SIZE(edge_table); i++)
829                 if (edge_table[i].vddmac == vdd)
830                         for (j = 0; j < sd_array_size; j++)
831                                 if (edge_table[i].slowdown[j] == sd)
832                                         return (sd_array_size - j - 1);
833
834         return -EINVAL;
835 }
836
837 static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
838                                    char *led,
839                                    u32 default_mode)
840 {
841         struct vsc8531_private *priv = phydev->priv;
842         struct device *dev = &phydev->mdio.dev;
843         struct device_node *of_node = dev->of_node;
844         u32 led_mode;
845         int err;
846
847         if (!of_node)
848                 return -ENODEV;
849
850         led_mode = default_mode;
851         err = of_property_read_u32(of_node, led, &led_mode);
852         if (!err && !(BIT(led_mode) & priv->supp_led_modes)) {
853                 phydev_err(phydev, "DT %s invalid\n", led);
854                 return -EINVAL;
855         }
856
857         return led_mode;
858 }
859
860 #else
861 static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
862 {
863         return 0;
864 }
865
866 static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
867                                    char *led,
868                                    u8 default_mode)
869 {
870         return default_mode;
871 }
872 #endif /* CONFIG_OF_MDIO */
873
874 static int vsc85xx_dt_led_modes_get(struct phy_device *phydev,
875                                     u32 *default_mode)
876 {
877         struct vsc8531_private *priv = phydev->priv;
878         char led_dt_prop[28];
879         int i, ret;
880
881         for (i = 0; i < priv->nleds; i++) {
882                 ret = sprintf(led_dt_prop, "vsc8531,led-%d-mode", i);
883                 if (ret < 0)
884                         return ret;
885
886                 ret = vsc85xx_dt_led_mode_get(phydev, led_dt_prop,
887                                               default_mode[i]);
888                 if (ret < 0)
889                         return ret;
890                 priv->leds_mode[i] = ret;
891         }
892
893         return 0;
894 }
895
896 static int vsc85xx_edge_rate_cntl_set(struct phy_device *phydev, u8 edge_rate)
897 {
898         int rc;
899
900         mutex_lock(&phydev->lock);
901         rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
902                               MSCC_PHY_WOL_MAC_CONTROL, EDGE_RATE_CNTL_MASK,
903                               edge_rate << EDGE_RATE_CNTL_POS);
904         mutex_unlock(&phydev->lock);
905
906         return rc;
907 }
908
909 static int vsc85xx_mac_if_set(struct phy_device *phydev,
910                               phy_interface_t interface)
911 {
912         int rc;
913         u16 reg_val;
914
915         mutex_lock(&phydev->lock);
916         reg_val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
917         reg_val &= ~(MAC_IF_SELECTION_MASK);
918         switch (interface) {
919         case PHY_INTERFACE_MODE_RGMII:
920                 reg_val |= (MAC_IF_SELECTION_RGMII << MAC_IF_SELECTION_POS);
921                 break;
922         case PHY_INTERFACE_MODE_RMII:
923                 reg_val |= (MAC_IF_SELECTION_RMII << MAC_IF_SELECTION_POS);
924                 break;
925         case PHY_INTERFACE_MODE_MII:
926         case PHY_INTERFACE_MODE_GMII:
927                 reg_val |= (MAC_IF_SELECTION_GMII << MAC_IF_SELECTION_POS);
928                 break;
929         default:
930                 rc = -EINVAL;
931                 goto out_unlock;
932         }
933         rc = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, reg_val);
934         if (rc)
935                 goto out_unlock;
936
937         rc = genphy_soft_reset(phydev);
938
939 out_unlock:
940         mutex_unlock(&phydev->lock);
941
942         return rc;
943 }
944
945 static int vsc85xx_default_config(struct phy_device *phydev)
946 {
947         int rc;
948         u16 reg_val;
949
950         phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
951         mutex_lock(&phydev->lock);
952
953         reg_val = RGMII_RX_CLK_DELAY_1_1_NS << RGMII_RX_CLK_DELAY_POS;
954
955         rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
956                               MSCC_PHY_RGMII_CNTL, RGMII_RX_CLK_DELAY_MASK,
957                               reg_val);
958
959         mutex_unlock(&phydev->lock);
960
961         return rc;
962 }
963
964 static int vsc85xx_get_tunable(struct phy_device *phydev,
965                                struct ethtool_tunable *tuna, void *data)
966 {
967         switch (tuna->id) {
968         case ETHTOOL_PHY_DOWNSHIFT:
969                 return vsc85xx_downshift_get(phydev, (u8 *)data);
970         default:
971                 return -EINVAL;
972         }
973 }
974
975 static int vsc85xx_set_tunable(struct phy_device *phydev,
976                                struct ethtool_tunable *tuna,
977                                const void *data)
978 {
979         switch (tuna->id) {
980         case ETHTOOL_PHY_DOWNSHIFT:
981                 return vsc85xx_downshift_set(phydev, *(u8 *)data);
982         default:
983                 return -EINVAL;
984         }
985 }
986
987 /* mdiobus lock should be locked when using this function */
988 static void vsc85xx_tr_write(struct phy_device *phydev, u16 addr, u32 val)
989 {
990         __phy_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
991         __phy_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
992         __phy_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
993 }
994
995 static int vsc8531_pre_init_seq_set(struct phy_device *phydev)
996 {
997         int rc;
998         static const struct reg_val init_seq[] = {
999                 {0x0f90, 0x00688980},
1000                 {0x0696, 0x00000003},
1001                 {0x07fa, 0x0050100f},
1002                 {0x1686, 0x00000004},
1003         };
1004         unsigned int i;
1005         int oldpage;
1006
1007         rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_STANDARD,
1008                               MSCC_PHY_EXT_CNTL_STATUS, SMI_BROADCAST_WR_EN,
1009                               SMI_BROADCAST_WR_EN);
1010         if (rc < 0)
1011                 return rc;
1012         rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
1013                               MSCC_PHY_TEST_PAGE_24, 0, 0x0400);
1014         if (rc < 0)
1015                 return rc;
1016         rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
1017                               MSCC_PHY_TEST_PAGE_5, 0x0a00, 0x0e00);
1018         if (rc < 0)
1019                 return rc;
1020         rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
1021                               MSCC_PHY_TEST_PAGE_8, 0x8000, 0x8000);
1022         if (rc < 0)
1023                 return rc;
1024
1025         mutex_lock(&phydev->lock);
1026         oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
1027         if (oldpage < 0)
1028                 goto out_unlock;
1029
1030         for (i = 0; i < ARRAY_SIZE(init_seq); i++)
1031                 vsc85xx_tr_write(phydev, init_seq[i].reg, init_seq[i].val);
1032
1033 out_unlock:
1034         oldpage = phy_restore_page(phydev, oldpage, oldpage);
1035         mutex_unlock(&phydev->lock);
1036
1037         return oldpage;
1038 }
1039
1040 static int vsc85xx_eee_init_seq_set(struct phy_device *phydev)
1041 {
1042         static const struct reg_val init_eee[] = {
1043                 {0x0f82, 0x0012b00a},
1044                 {0x1686, 0x00000004},
1045                 {0x168c, 0x00d2c46f},
1046                 {0x17a2, 0x00000620},
1047                 {0x16a0, 0x00eeffdd},
1048                 {0x16a6, 0x00071448},
1049                 {0x16a4, 0x0013132f},
1050                 {0x16a8, 0x00000000},
1051                 {0x0ffc, 0x00c0a028},
1052                 {0x0fe8, 0x0091b06c},
1053                 {0x0fea, 0x00041600},
1054                 {0x0f80, 0x00000af4},
1055                 {0x0fec, 0x00901809},
1056                 {0x0fee, 0x0000a6a1},
1057                 {0x0ffe, 0x00b01007},
1058                 {0x16b0, 0x00eeff00},
1059                 {0x16b2, 0x00007000},
1060                 {0x16b4, 0x00000814},
1061         };
1062         unsigned int i;
1063         int oldpage;
1064
1065         mutex_lock(&phydev->lock);
1066         oldpage = phy_select_page(phydev, MSCC_PHY_PAGE_TR);
1067         if (oldpage < 0)
1068                 goto out_unlock;
1069
1070         for (i = 0; i < ARRAY_SIZE(init_eee); i++)
1071                 vsc85xx_tr_write(phydev, init_eee[i].reg, init_eee[i].val);
1072
1073 out_unlock:
1074         oldpage = phy_restore_page(phydev, oldpage, oldpage);
1075         mutex_unlock(&phydev->lock);
1076
1077         return oldpage;
1078 }
1079
1080 /* phydev->bus->mdio_lock should be locked when using this function */
1081 static int phy_base_write(struct phy_device *phydev, u32 regnum, u16 val)
1082 {
1083         struct vsc8531_private *priv = phydev->priv;
1084
1085         if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
1086                 dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
1087                 dump_stack();
1088         }
1089
1090         return __mdiobus_write(phydev->mdio.bus, priv->base_addr, regnum, val);
1091 }
1092
1093 /* phydev->bus->mdio_lock should be locked when using this function */
1094 static int phy_base_read(struct phy_device *phydev, u32 regnum)
1095 {
1096         struct vsc8531_private *priv = phydev->priv;
1097
1098         if (unlikely(!mutex_is_locked(&phydev->mdio.bus->mdio_lock))) {
1099                 dev_err(&phydev->mdio.dev, "MDIO bus lock not held!\n");
1100                 dump_stack();
1101         }
1102
1103         return __mdiobus_read(phydev->mdio.bus, priv->base_addr, regnum);
1104 }
1105
1106 /* bus->mdio_lock should be locked when using this function */
1107 static void vsc8584_csr_write(struct phy_device *phydev, u16 addr, u32 val)
1108 {
1109         phy_base_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
1110         phy_base_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
1111         phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
1112 }
1113
1114 /* bus->mdio_lock should be locked when using this function */
1115 static int vsc8584_cmd(struct phy_device *phydev, u16 val)
1116 {
1117         unsigned long deadline;
1118         u16 reg_val;
1119
1120         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1121                        MSCC_PHY_PAGE_EXTENDED_GPIO);
1122
1123         phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NCOMPLETED | val);
1124
1125         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1126         do {
1127                 reg_val = phy_base_read(phydev, MSCC_PHY_PROC_CMD);
1128         } while (time_before(jiffies, deadline) &&
1129                  (reg_val & PROC_CMD_NCOMPLETED) &&
1130                  !(reg_val & PROC_CMD_FAILED));
1131
1132         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1133
1134         if (reg_val & PROC_CMD_FAILED)
1135                 return -EIO;
1136
1137         if (reg_val & PROC_CMD_NCOMPLETED)
1138                 return -ETIMEDOUT;
1139
1140         return 0;
1141 }
1142
1143 /* bus->mdio_lock should be locked when using this function */
1144 static int vsc8584_micro_deassert_reset(struct phy_device *phydev,
1145                                         bool patch_en)
1146 {
1147         u32 enable, release;
1148
1149         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1150                        MSCC_PHY_PAGE_EXTENDED_GPIO);
1151
1152         enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
1153         release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
1154                 MICRO_CLK_EN;
1155
1156         if (patch_en) {
1157                 enable |= MICRO_PATCH_EN;
1158                 release |= MICRO_PATCH_EN;
1159
1160                 /* Clear all patches */
1161                 phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
1162         }
1163
1164         /* Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
1165          * override and addr. auto-incr; operate at 125 MHz
1166          */
1167         phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, enable);
1168         /* Release 8051 Micro SW reset */
1169         phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, release);
1170
1171         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1172
1173         return 0;
1174 }
1175
1176 /* bus->mdio_lock should be locked when using this function */
1177 static int vsc8584_micro_assert_reset(struct phy_device *phydev)
1178 {
1179         int ret;
1180         u16 reg;
1181
1182         ret = vsc8584_cmd(phydev, PROC_CMD_NOP);
1183         if (ret)
1184                 return ret;
1185
1186         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1187                        MSCC_PHY_PAGE_EXTENDED_GPIO);
1188
1189         reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1190         reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
1191         phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
1192
1193         phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(4), 0x005b);
1194         phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(4), 0x005b);
1195
1196         reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1197         reg |= EN_PATCH_RAM_TRAP_ADDR(4);
1198         phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
1199
1200         phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
1201
1202         reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
1203         reg &= ~MICRO_NSOFT_RESET;
1204         phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, reg);
1205
1206         phy_base_write(phydev, MSCC_PHY_PROC_CMD, PROC_CMD_MCB_ACCESS_MAC_CONF |
1207                        PROC_CMD_SGMII_PORT(0) | PROC_CMD_NO_MAC_CONF |
1208                        PROC_CMD_READ);
1209
1210         reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1211         reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
1212         phy_base_write(phydev, MSCC_INT_MEM_CNTL, reg);
1213
1214         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1215
1216         return 0;
1217 }
1218
1219 /* bus->mdio_lock should be locked when using this function */
1220 static int vsc8584_get_fw_crc(struct phy_device *phydev, u16 start, u16 size,
1221                               u16 *crc)
1222 {
1223         int ret;
1224
1225         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
1226
1227         phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_2, start);
1228         phy_base_write(phydev, MSCC_PHY_VERIPHY_CNTL_3, size);
1229
1230         /* Start Micro command */
1231         ret = vsc8584_cmd(phydev, PROC_CMD_CRC16);
1232         if (ret)
1233                 goto out;
1234
1235         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
1236
1237         *crc = phy_base_read(phydev, MSCC_PHY_VERIPHY_CNTL_2);
1238
1239 out:
1240         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1241
1242         return ret;
1243 }
1244
1245 /* bus->mdio_lock should be locked when using this function */
1246 static int vsc8584_patch_fw(struct phy_device *phydev,
1247                             const struct firmware *fw)
1248 {
1249         int i, ret;
1250
1251         ret = vsc8584_micro_assert_reset(phydev);
1252         if (ret) {
1253                 dev_err(&phydev->mdio.dev,
1254                         "%s: failed to assert reset of micro\n", __func__);
1255                 return ret;
1256         }
1257
1258         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1259                        MSCC_PHY_PAGE_EXTENDED_GPIO);
1260
1261         /* Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
1262          * Disable the 8051 Micro clock
1263          */
1264         phy_base_write(phydev, MSCC_DW8051_CNTL_STATUS, RUN_FROM_INT_ROM |
1265                        AUTOINC_ADDR | PATCH_RAM_CLK | MICRO_CLK_EN |
1266                        MICRO_CLK_DIVIDE(2));
1267         phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM | INT_MEM_WRITE_EN |
1268                        INT_MEM_DATA(2));
1269         phy_base_write(phydev, MSCC_INT_MEM_ADDR, 0x0000);
1270
1271         for (i = 0; i < fw->size; i++)
1272                 phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_PRAM |
1273                                INT_MEM_WRITE_EN | fw->data[i]);
1274
1275         /* Clear internal memory access */
1276         phy_base_write(phydev, MSCC_INT_MEM_CNTL, READ_RAM);
1277
1278         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1279
1280         return 0;
1281 }
1282
1283 /* bus->mdio_lock should be locked when using this function */
1284 static bool vsc8574_is_serdes_init(struct phy_device *phydev)
1285 {
1286         u16 reg;
1287         bool ret;
1288
1289         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1290                        MSCC_PHY_PAGE_EXTENDED_GPIO);
1291
1292         reg = phy_base_read(phydev, MSCC_TRAP_ROM_ADDR(1));
1293         if (reg != 0x3eb7) {
1294                 ret = false;
1295                 goto out;
1296         }
1297
1298         reg = phy_base_read(phydev, MSCC_PATCH_RAM_ADDR(1));
1299         if (reg != 0x4012) {
1300                 ret = false;
1301                 goto out;
1302         }
1303
1304         reg = phy_base_read(phydev, MSCC_INT_MEM_CNTL);
1305         if (reg != EN_PATCH_RAM_TRAP_ADDR(1)) {
1306                 ret = false;
1307                 goto out;
1308         }
1309
1310         reg = phy_base_read(phydev, MSCC_DW8051_CNTL_STATUS);
1311         if ((MICRO_NSOFT_RESET | RUN_FROM_INT_ROM |  DW8051_CLK_EN |
1312              MICRO_CLK_EN) != (reg & MSCC_DW8051_VLD_MASK)) {
1313                 ret = false;
1314                 goto out;
1315         }
1316
1317         ret = true;
1318 out:
1319         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1320
1321         return ret;
1322 }
1323
1324 /* bus->mdio_lock should be locked when using this function */
1325 static int vsc8574_config_pre_init(struct phy_device *phydev)
1326 {
1327         static const struct reg_val pre_init1[] = {
1328                 {0x0fae, 0x000401bd},
1329                 {0x0fac, 0x000f000f},
1330                 {0x17a0, 0x00a0f147},
1331                 {0x0fe4, 0x00052f54},
1332                 {0x1792, 0x0027303d},
1333                 {0x07fe, 0x00000704},
1334                 {0x0fe0, 0x00060150},
1335                 {0x0f82, 0x0012b00a},
1336                 {0x0f80, 0x00000d74},
1337                 {0x02e0, 0x00000012},
1338                 {0x03a2, 0x00050208},
1339                 {0x03b2, 0x00009186},
1340                 {0x0fb0, 0x000e3700},
1341                 {0x1688, 0x00049f81},
1342                 {0x0fd2, 0x0000ffff},
1343                 {0x168a, 0x00039fa2},
1344                 {0x1690, 0x0020640b},
1345                 {0x0258, 0x00002220},
1346                 {0x025a, 0x00002a20},
1347                 {0x025c, 0x00003060},
1348                 {0x025e, 0x00003fa0},
1349                 {0x03a6, 0x0000e0f0},
1350                 {0x0f92, 0x00001489},
1351                 {0x16a2, 0x00007000},
1352                 {0x16a6, 0x00071448},
1353                 {0x16a0, 0x00eeffdd},
1354                 {0x0fe8, 0x0091b06c},
1355                 {0x0fea, 0x00041600},
1356                 {0x16b0, 0x00eeff00},
1357                 {0x16b2, 0x00007000},
1358                 {0x16b4, 0x00000814},
1359                 {0x0f90, 0x00688980},
1360                 {0x03a4, 0x0000d8f0},
1361                 {0x0fc0, 0x00000400},
1362                 {0x07fa, 0x0050100f},
1363                 {0x0796, 0x00000003},
1364                 {0x07f8, 0x00c3ff98},
1365                 {0x0fa4, 0x0018292a},
1366                 {0x168c, 0x00d2c46f},
1367                 {0x17a2, 0x00000620},
1368                 {0x16a4, 0x0013132f},
1369                 {0x16a8, 0x00000000},
1370                 {0x0ffc, 0x00c0a028},
1371                 {0x0fec, 0x00901c09},
1372                 {0x0fee, 0x0004a6a1},
1373                 {0x0ffe, 0x00b01807},
1374         };
1375         static const struct reg_val pre_init2[] = {
1376                 {0x0486, 0x0008a518},
1377                 {0x0488, 0x006dc696},
1378                 {0x048a, 0x00000912},
1379                 {0x048e, 0x00000db6},
1380                 {0x049c, 0x00596596},
1381                 {0x049e, 0x00000514},
1382                 {0x04a2, 0x00410280},
1383                 {0x04a4, 0x00000000},
1384                 {0x04a6, 0x00000000},
1385                 {0x04a8, 0x00000000},
1386                 {0x04aa, 0x00000000},
1387                 {0x04ae, 0x007df7dd},
1388                 {0x04b0, 0x006d95d4},
1389                 {0x04b2, 0x00492410},
1390         };
1391         struct device *dev = &phydev->mdio.dev;
1392         const struct firmware *fw;
1393         unsigned int i;
1394         u16 crc, reg;
1395         bool serdes_init;
1396         int ret;
1397
1398         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1399
1400         /* all writes below are broadcasted to all PHYs in the same package */
1401         reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1402         reg |= SMI_BROADCAST_WR_EN;
1403         phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1404
1405         phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
1406
1407         /* The below register writes are tweaking analog and electrical
1408          * configuration that were determined through characterization by PHY
1409          * engineers. These don't mean anything more than "these are the best
1410          * values".
1411          */
1412         phy_base_write(phydev, MSCC_PHY_EXT_PHY_CNTL_2, 0x0040);
1413
1414         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1415
1416         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_20, 0x4320);
1417         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_24, 0x0c00);
1418         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_9, 0x18ca);
1419         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1b20);
1420
1421         reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1422         reg |= 0x8000;
1423         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1424
1425         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1426
1427         for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1428                 vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1429
1430         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
1431
1432         phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
1433
1434         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1435
1436         for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
1437                 vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
1438
1439         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1440
1441         reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1442         reg &= ~0x8000;
1443         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1444
1445         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1446
1447         /* end of write broadcasting */
1448         reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1449         reg &= ~SMI_BROADCAST_WR_EN;
1450         phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1451
1452         ret = request_firmware(&fw, MSCC_VSC8574_REVB_INT8051_FW, dev);
1453         if (ret) {
1454                 dev_err(dev, "failed to load firmware %s, ret: %d\n",
1455                         MSCC_VSC8574_REVB_INT8051_FW, ret);
1456                 return ret;
1457         }
1458
1459         /* Add one byte to size for the one added by the patch_fw function */
1460         ret = vsc8584_get_fw_crc(phydev,
1461                                  MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
1462                                  fw->size + 1, &crc);
1463         if (ret)
1464                 goto out;
1465
1466         if (crc == MSCC_VSC8574_REVB_INT8051_FW_CRC) {
1467                 serdes_init = vsc8574_is_serdes_init(phydev);
1468
1469                 if (!serdes_init) {
1470                         ret = vsc8584_micro_assert_reset(phydev);
1471                         if (ret) {
1472                                 dev_err(dev,
1473                                         "%s: failed to assert reset of micro\n",
1474                                         __func__);
1475                                 goto out;
1476                         }
1477                 }
1478         } else {
1479                 dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
1480
1481                 serdes_init = false;
1482
1483                 if (vsc8584_patch_fw(phydev, fw))
1484                         dev_warn(dev,
1485                                  "failed to patch FW, expect non-optimal device\n");
1486         }
1487
1488         if (!serdes_init) {
1489                 phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1490                                MSCC_PHY_PAGE_EXTENDED_GPIO);
1491
1492                 phy_base_write(phydev, MSCC_TRAP_ROM_ADDR(1), 0x3eb7);
1493                 phy_base_write(phydev, MSCC_PATCH_RAM_ADDR(1), 0x4012);
1494                 phy_base_write(phydev, MSCC_INT_MEM_CNTL,
1495                                EN_PATCH_RAM_TRAP_ADDR(1));
1496
1497                 vsc8584_micro_deassert_reset(phydev, false);
1498
1499                 /* Add one byte to size for the one added by the patch_fw
1500                  * function
1501                  */
1502                 ret = vsc8584_get_fw_crc(phydev,
1503                                          MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
1504                                          fw->size + 1, &crc);
1505                 if (ret)
1506                         goto out;
1507
1508                 if (crc != MSCC_VSC8574_REVB_INT8051_FW_CRC)
1509                         dev_warn(dev,
1510                                  "FW CRC after patching is not the expected one, expect non-optimal device\n");
1511         }
1512
1513         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
1514                        MSCC_PHY_PAGE_EXTENDED_GPIO);
1515
1516         ret = vsc8584_cmd(phydev, PROC_CMD_1588_DEFAULT_INIT |
1517                           PROC_CMD_PHY_INIT);
1518
1519 out:
1520         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1521
1522         release_firmware(fw);
1523
1524         return ret;
1525 }
1526
1527 /* bus->mdio_lock should be locked when using this function */
1528 static int vsc8584_config_pre_init(struct phy_device *phydev)
1529 {
1530         static const struct reg_val pre_init1[] = {
1531                 {0x07fa, 0x0050100f},
1532                 {0x1688, 0x00049f81},
1533                 {0x0f90, 0x00688980},
1534                 {0x03a4, 0x0000d8f0},
1535                 {0x0fc0, 0x00000400},
1536                 {0x0f82, 0x0012b002},
1537                 {0x1686, 0x00000004},
1538                 {0x168c, 0x00d2c46f},
1539                 {0x17a2, 0x00000620},
1540                 {0x16a0, 0x00eeffdd},
1541                 {0x16a6, 0x00071448},
1542                 {0x16a4, 0x0013132f},
1543                 {0x16a8, 0x00000000},
1544                 {0x0ffc, 0x00c0a028},
1545                 {0x0fe8, 0x0091b06c},
1546                 {0x0fea, 0x00041600},
1547                 {0x0f80, 0x00fffaff},
1548                 {0x0fec, 0x00901809},
1549                 {0x0ffe, 0x00b01007},
1550                 {0x16b0, 0x00eeff00},
1551                 {0x16b2, 0x00007000},
1552                 {0x16b4, 0x00000814},
1553         };
1554         static const struct reg_val pre_init2[] = {
1555                 {0x0486, 0x0008a518},
1556                 {0x0488, 0x006dc696},
1557                 {0x048a, 0x00000912},
1558         };
1559         const struct firmware *fw;
1560         struct device *dev = &phydev->mdio.dev;
1561         unsigned int i;
1562         u16 crc, reg;
1563         int ret;
1564
1565         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1566
1567         /* all writes below are broadcasted to all PHYs in the same package */
1568         reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1569         reg |= SMI_BROADCAST_WR_EN;
1570         phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1571
1572         phy_base_write(phydev, MII_VSC85XX_INT_MASK, 0);
1573
1574         reg = phy_base_read(phydev,  MSCC_PHY_BYPASS_CONTROL);
1575         reg |= PARALLEL_DET_IGNORE_ADVERTISED;
1576         phy_base_write(phydev, MSCC_PHY_BYPASS_CONTROL, reg);
1577
1578         /* The below register writes are tweaking analog and electrical
1579          * configuration that were determined through characterization by PHY
1580          * engineers. These don't mean anything more than "these are the best
1581          * values".
1582          */
1583         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_3);
1584
1585         phy_base_write(phydev, MSCC_PHY_SERDES_TX_CRC_ERR_CNT, 0x2000);
1586
1587         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1588
1589         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1f20);
1590
1591         reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1592         reg |= 0x8000;
1593         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1594
1595         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1596
1597         phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x2fa4));
1598
1599         reg = phy_base_read(phydev, MSCC_PHY_TR_MSB);
1600         reg &= ~0x007f;
1601         reg |= 0x0019;
1602         phy_base_write(phydev, MSCC_PHY_TR_MSB, reg);
1603
1604         phy_base_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x0fa4));
1605
1606         for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
1607                 vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
1608
1609         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_2);
1610
1611         phy_base_write(phydev, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
1612
1613         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
1614
1615         for (i = 0; i < ARRAY_SIZE(pre_init2); i++)
1616                 vsc8584_csr_write(phydev, pre_init2[i].reg, pre_init2[i].val);
1617
1618         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
1619
1620         reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
1621         reg &= ~0x8000;
1622         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
1623
1624         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1625
1626         /* end of write broadcasting */
1627         reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
1628         reg &= ~SMI_BROADCAST_WR_EN;
1629         phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
1630
1631         ret = request_firmware(&fw, MSCC_VSC8584_REVB_INT8051_FW, dev);
1632         if (ret) {
1633                 dev_err(dev, "failed to load firmware %s, ret: %d\n",
1634                         MSCC_VSC8584_REVB_INT8051_FW, ret);
1635                 return ret;
1636         }
1637
1638         /* Add one byte to size for the one added by the patch_fw function */
1639         ret = vsc8584_get_fw_crc(phydev,
1640                                  MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
1641                                  fw->size + 1, &crc);
1642         if (ret)
1643                 goto out;
1644
1645         if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
1646                 dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
1647                 if (vsc8584_patch_fw(phydev, fw))
1648                         dev_warn(dev,
1649                                  "failed to patch FW, expect non-optimal device\n");
1650         }
1651
1652         vsc8584_micro_deassert_reset(phydev, false);
1653
1654         /* Add one byte to size for the one added by the patch_fw function */
1655         ret = vsc8584_get_fw_crc(phydev,
1656                                  MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
1657                                  fw->size + 1, &crc);
1658         if (ret)
1659                 goto out;
1660
1661         if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
1662                 dev_warn(dev,
1663                          "FW CRC after patching is not the expected one, expect non-optimal device\n");
1664
1665         ret = vsc8584_micro_assert_reset(phydev);
1666         if (ret)
1667                 goto out;
1668
1669         vsc8584_micro_deassert_reset(phydev, true);
1670
1671 out:
1672         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
1673
1674         release_firmware(fw);
1675
1676         return ret;
1677 }
1678
1679 #if IS_ENABLED(CONFIG_MACSEC)
1680 static u32 vsc8584_macsec_phy_read(struct phy_device *phydev,
1681                                    enum macsec_bank bank, u32 reg)
1682 {
1683         u32 val, val_l = 0, val_h = 0;
1684         unsigned long deadline;
1685         int rc;
1686
1687         rc = phy_select_page(phydev, MSCC_PHY_PAGE_MACSEC);
1688         if (rc < 0)
1689                 goto failed;
1690
1691         __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_20,
1692                     MSCC_PHY_MACSEC_20_TARGET(bank >> 2));
1693
1694         if (bank >> 2 == 0x1)
1695                 /* non-MACsec access */
1696                 bank &= 0x3;
1697         else
1698                 bank = 0;
1699
1700         __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_19,
1701                     MSCC_PHY_MACSEC_19_CMD | MSCC_PHY_MACSEC_19_READ |
1702                     MSCC_PHY_MACSEC_19_REG_ADDR(reg) |
1703                     MSCC_PHY_MACSEC_19_TARGET(bank));
1704
1705         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1706         do {
1707                 val = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_19);
1708         } while (time_before(jiffies, deadline) && !(val & MSCC_PHY_MACSEC_19_CMD));
1709
1710         val_l = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_17);
1711         val_h = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_18);
1712
1713 failed:
1714         phy_restore_page(phydev, rc, rc);
1715
1716         return (val_h << 16) | val_l;
1717 }
1718
1719 static void vsc8584_macsec_phy_write(struct phy_device *phydev,
1720                                      enum macsec_bank bank, u32 reg, u32 val)
1721 {
1722         unsigned long deadline;
1723         int rc;
1724
1725         rc = phy_select_page(phydev, MSCC_PHY_PAGE_MACSEC);
1726         if (rc < 0)
1727                 goto failed;
1728
1729         __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_20,
1730                     MSCC_PHY_MACSEC_20_TARGET(bank >> 2));
1731
1732         if ((bank >> 2 == 0x1) || (bank >> 2 == 0x3))
1733                 bank &= 0x3;
1734         else
1735                 /* MACsec access */
1736                 bank = 0;
1737
1738         __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_17, (u16)val);
1739         __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_18, (u16)(val >> 16));
1740
1741         __phy_write(phydev, MSCC_EXT_PAGE_MACSEC_19,
1742                     MSCC_PHY_MACSEC_19_CMD | MSCC_PHY_MACSEC_19_REG_ADDR(reg) |
1743                     MSCC_PHY_MACSEC_19_TARGET(bank));
1744
1745         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
1746         do {
1747                 val = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_19);
1748         } while (time_before(jiffies, deadline) && !(val & MSCC_PHY_MACSEC_19_CMD));
1749
1750 failed:
1751         phy_restore_page(phydev, rc, rc);
1752 }
1753
1754 static void vsc8584_macsec_classification(struct phy_device *phydev,
1755                                           enum macsec_bank bank)
1756 {
1757         /* enable VLAN tag parsing */
1758         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_CP_TAG,
1759                                  MSCC_MS_SAM_CP_TAG_PARSE_STAG |
1760                                  MSCC_MS_SAM_CP_TAG_PARSE_QTAG |
1761                                  MSCC_MS_SAM_CP_TAG_PARSE_QINQ);
1762 }
1763
1764 static void vsc8584_macsec_flow_default_action(struct phy_device *phydev,
1765                                                enum macsec_bank bank,
1766                                                bool block)
1767 {
1768         u32 port = (bank == MACSEC_INGR) ?
1769                     MSCC_MS_PORT_UNCONTROLLED : MSCC_MS_PORT_COMMON;
1770         u32 action = MSCC_MS_FLOW_BYPASS;
1771
1772         if (block)
1773                 action = MSCC_MS_FLOW_DROP;
1774
1775         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_NM_FLOW_NCP,
1776                                  /* MACsec untagged */
1777                                  MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_FLOW_TYPE(action) |
1778                                  MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1779                                  MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_DEST_PORT(port) |
1780                                  /* MACsec tagged */
1781                                  MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_FLOW_TYPE(action) |
1782                                  MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1783                                  MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_DEST_PORT(port) |
1784                                  /* Bad tag */
1785                                  MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_FLOW_TYPE(action) |
1786                                  MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1787                                  MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_DEST_PORT(port) |
1788                                  /* Kay tag */
1789                                  MSCC_MS_SAM_NM_FLOW_NCP_KAY_FLOW_TYPE(action) |
1790                                  MSCC_MS_SAM_NM_FLOW_NCP_KAY_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1791                                  MSCC_MS_SAM_NM_FLOW_NCP_KAY_DEST_PORT(port));
1792         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_NM_FLOW_CP,
1793                                  /* MACsec untagged */
1794                                  MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_FLOW_TYPE(action) |
1795                                  MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1796                                  MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_DEST_PORT(port) |
1797                                  /* MACsec tagged */
1798                                  MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_FLOW_TYPE(action) |
1799                                  MSCC_MS_SAM_NM_FLOW_CP_TAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1800                                  MSCC_MS_SAM_NM_FLOW_CP_TAGGED_DEST_PORT(port) |
1801                                  /* Bad tag */
1802                                  MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_FLOW_TYPE(action) |
1803                                  MSCC_MS_SAM_NM_FLOW_CP_BADTAG_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1804                                  MSCC_MS_SAM_NM_FLOW_CP_BADTAG_DEST_PORT(port) |
1805                                  /* Kay tag */
1806                                  MSCC_MS_SAM_NM_FLOW_NCP_KAY_FLOW_TYPE(action) |
1807                                  MSCC_MS_SAM_NM_FLOW_CP_KAY_DROP_ACTION(MSCC_MS_ACTION_DROP) |
1808                                  MSCC_MS_SAM_NM_FLOW_CP_KAY_DEST_PORT(port));
1809 }
1810
1811 static void vsc8584_macsec_integrity_checks(struct phy_device *phydev,
1812                                             enum macsec_bank bank)
1813 {
1814         u32 val;
1815
1816         if (bank != MACSEC_INGR)
1817                 return;
1818
1819         /* Set default rules to pass unmatched frames */
1820         val = vsc8584_macsec_phy_read(phydev, bank,
1821                                       MSCC_MS_PARAMS2_IG_CC_CONTROL);
1822         val |= MSCC_MS_PARAMS2_IG_CC_CONTROL_NON_MATCH_CTRL_ACT |
1823                MSCC_MS_PARAMS2_IG_CC_CONTROL_NON_MATCH_ACT;
1824         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PARAMS2_IG_CC_CONTROL,
1825                                  val);
1826
1827         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PARAMS2_IG_CP_TAG,
1828                                  MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_STAG |
1829                                  MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_QTAG |
1830                                  MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_QINQ);
1831 }
1832
1833 static void vsc8584_macsec_block_init(struct phy_device *phydev,
1834                                       enum macsec_bank bank)
1835 {
1836         u32 val;
1837         int i;
1838
1839         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
1840                                  MSCC_MS_ENA_CFG_SW_RST |
1841                                  MSCC_MS_ENA_CFG_MACSEC_BYPASS_ENA);
1842
1843         /* Set the MACsec block out of s/w reset and enable clocks */
1844         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
1845                                  MSCC_MS_ENA_CFG_CLK_ENA);
1846
1847         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_STATUS_CONTEXT_CTRL,
1848                                  bank == MACSEC_INGR ? 0xe5880214 : 0xe5880218);
1849         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_MISC_CONTROL,
1850                                  MSCC_MS_MISC_CONTROL_MC_LATENCY_FIX(bank == MACSEC_INGR ? 57 : 40) |
1851                                  MSCC_MS_MISC_CONTROL_XFORM_REC_SIZE(bank == MACSEC_INGR ? 1 : 2));
1852
1853         /* Clear the counters */
1854         val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_COUNT_CONTROL);
1855         val |= MSCC_MS_COUNT_CONTROL_AUTO_CNTR_RESET;
1856         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_COUNT_CONTROL, val);
1857
1858         /* Enable octet increment mode */
1859         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PP_CTRL,
1860                                  MSCC_MS_PP_CTRL_MACSEC_OCTET_INCR_MODE);
1861
1862         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_BLOCK_CTX_UPDATE, 0x3);
1863
1864         val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_COUNT_CONTROL);
1865         val |= MSCC_MS_COUNT_CONTROL_RESET_ALL;
1866         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_COUNT_CONTROL, val);
1867
1868         /* Set the MTU */
1869         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_NON_VLAN_MTU_CHECK,
1870                                  MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMPARE(32761) |
1871                                  MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMP_DROP);
1872
1873         for (i = 0; i < 8; i++)
1874                 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_VLAN_MTU_CHECK(i),
1875                                          MSCC_MS_VLAN_MTU_CHECK_MTU_COMPARE(32761) |
1876                                          MSCC_MS_VLAN_MTU_CHECK_MTU_COMP_DROP);
1877
1878         if (bank == MACSEC_EGR) {
1879                 val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_INTR_CTRL_STATUS);
1880                 val &= ~MSCC_MS_INTR_CTRL_STATUS_INTR_ENABLE_M;
1881                 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_INTR_CTRL_STATUS, val);
1882
1883                 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_FC_CFG,
1884                                          MSCC_MS_FC_CFG_FCBUF_ENA |
1885                                          MSCC_MS_FC_CFG_LOW_THRESH(0x1) |
1886                                          MSCC_MS_FC_CFG_HIGH_THRESH(0x4) |
1887                                          MSCC_MS_FC_CFG_LOW_BYTES_VAL(0x4) |
1888                                          MSCC_MS_FC_CFG_HIGH_BYTES_VAL(0x6));
1889         }
1890
1891         vsc8584_macsec_classification(phydev, bank);
1892         vsc8584_macsec_flow_default_action(phydev, bank, false);
1893         vsc8584_macsec_integrity_checks(phydev, bank);
1894
1895         /* Enable the MACsec block */
1896         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
1897                                  MSCC_MS_ENA_CFG_CLK_ENA |
1898                                  MSCC_MS_ENA_CFG_MACSEC_ENA |
1899                                  MSCC_MS_ENA_CFG_MACSEC_SPEED_MODE(0x5));
1900 }
1901
1902 static void vsc8584_macsec_mac_init(struct phy_device *phydev,
1903                                     enum macsec_bank bank)
1904 {
1905         u32 val;
1906         int i;
1907
1908         /* Clear host & line stats */
1909         for (i = 0; i < 36; i++)
1910                 vsc8584_macsec_phy_write(phydev, bank, 0x1c + i, 0);
1911
1912         val = vsc8584_macsec_phy_read(phydev, bank,
1913                                       MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL);
1914         val &= ~MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE_M;
1915         val |= MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE(2) |
1916                MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_VALUE(0xffff);
1917         vsc8584_macsec_phy_write(phydev, bank,
1918                                  MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL, val);
1919
1920         val = vsc8584_macsec_phy_read(phydev, bank,
1921                                       MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2);
1922         val |= 0xffff;
1923         vsc8584_macsec_phy_write(phydev, bank,
1924                                  MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2, val);
1925
1926         val = vsc8584_macsec_phy_read(phydev, bank,
1927                                       MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL);
1928         if (bank == HOST_MAC)
1929                 val |= MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_TIMER_ENA |
1930                        MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_FRAME_DROP_ENA;
1931         else
1932                 val |= MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_REACT_ENA |
1933                        MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_FRAME_DROP_ENA |
1934                        MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_MODE |
1935                        MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_EARLY_PAUSE_DETECT_ENA;
1936         vsc8584_macsec_phy_write(phydev, bank,
1937                                  MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL, val);
1938
1939         vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_PKTINF_CFG,
1940                                  MSCC_MAC_CFG_PKTINF_CFG_STRIP_FCS_ENA |
1941                                  MSCC_MAC_CFG_PKTINF_CFG_INSERT_FCS_ENA |
1942                                  MSCC_MAC_CFG_PKTINF_CFG_LPI_RELAY_ENA |
1943                                  MSCC_MAC_CFG_PKTINF_CFG_STRIP_PREAMBLE_ENA |
1944                                  MSCC_MAC_CFG_PKTINF_CFG_INSERT_PREAMBLE_ENA |
1945                                  (bank == HOST_MAC ?
1946                                   MSCC_MAC_CFG_PKTINF_CFG_ENABLE_TX_PADDING : 0));
1947
1948         val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_MODE_CFG);
1949         val &= ~MSCC_MAC_CFG_MODE_CFG_DISABLE_DIC;
1950         vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_MODE_CFG, val);
1951
1952         val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_MAXLEN_CFG);
1953         val &= ~MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN_M;
1954         val |= MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN(10240);
1955         vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_MAXLEN_CFG, val);
1956
1957         vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_ADV_CHK_CFG,
1958                                  MSCC_MAC_CFG_ADV_CHK_CFG_SFD_CHK_ENA |
1959                                  MSCC_MAC_CFG_ADV_CHK_CFG_PRM_CHK_ENA |
1960                                  MSCC_MAC_CFG_ADV_CHK_CFG_OOR_ERR_ENA |
1961                                  MSCC_MAC_CFG_ADV_CHK_CFG_INR_ERR_ENA);
1962
1963         val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_LFS_CFG);
1964         val &= ~MSCC_MAC_CFG_LFS_CFG_LFS_MODE_ENA;
1965         vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_LFS_CFG, val);
1966
1967         vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_ENA_CFG,
1968                                  MSCC_MAC_CFG_ENA_CFG_RX_CLK_ENA |
1969                                  MSCC_MAC_CFG_ENA_CFG_TX_CLK_ENA |
1970                                  MSCC_MAC_CFG_ENA_CFG_RX_ENA |
1971                                  MSCC_MAC_CFG_ENA_CFG_TX_ENA);
1972 }
1973
1974 /* Must be called with mdio_lock taken */
1975 static int vsc8584_macsec_init(struct phy_device *phydev)
1976 {
1977         u32 val;
1978
1979         vsc8584_macsec_block_init(phydev, MACSEC_INGR);
1980         vsc8584_macsec_block_init(phydev, MACSEC_EGR);
1981         vsc8584_macsec_mac_init(phydev, HOST_MAC);
1982         vsc8584_macsec_mac_init(phydev, LINE_MAC);
1983
1984         vsc8584_macsec_phy_write(phydev, FC_BUFFER,
1985                                  MSCC_FCBUF_FC_READ_THRESH_CFG,
1986                                  MSCC_FCBUF_FC_READ_THRESH_CFG_TX_THRESH(4) |
1987                                  MSCC_FCBUF_FC_READ_THRESH_CFG_RX_THRESH(5));
1988
1989         val = vsc8584_macsec_phy_read(phydev, FC_BUFFER, MSCC_FCBUF_MODE_CFG);
1990         val |= MSCC_FCBUF_MODE_CFG_PAUSE_GEN_ENA |
1991                MSCC_FCBUF_MODE_CFG_RX_PPM_RATE_ADAPT_ENA |
1992                MSCC_FCBUF_MODE_CFG_TX_PPM_RATE_ADAPT_ENA;
1993         vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_MODE_CFG, val);
1994
1995         vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG,
1996                                  MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_THRESH(8) |
1997                                  MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_OFFSET(9));
1998
1999         val = vsc8584_macsec_phy_read(phydev, FC_BUFFER,
2000                                       MSCC_FCBUF_TX_DATA_QUEUE_CFG);
2001         val &= ~(MSCC_FCBUF_TX_DATA_QUEUE_CFG_START_M |
2002                  MSCC_FCBUF_TX_DATA_QUEUE_CFG_END_M);
2003         val |= MSCC_FCBUF_TX_DATA_QUEUE_CFG_START(0) |
2004                 MSCC_FCBUF_TX_DATA_QUEUE_CFG_END(5119);
2005         vsc8584_macsec_phy_write(phydev, FC_BUFFER,
2006                                  MSCC_FCBUF_TX_DATA_QUEUE_CFG, val);
2007
2008         val = vsc8584_macsec_phy_read(phydev, FC_BUFFER, MSCC_FCBUF_ENA_CFG);
2009         val |= MSCC_FCBUF_ENA_CFG_TX_ENA | MSCC_FCBUF_ENA_CFG_RX_ENA;
2010         vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_ENA_CFG, val);
2011
2012         val = vsc8584_macsec_phy_read(phydev, IP_1588,
2013                                       MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL);
2014         val &= ~MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE_M;
2015         val |= MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE(4);
2016         vsc8584_macsec_phy_write(phydev, IP_1588,
2017                                  MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL, val);
2018
2019         return 0;
2020 }
2021
2022 static void vsc8584_macsec_flow(struct phy_device *phydev,
2023                                 struct macsec_flow *flow)
2024 {
2025         struct vsc8531_private *priv = phydev->priv;
2026         enum macsec_bank bank = flow->bank;
2027         u32 val, match = 0, mask = 0, action = 0, idx = flow->index;
2028
2029         if (flow->match.tagged)
2030                 match |= MSCC_MS_SAM_MISC_MATCH_TAGGED;
2031         if (flow->match.untagged)
2032                 match |= MSCC_MS_SAM_MISC_MATCH_UNTAGGED;
2033
2034         if (bank == MACSEC_INGR && flow->assoc_num >= 0) {
2035                 match |= MSCC_MS_SAM_MISC_MATCH_AN(flow->assoc_num);
2036                 mask |= MSCC_MS_SAM_MASK_AN_MASK(0x3);
2037         }
2038
2039         if (bank == MACSEC_INGR && flow->match.sci && flow->rx_sa->sc->sci) {
2040                 match |= MSCC_MS_SAM_MISC_MATCH_TCI(BIT(3));
2041                 mask |= MSCC_MS_SAM_MASK_TCI_MASK(BIT(3)) |
2042                         MSCC_MS_SAM_MASK_SCI_MASK;
2043
2044                 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MATCH_SCI_LO(idx),
2045                                          lower_32_bits(flow->rx_sa->sc->sci));
2046                 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MATCH_SCI_HI(idx),
2047                                          upper_32_bits(flow->rx_sa->sc->sci));
2048         }
2049
2050         if (flow->match.etype) {
2051                 mask |= MSCC_MS_SAM_MASK_MAC_ETYPE_MASK;
2052
2053                 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MAC_SA_MATCH_HI(idx),
2054                                          MSCC_MS_SAM_MAC_SA_MATCH_HI_ETYPE(htons(flow->etype)));
2055         }
2056
2057         match |= MSCC_MS_SAM_MISC_MATCH_PRIORITY(flow->priority);
2058
2059         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MISC_MATCH(idx), match);
2060         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MASK(idx), mask);
2061
2062         /* Action for matching packets */
2063         if (flow->action.drop)
2064                 action = MSCC_MS_FLOW_DROP;
2065         else if (flow->action.bypass || flow->port == MSCC_MS_PORT_UNCONTROLLED)
2066                 action = MSCC_MS_FLOW_BYPASS;
2067         else
2068                 action = (bank == MACSEC_INGR) ?
2069                          MSCC_MS_FLOW_INGRESS : MSCC_MS_FLOW_EGRESS;
2070
2071         val = MSCC_MS_SAM_FLOW_CTRL_FLOW_TYPE(action) |
2072               MSCC_MS_SAM_FLOW_CTRL_DROP_ACTION(MSCC_MS_ACTION_DROP) |
2073               MSCC_MS_SAM_FLOW_CTRL_DEST_PORT(flow->port);
2074
2075         if (action == MSCC_MS_FLOW_BYPASS)
2076                 goto write_ctrl;
2077
2078         if (bank == MACSEC_INGR) {
2079                 if (priv->secy->replay_protect)
2080                         val |= MSCC_MS_SAM_FLOW_CTRL_REPLAY_PROTECT;
2081                 if (priv->secy->validate_frames == MACSEC_VALIDATE_STRICT)
2082                         val |= MSCC_MS_SAM_FLOW_CTRL_VALIDATE_FRAMES(MSCC_MS_VALIDATE_STRICT);
2083                 else if (priv->secy->validate_frames == MACSEC_VALIDATE_CHECK)
2084                         val |= MSCC_MS_SAM_FLOW_CTRL_VALIDATE_FRAMES(MSCC_MS_VALIDATE_CHECK);
2085         } else if (bank == MACSEC_EGR) {
2086                 if (priv->secy->protect_frames)
2087                         val |= MSCC_MS_SAM_FLOW_CTRL_PROTECT_FRAME;
2088                 if (priv->secy->tx_sc.encrypt)
2089                         val |= MSCC_MS_SAM_FLOW_CTRL_CONF_PROTECT;
2090                 if (priv->secy->tx_sc.send_sci)
2091                         val |= MSCC_MS_SAM_FLOW_CTRL_INCLUDE_SCI;
2092         }
2093
2094 write_ctrl:
2095         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx), val);
2096 }
2097
2098 static struct macsec_flow *vsc8584_macsec_find_flow(struct macsec_context *ctx,
2099                                                     enum macsec_bank bank)
2100 {
2101         struct vsc8531_private *priv = ctx->phydev->priv;
2102         struct macsec_flow *pos, *tmp;
2103
2104         list_for_each_entry_safe(pos, tmp, &priv->macsec_flows, list)
2105                 if (pos->assoc_num == ctx->sa.assoc_num && pos->bank == bank)
2106                         return pos;
2107
2108         return ERR_PTR(-ENOENT);
2109 }
2110
2111 static void vsc8584_macsec_flow_enable(struct phy_device *phydev,
2112                                        struct macsec_flow *flow)
2113 {
2114         enum macsec_bank bank = flow->bank;
2115         u32 val, idx = flow->index;
2116
2117         if ((flow->bank == MACSEC_INGR && flow->rx_sa && !flow->rx_sa->active) ||
2118             (flow->bank == MACSEC_EGR && flow->tx_sa && !flow->tx_sa->active))
2119                 return;
2120
2121         /* Enable */
2122         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_ENTRY_SET1, BIT(idx));
2123
2124         /* Set in-use */
2125         val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx));
2126         val |= MSCC_MS_SAM_FLOW_CTRL_SA_IN_USE;
2127         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx), val);
2128 }
2129
2130 static void vsc8584_macsec_flow_disable(struct phy_device *phydev,
2131                                         struct macsec_flow *flow)
2132 {
2133         enum macsec_bank bank = flow->bank;
2134         u32 val, idx = flow->index;
2135
2136         /* Disable */
2137         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_ENTRY_CLEAR1, BIT(idx));
2138
2139         /* Clear in-use */
2140         val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx));
2141         val &= ~MSCC_MS_SAM_FLOW_CTRL_SA_IN_USE;
2142         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_FLOW_CTRL(idx), val);
2143 }
2144
2145 static u32 vsc8584_macsec_flow_context_id(struct macsec_flow *flow)
2146 {
2147         if (flow->bank == MACSEC_INGR)
2148                 return flow->index + MSCC_MS_MAX_FLOWS;
2149
2150         return flow->index;
2151 }
2152
2153 /* Derive the AES key to get a key for the hash autentication */
2154 static int vsc8584_macsec_derive_key(const u8 key[MACSEC_KEYID_LEN],
2155                                      u16 key_len, u8 hkey[16])
2156 {
2157         struct crypto_skcipher *tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0);
2158         struct skcipher_request *req = NULL;
2159         struct scatterlist src, dst;
2160         DECLARE_CRYPTO_WAIT(wait);
2161         u32 input[4] = {0};
2162         int ret;
2163
2164         if (IS_ERR(tfm))
2165                 return PTR_ERR(tfm);
2166
2167         req = skcipher_request_alloc(tfm, GFP_KERNEL);
2168         if (!req) {
2169                 ret = -ENOMEM;
2170                 goto out;
2171         }
2172
2173         skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
2174                                       CRYPTO_TFM_REQ_MAY_SLEEP, crypto_req_done,
2175                                       &wait);
2176         ret = crypto_skcipher_setkey(tfm, key, key_len);
2177         if (ret < 0)
2178                 goto out;
2179
2180         sg_init_one(&src, input, 16);
2181         sg_init_one(&dst, hkey, 16);
2182         skcipher_request_set_crypt(req, &src, &dst, 16, NULL);
2183
2184         ret = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
2185
2186 out:
2187         skcipher_request_free(req);
2188         crypto_free_skcipher(tfm);
2189         return ret;
2190 }
2191
2192 static int vsc8584_macsec_transformation(struct phy_device *phydev,
2193                                          struct macsec_flow *flow)
2194 {
2195         struct vsc8531_private *priv = phydev->priv;
2196         enum macsec_bank bank = flow->bank;
2197         int i, ret, index = flow->index;
2198         u32 rec = 0, control = 0;
2199         u8 hkey[16];
2200         sci_t sci;
2201
2202         ret = vsc8584_macsec_derive_key(flow->key, priv->secy->key_len, hkey);
2203         if (ret)
2204                 return ret;
2205
2206         switch (priv->secy->key_len) {
2207         case 16:
2208                 control |= CONTROL_CRYPTO_ALG(CTRYPTO_ALG_AES_CTR_128);
2209                 break;
2210         case 32:
2211                 control |= CONTROL_CRYPTO_ALG(CTRYPTO_ALG_AES_CTR_256);
2212                 break;
2213         default:
2214                 return -EINVAL;
2215         }
2216
2217         control |= (bank == MACSEC_EGR) ?
2218                    (CONTROL_TYPE_EGRESS | CONTROL_AN(priv->secy->tx_sc.encoding_sa)) :
2219                    (CONTROL_TYPE_INGRESS | CONTROL_SEQ_MASK);
2220
2221         control |= CONTROL_UPDATE_SEQ | CONTROL_ENCRYPT_AUTH | CONTROL_KEY_IN_CTX |
2222                    CONTROL_IV0 | CONTROL_IV1 | CONTROL_IV_IN_SEQ |
2223                    CONTROL_DIGEST_TYPE(0x2) | CONTROL_SEQ_TYPE(0x1) |
2224                    CONTROL_AUTH_ALG(AUTH_ALG_AES_GHAS) | CONTROL_CONTEXT_ID;
2225
2226         /* Set the control word */
2227         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
2228                                  control);
2229
2230         /* Set the context ID. Must be unique. */
2231         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
2232                                  vsc8584_macsec_flow_context_id(flow));
2233
2234         /* Set the encryption/decryption key */
2235         for (i = 0; i < priv->secy->key_len / sizeof(u32); i++)
2236                 vsc8584_macsec_phy_write(phydev, bank,
2237                                          MSCC_MS_XFORM_REC(index, rec++),
2238                                          ((u32 *)flow->key)[i]);
2239
2240         /* Set the authentication key */
2241         for (i = 0; i < 4; i++)
2242                 vsc8584_macsec_phy_write(phydev, bank,
2243                                          MSCC_MS_XFORM_REC(index, rec++),
2244                                          ((u32 *)hkey)[i]);
2245
2246         /* Initial sequence number */
2247         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
2248                                  bank == MACSEC_INGR ?
2249                                  flow->rx_sa->next_pn : flow->tx_sa->next_pn);
2250
2251         if (bank == MACSEC_INGR)
2252                 /* Set the mask (replay window size) */
2253                 vsc8584_macsec_phy_write(phydev, bank,
2254                                          MSCC_MS_XFORM_REC(index, rec++),
2255                                          priv->secy->replay_window);
2256
2257         /* Set the input vectors */
2258         sci = bank == MACSEC_INGR ? flow->rx_sa->sc->sci : priv->secy->sci;
2259         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
2260                                  lower_32_bits(sci));
2261         vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
2262                                  upper_32_bits(sci));
2263
2264         while (rec < 20)
2265                 vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
2266                                          0);
2267
2268         flow->has_transformation = true;
2269         return 0;
2270 }
2271
2272 static struct macsec_flow *vsc8584_macsec_alloc_flow(struct vsc8531_private *priv,
2273                                                      enum macsec_bank bank)
2274 {
2275         unsigned long *bitmap = bank == MACSEC_INGR ?
2276                                 &priv->ingr_flows : &priv->egr_flows;
2277         struct macsec_flow *flow;
2278         int index;
2279
2280         index = find_first_zero_bit(bitmap, MSCC_MS_MAX_FLOWS);
2281
2282         if (index == MSCC_MS_MAX_FLOWS)
2283                 return ERR_PTR(-ENOMEM);
2284
2285         flow = kzalloc(sizeof(*flow), GFP_KERNEL);
2286         if (!flow)
2287                 return ERR_PTR(-ENOMEM);
2288
2289         set_bit(index, bitmap);
2290         flow->index = index;
2291         flow->bank = bank;
2292         flow->priority = 8;
2293         flow->assoc_num = -1;
2294
2295         list_add_tail(&flow->list, &priv->macsec_flows);
2296         return flow;
2297 }
2298
2299 static void vsc8584_macsec_free_flow(struct vsc8531_private *priv,
2300                                      struct macsec_flow *flow)
2301 {
2302         unsigned long *bitmap = flow->bank == MACSEC_INGR ?
2303                                 &priv->ingr_flows : &priv->egr_flows;
2304
2305         list_del(&flow->list);
2306         clear_bit(flow->index, bitmap);
2307         kfree(flow);
2308 }
2309
2310 static int vsc8584_macsec_add_flow(struct phy_device *phydev,
2311                                    struct macsec_flow *flow, bool update)
2312 {
2313         int ret;
2314
2315         flow->port = MSCC_MS_PORT_CONTROLLED;
2316         vsc8584_macsec_flow(phydev, flow);
2317
2318         if (update)
2319                 return 0;
2320
2321         ret = vsc8584_macsec_transformation(phydev, flow);
2322         if (ret) {
2323                 vsc8584_macsec_free_flow(phydev->priv, flow);
2324                 return ret;
2325         }
2326
2327         return 0;
2328 }
2329
2330 static int vsc8584_macsec_default_flows(struct phy_device *phydev)
2331 {
2332         struct macsec_flow *flow;
2333
2334         /* Add a rule to let the MKA traffic go through, ingress */
2335         flow = vsc8584_macsec_alloc_flow(phydev->priv, MACSEC_INGR);
2336         if (IS_ERR(flow))
2337                 return PTR_ERR(flow);
2338
2339         flow->priority = 15;
2340         flow->port = MSCC_MS_PORT_UNCONTROLLED;
2341         flow->match.tagged = 1;
2342         flow->match.untagged = 1;
2343         flow->match.etype = 1;
2344         flow->etype = ETH_P_PAE;
2345         flow->action.bypass = 1;
2346
2347         vsc8584_macsec_flow(phydev, flow);
2348         vsc8584_macsec_flow_enable(phydev, flow);
2349
2350         /* Add a rule to let the MKA traffic go through, egress */
2351         flow = vsc8584_macsec_alloc_flow(phydev->priv, MACSEC_EGR);
2352         if (IS_ERR(flow))
2353                 return PTR_ERR(flow);
2354
2355         flow->priority = 15;
2356         flow->port = MSCC_MS_PORT_COMMON;
2357         flow->match.untagged = 1;
2358         flow->match.etype = 1;
2359         flow->etype = ETH_P_PAE;
2360         flow->action.bypass = 1;
2361
2362         vsc8584_macsec_flow(phydev, flow);
2363         vsc8584_macsec_flow_enable(phydev, flow);
2364
2365         return 0;
2366 }
2367
2368 static void vsc8584_macsec_del_flow(struct phy_device *phydev,
2369                                     struct macsec_flow *flow)
2370 {
2371         vsc8584_macsec_flow_disable(phydev, flow);
2372         vsc8584_macsec_free_flow(phydev->priv, flow);
2373 }
2374
2375 static int __vsc8584_macsec_add_rxsa(struct macsec_context *ctx,
2376                                      struct macsec_flow *flow, bool update)
2377 {
2378         struct phy_device *phydev = ctx->phydev;
2379         struct vsc8531_private *priv = phydev->priv;
2380
2381         if (!flow) {
2382                 flow = vsc8584_macsec_alloc_flow(priv, MACSEC_INGR);
2383                 if (IS_ERR(flow))
2384                         return PTR_ERR(flow);
2385
2386                 memcpy(flow->key, ctx->sa.key, priv->secy->key_len);
2387         }
2388
2389         flow->assoc_num = ctx->sa.assoc_num;
2390         flow->rx_sa = ctx->sa.rx_sa;
2391
2392         /* Always match tagged packets on ingress */
2393         flow->match.tagged = 1;
2394         flow->match.sci = 1;
2395
2396         if (priv->secy->validate_frames != MACSEC_VALIDATE_DISABLED)
2397                 flow->match.untagged = 1;
2398
2399         return vsc8584_macsec_add_flow(phydev, flow, update);
2400 }
2401
2402 static int __vsc8584_macsec_add_txsa(struct macsec_context *ctx,
2403                                      struct macsec_flow *flow, bool update)
2404 {
2405         struct phy_device *phydev = ctx->phydev;
2406         struct vsc8531_private *priv = phydev->priv;
2407
2408         if (!flow) {
2409                 flow = vsc8584_macsec_alloc_flow(priv, MACSEC_EGR);
2410                 if (IS_ERR(flow))
2411                         return PTR_ERR(flow);
2412
2413                 memcpy(flow->key, ctx->sa.key, priv->secy->key_len);
2414         }
2415
2416         flow->assoc_num = ctx->sa.assoc_num;
2417         flow->tx_sa = ctx->sa.tx_sa;
2418
2419         /* Always match untagged packets on egress */
2420         flow->match.untagged = 1;
2421
2422         return vsc8584_macsec_add_flow(phydev, flow, update);
2423 }
2424
2425 static int vsc8584_macsec_dev_open(struct macsec_context *ctx)
2426 {
2427         struct vsc8531_private *priv = ctx->phydev->priv;
2428         struct macsec_flow *flow, *tmp;
2429
2430         /* No operation to perform before the commit step */
2431         if (ctx->prepare)
2432                 return 0;
2433
2434         list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list)
2435                 vsc8584_macsec_flow_enable(ctx->phydev, flow);
2436
2437         return 0;
2438 }
2439
2440 static int vsc8584_macsec_dev_stop(struct macsec_context *ctx)
2441 {
2442         struct vsc8531_private *priv = ctx->phydev->priv;
2443         struct macsec_flow *flow, *tmp;
2444
2445         /* No operation to perform before the commit step */
2446         if (ctx->prepare)
2447                 return 0;
2448
2449         list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list)
2450                 vsc8584_macsec_flow_disable(ctx->phydev, flow);
2451
2452         return 0;
2453 }
2454
2455 static int vsc8584_macsec_add_secy(struct macsec_context *ctx)
2456 {
2457         struct vsc8531_private *priv = ctx->phydev->priv;
2458         struct macsec_secy *secy = ctx->secy;
2459
2460         if (ctx->prepare) {
2461                 if (priv->secy)
2462                         return -EEXIST;
2463
2464                 return 0;
2465         }
2466
2467         priv->secy = secy;
2468
2469         vsc8584_macsec_flow_default_action(ctx->phydev, MACSEC_EGR,
2470                                            secy->validate_frames != MACSEC_VALIDATE_DISABLED);
2471         vsc8584_macsec_flow_default_action(ctx->phydev, MACSEC_INGR,
2472                                            secy->validate_frames != MACSEC_VALIDATE_DISABLED);
2473
2474         return vsc8584_macsec_default_flows(ctx->phydev);
2475 }
2476
2477 static int vsc8584_macsec_del_secy(struct macsec_context *ctx)
2478 {
2479         struct vsc8531_private *priv = ctx->phydev->priv;
2480         struct macsec_flow *flow, *tmp;
2481
2482         /* No operation to perform before the commit step */
2483         if (ctx->prepare)
2484                 return 0;
2485
2486         list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list)
2487                 vsc8584_macsec_del_flow(ctx->phydev, flow);
2488
2489         vsc8584_macsec_flow_default_action(ctx->phydev, MACSEC_EGR, false);
2490         vsc8584_macsec_flow_default_action(ctx->phydev, MACSEC_INGR, false);
2491
2492         priv->secy = NULL;
2493         return 0;
2494 }
2495
2496 static int vsc8584_macsec_upd_secy(struct macsec_context *ctx)
2497 {
2498         /* No operation to perform before the commit step */
2499         if (ctx->prepare)
2500                 return 0;
2501
2502         vsc8584_macsec_del_secy(ctx);
2503         return vsc8584_macsec_add_secy(ctx);
2504 }
2505
2506 static int vsc8584_macsec_add_rxsc(struct macsec_context *ctx)
2507 {
2508         /* Nothing to do */
2509         return 0;
2510 }
2511
2512 static int vsc8584_macsec_upd_rxsc(struct macsec_context *ctx)
2513 {
2514         return -EOPNOTSUPP;
2515 }
2516
2517 static int vsc8584_macsec_del_rxsc(struct macsec_context *ctx)
2518 {
2519         struct vsc8531_private *priv = ctx->phydev->priv;
2520         struct macsec_flow *flow, *tmp;
2521
2522         /* No operation to perform before the commit step */
2523         if (ctx->prepare)
2524                 return 0;
2525
2526         list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list) {
2527                 if (flow->bank == MACSEC_INGR && flow->rx_sa &&
2528                     flow->rx_sa->sc->sci == ctx->rx_sc->sci)
2529                         vsc8584_macsec_del_flow(ctx->phydev, flow);
2530         }
2531
2532         return 0;
2533 }
2534
2535 static int vsc8584_macsec_add_rxsa(struct macsec_context *ctx)
2536 {
2537         struct macsec_flow *flow = NULL;
2538
2539         if (ctx->prepare)
2540                 return __vsc8584_macsec_add_rxsa(ctx, flow, false);
2541
2542         flow = vsc8584_macsec_find_flow(ctx, MACSEC_INGR);
2543         if (IS_ERR(flow))
2544                 return PTR_ERR(flow);
2545
2546         vsc8584_macsec_flow_enable(ctx->phydev, flow);
2547         return 0;
2548 }
2549
2550 static int vsc8584_macsec_upd_rxsa(struct macsec_context *ctx)
2551 {
2552         struct macsec_flow *flow;
2553
2554         flow = vsc8584_macsec_find_flow(ctx, MACSEC_INGR);
2555         if (IS_ERR(flow))
2556                 return PTR_ERR(flow);
2557
2558         if (ctx->prepare) {
2559                 /* Make sure the flow is disabled before updating it */
2560                 vsc8584_macsec_flow_disable(ctx->phydev, flow);
2561
2562                 return __vsc8584_macsec_add_rxsa(ctx, flow, true);
2563         }
2564
2565         vsc8584_macsec_flow_enable(ctx->phydev, flow);
2566         return 0;
2567 }
2568
2569 static int vsc8584_macsec_del_rxsa(struct macsec_context *ctx)
2570 {
2571         struct macsec_flow *flow;
2572
2573         flow = vsc8584_macsec_find_flow(ctx, MACSEC_INGR);
2574
2575         if (IS_ERR(flow))
2576                 return PTR_ERR(flow);
2577         if (ctx->prepare)
2578                 return 0;
2579
2580         vsc8584_macsec_del_flow(ctx->phydev, flow);
2581         return 0;
2582 }
2583
2584 static int vsc8584_macsec_add_txsa(struct macsec_context *ctx)
2585 {
2586         struct macsec_flow *flow = NULL;
2587
2588         if (ctx->prepare)
2589                 return __vsc8584_macsec_add_txsa(ctx, flow, false);
2590
2591         flow = vsc8584_macsec_find_flow(ctx, MACSEC_EGR);
2592         if (IS_ERR(flow))
2593                 return PTR_ERR(flow);
2594
2595         vsc8584_macsec_flow_enable(ctx->phydev, flow);
2596         return 0;
2597 }
2598
2599 static int vsc8584_macsec_upd_txsa(struct macsec_context *ctx)
2600 {
2601         struct macsec_flow *flow;
2602
2603         flow = vsc8584_macsec_find_flow(ctx, MACSEC_EGR);
2604         if (IS_ERR(flow))
2605                 return PTR_ERR(flow);
2606
2607         if (ctx->prepare) {
2608                 /* Make sure the flow is disabled before updating it */
2609                 vsc8584_macsec_flow_disable(ctx->phydev, flow);
2610
2611                 return __vsc8584_macsec_add_txsa(ctx, flow, true);
2612         }
2613
2614         vsc8584_macsec_flow_enable(ctx->phydev, flow);
2615         return 0;
2616 }
2617
2618 static int vsc8584_macsec_del_txsa(struct macsec_context *ctx)
2619 {
2620         struct macsec_flow *flow;
2621
2622         flow = vsc8584_macsec_find_flow(ctx, MACSEC_EGR);
2623
2624         if (IS_ERR(flow))
2625                 return PTR_ERR(flow);
2626         if (ctx->prepare)
2627                 return 0;
2628
2629         vsc8584_macsec_del_flow(ctx->phydev, flow);
2630         return 0;
2631 }
2632
2633 static struct macsec_ops vsc8584_macsec_ops = {
2634         .mdo_dev_open = vsc8584_macsec_dev_open,
2635         .mdo_dev_stop = vsc8584_macsec_dev_stop,
2636         .mdo_add_secy = vsc8584_macsec_add_secy,
2637         .mdo_upd_secy = vsc8584_macsec_upd_secy,
2638         .mdo_del_secy = vsc8584_macsec_del_secy,
2639         .mdo_add_rxsc = vsc8584_macsec_add_rxsc,
2640         .mdo_upd_rxsc = vsc8584_macsec_upd_rxsc,
2641         .mdo_del_rxsc = vsc8584_macsec_del_rxsc,
2642         .mdo_add_rxsa = vsc8584_macsec_add_rxsa,
2643         .mdo_upd_rxsa = vsc8584_macsec_upd_rxsa,
2644         .mdo_del_rxsa = vsc8584_macsec_del_rxsa,
2645         .mdo_add_txsa = vsc8584_macsec_add_txsa,
2646         .mdo_upd_txsa = vsc8584_macsec_upd_txsa,
2647         .mdo_del_txsa = vsc8584_macsec_del_txsa,
2648 };
2649 #endif /* CONFIG_MACSEC */
2650
2651 /* Check if one PHY has already done the init of the parts common to all PHYs
2652  * in the Quad PHY package.
2653  */
2654 static bool vsc8584_is_pkg_init(struct phy_device *phydev, bool reversed)
2655 {
2656         struct mdio_device **map = phydev->mdio.bus->mdio_map;
2657         struct vsc8531_private *vsc8531;
2658         struct phy_device *phy;
2659         int i, addr;
2660
2661         /* VSC8584 is a Quad PHY */
2662         for (i = 0; i < 4; i++) {
2663                 vsc8531 = phydev->priv;
2664
2665                 if (reversed)
2666                         addr = vsc8531->base_addr - i;
2667                 else
2668                         addr = vsc8531->base_addr + i;
2669
2670                 if (!map[addr])
2671                         continue;
2672
2673                 phy = container_of(map[addr], struct phy_device, mdio);
2674
2675                 if ((phy->phy_id & phydev->drv->phy_id_mask) !=
2676                     (phydev->drv->phy_id & phydev->drv->phy_id_mask))
2677                         continue;
2678
2679                 vsc8531 = phy->priv;
2680
2681                 if (vsc8531 && vsc8531->pkg_init)
2682                         return true;
2683         }
2684
2685         return false;
2686 }
2687
2688 static int vsc8584_config_init(struct phy_device *phydev)
2689 {
2690         struct vsc8531_private *vsc8531 = phydev->priv;
2691         u16 addr, val;
2692         int ret, i;
2693
2694         phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
2695
2696         mutex_lock(&phydev->mdio.bus->mdio_lock);
2697
2698         __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
2699                         MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
2700         addr = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
2701                               MSCC_PHY_EXT_PHY_CNTL_4);
2702         addr >>= PHY_CNTL_4_ADDR_POS;
2703
2704         val = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
2705                              MSCC_PHY_ACTIPHY_CNTL);
2706         if (val & PHY_ADDR_REVERSED)
2707                 vsc8531->base_addr = phydev->mdio.addr + addr;
2708         else
2709                 vsc8531->base_addr = phydev->mdio.addr - addr;
2710
2711         /* Some parts of the init sequence are identical for every PHY in the
2712          * package. Some parts are modifying the GPIO register bank which is a
2713          * set of registers that are affecting all PHYs, a few resetting the
2714          * microprocessor common to all PHYs. The CRC check responsible of the
2715          * checking the firmware within the 8051 microprocessor can only be
2716          * accessed via the PHY whose internal address in the package is 0.
2717          * All PHYs' interrupts mask register has to be zeroed before enabling
2718          * any PHY's interrupt in this register.
2719          * For all these reasons, we need to do the init sequence once and only
2720          * once whatever is the first PHY in the package that is initialized and
2721          * do the correct init sequence for all PHYs that are package-critical
2722          * in this pre-init function.
2723          */
2724         if (!vsc8584_is_pkg_init(phydev, val & PHY_ADDR_REVERSED ? 1 : 0)) {
2725                 /* The following switch statement assumes that the lowest
2726                  * nibble of the phy_id_mask is always 0. This works because
2727                  * the lowest nibble of the PHY_ID's below are also 0.
2728                  */
2729                 WARN_ON(phydev->drv->phy_id_mask & 0xf);
2730
2731                 switch (phydev->phy_id & phydev->drv->phy_id_mask) {
2732                 case PHY_ID_VSC8504:
2733                 case PHY_ID_VSC8552:
2734                 case PHY_ID_VSC8572:
2735                 case PHY_ID_VSC8574:
2736                         ret = vsc8574_config_pre_init(phydev);
2737                         break;
2738                 case PHY_ID_VSC856X:
2739                 case PHY_ID_VSC8575:
2740                 case PHY_ID_VSC8582:
2741                 case PHY_ID_VSC8584:
2742                         ret = vsc8584_config_pre_init(phydev);
2743                         break;
2744                 default:
2745                         ret = -EINVAL;
2746                         break;
2747                 }
2748
2749                 if (ret)
2750                         goto err;
2751         }
2752
2753         vsc8531->pkg_init = true;
2754
2755         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
2756                        MSCC_PHY_PAGE_EXTENDED_GPIO);
2757
2758         val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
2759         val &= ~MAC_CFG_MASK;
2760         if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
2761                 val |= MAC_CFG_QSGMII;
2762         else
2763                 val |= MAC_CFG_SGMII;
2764
2765         ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
2766         if (ret)
2767                 goto err;
2768
2769         val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
2770                 PROC_CMD_READ_MOD_WRITE_PORT;
2771         if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
2772                 val |= PROC_CMD_QSGMII_MAC;
2773         else
2774                 val |= PROC_CMD_SGMII_MAC;
2775
2776         ret = vsc8584_cmd(phydev, val);
2777         if (ret)
2778                 goto err;
2779
2780         usleep_range(10000, 20000);
2781
2782         /* Disable SerDes for 100Base-FX */
2783         ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
2784                           PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
2785                           PROC_CMD_READ_MOD_WRITE_PORT |
2786                           PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
2787         if (ret)
2788                 goto err;
2789
2790         /* Disable SerDes for 1000Base-X */
2791         ret = vsc8584_cmd(phydev, PROC_CMD_FIBER_MEDIA_CONF |
2792                           PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
2793                           PROC_CMD_READ_MOD_WRITE_PORT |
2794                           PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
2795         if (ret)
2796                 goto err;
2797
2798         mutex_unlock(&phydev->mdio.bus->mdio_lock);
2799
2800 #if IS_ENABLED(CONFIG_MACSEC)
2801         /* MACsec */
2802         switch (phydev->phy_id & phydev->drv->phy_id_mask) {
2803         case PHY_ID_VSC856X:
2804         case PHY_ID_VSC8575:
2805         case PHY_ID_VSC8582:
2806         case PHY_ID_VSC8584:
2807                 INIT_LIST_HEAD(&vsc8531->macsec_flows);
2808                 vsc8531->secy = NULL;
2809
2810                 phydev->macsec_ops = &vsc8584_macsec_ops;
2811
2812                 ret = vsc8584_macsec_init(phydev);
2813                 if (ret)
2814                         goto err;
2815         }
2816 #endif
2817
2818         phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2819
2820         val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
2821         val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
2822         val |= (MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS) |
2823                (VSC8584_MAC_IF_SELECTION_SGMII << VSC8584_MAC_IF_SELECTION_POS);
2824         ret = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, val);
2825
2826         ret = genphy_soft_reset(phydev);
2827         if (ret)
2828                 return ret;
2829
2830         for (i = 0; i < vsc8531->nleds; i++) {
2831                 ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
2832                 if (ret)
2833                         return ret;
2834         }
2835
2836         return 0;
2837
2838 err:
2839         mutex_unlock(&phydev->mdio.bus->mdio_lock);
2840         return ret;
2841 }
2842
2843 static int vsc8584_handle_interrupt(struct phy_device *phydev)
2844 {
2845 #if IS_ENABLED(CONFIG_MACSEC)
2846         struct vsc8531_private *priv = phydev->priv;
2847         struct macsec_flow *flow, *tmp;
2848         u32 cause, rec;
2849
2850         /* Check MACsec PN rollover */
2851         cause = vsc8584_macsec_phy_read(phydev, MACSEC_EGR,
2852                                         MSCC_MS_INTR_CTRL_STATUS);
2853         cause &= MSCC_MS_INTR_CTRL_STATUS_INTR_CLR_STATUS_M;
2854         if (!(cause & MACSEC_INTR_CTRL_STATUS_ROLLOVER))
2855                 goto skip_rollover;
2856
2857         rec = 6 + priv->secy->key_len / sizeof(u32);
2858         list_for_each_entry_safe(flow, tmp, &priv->macsec_flows, list) {
2859                 u32 val;
2860
2861                 if (flow->bank != MACSEC_EGR || !flow->has_transformation)
2862                         continue;
2863
2864                 val = vsc8584_macsec_phy_read(phydev, MACSEC_EGR,
2865                                               MSCC_MS_XFORM_REC(flow->index, rec));
2866                 if (val == 0xffffffff) {
2867                         vsc8584_macsec_flow_disable(phydev, flow);
2868                         macsec_pn_wrapped(priv->secy, flow->tx_sa);
2869                         break;
2870                 }
2871         }
2872
2873 skip_rollover:
2874 #endif
2875
2876         phy_mac_interrupt(phydev);
2877         return 0;
2878 }
2879
2880 static int vsc85xx_config_init(struct phy_device *phydev)
2881 {
2882         int rc, i, phy_id;
2883         struct vsc8531_private *vsc8531 = phydev->priv;
2884
2885         rc = vsc85xx_default_config(phydev);
2886         if (rc)
2887                 return rc;
2888
2889         rc = vsc85xx_mac_if_set(phydev, phydev->interface);
2890         if (rc)
2891                 return rc;
2892
2893         rc = vsc85xx_edge_rate_cntl_set(phydev, vsc8531->rate_magic);
2894         if (rc)
2895                 return rc;
2896
2897         phy_id = phydev->drv->phy_id & phydev->drv->phy_id_mask;
2898         if (PHY_ID_VSC8531 == phy_id || PHY_ID_VSC8541 == phy_id ||
2899             PHY_ID_VSC8530 == phy_id || PHY_ID_VSC8540 == phy_id) {
2900                 rc = vsc8531_pre_init_seq_set(phydev);
2901                 if (rc)
2902                         return rc;
2903         }
2904
2905         rc = vsc85xx_eee_init_seq_set(phydev);
2906         if (rc)
2907                 return rc;
2908
2909         for (i = 0; i < vsc8531->nleds; i++) {
2910                 rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
2911                 if (rc)
2912                         return rc;
2913         }
2914
2915         return 0;
2916 }
2917
2918 static int vsc8584_did_interrupt(struct phy_device *phydev)
2919 {
2920         int rc = 0;
2921
2922         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
2923                 rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
2924
2925         return (rc < 0) ? 0 : rc & MII_VSC85XX_INT_MASK_MASK;
2926 }
2927
2928 static int vsc8514_config_pre_init(struct phy_device *phydev)
2929 {
2930         /* These are the settings to override the silicon default
2931          * values to handle hardware performance of PHY. They
2932          * are set at Power-On state and remain until PHY Reset.
2933          */
2934         static const struct reg_val pre_init1[] = {
2935                 {0x0f90, 0x00688980},
2936                 {0x0786, 0x00000003},
2937                 {0x07fa, 0x0050100f},
2938                 {0x0f82, 0x0012b002},
2939                 {0x1686, 0x00000004},
2940                 {0x168c, 0x00d2c46f},
2941                 {0x17a2, 0x00000620},
2942                 {0x16a0, 0x00eeffdd},
2943                 {0x16a6, 0x00071448},
2944                 {0x16a4, 0x0013132f},
2945                 {0x16a8, 0x00000000},
2946                 {0x0ffc, 0x00c0a028},
2947                 {0x0fe8, 0x0091b06c},
2948                 {0x0fea, 0x00041600},
2949                 {0x0f80, 0x00fffaff},
2950                 {0x0fec, 0x00901809},
2951                 {0x0ffe, 0x00b01007},
2952                 {0x16b0, 0x00eeff00},
2953                 {0x16b2, 0x00007000},
2954                 {0x16b4, 0x00000814},
2955         };
2956         unsigned int i;
2957         u16 reg;
2958
2959         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2960
2961         /* all writes below are broadcasted to all PHYs in the same package */
2962         reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
2963         reg |= SMI_BROADCAST_WR_EN;
2964         phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
2965
2966         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
2967
2968         reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
2969         reg |= BIT(15);
2970         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
2971
2972         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
2973
2974         for (i = 0; i < ARRAY_SIZE(pre_init1); i++)
2975                 vsc8584_csr_write(phydev, pre_init1[i].reg, pre_init1[i].val);
2976
2977         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
2978
2979         reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
2980         reg &= ~BIT(15);
2981         phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
2982
2983         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
2984
2985         reg = phy_base_read(phydev, MSCC_PHY_EXT_CNTL_STATUS);
2986         reg &= ~SMI_BROADCAST_WR_EN;
2987         phy_base_write(phydev, MSCC_PHY_EXT_CNTL_STATUS, reg);
2988
2989         return 0;
2990 }
2991
2992 static u32 vsc85xx_csr_ctrl_phy_read(struct phy_device *phydev,
2993                                      u32 target, u32 reg)
2994 {
2995         unsigned long deadline;
2996         u32 val, val_l, val_h;
2997
2998         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
2999
3000         /* CSR registers are grouped under different Target IDs.
3001          * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
3002          * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
3003          * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
3004          * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
3005          */
3006
3007         /* Setup the Target ID */
3008         phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
3009                        MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
3010
3011         /* Trigger CSR Action - Read into the CSR's */
3012         phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
3013                        MSCC_PHY_CSR_CNTL_19_CMD | MSCC_PHY_CSR_CNTL_19_READ |
3014                        MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
3015                        MSCC_PHY_CSR_CNTL_19_TARGET(target & 0x3));
3016
3017         /* Wait for register access*/
3018         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
3019         do {
3020                 usleep_range(500, 1000);
3021                 val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
3022         } while (time_before(jiffies, deadline) &&
3023                 !(val & MSCC_PHY_CSR_CNTL_19_CMD));
3024
3025         if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
3026                 return 0xffffffff;
3027
3028         /* Read the Least Significant Word (LSW) (17) */
3029         val_l = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_17);
3030
3031         /* Read the Most Significant Word (MSW) (18) */
3032         val_h = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_18);
3033
3034         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
3035                        MSCC_PHY_PAGE_STANDARD);
3036
3037         return (val_h << 16) | val_l;
3038 }
3039
3040 static int vsc85xx_csr_ctrl_phy_write(struct phy_device *phydev,
3041                                       u32 target, u32 reg, u32 val)
3042 {
3043         unsigned long deadline;
3044
3045         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_CSR_CNTL);
3046
3047         /* CSR registers are grouped under different Target IDs.
3048          * 6-bit Target_ID is split between MSCC_EXT_PAGE_CSR_CNTL_20 and
3049          * MSCC_EXT_PAGE_CSR_CNTL_19 registers.
3050          * Target_ID[5:2] maps to bits[3:0] of MSCC_EXT_PAGE_CSR_CNTL_20
3051          * and Target_ID[1:0] maps to bits[13:12] of MSCC_EXT_PAGE_CSR_CNTL_19.
3052          */
3053
3054         /* Setup the Target ID */
3055         phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_20,
3056                        MSCC_PHY_CSR_CNTL_20_TARGET(target >> 2));
3057
3058         /* Write the Least Significant Word (LSW) (17) */
3059         phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_17, (u16)val);
3060
3061         /* Write the Most Significant Word (MSW) (18) */
3062         phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_18, (u16)(val >> 16));
3063
3064         /* Trigger CSR Action - Write into the CSR's */
3065         phy_base_write(phydev, MSCC_EXT_PAGE_CSR_CNTL_19,
3066                        MSCC_PHY_CSR_CNTL_19_CMD |
3067                        MSCC_PHY_CSR_CNTL_19_REG_ADDR(reg) |
3068                        MSCC_PHY_CSR_CNTL_19_TARGET(target & 0x3));
3069
3070         /* Wait for register access */
3071         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
3072         do {
3073                 usleep_range(500, 1000);
3074                 val = phy_base_read(phydev, MSCC_EXT_PAGE_CSR_CNTL_19);
3075         } while (time_before(jiffies, deadline) &&
3076                  !(val & MSCC_PHY_CSR_CNTL_19_CMD));
3077
3078         if (!(val & MSCC_PHY_CSR_CNTL_19_CMD))
3079                 return -ETIMEDOUT;
3080
3081         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
3082                        MSCC_PHY_PAGE_STANDARD);
3083
3084         return 0;
3085 }
3086
3087 static int __phy_write_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb,
3088                                u32 op)
3089 {
3090         unsigned long deadline;
3091         u32 val;
3092         int ret;
3093
3094         ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET, reg,
3095                                          op | (1 << mcb));
3096         if (ret)
3097                 return -EINVAL;
3098
3099         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
3100         do {
3101                 usleep_range(500, 1000);
3102                 val = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET, reg);
3103
3104                 if (val == 0xffffffff)
3105                         return -EIO;
3106
3107         } while (time_before(jiffies, deadline) && (val & op));
3108
3109         if (val & op)
3110                 return -ETIMEDOUT;
3111
3112         return 0;
3113 }
3114
3115 /* Trigger a read to the spcified MCB */
3116 static int phy_update_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
3117 {
3118         return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_READ);
3119 }
3120
3121 /* Trigger a write to the spcified MCB */
3122 static int phy_commit_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
3123 {
3124         return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_WRITE);
3125 }
3126
3127 static int vsc8514_config_init(struct phy_device *phydev)
3128 {
3129         struct vsc8531_private *vsc8531 = phydev->priv;
3130         unsigned long deadline;
3131         u16 val, addr;
3132         int ret, i;
3133         u32 reg;
3134
3135         phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
3136
3137         mutex_lock(&phydev->mdio.bus->mdio_lock);
3138
3139         __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
3140
3141         addr = __phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_4);
3142         addr >>= PHY_CNTL_4_ADDR_POS;
3143
3144         val = __phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL);
3145
3146         if (val & PHY_ADDR_REVERSED)
3147                 vsc8531->base_addr = phydev->mdio.addr + addr;
3148         else
3149                 vsc8531->base_addr = phydev->mdio.addr - addr;
3150
3151         /* Some parts of the init sequence are identical for every PHY in the
3152          * package. Some parts are modifying the GPIO register bank which is a
3153          * set of registers that are affecting all PHYs, a few resetting the
3154          * microprocessor common to all PHYs.
3155          * All PHYs' interrupts mask register has to be zeroed before enabling
3156          * any PHY's interrupt in this register.
3157          * For all these reasons, we need to do the init sequence once and only
3158          * once whatever is the first PHY in the package that is initialized and
3159          * do the correct init sequence for all PHYs that are package-critical
3160          * in this pre-init function.
3161          */
3162         if (!vsc8584_is_pkg_init(phydev, val & PHY_ADDR_REVERSED ? 1 : 0))
3163                 vsc8514_config_pre_init(phydev);
3164
3165         vsc8531->pkg_init = true;
3166
3167         phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
3168                        MSCC_PHY_PAGE_EXTENDED_GPIO);
3169
3170         val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
3171
3172         val &= ~MAC_CFG_MASK;
3173         val |= MAC_CFG_QSGMII;
3174         ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
3175
3176         if (ret)
3177                 goto err;
3178
3179         ret = vsc8584_cmd(phydev,
3180                           PROC_CMD_MCB_ACCESS_MAC_CONF |
3181                           PROC_CMD_RST_CONF_PORT |
3182                           PROC_CMD_READ_MOD_WRITE_PORT | PROC_CMD_QSGMII_MAC);
3183         if (ret)
3184                 goto err;
3185
3186         /* 6g mcb */
3187         phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG, 0);
3188         /* lcpll mcb */
3189         phy_update_mcb_s6g(phydev, PHY_S6G_LCPLL_CFG, 0);
3190         /* pll5gcfg0 */
3191         ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
3192                                          PHY_S6G_PLL5G_CFG0, 0x7036f145);
3193         if (ret)
3194                 goto err;
3195
3196         phy_commit_mcb_s6g(phydev, PHY_S6G_LCPLL_CFG, 0);
3197         /* pllcfg */
3198         ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
3199                                          PHY_S6G_PLL_CFG,
3200                                          (3 << PHY_S6G_PLL_ENA_OFFS_POS) |
3201                                          (120 << PHY_S6G_PLL_FSM_CTRL_DATA_POS)
3202                                          | (0 << PHY_S6G_PLL_FSM_ENA_POS));
3203         if (ret)
3204                 goto err;
3205
3206         /* commoncfg */
3207         ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
3208                                          PHY_S6G_COMMON_CFG,
3209                                          (0 << PHY_S6G_SYS_RST_POS) |
3210                                          (0 << PHY_S6G_ENA_LANE_POS) |
3211                                          (0 << PHY_S6G_ENA_LOOP_POS) |
3212                                          (0 << PHY_S6G_QRATE_POS) |
3213                                          (3 << PHY_S6G_IF_MODE_POS));
3214         if (ret)
3215                 goto err;
3216
3217         /* misccfg */
3218         ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
3219                                          PHY_S6G_MISC_CFG, 1);
3220         if (ret)
3221                 goto err;
3222
3223         /* gpcfg */
3224         ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
3225                                          PHY_S6G_GPC_CFG, 768);
3226         if (ret)
3227                 goto err;
3228
3229         phy_commit_mcb_s6g(phydev, PHY_S6G_DFT_CFG2, 0);
3230
3231         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
3232         do {
3233                 usleep_range(500, 1000);
3234                 phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG,
3235                                    0); /* read 6G MCB into CSRs */
3236                 reg = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET,
3237                                                 PHY_S6G_PLL_STATUS);
3238                 if (reg == 0xffffffff) {
3239                         mutex_unlock(&phydev->mdio.bus->mdio_lock);
3240                         return -EIO;
3241                 }
3242
3243         } while (time_before(jiffies, deadline) && (reg & BIT(12)));
3244
3245         if (reg & BIT(12)) {
3246                 mutex_unlock(&phydev->mdio.bus->mdio_lock);
3247                 return -ETIMEDOUT;
3248         }
3249
3250         /* misccfg */
3251         ret = vsc85xx_csr_ctrl_phy_write(phydev, PHY_MCB_TARGET,
3252                                          PHY_S6G_MISC_CFG, 0);
3253         if (ret)
3254                 goto err;
3255
3256         phy_commit_mcb_s6g(phydev, PHY_MCB_S6G_CFG, 0);
3257
3258         deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
3259         do {
3260                 usleep_range(500, 1000);
3261                 phy_update_mcb_s6g(phydev, PHY_MCB_S6G_CFG,
3262                                    0); /* read 6G MCB into CSRs */
3263                 reg = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET,
3264                                                 PHY_S6G_IB_STATUS0);
3265                 if (reg == 0xffffffff) {
3266                         mutex_unlock(&phydev->mdio.bus->mdio_lock);
3267                         return -EIO;
3268                 }
3269
3270         } while (time_before(jiffies, deadline) && !(reg & BIT(8)));
3271
3272         if (!(reg & BIT(8))) {
3273                 mutex_unlock(&phydev->mdio.bus->mdio_lock);
3274                 return -ETIMEDOUT;
3275         }
3276
3277         mutex_unlock(&phydev->mdio.bus->mdio_lock);
3278
3279         ret = phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
3280
3281         if (ret)
3282                 return ret;
3283
3284         ret = phy_modify(phydev, MSCC_PHY_EXT_PHY_CNTL_1, MEDIA_OP_MODE_MASK,
3285                          MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS);
3286
3287         if (ret)
3288                 return ret;
3289
3290         ret = genphy_soft_reset(phydev);
3291
3292         if (ret)
3293                 return ret;
3294
3295         for (i = 0; i < vsc8531->nleds; i++) {
3296                 ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
3297                 if (ret)
3298                         return ret;
3299         }
3300
3301         return ret;
3302
3303 err:
3304         mutex_unlock(&phydev->mdio.bus->mdio_lock);
3305         return ret;
3306 }
3307
3308 static int vsc85xx_ack_interrupt(struct phy_device *phydev)
3309 {
3310         int rc = 0;
3311
3312         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
3313                 rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
3314
3315         return (rc < 0) ? rc : 0;
3316 }
3317
3318 static int vsc85xx_config_intr(struct phy_device *phydev)
3319 {
3320         int rc;
3321
3322         if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
3323 #if IS_ENABLED(CONFIG_MACSEC)
3324                 phy_write(phydev, MSCC_EXT_PAGE_ACCESS,
3325                           MSCC_PHY_PAGE_EXTENDED_2);
3326                 phy_write(phydev, MSCC_PHY_EXTENDED_INT,
3327                           MSCC_PHY_EXTENDED_INT_MS_EGR);
3328                 phy_write(phydev, MSCC_EXT_PAGE_ACCESS,
3329                           MSCC_PHY_PAGE_STANDARD);
3330
3331                 vsc8584_macsec_phy_write(phydev, MACSEC_EGR,
3332                                          MSCC_MS_AIC_CTRL, 0xf);
3333                 vsc8584_macsec_phy_write(phydev, MACSEC_EGR,
3334                         MSCC_MS_INTR_CTRL_STATUS,
3335                         MSCC_MS_INTR_CTRL_STATUS_INTR_ENABLE(MACSEC_INTR_CTRL_STATUS_ROLLOVER));
3336 #endif
3337                 rc = phy_write(phydev, MII_VSC85XX_INT_MASK,
3338                                MII_VSC85XX_INT_MASK_MASK);
3339         } else {
3340                 rc = phy_write(phydev, MII_VSC85XX_INT_MASK, 0);
3341                 if (rc < 0)
3342                         return rc;
3343                 rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
3344         }
3345
3346         return rc;
3347 }
3348
3349 static int vsc85xx_config_aneg(struct phy_device *phydev)
3350 {
3351         int rc;
3352
3353         rc = vsc85xx_mdix_set(phydev, phydev->mdix_ctrl);
3354         if (rc < 0)
3355                 return rc;
3356
3357         return genphy_config_aneg(phydev);
3358 }
3359
3360 static int vsc85xx_read_status(struct phy_device *phydev)
3361 {
3362         int rc;
3363
3364         rc = vsc85xx_mdix_get(phydev, &phydev->mdix);
3365         if (rc < 0)
3366                 return rc;
3367
3368         return genphy_read_status(phydev);
3369 }
3370
3371 static int vsc8514_probe(struct phy_device *phydev)
3372 {
3373         struct vsc8531_private *vsc8531;
3374         u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
3375            VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
3376            VSC8531_DUPLEX_COLLISION};
3377
3378         vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
3379         if (!vsc8531)
3380                 return -ENOMEM;
3381
3382         phydev->priv = vsc8531;
3383
3384         vsc8531->nleds = 4;
3385         vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
3386         vsc8531->hw_stats = vsc85xx_hw_stats;
3387         vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
3388         vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
3389                                       sizeof(u64), GFP_KERNEL);
3390         if (!vsc8531->stats)
3391                 return -ENOMEM;
3392
3393         return vsc85xx_dt_led_modes_get(phydev, default_mode);
3394 }
3395
3396 static int vsc8574_probe(struct phy_device *phydev)
3397 {
3398         struct vsc8531_private *vsc8531;
3399         u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
3400            VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
3401            VSC8531_DUPLEX_COLLISION};
3402
3403         vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
3404         if (!vsc8531)
3405                 return -ENOMEM;
3406
3407         phydev->priv = vsc8531;
3408
3409         vsc8531->nleds = 4;
3410         vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
3411         vsc8531->hw_stats = vsc8584_hw_stats;
3412         vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
3413         vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
3414                                       sizeof(u64), GFP_KERNEL);
3415         if (!vsc8531->stats)
3416                 return -ENOMEM;
3417
3418         return vsc85xx_dt_led_modes_get(phydev, default_mode);
3419 }
3420
3421 static int vsc8584_probe(struct phy_device *phydev)
3422 {
3423         struct vsc8531_private *vsc8531;
3424         u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
3425            VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
3426            VSC8531_DUPLEX_COLLISION};
3427
3428         if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
3429                 dev_err(&phydev->mdio.dev, "Only VSC8584 revB is supported.\n");
3430                 return -ENOTSUPP;
3431         }
3432
3433         vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
3434         if (!vsc8531)
3435                 return -ENOMEM;
3436
3437         phydev->priv = vsc8531;
3438
3439         vsc8531->nleds = 4;
3440         vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
3441         vsc8531->hw_stats = vsc8584_hw_stats;
3442         vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
3443         vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
3444                                       sizeof(u64), GFP_KERNEL);
3445         if (!vsc8531->stats)
3446                 return -ENOMEM;
3447
3448         return vsc85xx_dt_led_modes_get(phydev, default_mode);
3449 }
3450
3451 static int vsc85xx_probe(struct phy_device *phydev)
3452 {
3453         struct vsc8531_private *vsc8531;
3454         int rate_magic;
3455         u32 default_mode[2] = {VSC8531_LINK_1000_ACTIVITY,
3456            VSC8531_LINK_100_ACTIVITY};
3457
3458         rate_magic = vsc85xx_edge_rate_magic_get(phydev);
3459         if (rate_magic < 0)
3460                 return rate_magic;
3461
3462         vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
3463         if (!vsc8531)
3464                 return -ENOMEM;
3465
3466         phydev->priv = vsc8531;
3467
3468         vsc8531->rate_magic = rate_magic;
3469         vsc8531->nleds = 2;
3470         vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
3471         vsc8531->hw_stats = vsc85xx_hw_stats;
3472         vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
3473         vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats,
3474                                       sizeof(u64), GFP_KERNEL);
3475         if (!vsc8531->stats)
3476                 return -ENOMEM;
3477
3478         return vsc85xx_dt_led_modes_get(phydev, default_mode);
3479 }
3480
3481 /* Microsemi VSC85xx PHYs */
3482 static struct phy_driver vsc85xx_driver[] = {
3483 {
3484         .phy_id         = PHY_ID_VSC8504,
3485         .name           = "Microsemi GE VSC8504 SyncE",
3486         .phy_id_mask    = 0xfffffff0,
3487         /* PHY_GBIT_FEATURES */
3488         .soft_reset     = &genphy_soft_reset,
3489         .config_init    = &vsc8584_config_init,
3490         .config_aneg    = &vsc85xx_config_aneg,
3491         .aneg_done      = &genphy_aneg_done,
3492         .read_status    = &vsc85xx_read_status,
3493         .ack_interrupt  = &vsc85xx_ack_interrupt,
3494         .config_intr    = &vsc85xx_config_intr,
3495         .did_interrupt  = &vsc8584_did_interrupt,
3496         .suspend        = &genphy_suspend,
3497         .resume         = &genphy_resume,
3498         .probe          = &vsc8574_probe,
3499         .set_wol        = &vsc85xx_wol_set,
3500         .get_wol        = &vsc85xx_wol_get,
3501         .get_tunable    = &vsc85xx_get_tunable,
3502         .set_tunable    = &vsc85xx_set_tunable,
3503         .read_page      = &vsc85xx_phy_read_page,
3504         .write_page     = &vsc85xx_phy_write_page,
3505         .get_sset_count = &vsc85xx_get_sset_count,
3506         .get_strings    = &vsc85xx_get_strings,
3507         .get_stats      = &vsc85xx_get_stats,
3508 },
3509 {
3510         .phy_id         = PHY_ID_VSC8514,
3511         .name           = "Microsemi GE VSC8514 SyncE",
3512         .phy_id_mask    = 0xfffffff0,
3513         .soft_reset     = &genphy_soft_reset,
3514         .config_init    = &vsc8514_config_init,
3515         .config_aneg    = &vsc85xx_config_aneg,
3516         .read_status    = &vsc85xx_read_status,
3517         .ack_interrupt  = &vsc85xx_ack_interrupt,
3518         .config_intr    = &vsc85xx_config_intr,
3519         .suspend        = &genphy_suspend,
3520         .resume         = &genphy_resume,
3521         .probe          = &vsc8514_probe,
3522         .set_wol        = &vsc85xx_wol_set,
3523         .get_wol        = &vsc85xx_wol_get,
3524         .get_tunable    = &vsc85xx_get_tunable,
3525         .set_tunable    = &vsc85xx_set_tunable,
3526         .read_page      = &vsc85xx_phy_read_page,
3527         .write_page     = &vsc85xx_phy_write_page,
3528         .get_sset_count = &vsc85xx_get_sset_count,
3529         .get_strings    = &vsc85xx_get_strings,
3530         .get_stats      = &vsc85xx_get_stats,
3531 },
3532 {
3533         .phy_id         = PHY_ID_VSC8530,
3534         .name           = "Microsemi FE VSC8530",
3535         .phy_id_mask    = 0xfffffff0,
3536         /* PHY_BASIC_FEATURES */
3537         .soft_reset     = &genphy_soft_reset,
3538         .config_init    = &vsc85xx_config_init,
3539         .config_aneg    = &vsc85xx_config_aneg,
3540         .read_status    = &vsc85xx_read_status,
3541         .ack_interrupt  = &vsc85xx_ack_interrupt,
3542         .config_intr    = &vsc85xx_config_intr,
3543         .suspend        = &genphy_suspend,
3544         .resume         = &genphy_resume,
3545         .probe          = &vsc85xx_probe,
3546         .set_wol        = &vsc85xx_wol_set,
3547         .get_wol        = &vsc85xx_wol_get,
3548         .get_tunable    = &vsc85xx_get_tunable,
3549         .set_tunable    = &vsc85xx_set_tunable,
3550         .read_page      = &vsc85xx_phy_read_page,
3551         .write_page     = &vsc85xx_phy_write_page,
3552         .get_sset_count = &vsc85xx_get_sset_count,
3553         .get_strings    = &vsc85xx_get_strings,
3554         .get_stats      = &vsc85xx_get_stats,
3555 },
3556 {
3557         .phy_id         = PHY_ID_VSC8531,
3558         .name           = "Microsemi VSC8531",
3559         .phy_id_mask    = 0xfffffff0,
3560         /* PHY_GBIT_FEATURES */
3561         .soft_reset     = &genphy_soft_reset,
3562         .config_init    = &vsc85xx_config_init,
3563         .config_aneg    = &vsc85xx_config_aneg,
3564         .read_status    = &vsc85xx_read_status,
3565         .ack_interrupt  = &vsc85xx_ack_interrupt,
3566         .config_intr    = &vsc85xx_config_intr,
3567         .suspend        = &genphy_suspend,
3568         .resume         = &genphy_resume,
3569         .probe          = &vsc85xx_probe,
3570         .set_wol        = &vsc85xx_wol_set,
3571         .get_wol        = &vsc85xx_wol_get,
3572         .get_tunable    = &vsc85xx_get_tunable,
3573         .set_tunable    = &vsc85xx_set_tunable,
3574         .read_page      = &vsc85xx_phy_read_page,
3575         .write_page     = &vsc85xx_phy_write_page,
3576         .get_sset_count = &vsc85xx_get_sset_count,
3577         .get_strings    = &vsc85xx_get_strings,
3578         .get_stats      = &vsc85xx_get_stats,
3579 },
3580 {
3581         .phy_id         = PHY_ID_VSC8540,
3582         .name           = "Microsemi FE VSC8540 SyncE",
3583         .phy_id_mask    = 0xfffffff0,
3584         /* PHY_BASIC_FEATURES */
3585         .soft_reset     = &genphy_soft_reset,
3586         .config_init    = &vsc85xx_config_init,
3587         .config_aneg    = &vsc85xx_config_aneg,
3588         .read_status    = &vsc85xx_read_status,
3589         .ack_interrupt  = &vsc85xx_ack_interrupt,
3590         .config_intr    = &vsc85xx_config_intr,
3591         .suspend        = &genphy_suspend,
3592         .resume         = &genphy_resume,
3593         .probe          = &vsc85xx_probe,
3594         .set_wol        = &vsc85xx_wol_set,
3595         .get_wol        = &vsc85xx_wol_get,
3596         .get_tunable    = &vsc85xx_get_tunable,
3597         .set_tunable    = &vsc85xx_set_tunable,
3598         .read_page      = &vsc85xx_phy_read_page,
3599         .write_page     = &vsc85xx_phy_write_page,
3600         .get_sset_count = &vsc85xx_get_sset_count,
3601         .get_strings    = &vsc85xx_get_strings,
3602         .get_stats      = &vsc85xx_get_stats,
3603 },
3604 {
3605         .phy_id         = PHY_ID_VSC8541,
3606         .name           = "Microsemi VSC8541 SyncE",
3607         .phy_id_mask    = 0xfffffff0,
3608         /* PHY_GBIT_FEATURES */
3609         .soft_reset     = &genphy_soft_reset,
3610         .config_init    = &vsc85xx_config_init,
3611         .config_aneg    = &vsc85xx_config_aneg,
3612         .read_status    = &vsc85xx_read_status,
3613         .ack_interrupt  = &vsc85xx_ack_interrupt,
3614         .config_intr    = &vsc85xx_config_intr,
3615         .suspend        = &genphy_suspend,
3616         .resume         = &genphy_resume,
3617         .probe          = &vsc85xx_probe,
3618         .set_wol        = &vsc85xx_wol_set,
3619         .get_wol        = &vsc85xx_wol_get,
3620         .get_tunable    = &vsc85xx_get_tunable,
3621         .set_tunable    = &vsc85xx_set_tunable,
3622         .read_page      = &vsc85xx_phy_read_page,
3623         .write_page     = &vsc85xx_phy_write_page,
3624         .get_sset_count = &vsc85xx_get_sset_count,
3625         .get_strings    = &vsc85xx_get_strings,
3626         .get_stats      = &vsc85xx_get_stats,
3627 },
3628 {
3629         .phy_id         = PHY_ID_VSC8552,
3630         .name           = "Microsemi GE VSC8552 SyncE",
3631         .phy_id_mask    = 0xfffffff0,
3632         /* PHY_GBIT_FEATURES */
3633         .soft_reset     = &genphy_soft_reset,
3634         .config_init    = &vsc8584_config_init,
3635         .config_aneg    = &vsc85xx_config_aneg,
3636         .read_status    = &vsc85xx_read_status,
3637         .ack_interrupt  = &vsc85xx_ack_interrupt,
3638         .config_intr    = &vsc85xx_config_intr,
3639         .did_interrupt  = &vsc8584_did_interrupt,
3640         .suspend        = &genphy_suspend,
3641         .resume         = &genphy_resume,
3642         .probe          = &vsc8574_probe,
3643         .set_wol        = &vsc85xx_wol_set,
3644         .get_wol        = &vsc85xx_wol_get,
3645         .get_tunable    = &vsc85xx_get_tunable,
3646         .set_tunable    = &vsc85xx_set_tunable,
3647         .read_page      = &vsc85xx_phy_read_page,
3648         .write_page     = &vsc85xx_phy_write_page,
3649         .get_sset_count = &vsc85xx_get_sset_count,
3650         .get_strings    = &vsc85xx_get_strings,
3651         .get_stats      = &vsc85xx_get_stats,
3652 },
3653 {
3654         .phy_id         = PHY_ID_VSC856X,
3655         .name           = "Microsemi GE VSC856X SyncE",
3656         .phy_id_mask    = 0xfffffff0,
3657         /* PHY_GBIT_FEATURES */
3658         .soft_reset     = &genphy_soft_reset,
3659         .config_init    = &vsc8584_config_init,
3660         .config_aneg    = &vsc85xx_config_aneg,
3661         .read_status    = &vsc85xx_read_status,
3662         .ack_interrupt  = &vsc85xx_ack_interrupt,
3663         .config_intr    = &vsc85xx_config_intr,
3664         .did_interrupt  = &vsc8584_did_interrupt,
3665         .suspend        = &genphy_suspend,
3666         .resume         = &genphy_resume,
3667         .probe          = &vsc8584_probe,
3668         .get_tunable    = &vsc85xx_get_tunable,
3669         .set_tunable    = &vsc85xx_set_tunable,
3670         .read_page      = &vsc85xx_phy_read_page,
3671         .write_page     = &vsc85xx_phy_write_page,
3672         .get_sset_count = &vsc85xx_get_sset_count,
3673         .get_strings    = &vsc85xx_get_strings,
3674         .get_stats      = &vsc85xx_get_stats,
3675 },
3676 {
3677         .phy_id         = PHY_ID_VSC8572,
3678         .name           = "Microsemi GE VSC8572 SyncE",
3679         .phy_id_mask    = 0xfffffff0,
3680         /* PHY_GBIT_FEATURES */
3681         .soft_reset     = &genphy_soft_reset,
3682         .config_init    = &vsc8584_config_init,
3683         .config_aneg    = &vsc85xx_config_aneg,
3684         .aneg_done      = &genphy_aneg_done,
3685         .read_status    = &vsc85xx_read_status,
3686         .handle_interrupt = &vsc8584_handle_interrupt,
3687         .ack_interrupt  = &vsc85xx_ack_interrupt,
3688         .config_intr    = &vsc85xx_config_intr,
3689         .did_interrupt  = &vsc8584_did_interrupt,
3690         .suspend        = &genphy_suspend,
3691         .resume         = &genphy_resume,
3692         .probe          = &vsc8574_probe,
3693         .set_wol        = &vsc85xx_wol_set,
3694         .get_wol        = &vsc85xx_wol_get,
3695         .get_tunable    = &vsc85xx_get_tunable,
3696         .set_tunable    = &vsc85xx_set_tunable,
3697         .read_page      = &vsc85xx_phy_read_page,
3698         .write_page     = &vsc85xx_phy_write_page,
3699         .get_sset_count = &vsc85xx_get_sset_count,
3700         .get_strings    = &vsc85xx_get_strings,
3701         .get_stats      = &vsc85xx_get_stats,
3702 },
3703 {
3704         .phy_id         = PHY_ID_VSC8574,
3705         .name           = "Microsemi GE VSC8574 SyncE",
3706         .phy_id_mask    = 0xfffffff0,
3707         /* PHY_GBIT_FEATURES */
3708         .soft_reset     = &genphy_soft_reset,
3709         .config_init    = &vsc8584_config_init,
3710         .config_aneg    = &vsc85xx_config_aneg,
3711         .aneg_done      = &genphy_aneg_done,
3712         .read_status    = &vsc85xx_read_status,
3713         .ack_interrupt  = &vsc85xx_ack_interrupt,
3714         .config_intr    = &vsc85xx_config_intr,
3715         .did_interrupt  = &vsc8584_did_interrupt,
3716         .suspend        = &genphy_suspend,
3717         .resume         = &genphy_resume,
3718         .probe          = &vsc8574_probe,
3719         .set_wol        = &vsc85xx_wol_set,
3720         .get_wol        = &vsc85xx_wol_get,
3721         .get_tunable    = &vsc85xx_get_tunable,
3722         .set_tunable    = &vsc85xx_set_tunable,
3723         .read_page      = &vsc85xx_phy_read_page,
3724         .write_page     = &vsc85xx_phy_write_page,
3725         .get_sset_count = &vsc85xx_get_sset_count,
3726         .get_strings    = &vsc85xx_get_strings,
3727         .get_stats      = &vsc85xx_get_stats,
3728 },
3729 {
3730         .phy_id         = PHY_ID_VSC8575,
3731         .name           = "Microsemi GE VSC8575 SyncE",
3732         .phy_id_mask    = 0xfffffff0,
3733         /* PHY_GBIT_FEATURES */
3734         .soft_reset     = &genphy_soft_reset,
3735         .config_init    = &vsc8584_config_init,
3736         .config_aneg    = &vsc85xx_config_aneg,
3737         .aneg_done      = &genphy_aneg_done,
3738         .read_status    = &vsc85xx_read_status,
3739         .handle_interrupt = &vsc8584_handle_interrupt,
3740         .ack_interrupt  = &vsc85xx_ack_interrupt,
3741         .config_intr    = &vsc85xx_config_intr,
3742         .did_interrupt  = &vsc8584_did_interrupt,
3743         .suspend        = &genphy_suspend,
3744         .resume         = &genphy_resume,
3745         .probe          = &vsc8584_probe,
3746         .get_tunable    = &vsc85xx_get_tunable,
3747         .set_tunable    = &vsc85xx_set_tunable,
3748         .read_page      = &vsc85xx_phy_read_page,
3749         .write_page     = &vsc85xx_phy_write_page,
3750         .get_sset_count = &vsc85xx_get_sset_count,
3751         .get_strings    = &vsc85xx_get_strings,
3752         .get_stats      = &vsc85xx_get_stats,
3753 },
3754 {
3755         .phy_id         = PHY_ID_VSC8582,
3756         .name           = "Microsemi GE VSC8582 SyncE",
3757         .phy_id_mask    = 0xfffffff0,
3758         /* PHY_GBIT_FEATURES */
3759         .soft_reset     = &genphy_soft_reset,
3760         .config_init    = &vsc8584_config_init,
3761         .config_aneg    = &vsc85xx_config_aneg,
3762         .aneg_done      = &genphy_aneg_done,
3763         .read_status    = &vsc85xx_read_status,
3764         .handle_interrupt = &vsc8584_handle_interrupt,
3765         .ack_interrupt  = &vsc85xx_ack_interrupt,
3766         .config_intr    = &vsc85xx_config_intr,
3767         .did_interrupt  = &vsc8584_did_interrupt,
3768         .suspend        = &genphy_suspend,
3769         .resume         = &genphy_resume,
3770         .probe          = &vsc8584_probe,
3771         .get_tunable    = &vsc85xx_get_tunable,
3772         .set_tunable    = &vsc85xx_set_tunable,
3773         .read_page      = &vsc85xx_phy_read_page,
3774         .write_page     = &vsc85xx_phy_write_page,
3775         .get_sset_count = &vsc85xx_get_sset_count,
3776         .get_strings    = &vsc85xx_get_strings,
3777         .get_stats      = &vsc85xx_get_stats,
3778 },
3779 {
3780         .phy_id         = PHY_ID_VSC8584,
3781         .name           = "Microsemi GE VSC8584 SyncE",
3782         .phy_id_mask    = 0xfffffff0,
3783         /* PHY_GBIT_FEATURES */
3784         .soft_reset     = &genphy_soft_reset,
3785         .config_init    = &vsc8584_config_init,
3786         .config_aneg    = &vsc85xx_config_aneg,
3787         .aneg_done      = &genphy_aneg_done,
3788         .read_status    = &vsc85xx_read_status,
3789         .handle_interrupt = &vsc8584_handle_interrupt,
3790         .ack_interrupt  = &vsc85xx_ack_interrupt,
3791         .config_intr    = &vsc85xx_config_intr,
3792         .did_interrupt  = &vsc8584_did_interrupt,
3793         .suspend        = &genphy_suspend,
3794         .resume         = &genphy_resume,
3795         .probe          = &vsc8584_probe,
3796         .get_tunable    = &vsc85xx_get_tunable,
3797         .set_tunable    = &vsc85xx_set_tunable,
3798         .read_page      = &vsc85xx_phy_read_page,
3799         .write_page     = &vsc85xx_phy_write_page,
3800         .get_sset_count = &vsc85xx_get_sset_count,
3801         .get_strings    = &vsc85xx_get_strings,
3802         .get_stats      = &vsc85xx_get_stats,
3803 }
3804
3805 };
3806
3807 module_phy_driver(vsc85xx_driver);
3808
3809 static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
3810         { PHY_ID_VSC8504, 0xfffffff0, },
3811         { PHY_ID_VSC8514, 0xfffffff0, },
3812         { PHY_ID_VSC8530, 0xfffffff0, },
3813         { PHY_ID_VSC8531, 0xfffffff0, },
3814         { PHY_ID_VSC8540, 0xfffffff0, },
3815         { PHY_ID_VSC8541, 0xfffffff0, },
3816         { PHY_ID_VSC8552, 0xfffffff0, },
3817         { PHY_ID_VSC856X, 0xfffffff0, },
3818         { PHY_ID_VSC8572, 0xfffffff0, },
3819         { PHY_ID_VSC8574, 0xfffffff0, },
3820         { PHY_ID_VSC8575, 0xfffffff0, },
3821         { PHY_ID_VSC8582, 0xfffffff0, },
3822         { PHY_ID_VSC8584, 0xfffffff0, },
3823         { }
3824 };
3825
3826 MODULE_DEVICE_TABLE(mdio, vsc85xx_tbl);
3827
3828 MODULE_DESCRIPTION("Microsemi VSC85xx PHY driver");
3829 MODULE_AUTHOR("Nagaraju Lakkaraju");
3830 MODULE_LICENSE("Dual MIT/GPL");