1 // SPDX-License-Identifier: MIT
3 * Microsemi PHY drivers
6 * Copyright (c) 2016 Microsemi Corporation
8 * Author: John Haechten
15 #include <linux/delay.h>
17 /* Microsemi PHY ID's */
18 #define PHY_ID_VSC8530 0x00070560
19 #define PHY_ID_VSC8531 0x00070570
20 #define PHY_ID_VSC8540 0x00070760
21 #define PHY_ID_VSC8541 0x00070770
22 #define PHY_ID_VSC8584 0x000707c0
24 /* Microsemi VSC85xx PHY Register Pages */
25 #define MSCC_EXT_PAGE_ACCESS 31 /* Page Access Register */
26 #define MSCC_PHY_PAGE_STD 0x0000 /* Standard registers */
27 #define MSCC_PHY_PAGE_EXT1 0x0001 /* Extended registers - page 1 */
28 #define MSCC_PHY_PAGE_EXT2 0x0002 /* Extended registers - page 2 */
29 #define MSCC_PHY_PAGE_EXT3 0x0003 /* Extended registers - page 3 */
30 #define MSCC_PHY_PAGE_EXT4 0x0004 /* Extended registers - page 4 */
31 #define MSCC_PHY_PAGE_GPIO 0x0010 /* GPIO registers */
32 #define MSCC_PHY_PAGE_TEST 0x2A30 /* TEST Page registers */
33 #define MSCC_PHY_PAGE_TR 0x52B5 /* Token Ring Page registers */
35 /* Std Page Register 18 */
36 #define MSCC_PHY_BYPASS_CONTROL 18
37 #define PARALLEL_DET_IGNORE_ADVERTISED BIT(3)
39 /* Std Page Register 22 */
40 #define MSCC_PHY_EXT_CNTL_STATUS 22
41 #define SMI_BROADCAST_WR_EN BIT(0)
43 /* Std Page Register 28 - PHY AUX Control/Status */
44 #define MIIM_AUX_CNTRL_STAT_REG 28
45 #define MIIM_AUX_CNTRL_STAT_ACTIPHY_TO (0x0004)
46 #define MIIM_AUX_CNTRL_STAT_F_DUPLEX (0x0020)
47 #define MIIM_AUX_CNTRL_STAT_SPEED_MASK (0x0018)
48 #define MIIM_AUX_CNTRL_STAT_SPEED_POS (3)
49 #define MIIM_AUX_CNTRL_STAT_SPEED_10M (0x0)
50 #define MIIM_AUX_CNTRL_STAT_SPEED_100M (0x1)
51 #define MIIM_AUX_CNTRL_STAT_SPEED_1000M (0x2)
53 /* Std Page Register 23 - Extended PHY CTRL_1 */
54 #define MSCC_PHY_EXT_PHY_CNTL_1_REG 23
55 #define MAC_IF_SELECTION_MASK (0x1800)
56 #define MAC_IF_SELECTION_GMII (0)
57 #define MAC_IF_SELECTION_RMII (1)
58 #define MAC_IF_SELECTION_RGMII (2)
59 #define MAC_IF_SELECTION_POS (11)
60 #define MAC_IF_SELECTION_WIDTH (2)
61 #define VSC8584_MAC_IF_SELECTION_MASK BIT(12)
62 #define VSC8584_MAC_IF_SELECTION_SGMII 0
63 #define VSC8584_MAC_IF_SELECTION_1000BASEX 1
64 #define VSC8584_MAC_IF_SELECTION_POS 12
65 #define MEDIA_OP_MODE_MASK GENMASK(10, 8)
66 #define MEDIA_OP_MODE_COPPER 0
67 #define MEDIA_OP_MODE_SERDES 1
68 #define MEDIA_OP_MODE_1000BASEX 2
69 #define MEDIA_OP_MODE_100BASEFX 3
70 #define MEDIA_OP_MODE_AMS_COPPER_SERDES 5
71 #define MEDIA_OP_MODE_AMS_COPPER_1000BASEX 6
72 #define MEDIA_OP_MODE_AMS_COPPER_100BASEFX 7
73 #define MEDIA_OP_MODE_POS 8
75 /* Extended Page 1 Register 20E1 */
76 #define MSCC_PHY_ACTIPHY_CNTL 20
77 #define PHY_ADDR_REVERSED BIT(9)
79 /* Extended Page 1 Register 23E1 */
81 #define MSCC_PHY_EXT_PHY_CNTL_4 23
82 #define PHY_CNTL_4_ADDR_POS 11
84 /* Extended Page 1 Register 25E1 */
85 #define MSCC_PHY_VERIPHY_CNTL_2 25
87 /* Extended Page 1 Register 26E1 */
88 #define MSCC_PHY_VERIPHY_CNTL_3 26
90 /* Extended Page 2 Register 16E2 */
91 #define MSCC_PHY_CU_PMD_TX_CNTL 16
93 /* Extended Page 2 Register 20E2 */
94 #define MSCC_PHY_RGMII_CNTL_REG 20
95 #define VSC_FAST_LINK_FAIL2_ENA_MASK (0x8000)
96 #define RX_CLK_OUT_MASK (0x0800)
97 #define RX_CLK_OUT_POS (11)
98 #define RX_CLK_OUT_WIDTH (1)
99 #define RX_CLK_OUT_NORMAL (0)
100 #define RX_CLK_OUT_DISABLE (1)
101 #define RGMII_RX_CLK_DELAY_POS (4)
102 #define RGMII_RX_CLK_DELAY_WIDTH (3)
103 #define RGMII_RX_CLK_DELAY_MASK (0x0070)
104 #define RGMII_TX_CLK_DELAY_POS (0)
105 #define RGMII_TX_CLK_DELAY_WIDTH (3)
106 #define RGMII_TX_CLK_DELAY_MASK (0x0007)
108 /* Extended Page 2 Register 27E2 */
109 #define MSCC_PHY_WOL_MAC_CONTROL 27
110 #define EDGE_RATE_CNTL_POS (5)
111 #define EDGE_RATE_CNTL_WIDTH (3)
112 #define EDGE_RATE_CNTL_MASK (0x00E0)
113 #define RMII_CLK_OUT_ENABLE_POS (4)
114 #define RMII_CLK_OUT_ENABLE_WIDTH (1)
115 #define RMII_CLK_OUT_ENABLE_MASK (0x10)
117 /* Extended Page 3 Register 22E3 */
118 #define MSCC_PHY_SERDES_TX_CRC_ERR_CNT 22
120 /* Extended page GPIO register 00G */
121 #define MSCC_DW8051_CNTL_STATUS 0
122 #define MICRO_NSOFT_RESET BIT(15)
123 #define RUN_FROM_INT_ROM BIT(14)
124 #define AUTOINC_ADDR BIT(13)
125 #define PATCH_RAM_CLK BIT(12)
126 #define MICRO_PATCH_EN BIT(7)
127 #define DW8051_CLK_EN BIT(4)
128 #define MICRO_CLK_EN BIT(3)
129 #define MICRO_CLK_DIVIDE(x) ((x) >> 1)
131 /* Extended page GPIO register 09G */
132 #define MSCC_TRAP_ROM_ADDR(x) ((x) * 2 + 1)
134 /* Extended page GPIO register 10G */
135 #define MSCC_PATCH_RAM_ADDR(x) (((x) + 1) * 2)
137 /* Extended page GPIO register 11G */
138 #define MSCC_INT_MEM_ADDR 11
140 /* Extended page GPIO register 12G */
141 #define MSCC_INT_MEM_CNTL 12
142 #define READ_SFR (BIT(14) | BIT(13))
143 #define READ_PRAM BIT(14)
144 #define READ_ROM BIT(13)
145 #define READ_RAM (0x00 << 13)
146 #define INT_MEM_WRITE_EN BIT(12)
147 #define EN_PATCH_RAM_TRAP_ADDR(x) BIT((x) + 7)
148 #define INT_MEM_DATA_M GENMASK(7, 0)
149 #define INT_MEM_DATA(x) (INT_MEM_DATA_M & (x))
151 /* Extended page GPIO register 18G */
152 #define MSCC_PHY_PROC_CMD 18
153 #define PROC_CMD_NCOMPLETED BIT(15)
154 #define PROC_CMD_FAILED BIT(14)
155 #define PROC_CMD_SGMII_PORT(x) ((x) << 8)
156 #define PROC_CMD_FIBER_PORT(x) BIT(8 + (x) % 4)
157 #define PROC_CMD_QSGMII_PORT (BIT(11) | BIT(10))
158 #define PROC_CMD_RST_CONF_PORT BIT(7)
159 #define PROC_CMD_RECONF_PORT (0 << 7)
160 #define PROC_CMD_READ_MOD_WRITE_PORT BIT(6)
161 #define PROC_CMD_WRITE BIT(6)
162 #define PROC_CMD_READ (0 << 6)
163 #define PROC_CMD_FIBER_DISABLE BIT(5)
164 #define PROC_CMD_FIBER_100BASE_FX BIT(4)
165 #define PROC_CMD_FIBER_1000BASE_X (0 << 4)
166 #define PROC_CMD_SGMII_MAC (BIT(5) | BIT(4))
167 #define PROC_CMD_QSGMII_MAC BIT(5)
168 #define PROC_CMD_NO_MAC_CONF (0x00 << 4)
169 #define PROC_CMD_NOP GENMASK(3, 0)
170 #define PROC_CMD_CRC16 BIT(3)
171 #define PROC_CMD_FIBER_MEDIA_CONF BIT(0)
172 #define PROC_CMD_MCB_ACCESS_MAC_CONF (0x0000 << 0)
173 #define PROC_CMD_NCOMPLETED_TIMEOUT_MS 500
175 /* Extended page GPIO register 19G */
176 #define MSCC_PHY_MAC_CFG_FASTLINK 19
177 #define MAC_CFG_MASK GENMASK(15, 14)
178 #define MAC_CFG_SGMII (0x00 << 14)
179 #define MAC_CFG_QSGMII BIT(14)
182 #define MSCC_PHY_TEST_PAGE_5 5
184 #define MSCC_PHY_TEST_PAGE_8 8
185 #define TR_CLK_DISABLE BIT(15)
187 /* Token Ring Page 0x52B5 Registers */
188 #define MSCC_PHY_REG_TR_ADDR_16 16
189 #define MSCC_PHY_REG_TR_DATA_17 17
190 #define MSCC_PHY_REG_TR_DATA_18 18
192 /* Token Ring - Read Value in */
193 #define MSCC_PHY_TR_16_READ (0xA000)
194 /* Token Ring - Write Value out */
195 #define MSCC_PHY_TR_16_WRITE (0x8000)
197 /* Token Ring Registers */
198 #define MSCC_PHY_TR_LINKDETCTRL_POS (3)
199 #define MSCC_PHY_TR_LINKDETCTRL_WIDTH (2)
200 #define MSCC_PHY_TR_LINKDETCTRL_VAL (3)
201 #define MSCC_PHY_TR_LINKDETCTRL_MASK (0x0018)
202 #define MSCC_PHY_TR_LINKDETCTRL_ADDR (0x07F8)
204 #define MSCC_PHY_TR_VGATHRESH100_POS (0)
205 #define MSCC_PHY_TR_VGATHRESH100_WIDTH (7)
206 #define MSCC_PHY_TR_VGATHRESH100_VAL (0x0018)
207 #define MSCC_PHY_TR_VGATHRESH100_MASK (0x007f)
208 #define MSCC_PHY_TR_VGATHRESH100_ADDR (0x0FA4)
210 #define MSCC_PHY_TR_VGAGAIN10_U_POS (0)
211 #define MSCC_PHY_TR_VGAGAIN10_U_WIDTH (1)
212 #define MSCC_PHY_TR_VGAGAIN10_U_MASK (0x0001)
213 #define MSCC_PHY_TR_VGAGAIN10_U_VAL (0)
215 #define MSCC_PHY_TR_VGAGAIN10_L_POS (12)
216 #define MSCC_PHY_TR_VGAGAIN10_L_WIDTH (4)
217 #define MSCC_PHY_TR_VGAGAIN10_L_MASK (0xf000)
218 #define MSCC_PHY_TR_VGAGAIN10_L_VAL (0x0001)
219 #define MSCC_PHY_TR_VGAGAIN10_ADDR (0x0F92)
221 /* General Timeout Values */
222 #define MSCC_PHY_RESET_TIMEOUT (100)
223 #define MSCC_PHY_MICRO_TIMEOUT (500)
225 #define VSC8584_REVB 0x0001
226 #define MSCC_DEV_REV_MASK GENMASK(3, 0)
228 #define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800
229 #define MSCC_VSC8584_REVB_INT8051_FW_CRC 0xfb48
231 /* RGMII/GMII Clock Delay (Skew) Options */ enum vsc_phy_rgmii_skew {
232 VSC_PHY_RGMII_DELAY_200_PS,
233 VSC_PHY_RGMII_DELAY_800_PS,
234 VSC_PHY_RGMII_DELAY_1100_PS,
235 VSC_PHY_RGMII_DELAY_1700_PS,
236 VSC_PHY_RGMII_DELAY_2000_PS,
237 VSC_PHY_RGMII_DELAY_2300_PS,
238 VSC_PHY_RGMII_DELAY_2600_PS,
239 VSC_PHY_RGMII_DELAY_3400_PS,
242 /* MAC i/f Clock Edge Rage Control (Slew), See Reg27E2 */ enum
244 VSC_PHY_CLK_SLEW_RATE_0,
245 VSC_PHY_CLK_SLEW_RATE_1,
246 VSC_PHY_CLK_SLEW_RATE_2,
247 VSC_PHY_CLK_SLEW_RATE_3,
248 VSC_PHY_CLK_SLEW_RATE_4,
249 VSC_PHY_CLK_SLEW_RATE_5,
250 VSC_PHY_CLK_SLEW_RATE_6,
251 VSC_PHY_CLK_SLEW_RATE_7,
254 struct vsc85xx_priv {
255 int (*config_pre)(struct phy_device *phydev);
258 static void vsc8584_csr_write(struct mii_dev *bus, int phy0, u16 addr, u32 val)
260 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18,
262 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17,
263 val & GENMASK(15, 0));
264 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
265 MSCC_PHY_TR_16_WRITE | addr);
268 static int vsc8584_cmd(struct mii_dev *bus, int phy, u16 val)
270 unsigned long deadline;
273 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
276 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD,
277 PROC_CMD_NCOMPLETED | val);
279 deadline = timer_get_us() + PROC_CMD_NCOMPLETED_TIMEOUT_MS * 1000;
281 reg_val = bus->read(bus, phy, MDIO_DEVAD_NONE,
283 } while (timer_get_us() <= deadline &&
284 (reg_val & PROC_CMD_NCOMPLETED) &&
285 !(reg_val & PROC_CMD_FAILED));
287 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
290 if (reg_val & PROC_CMD_FAILED)
292 if (reg_val & PROC_CMD_NCOMPLETED)
298 static int vsc8584_micro_deassert_reset(struct mii_dev *bus, int phy,
303 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
306 enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
307 release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
311 enable |= MICRO_PATCH_EN;
312 release |= MICRO_PATCH_EN;
314 /* Clear all patches */
315 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL,
320 * Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
321 * override and addr. auto-incr; operate at 125 MHz
323 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, enable);
324 /* Release 8051 Micro SW reset */
325 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, release);
327 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
333 static int vsc8584_micro_assert_reset(struct mii_dev *bus, int phy)
338 ret = vsc8584_cmd(bus, phy, PROC_CMD_NOP);
342 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
345 reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
346 reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
347 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
349 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_TRAP_ROM_ADDR(4), 0x005b);
350 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PATCH_RAM_ADDR(4), 0x005b);
352 reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
353 reg |= EN_PATCH_RAM_TRAP_ADDR(4);
354 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
356 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
358 reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS);
359 reg &= ~MICRO_NSOFT_RESET;
360 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, reg);
362 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD,
363 PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_SGMII_PORT(0) |
364 PROC_CMD_NO_MAC_CONF | PROC_CMD_READ);
366 reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
367 reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
368 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
370 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
376 static const u8 fw_patch_vsc8584[] = {
377 0xe8, 0x59, 0x02, 0xe8, 0x12, 0x02, 0xe8, 0x42, 0x02, 0xe8, 0x5a, 0x02,
378 0xe8, 0x5b, 0x02, 0xe8, 0x5c, 0xe5, 0x69, 0x54, 0x0f, 0x24, 0xf7, 0x60,
379 0x27, 0x24, 0xfc, 0x60, 0x23, 0x24, 0x08, 0x70, 0x14, 0xe5, 0x69, 0xae,
380 0x68, 0x78, 0x04, 0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0xd8, 0xf8, 0x7e,
381 0x00, 0x54, 0x0f, 0x80, 0x00, 0x7b, 0x01, 0x7a, 0x00, 0x7d, 0xee, 0x7f,
382 0x92, 0x12, 0x50, 0xee, 0x22, 0xe4, 0xf5, 0x10, 0x85, 0x10, 0xfb, 0x7d,
383 0x1c, 0xe4, 0xff, 0x12, 0x59, 0xea, 0x05, 0x10, 0xe5, 0x10, 0xc3, 0x94,
384 0x04, 0x40, 0xed, 0x22, 0x22, 0x22, 0x22, 0x22,
387 static int vsc8584_get_fw_crc(struct mii_dev *bus, int phy, u16 start,
388 u16 *crc, const u8 *fw_patch, int fw_size)
392 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
395 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_2, start);
396 /* Add one byte to size for the one added by the patch_fw function */
397 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_3,
400 ret = vsc8584_cmd(bus, phy, PROC_CMD_CRC16);
404 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
407 *crc = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_2);
410 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
416 static int vsc8584_patch_fw(struct mii_dev *bus, int phy, const u8 *fw_patch,
421 ret = vsc8584_micro_assert_reset(bus, phy);
423 pr_err("%s: failed to assert reset of micro\n", __func__);
427 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
431 * Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
432 * Disable the 8051 Micro clock
434 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS,
435 RUN_FROM_INT_ROM | AUTOINC_ADDR | PATCH_RAM_CLK |
436 MICRO_CLK_EN | MICRO_CLK_DIVIDE(2));
437 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, READ_PRAM |
438 INT_MEM_WRITE_EN | INT_MEM_DATA(2));
439 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_ADDR, 0x0000);
441 for (i = 0; i < fw_size; i++)
442 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL,
443 READ_PRAM | INT_MEM_WRITE_EN | fw_patch[i]);
445 /* Clear internal memory access */
446 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, READ_RAM);
448 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
454 static int vsc8584_config_pre_init(struct phy_device *phydev)
456 struct mii_dev *bus = phydev->bus;
457 u16 reg, crc, phy0, addr;
460 if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
461 pr_warn("VSC8584 revA not officially supported, skipping firmware patching. Use at your own risk.\n");
465 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
467 addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4);
468 addr >>= PHY_CNTL_4_ADDR_POS;
470 reg = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_ACTIPHY_CNTL);
471 if (reg & PHY_ADDR_REVERSED)
472 phy0 = phydev->addr + addr;
474 phy0 = phydev->addr - addr;
476 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
479 /* all writes below are broadcasted to all PHYs in the same package */
480 reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
481 reg |= SMI_BROADCAST_WR_EN;
482 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
485 * The below register writes are tweaking analog and electrical
486 * configuration that were determined through characterization by PHY
487 * engineers. These don't mean anything more than "these are the best
490 reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_BYPASS_CONTROL);
491 reg |= PARALLEL_DET_IGNORE_ADVERTISED;
492 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_BYPASS_CONTROL, reg);
494 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
497 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
500 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
503 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_5, 0x1f20);
505 reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
506 reg |= TR_CLK_DISABLE;
507 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
509 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
512 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0xafa4);
514 reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
517 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg);
519 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0x8fa4);
521 vsc8584_csr_write(bus, phy0, 0x07fa, 0x0050100f);
522 vsc8584_csr_write(bus, phy0, 0x1688, 0x00049f81);
523 vsc8584_csr_write(bus, phy0, 0x0f90, 0x00688980);
524 vsc8584_csr_write(bus, phy0, 0x03a4, 0x0000d8f0);
525 vsc8584_csr_write(bus, phy0, 0x0fc0, 0x00000400);
526 vsc8584_csr_write(bus, phy0, 0x0f82, 0x0012b002);
527 vsc8584_csr_write(bus, phy0, 0x1686, 0x00000004);
528 vsc8584_csr_write(bus, phy0, 0x168c, 0x00d2c46f);
529 vsc8584_csr_write(bus, phy0, 0x17a2, 0x00000620);
530 vsc8584_csr_write(bus, phy0, 0x16a0, 0x00eeffdd);
531 vsc8584_csr_write(bus, phy0, 0x16a6, 0x00071448);
532 vsc8584_csr_write(bus, phy0, 0x16a4, 0x0013132f);
533 vsc8584_csr_write(bus, phy0, 0x16a8, 0x00000000);
534 vsc8584_csr_write(bus, phy0, 0x0ffc, 0x00c0a028);
535 vsc8584_csr_write(bus, phy0, 0x0fe8, 0x0091b06c);
536 vsc8584_csr_write(bus, phy0, 0x0fea, 0x00041600);
537 vsc8584_csr_write(bus, phy0, 0x0f80, 0x00fffaff);
538 vsc8584_csr_write(bus, phy0, 0x0fec, 0x00901809);
539 vsc8584_csr_write(bus, phy0, 0x0ffe, 0x00b01007);
540 vsc8584_csr_write(bus, phy0, 0x16b0, 0x00eeff00);
541 vsc8584_csr_write(bus, phy0, 0x16b2, 0x00007000);
542 vsc8584_csr_write(bus, phy0, 0x16b4, 0x00000814);
544 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
547 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
549 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
552 vsc8584_csr_write(bus, phy0, 0x0486, 0x0008a518);
553 vsc8584_csr_write(bus, phy0, 0x0488, 0x006dc696);
554 vsc8584_csr_write(bus, phy0, 0x048a, 0x00000912);
556 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
559 reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
560 reg &= ~TR_CLK_DISABLE;
561 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
563 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
566 /* end of write broadcasting */
567 reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
568 reg &= ~SMI_BROADCAST_WR_EN;
569 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
571 ret = vsc8584_get_fw_crc(bus, phy0,
572 MSCC_VSC8584_REVB_INT8051_FW_START_ADDR, &crc,
574 ARRAY_SIZE(fw_patch_vsc8584));
578 if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
579 debug("FW CRC is not the expected one, patching FW...\n");
580 if (vsc8584_patch_fw(bus, phy0, fw_patch_vsc8584,
581 ARRAY_SIZE(fw_patch_vsc8584)))
582 pr_warn("failed to patch FW, expect non-optimal device\n");
585 vsc8584_micro_deassert_reset(bus, phy0, false);
587 ret = vsc8584_get_fw_crc(bus, phy0,
588 MSCC_VSC8584_REVB_INT8051_FW_START_ADDR, &crc,
590 ARRAY_SIZE(fw_patch_vsc8584));
594 if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
595 pr_warn("FW CRC after patching is not the expected one, expect non-optimal device\n");
597 ret = vsc8584_micro_assert_reset(bus, phy0);
601 vsc8584_micro_deassert_reset(bus, phy0, true);
604 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
610 static int mscc_vsc8531_vsc8541_init_scripts(struct phy_device *phydev)
614 /* Set to Access Token Ring Registers */
615 phy_write(phydev, MDIO_DEVAD_NONE,
616 MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
618 /* Update LinkDetectCtrl default to optimized values */
619 /* Determined during Silicon Validation Testing */
620 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
621 (MSCC_PHY_TR_LINKDETCTRL_ADDR | MSCC_PHY_TR_16_READ));
622 reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17);
623 reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_LINKDETCTRL_POS,
624 MSCC_PHY_TR_LINKDETCTRL_WIDTH,
625 MSCC_PHY_TR_LINKDETCTRL_VAL);
627 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17, reg_val);
628 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
629 (MSCC_PHY_TR_LINKDETCTRL_ADDR | MSCC_PHY_TR_16_WRITE));
631 /* Update VgaThresh100 defaults to optimized values */
632 /* Determined during Silicon Validation Testing */
633 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
634 (MSCC_PHY_TR_VGATHRESH100_ADDR | MSCC_PHY_TR_16_READ));
636 reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
637 reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGATHRESH100_POS,
638 MSCC_PHY_TR_VGATHRESH100_WIDTH,
639 MSCC_PHY_TR_VGATHRESH100_VAL);
641 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg_val);
642 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
643 (MSCC_PHY_TR_VGATHRESH100_ADDR | MSCC_PHY_TR_16_WRITE));
645 /* Update VgaGain10 defaults to optimized values */
646 /* Determined during Silicon Validation Testing */
647 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
648 (MSCC_PHY_TR_VGAGAIN10_ADDR | MSCC_PHY_TR_16_READ));
650 reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
651 reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGAGAIN10_U_POS,
652 MSCC_PHY_TR_VGAGAIN10_U_WIDTH,
653 MSCC_PHY_TR_VGAGAIN10_U_VAL);
655 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg_val);
656 reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17);
657 reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGAGAIN10_L_POS,
658 MSCC_PHY_TR_VGAGAIN10_L_WIDTH,
659 MSCC_PHY_TR_VGAGAIN10_L_VAL);
661 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17, reg_val);
662 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
663 (MSCC_PHY_TR_VGAGAIN10_ADDR | MSCC_PHY_TR_16_WRITE));
665 /* Set back to Access Standard Page Registers */
666 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
672 static int mscc_parse_status(struct phy_device *phydev)
677 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_AUX_CNTRL_STAT_REG);
679 if (mii_reg & MIIM_AUX_CNTRL_STAT_F_DUPLEX)
680 phydev->duplex = DUPLEX_FULL;
682 phydev->duplex = DUPLEX_HALF;
684 speed = mii_reg & MIIM_AUX_CNTRL_STAT_SPEED_MASK;
685 speed = speed >> MIIM_AUX_CNTRL_STAT_SPEED_POS;
688 case MIIM_AUX_CNTRL_STAT_SPEED_1000M:
689 phydev->speed = SPEED_1000;
691 case MIIM_AUX_CNTRL_STAT_SPEED_100M:
692 phydev->speed = SPEED_100;
694 case MIIM_AUX_CNTRL_STAT_SPEED_10M:
695 phydev->speed = SPEED_10;
698 phydev->speed = SPEED_10;
705 static int mscc_startup(struct phy_device *phydev)
709 retval = genphy_update_link(phydev);
714 return mscc_parse_status(phydev);
717 static int mscc_phy_soft_reset(struct phy_device *phydev)
720 u16 timeout = MSCC_PHY_RESET_TIMEOUT;
723 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
726 reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
727 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, (reg_val | BMCR_RESET));
729 reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
731 while ((reg_val & BMCR_RESET) && (timeout > 0)) {
732 reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
734 udelay(1000); /* 1 ms */
738 printf("MSCC PHY Soft_Reset Error: mac i/f = 0x%x\n",
746 static int vsc8531_vsc8541_mac_config(struct phy_device *phydev)
752 /* For VSC8530/31 the only MAC modes are RMII/RGMII. */
753 /* For VSC8540/41 the only MAC modes are (G)MII and RMII/RGMII. */
754 /* Setup MAC Configuration */
755 switch (phydev->interface) {
756 case PHY_INTERFACE_MODE_MII:
757 case PHY_INTERFACE_MODE_GMII:
758 /* Set Reg23.12:11=0 */
759 mac_if = MAC_IF_SELECTION_GMII;
760 /* Set Reg20E2.11=1 */
761 rx_clk_out = RX_CLK_OUT_DISABLE;
764 case PHY_INTERFACE_MODE_RMII:
765 /* Set Reg23.12:11=1 */
766 mac_if = MAC_IF_SELECTION_RMII;
767 /* Set Reg20E2.11=0 */
768 rx_clk_out = RX_CLK_OUT_NORMAL;
771 case PHY_INTERFACE_MODE_RGMII:
772 /* Set Reg23.12:11=2 */
773 mac_if = MAC_IF_SELECTION_RGMII;
774 /* Set Reg20E2.11=0 */
775 rx_clk_out = RX_CLK_OUT_NORMAL;
779 printf("MSCC PHY - INVALID MAC i/f Config: mac i/f = 0x%x\n",
784 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
787 reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
788 MSCC_PHY_EXT_PHY_CNTL_1_REG);
789 /* Set MAC i/f bits Reg23.12:11 */
790 reg_val = bitfield_replace(reg_val, MAC_IF_SELECTION_POS,
791 MAC_IF_SELECTION_WIDTH, mac_if);
792 /* Update Reg23.12:11 */
793 phy_write(phydev, MDIO_DEVAD_NONE,
794 MSCC_PHY_EXT_PHY_CNTL_1_REG, reg_val);
795 /* Setup ExtPg_2 Register Access */
796 phy_write(phydev, MDIO_DEVAD_NONE,
797 MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXT2);
799 reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
800 MSCC_PHY_RGMII_CNTL_REG);
801 reg_val = bitfield_replace(reg_val, RX_CLK_OUT_POS,
802 RX_CLK_OUT_WIDTH, rx_clk_out);
803 /* Update Reg20E2.11 */
804 phy_write(phydev, MDIO_DEVAD_NONE,
805 MSCC_PHY_RGMII_CNTL_REG, reg_val);
806 /* Before leaving - Change back to Std Page Register Access */
807 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
813 static int vsc8531_config(struct phy_device *phydev)
815 int retval = -EINVAL;
818 enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_1700_PS;
819 enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_800_PS;
820 enum vsc_phy_clk_slew edge_rate = VSC_PHY_CLK_SLEW_RATE_4;
822 /* For VSC8530/31 and VSC8540/41 the init scripts are the same */
823 mscc_vsc8531_vsc8541_init_scripts(phydev);
825 /* For VSC8530/31 the only MAC modes are RMII/RGMII. */
826 switch (phydev->interface) {
827 case PHY_INTERFACE_MODE_RMII:
828 case PHY_INTERFACE_MODE_RGMII:
829 retval = vsc8531_vsc8541_mac_config(phydev);
833 retval = mscc_phy_soft_reset(phydev);
838 printf("PHY 8530/31 MAC i/f Config Error: mac i/f = 0x%x\n",
842 /* Default RMII Clk Output to 0=OFF/1=ON */
845 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
847 reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
849 /* Reg20E2 - Update RGMII RX_Clk Skews. */
850 reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
851 RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
852 /* Reg20E2 - Update RGMII TX_Clk Skews. */
853 reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
854 RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
856 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
858 reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL);
859 /* Reg27E2 - Update Clk Slew Rate. */
860 reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
861 EDGE_RATE_CNTL_WIDTH, edge_rate);
862 /* Reg27E2 - Update RMII Clk Out. */
863 reg_val = bitfield_replace(reg_val, RMII_CLK_OUT_ENABLE_POS,
864 RMII_CLK_OUT_ENABLE_WIDTH, rmii_clk_out);
866 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
867 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
870 return genphy_config_aneg(phydev);
873 static int vsc8541_config(struct phy_device *phydev)
875 int retval = -EINVAL;
878 enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_1700_PS;
879 enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_800_PS;
880 enum vsc_phy_clk_slew edge_rate = VSC_PHY_CLK_SLEW_RATE_4;
882 /* For VSC8530/31 and VSC8540/41 the init scripts are the same */
883 mscc_vsc8531_vsc8541_init_scripts(phydev);
885 /* For VSC8540/41 the only MAC modes are (G)MII and RMII/RGMII. */
886 switch (phydev->interface) {
887 case PHY_INTERFACE_MODE_MII:
888 case PHY_INTERFACE_MODE_GMII:
889 case PHY_INTERFACE_MODE_RMII:
890 case PHY_INTERFACE_MODE_RGMII:
891 retval = vsc8531_vsc8541_mac_config(phydev);
895 retval = mscc_phy_soft_reset(phydev);
900 printf("PHY 8541 MAC i/f config Error: mac i/f = 0x%x\n",
904 /* Default RMII Clk Output to 0=OFF/1=ON */
907 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
909 reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
910 /* Reg20E2 - Update RGMII RX_Clk Skews. */
911 reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
912 RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
913 /* Reg20E2 - Update RGMII TX_Clk Skews. */
914 reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
915 RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
916 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
918 reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL);
919 /* Reg27E2 - Update Clk Slew Rate. */
920 reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
921 EDGE_RATE_CNTL_WIDTH, edge_rate);
922 /* Reg27E2 - Update RMII Clk Out. */
923 reg_val = bitfield_replace(reg_val, RMII_CLK_OUT_ENABLE_POS,
924 RMII_CLK_OUT_ENABLE_WIDTH, rmii_clk_out);
926 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
927 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
930 return genphy_config_aneg(phydev);
933 static int vsc8584_config_init(struct phy_device *phydev)
935 struct vsc85xx_priv *priv = phydev->priv;
941 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
943 addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4);
944 addr >>= PHY_CNTL_4_ADDR_POS;
946 ret = priv->config_pre(phydev);
950 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
953 if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
954 val = MAC_CFG_QSGMII;
958 reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_MAC_CFG_FASTLINK);
959 reg_val &= ~MAC_CFG_MASK;
961 ret = phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_MAC_CFG_FASTLINK,
966 reg_val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
967 PROC_CMD_READ_MOD_WRITE_PORT;
968 if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
969 reg_val |= PROC_CMD_QSGMII_MAC;
971 reg_val |= PROC_CMD_SGMII_MAC;
973 ret = vsc8584_cmd(phydev->bus, phydev->addr, reg_val);
979 /* Disable SerDes for 100Base-FX */
980 ret = vsc8584_cmd(phydev->bus, phydev->addr, PROC_CMD_FIBER_MEDIA_CONF |
981 PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
982 PROC_CMD_READ_MOD_WRITE_PORT |
983 PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
987 /* Disable SerDes for 1000Base-X */
988 ret = vsc8584_cmd(phydev->bus, phydev->addr, PROC_CMD_FIBER_MEDIA_CONF |
989 PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
990 PROC_CMD_READ_MOD_WRITE_PORT |
991 PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
995 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
997 reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
998 MSCC_PHY_EXT_PHY_CNTL_1_REG);
999 reg_val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
1000 reg_val |= MEDIA_OP_MODE_COPPER |
1001 (VSC8584_MAC_IF_SELECTION_SGMII <<
1002 VSC8584_MAC_IF_SELECTION_POS);
1003 ret = phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_1_REG,
1006 ret = mscc_phy_soft_reset(phydev);
1010 return genphy_config(phydev);
1013 static struct vsc85xx_priv vsc8584_priv = {
1014 .config_pre = vsc8584_config_pre_init,
1017 static int vsc8584_config(struct phy_device *phydev)
1019 phydev->priv = &vsc8584_priv;
1021 return vsc8584_config_init(phydev);
1024 static struct phy_driver VSC8530_driver = {
1025 .name = "Microsemi VSC8530",
1026 .uid = PHY_ID_VSC8530,
1028 .features = PHY_BASIC_FEATURES,
1029 .config = &vsc8531_config,
1030 .startup = &mscc_startup,
1031 .shutdown = &genphy_shutdown,
1034 static struct phy_driver VSC8531_driver = {
1035 .name = "Microsemi VSC8531",
1036 .uid = PHY_ID_VSC8531,
1038 .features = PHY_GBIT_FEATURES,
1039 .config = &vsc8531_config,
1040 .startup = &mscc_startup,
1041 .shutdown = &genphy_shutdown,
1044 static struct phy_driver VSC8540_driver = {
1045 .name = "Microsemi VSC8540",
1046 .uid = PHY_ID_VSC8540,
1048 .features = PHY_BASIC_FEATURES,
1049 .config = &vsc8541_config,
1050 .startup = &mscc_startup,
1051 .shutdown = &genphy_shutdown,
1054 static struct phy_driver VSC8541_driver = {
1055 .name = "Microsemi VSC8541",
1056 .uid = PHY_ID_VSC8541,
1058 .features = PHY_GBIT_FEATURES,
1059 .config = &vsc8541_config,
1060 .startup = &mscc_startup,
1061 .shutdown = &genphy_shutdown,
1064 static struct phy_driver VSC8584_driver = {
1065 .name = "Microsemi VSC8584",
1066 .uid = PHY_ID_VSC8584,
1068 .features = PHY_GBIT_FEATURES,
1069 .config = &vsc8584_config,
1070 .startup = &mscc_startup,
1071 .shutdown = &genphy_shutdown,
1074 int phy_mscc_init(void)
1076 phy_register(&VSC8530_driver);
1077 phy_register(&VSC8531_driver);
1078 phy_register(&VSC8540_driver);
1079 phy_register(&VSC8541_driver);
1080 phy_register(&VSC8584_driver);