xref: /rk3399_rockchip-uboot/drivers/net/phy/generic_10g.c (revision 5f184715ecd31bfcb8d09ba2d9f14adfa172a141)
1*5f184715SAndy Fleming /*
2*5f184715SAndy Fleming  * Generic PHY Management code
3*5f184715SAndy Fleming  *
4*5f184715SAndy Fleming  * This program is free software; you can redistribute it and/or
5*5f184715SAndy Fleming  * modify it under the terms of the GNU General Public License as
6*5f184715SAndy Fleming  * published by the Free Software Foundation; either version 2 of
7*5f184715SAndy Fleming  * the License, or (at your option) any later version.
8*5f184715SAndy Fleming  *
9*5f184715SAndy Fleming  * This program is distributed in the hope that it will be useful,
10*5f184715SAndy Fleming  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*5f184715SAndy Fleming  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12*5f184715SAndy Fleming  * GNU General Public License for more details.
13*5f184715SAndy Fleming  *
14*5f184715SAndy Fleming  * You should have received a copy of the GNU General Public License
15*5f184715SAndy Fleming  * along with this program; if not, write to the Free Software
16*5f184715SAndy Fleming  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17*5f184715SAndy Fleming  * MA 02111-1307 USA
18*5f184715SAndy Fleming  *
19*5f184715SAndy Fleming  *
20*5f184715SAndy Fleming  * Copyright 2011 Freescale Semiconductor, Inc.
21*5f184715SAndy Fleming  * author Andy Fleming
22*5f184715SAndy Fleming  *
23*5f184715SAndy Fleming  * Based loosely off of Linux's PHY Lib
24*5f184715SAndy Fleming  */
25*5f184715SAndy Fleming 
26*5f184715SAndy Fleming #include <config.h>
27*5f184715SAndy Fleming #include <common.h>
28*5f184715SAndy Fleming #include <miiphy.h>
29*5f184715SAndy Fleming #include <phy.h>
30*5f184715SAndy Fleming 
31*5f184715SAndy Fleming int gen10g_shutdown(struct phy_device *phydev)
32*5f184715SAndy Fleming {
33*5f184715SAndy Fleming 	return 0;
34*5f184715SAndy Fleming }
35*5f184715SAndy Fleming 
36*5f184715SAndy Fleming int gen10g_startup(struct phy_device *phydev)
37*5f184715SAndy Fleming {
38*5f184715SAndy Fleming 	int devad, reg;
39*5f184715SAndy Fleming 	u32 mmd_mask = phydev->mmds;
40*5f184715SAndy Fleming 
41*5f184715SAndy Fleming 	phydev->link = 1;
42*5f184715SAndy Fleming 
43*5f184715SAndy Fleming 	/* For now just lie and say it's 10G all the time */
44*5f184715SAndy Fleming 	phydev->speed = SPEED_10000;
45*5f184715SAndy Fleming 	phydev->duplex = DUPLEX_FULL;
46*5f184715SAndy Fleming 
47*5f184715SAndy Fleming 	for (devad = 0; mmd_mask; devad++, mmd_mask = mmd_mask >> 1) {
48*5f184715SAndy Fleming 		if (!mmd_mask & 1)
49*5f184715SAndy Fleming 			continue;
50*5f184715SAndy Fleming 
51*5f184715SAndy Fleming 		/* Read twice because link state is latched and a
52*5f184715SAndy Fleming 		 * read moves the current state into the register */
53*5f184715SAndy Fleming 		phy_read(phydev, devad, MDIO_STAT1);
54*5f184715SAndy Fleming 		reg = phy_read(phydev, devad, MDIO_STAT1);
55*5f184715SAndy Fleming 		if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS))
56*5f184715SAndy Fleming 			phydev->link = 0;
57*5f184715SAndy Fleming 	}
58*5f184715SAndy Fleming 
59*5f184715SAndy Fleming 	return 0;
60*5f184715SAndy Fleming }
61*5f184715SAndy Fleming 
62*5f184715SAndy Fleming int gen10g_discover_mmds(struct phy_device *phydev)
63*5f184715SAndy Fleming {
64*5f184715SAndy Fleming 	int mmd, stat2, devs1, devs2;
65*5f184715SAndy Fleming 
66*5f184715SAndy Fleming 	/* Assume PHY must have at least one of PMA/PMD, WIS, PCS, PHY
67*5f184715SAndy Fleming 	 * XS or DTE XS; give up if none is present. */
68*5f184715SAndy Fleming 	for (mmd = 1; mmd <= 5; mmd++) {
69*5f184715SAndy Fleming 		/* Is this MMD present? */
70*5f184715SAndy Fleming 		stat2 = phy_read(phydev, mmd, MDIO_STAT2);
71*5f184715SAndy Fleming 		if (stat2 < 0 ||
72*5f184715SAndy Fleming 			(stat2 & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL)
73*5f184715SAndy Fleming 			continue;
74*5f184715SAndy Fleming 
75*5f184715SAndy Fleming 		/* It should tell us about all the other MMDs */
76*5f184715SAndy Fleming 		devs1 = phy_read(phydev, mmd, MDIO_DEVS1);
77*5f184715SAndy Fleming 		devs2 = phy_read(phydev, mmd, MDIO_DEVS2);
78*5f184715SAndy Fleming 		if (devs1 < 0 || devs2 < 0)
79*5f184715SAndy Fleming 			continue;
80*5f184715SAndy Fleming 
81*5f184715SAndy Fleming 		phydev->mmds = devs1 | (devs2 << 16);
82*5f184715SAndy Fleming 		return 0;
83*5f184715SAndy Fleming 	}
84*5f184715SAndy Fleming 
85*5f184715SAndy Fleming 	return 0;
86*5f184715SAndy Fleming }
87*5f184715SAndy Fleming 
88*5f184715SAndy Fleming int gen10g_config(struct phy_device *phydev)
89*5f184715SAndy Fleming {
90*5f184715SAndy Fleming 	/* For now, assume 10000baseT. Fill in later */
91*5f184715SAndy Fleming 	phydev->supported = phydev->advertising = SUPPORTED_10000baseT_Full;
92*5f184715SAndy Fleming 
93*5f184715SAndy Fleming 	return gen10g_discover_mmds(phydev);
94*5f184715SAndy Fleming }
95*5f184715SAndy Fleming 
96*5f184715SAndy Fleming struct phy_driver gen10g_driver = {
97*5f184715SAndy Fleming 	.uid		= 0xffffffff,
98*5f184715SAndy Fleming 	.mask		= 0xffffffff,
99*5f184715SAndy Fleming 	.name		= "Generic 10G PHY",
100*5f184715SAndy Fleming 	.features	= 0,
101*5f184715SAndy Fleming 	.config		= gen10g_config,
102*5f184715SAndy Fleming 	.startup	= gen10g_startup,
103*5f184715SAndy Fleming 	.shutdown	= gen10g_shutdown,
104*5f184715SAndy Fleming };
105*5f184715SAndy Fleming 
106