OSDN Git Service

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