xref: /OK3568_Linux_fs/u-boot/drivers/net/phy/vitesse.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Vitesse PHY drivers
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright 2010-2014 Freescale Semiconductor, Inc.
5*4882a593Smuzhiyun  * Original Author: Andy Fleming
6*4882a593Smuzhiyun  * Add vsc8662 phy support - Priyanka Jain
7*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun #include <miiphy.h>
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun /* Cicada Auxiliary Control/Status Register */
12*4882a593Smuzhiyun #define MIIM_CIS82xx_AUX_CONSTAT	0x1c
13*4882a593Smuzhiyun #define MIIM_CIS82xx_AUXCONSTAT_INIT	0x0004
14*4882a593Smuzhiyun #define MIIM_CIS82xx_AUXCONSTAT_DUPLEX	0x0020
15*4882a593Smuzhiyun #define MIIM_CIS82xx_AUXCONSTAT_SPEED	0x0018
16*4882a593Smuzhiyun #define MIIM_CIS82xx_AUXCONSTAT_GBIT	0x0010
17*4882a593Smuzhiyun #define MIIM_CIS82xx_AUXCONSTAT_100	0x0008
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /* Cicada Extended Control Register 1 */
20*4882a593Smuzhiyun #define MIIM_CIS82xx_EXT_CON1		0x17
21*4882a593Smuzhiyun #define MIIM_CIS8201_EXTCON1_INIT	0x0000
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun /* Cicada 8204 Extended PHY Control Register 1 */
24*4882a593Smuzhiyun #define MIIM_CIS8204_EPHY_CON		0x17
25*4882a593Smuzhiyun #define MIIM_CIS8204_EPHYCON_INIT	0x0006
26*4882a593Smuzhiyun #define MIIM_CIS8204_EPHYCON_RGMII	0x1100
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun /* Cicada 8204 Serial LED Control Register */
29*4882a593Smuzhiyun #define MIIM_CIS8204_SLED_CON		0x1b
30*4882a593Smuzhiyun #define MIIM_CIS8204_SLEDCON_INIT	0x1115
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun /* Vitesse VSC8601 Extended PHY Control Register 1 */
33*4882a593Smuzhiyun #define MII_VSC8601_EPHY_CTL		0x17
34*4882a593Smuzhiyun #define MII_VSC8601_EPHY_CTL_RGMII_SKEW	(1 << 8)
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #define PHY_EXT_PAGE_ACCESS    0x1f
37*4882a593Smuzhiyun #define PHY_EXT_PAGE_ACCESS_GENERAL	0x10
38*4882a593Smuzhiyun #define PHY_EXT_PAGE_ACCESS_EXTENDED3	0x3
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun /* Vitesse VSC8574 control register */
41*4882a593Smuzhiyun #define MIIM_VSC8574_MAC_SERDES_CON	0x10
42*4882a593Smuzhiyun #define MIIM_VSC8574_MAC_SERDES_ANEG	0x80
43*4882a593Smuzhiyun #define MIIM_VSC8574_GENERAL18		0x12
44*4882a593Smuzhiyun #define MIIM_VSC8574_GENERAL19		0x13
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun /* Vitesse VSC8574 gerenal purpose register 18 */
47*4882a593Smuzhiyun #define MIIM_VSC8574_18G_SGMII		0x80f0
48*4882a593Smuzhiyun #define MIIM_VSC8574_18G_QSGMII		0x80e0
49*4882a593Smuzhiyun #define MIIM_VSC8574_18G_CMDSTAT	0x8000
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun /* Vitesse VSC8514 control register */
52*4882a593Smuzhiyun #define MIIM_VSC8514_MAC_SERDES_CON     0x10
53*4882a593Smuzhiyun #define MIIM_VSC8514_GENERAL18		0x12
54*4882a593Smuzhiyun #define MIIM_VSC8514_GENERAL19		0x13
55*4882a593Smuzhiyun #define MIIM_VSC8514_GENERAL23		0x17
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun /* Vitesse VSC8514 gerenal purpose register 18 */
58*4882a593Smuzhiyun #define MIIM_VSC8514_18G_QSGMII		0x80e0
59*4882a593Smuzhiyun #define MIIM_VSC8514_18G_CMDSTAT	0x8000
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun /* Vitesse VSC8664 Control/Status Register */
62*4882a593Smuzhiyun #define MIIM_VSC8664_SERDES_AND_SIGDET	0x13
63*4882a593Smuzhiyun #define MIIM_VSC8664_ADDITIONAL_DEV	0x16
64*4882a593Smuzhiyun #define MIIM_VSC8664_EPHY_CON		0x17
65*4882a593Smuzhiyun #define MIIM_VSC8664_LED_CON		0x1E
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun #define PHY_EXT_PAGE_ACCESS_EXTENDED	0x0001
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun /* CIS8201 */
vitesse_config(struct phy_device * phydev)70*4882a593Smuzhiyun static int vitesse_config(struct phy_device *phydev)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun 	/* Override PHY config settings */
73*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT,
74*4882a593Smuzhiyun 			MIIM_CIS82xx_AUXCONSTAT_INIT);
75*4882a593Smuzhiyun 	/* Set up the interface mode */
76*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_EXT_CON1,
77*4882a593Smuzhiyun 			MIIM_CIS8201_EXTCON1_INIT);
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	genphy_config_aneg(phydev);
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	return 0;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun 
vitesse_parse_status(struct phy_device * phydev)84*4882a593Smuzhiyun static int vitesse_parse_status(struct phy_device *phydev)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun 	int speed;
87*4882a593Smuzhiyun 	int mii_reg;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT);
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	if (mii_reg & MIIM_CIS82xx_AUXCONSTAT_DUPLEX)
92*4882a593Smuzhiyun 		phydev->duplex = DUPLEX_FULL;
93*4882a593Smuzhiyun 	else
94*4882a593Smuzhiyun 		phydev->duplex = DUPLEX_HALF;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	speed = mii_reg & MIIM_CIS82xx_AUXCONSTAT_SPEED;
97*4882a593Smuzhiyun 	switch (speed) {
98*4882a593Smuzhiyun 	case MIIM_CIS82xx_AUXCONSTAT_GBIT:
99*4882a593Smuzhiyun 		phydev->speed = SPEED_1000;
100*4882a593Smuzhiyun 		break;
101*4882a593Smuzhiyun 	case MIIM_CIS82xx_AUXCONSTAT_100:
102*4882a593Smuzhiyun 		phydev->speed = SPEED_100;
103*4882a593Smuzhiyun 		break;
104*4882a593Smuzhiyun 	default:
105*4882a593Smuzhiyun 		phydev->speed = SPEED_10;
106*4882a593Smuzhiyun 		break;
107*4882a593Smuzhiyun 	}
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	return 0;
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun 
vitesse_startup(struct phy_device * phydev)112*4882a593Smuzhiyun static int vitesse_startup(struct phy_device *phydev)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun 	int ret;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	ret = genphy_update_link(phydev);
117*4882a593Smuzhiyun 	if (ret)
118*4882a593Smuzhiyun 		return ret;
119*4882a593Smuzhiyun 	return vitesse_parse_status(phydev);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun 
cis8204_config(struct phy_device * phydev)122*4882a593Smuzhiyun static int cis8204_config(struct phy_device *phydev)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun 	/* Override PHY config settings */
125*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT,
126*4882a593Smuzhiyun 			MIIM_CIS82xx_AUXCONSTAT_INIT);
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	genphy_config_aneg(phydev);
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	if (phy_interface_is_rgmii(phydev))
131*4882a593Smuzhiyun 		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS8204_EPHY_CON,
132*4882a593Smuzhiyun 				MIIM_CIS8204_EPHYCON_INIT |
133*4882a593Smuzhiyun 				MIIM_CIS8204_EPHYCON_RGMII);
134*4882a593Smuzhiyun 	else
135*4882a593Smuzhiyun 		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS8204_EPHY_CON,
136*4882a593Smuzhiyun 				MIIM_CIS8204_EPHYCON_INIT);
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	return 0;
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun /* Vitesse VSC8601 */
142*4882a593Smuzhiyun /* This adds a skew for both TX and RX clocks, so the skew should only be
143*4882a593Smuzhiyun  * applied to "rgmii-id" interfaces. It may not work as expected
144*4882a593Smuzhiyun  * on "rgmii-txid", "rgmii-rxid" or "rgmii" interfaces. */
vsc8601_add_skew(struct phy_device * phydev)145*4882a593Smuzhiyun static int vsc8601_add_skew(struct phy_device *phydev)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun 	int ret;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_VSC8601_EPHY_CTL);
150*4882a593Smuzhiyun 	if (ret < 0)
151*4882a593Smuzhiyun 		return ret;
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	ret |= MII_VSC8601_EPHY_CTL_RGMII_SKEW;
154*4882a593Smuzhiyun 	return phy_write(phydev, MDIO_DEVAD_NONE, MII_VSC8601_EPHY_CTL, ret);
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun 
vsc8601_config(struct phy_device * phydev)157*4882a593Smuzhiyun static int vsc8601_config(struct phy_device *phydev)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun 	int ret = 0;
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
162*4882a593Smuzhiyun 		ret = vsc8601_add_skew(phydev);
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	if (ret < 0)
165*4882a593Smuzhiyun 		return ret;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	return genphy_config_aneg(phydev);
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun 
vsc8574_config(struct phy_device * phydev)170*4882a593Smuzhiyun static int vsc8574_config(struct phy_device *phydev)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun 	u32 val;
173*4882a593Smuzhiyun 	/* configure register 19G for MAC */
174*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
175*4882a593Smuzhiyun 		  PHY_EXT_PAGE_ACCESS_GENERAL);
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL19);
178*4882a593Smuzhiyun 	if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
179*4882a593Smuzhiyun 		/* set bit 15:14 to '01' for QSGMII mode */
180*4882a593Smuzhiyun 		val = (val & 0x3fff) | (1 << 14);
181*4882a593Smuzhiyun 		phy_write(phydev, MDIO_DEVAD_NONE,
182*4882a593Smuzhiyun 			  MIIM_VSC8574_GENERAL19, val);
183*4882a593Smuzhiyun 		/* Enable 4 ports MAC QSGMII */
184*4882a593Smuzhiyun 		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18,
185*4882a593Smuzhiyun 			  MIIM_VSC8574_18G_QSGMII);
186*4882a593Smuzhiyun 	} else {
187*4882a593Smuzhiyun 		/* set bit 15:14 to '00' for SGMII mode */
188*4882a593Smuzhiyun 		val = val & 0x3fff;
189*4882a593Smuzhiyun 		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL19, val);
190*4882a593Smuzhiyun 		/* Enable 4 ports MAC SGMII */
191*4882a593Smuzhiyun 		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18,
192*4882a593Smuzhiyun 			  MIIM_VSC8574_18G_SGMII);
193*4882a593Smuzhiyun 	}
194*4882a593Smuzhiyun 	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18);
195*4882a593Smuzhiyun 	/* When bit 15 is cleared the command has completed */
196*4882a593Smuzhiyun 	while (val & MIIM_VSC8574_18G_CMDSTAT)
197*4882a593Smuzhiyun 		val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18);
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	/* Enable Serdes Auto-negotiation */
200*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
201*4882a593Smuzhiyun 		  PHY_EXT_PAGE_ACCESS_EXTENDED3);
202*4882a593Smuzhiyun 	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_MAC_SERDES_CON);
203*4882a593Smuzhiyun 	val = val | MIIM_VSC8574_MAC_SERDES_ANEG;
204*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_MAC_SERDES_CON, val);
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	genphy_config_aneg(phydev);
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	return 0;
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun 
vsc8514_config(struct phy_device * phydev)213*4882a593Smuzhiyun static int vsc8514_config(struct phy_device *phydev)
214*4882a593Smuzhiyun {
215*4882a593Smuzhiyun 	u32 val;
216*4882a593Smuzhiyun 	int timeout = 1000000;
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	/* configure register to access 19G */
219*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
220*4882a593Smuzhiyun 		  PHY_EXT_PAGE_ACCESS_GENERAL);
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL19);
223*4882a593Smuzhiyun 	if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
224*4882a593Smuzhiyun 		/* set bit 15:14 to '01' for QSGMII mode */
225*4882a593Smuzhiyun 		val = (val & 0x3fff) | (1 << 14);
226*4882a593Smuzhiyun 		phy_write(phydev, MDIO_DEVAD_NONE,
227*4882a593Smuzhiyun 			  MIIM_VSC8514_GENERAL19, val);
228*4882a593Smuzhiyun 		/* Enable 4 ports MAC QSGMII */
229*4882a593Smuzhiyun 		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18,
230*4882a593Smuzhiyun 			  MIIM_VSC8514_18G_QSGMII);
231*4882a593Smuzhiyun 	} else {
232*4882a593Smuzhiyun 		/*TODO Add SGMII functionality once spec sheet
233*4882a593Smuzhiyun 		 * for VSC8514 defines complete functionality
234*4882a593Smuzhiyun 		 */
235*4882a593Smuzhiyun 	}
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18);
238*4882a593Smuzhiyun 	/* When bit 15 is cleared the command has completed */
239*4882a593Smuzhiyun 	while ((val & MIIM_VSC8514_18G_CMDSTAT) && timeout--)
240*4882a593Smuzhiyun 		val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18);
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	if (0 == timeout) {
243*4882a593Smuzhiyun 		printf("PHY 8514 config failed\n");
244*4882a593Smuzhiyun 		return -1;
245*4882a593Smuzhiyun 	}
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 	/* configure register to access 23 */
250*4882a593Smuzhiyun 	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL23);
251*4882a593Smuzhiyun 	/* set bits 10:8 to '000' */
252*4882a593Smuzhiyun 	val = (val & 0xf8ff);
253*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL23, val);
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	/* Enable Serdes Auto-negotiation */
256*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
257*4882a593Smuzhiyun 		  PHY_EXT_PAGE_ACCESS_EXTENDED3);
258*4882a593Smuzhiyun 	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_MAC_SERDES_CON);
259*4882a593Smuzhiyun 	val = val | MIIM_VSC8574_MAC_SERDES_ANEG;
260*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_MAC_SERDES_CON, val);
261*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	genphy_config_aneg(phydev);
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	return 0;
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun 
vsc8664_config(struct phy_device * phydev)268*4882a593Smuzhiyun static int vsc8664_config(struct phy_device *phydev)
269*4882a593Smuzhiyun {
270*4882a593Smuzhiyun 	u32 val;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	/* Enable MAC interface auto-negotiation */
273*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
274*4882a593Smuzhiyun 	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8664_EPHY_CON);
275*4882a593Smuzhiyun 	val |= (1 << 13);
276*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8664_EPHY_CON, val);
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
279*4882a593Smuzhiyun 		  PHY_EXT_PAGE_ACCESS_EXTENDED);
280*4882a593Smuzhiyun 	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8664_SERDES_AND_SIGDET);
281*4882a593Smuzhiyun 	val |= (1 << 11);
282*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8664_SERDES_AND_SIGDET, val);
283*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 	/* Enable LED blink */
286*4882a593Smuzhiyun 	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8664_LED_CON);
287*4882a593Smuzhiyun 	val &= ~(1 << 2);
288*4882a593Smuzhiyun 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8664_LED_CON, val);
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	genphy_config_aneg(phydev);
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	return 0;
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun static struct phy_driver VSC8211_driver = {
296*4882a593Smuzhiyun 	.name	= "Vitesse VSC8211",
297*4882a593Smuzhiyun 	.uid	= 0xfc4b0,
298*4882a593Smuzhiyun 	.mask	= 0xffff0,
299*4882a593Smuzhiyun 	.features = PHY_GBIT_FEATURES,
300*4882a593Smuzhiyun 	.config = &vitesse_config,
301*4882a593Smuzhiyun 	.startup = &vitesse_startup,
302*4882a593Smuzhiyun 	.shutdown = &genphy_shutdown,
303*4882a593Smuzhiyun };
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun static struct phy_driver VSC8221_driver = {
306*4882a593Smuzhiyun 	.name = "Vitesse VSC8221",
307*4882a593Smuzhiyun 	.uid = 0xfc550,
308*4882a593Smuzhiyun 	.mask = 0xffff0,
309*4882a593Smuzhiyun 	.features = PHY_GBIT_FEATURES,
310*4882a593Smuzhiyun 	.config = &genphy_config_aneg,
311*4882a593Smuzhiyun 	.startup = &vitesse_startup,
312*4882a593Smuzhiyun 	.shutdown = &genphy_shutdown,
313*4882a593Smuzhiyun };
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun static struct phy_driver VSC8244_driver = {
316*4882a593Smuzhiyun 	.name = "Vitesse VSC8244",
317*4882a593Smuzhiyun 	.uid = 0xfc6c0,
318*4882a593Smuzhiyun 	.mask = 0xffff0,
319*4882a593Smuzhiyun 	.features = PHY_GBIT_FEATURES,
320*4882a593Smuzhiyun 	.config = &genphy_config_aneg,
321*4882a593Smuzhiyun 	.startup = &vitesse_startup,
322*4882a593Smuzhiyun 	.shutdown = &genphy_shutdown,
323*4882a593Smuzhiyun };
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun static struct phy_driver VSC8234_driver = {
326*4882a593Smuzhiyun 	.name = "Vitesse VSC8234",
327*4882a593Smuzhiyun 	.uid = 0xfc620,
328*4882a593Smuzhiyun 	.mask = 0xffff0,
329*4882a593Smuzhiyun 	.features = PHY_GBIT_FEATURES,
330*4882a593Smuzhiyun 	.config = &genphy_config_aneg,
331*4882a593Smuzhiyun 	.startup = &vitesse_startup,
332*4882a593Smuzhiyun 	.shutdown = &genphy_shutdown,
333*4882a593Smuzhiyun };
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun static struct phy_driver VSC8574_driver = {
336*4882a593Smuzhiyun 	.name = "Vitesse VSC8574",
337*4882a593Smuzhiyun 	.uid = 0x704a0,
338*4882a593Smuzhiyun 	.mask = 0xffff0,
339*4882a593Smuzhiyun 	.features = PHY_GBIT_FEATURES,
340*4882a593Smuzhiyun 	.config = &vsc8574_config,
341*4882a593Smuzhiyun 	.startup = &vitesse_startup,
342*4882a593Smuzhiyun 	.shutdown = &genphy_shutdown,
343*4882a593Smuzhiyun };
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun static struct phy_driver VSC8514_driver = {
346*4882a593Smuzhiyun 	.name = "Vitesse VSC8514",
347*4882a593Smuzhiyun 	.uid = 0x70670,
348*4882a593Smuzhiyun 	.mask = 0xffff0,
349*4882a593Smuzhiyun 	.features = PHY_GBIT_FEATURES,
350*4882a593Smuzhiyun 	.config = &vsc8514_config,
351*4882a593Smuzhiyun 	.startup = &vitesse_startup,
352*4882a593Smuzhiyun 	.shutdown = &genphy_shutdown,
353*4882a593Smuzhiyun };
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun static struct phy_driver VSC8584_driver = {
356*4882a593Smuzhiyun 	.name = "Vitesse VSC8584",
357*4882a593Smuzhiyun 	.uid = 0x707c0,
358*4882a593Smuzhiyun 	.mask = 0xffff0,
359*4882a593Smuzhiyun 	.features = PHY_GBIT_FEATURES,
360*4882a593Smuzhiyun 	.config = &vsc8574_config,
361*4882a593Smuzhiyun 	.startup = &vitesse_startup,
362*4882a593Smuzhiyun 	.shutdown = &genphy_shutdown,
363*4882a593Smuzhiyun };
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun static struct phy_driver VSC8601_driver = {
366*4882a593Smuzhiyun 	.name = "Vitesse VSC8601",
367*4882a593Smuzhiyun 	.uid = 0x70420,
368*4882a593Smuzhiyun 	.mask = 0xffff0,
369*4882a593Smuzhiyun 	.features = PHY_GBIT_FEATURES,
370*4882a593Smuzhiyun 	.config = &vsc8601_config,
371*4882a593Smuzhiyun 	.startup = &vitesse_startup,
372*4882a593Smuzhiyun 	.shutdown = &genphy_shutdown,
373*4882a593Smuzhiyun };
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun static struct phy_driver VSC8641_driver = {
376*4882a593Smuzhiyun 	.name = "Vitesse VSC8641",
377*4882a593Smuzhiyun 	.uid = 0x70430,
378*4882a593Smuzhiyun 	.mask = 0xffff0,
379*4882a593Smuzhiyun 	.features = PHY_GBIT_FEATURES,
380*4882a593Smuzhiyun 	.config = &genphy_config_aneg,
381*4882a593Smuzhiyun 	.startup = &vitesse_startup,
382*4882a593Smuzhiyun 	.shutdown = &genphy_shutdown,
383*4882a593Smuzhiyun };
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun static struct phy_driver VSC8662_driver = {
386*4882a593Smuzhiyun 	.name = "Vitesse VSC8662",
387*4882a593Smuzhiyun 	.uid = 0x70660,
388*4882a593Smuzhiyun 	.mask = 0xffff0,
389*4882a593Smuzhiyun 	.features = PHY_GBIT_FEATURES,
390*4882a593Smuzhiyun 	.config = &genphy_config_aneg,
391*4882a593Smuzhiyun 	.startup = &vitesse_startup,
392*4882a593Smuzhiyun 	.shutdown = &genphy_shutdown,
393*4882a593Smuzhiyun };
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun static struct phy_driver VSC8664_driver = {
396*4882a593Smuzhiyun 	.name = "Vitesse VSC8664",
397*4882a593Smuzhiyun 	.uid = 0x70660,
398*4882a593Smuzhiyun 	.mask = 0xffff0,
399*4882a593Smuzhiyun 	.features = PHY_GBIT_FEATURES,
400*4882a593Smuzhiyun 	.config = &vsc8664_config,
401*4882a593Smuzhiyun 	.startup = &vitesse_startup,
402*4882a593Smuzhiyun 	.shutdown = &genphy_shutdown,
403*4882a593Smuzhiyun };
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun /* Vitesse bought Cicada, so we'll put these here */
406*4882a593Smuzhiyun static struct phy_driver cis8201_driver = {
407*4882a593Smuzhiyun 	.name = "CIS8201",
408*4882a593Smuzhiyun 	.uid = 0xfc410,
409*4882a593Smuzhiyun 	.mask = 0xffff0,
410*4882a593Smuzhiyun 	.features = PHY_GBIT_FEATURES,
411*4882a593Smuzhiyun 	.config = &vitesse_config,
412*4882a593Smuzhiyun 	.startup = &vitesse_startup,
413*4882a593Smuzhiyun 	.shutdown = &genphy_shutdown,
414*4882a593Smuzhiyun };
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun static struct phy_driver cis8204_driver = {
417*4882a593Smuzhiyun 	.name = "Cicada Cis8204",
418*4882a593Smuzhiyun 	.uid = 0xfc440,
419*4882a593Smuzhiyun 	.mask = 0xffff0,
420*4882a593Smuzhiyun 	.features = PHY_GBIT_FEATURES,
421*4882a593Smuzhiyun 	.config = &cis8204_config,
422*4882a593Smuzhiyun 	.startup = &vitesse_startup,
423*4882a593Smuzhiyun 	.shutdown = &genphy_shutdown,
424*4882a593Smuzhiyun };
425*4882a593Smuzhiyun 
phy_vitesse_init(void)426*4882a593Smuzhiyun int phy_vitesse_init(void)
427*4882a593Smuzhiyun {
428*4882a593Smuzhiyun 	phy_register(&VSC8641_driver);
429*4882a593Smuzhiyun 	phy_register(&VSC8601_driver);
430*4882a593Smuzhiyun 	phy_register(&VSC8234_driver);
431*4882a593Smuzhiyun 	phy_register(&VSC8244_driver);
432*4882a593Smuzhiyun 	phy_register(&VSC8211_driver);
433*4882a593Smuzhiyun 	phy_register(&VSC8221_driver);
434*4882a593Smuzhiyun 	phy_register(&VSC8574_driver);
435*4882a593Smuzhiyun 	phy_register(&VSC8584_driver);
436*4882a593Smuzhiyun 	phy_register(&VSC8514_driver);
437*4882a593Smuzhiyun 	phy_register(&VSC8662_driver);
438*4882a593Smuzhiyun 	phy_register(&VSC8664_driver);
439*4882a593Smuzhiyun 	phy_register(&cis8201_driver);
440*4882a593Smuzhiyun 	phy_register(&cis8204_driver);
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 	return 0;
443*4882a593Smuzhiyun }
444