1/*
2 * @TAG(OTHER_GPL)
3 */
4
5/*
6 * Copyright 2011 Freescale Semiconductor, Inc.
7 *	Andy Fleming <afleming@freescale.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 */
24
25/*
26 * This file derived from Linux's mii.h/ethtool.h/phy.h
27 */
28
29#pragma once
30
31#include "list.h"
32#include <stdio.h>
33#include "mii.h"
34#include "ethtool.h"
35#include "mdio.h"
36
37#define PHY_MAX_ADDR 32
38
39#define PHY_BASIC_FEATURES	(SUPPORTED_10baseT_Half | \
40				 SUPPORTED_10baseT_Full | \
41				 SUPPORTED_100baseT_Half | \
42				 SUPPORTED_100baseT_Full | \
43				 SUPPORTED_Autoneg | \
44				 SUPPORTED_TP | \
45				 SUPPORTED_MII)
46
47#define PHY_GBIT_FEATURES	(PHY_BASIC_FEATURES | \
48				 SUPPORTED_1000baseT_Half | \
49				 SUPPORTED_1000baseT_Full)
50
51#define PHY_10G_FEATURES	(PHY_GBIT_FEATURES | \
52				SUPPORTED_10000baseT_Full)
53
54#define PHY_ANEG_TIMEOUT	40000
55
56typedef enum {
57	PHY_INTERFACE_MODE_MII,
58	PHY_INTERFACE_MODE_GMII,
59	PHY_INTERFACE_MODE_SGMII,
60	PHY_INTERFACE_MODE_TBI,
61	PHY_INTERFACE_MODE_RMII,
62	PHY_INTERFACE_MODE_RGMII,
63	PHY_INTERFACE_MODE_RGMII_ID,
64	PHY_INTERFACE_MODE_RGMII_RXID,
65	PHY_INTERFACE_MODE_RGMII_TXID,
66	PHY_INTERFACE_MODE_RTBI,
67	PHY_INTERFACE_MODE_XGMII,
68	PHY_INTERFACE_MODE_NONE	/* Must be last */
69} phy_interface_t;
70
71static const char *phy_interface_strings[] = {
72	[PHY_INTERFACE_MODE_MII]		= "mii",
73	[PHY_INTERFACE_MODE_GMII]		= "gmii",
74	[PHY_INTERFACE_MODE_SGMII]		= "sgmii",
75	[PHY_INTERFACE_MODE_TBI]		= "tbi",
76	[PHY_INTERFACE_MODE_RMII]		= "rmii",
77	[PHY_INTERFACE_MODE_RGMII]		= "rgmii",
78	[PHY_INTERFACE_MODE_RGMII_ID]		= "rgmii-id",
79	[PHY_INTERFACE_MODE_RGMII_RXID]		= "rgmii-rxid",
80	[PHY_INTERFACE_MODE_RGMII_TXID]		= "rgmii-txid",
81	[PHY_INTERFACE_MODE_RTBI]		= "rtbi",
82	[PHY_INTERFACE_MODE_XGMII]		= "xgmii",
83	[PHY_INTERFACE_MODE_NONE]		= "",
84};
85
86static inline const char *phy_string_for_interface(phy_interface_t i)
87{
88	/* Default to unknown */
89	if (i > PHY_INTERFACE_MODE_NONE)
90		i = PHY_INTERFACE_MODE_NONE;
91
92	return phy_interface_strings[i];
93}
94
95struct phy_device;
96
97#define MDIO_NAME_LEN 32
98
99struct mii_dev {
100	struct list_head link;
101	char name[MDIO_NAME_LEN];
102	void *priv;
103	int (*read)(struct mii_dev *bus, int addr, int devad, int reg);
104	int (*write)(struct mii_dev *bus, int addr, int devad, int reg,
105			uint16_t val);
106	int (*reset)(struct mii_dev *bus);
107	struct phy_device *phymap[PHY_MAX_ADDR];
108	uint32_t phy_mask;
109};
110
111/* struct phy_driver: a structure which defines PHY behavior
112 *
113 * uid will contain a number which represents the PHY.  During
114 * startup, the driver will poll the PHY to find out what its
115 * UID--as defined by registers 2 and 3--is.  The 32-bit result
116 * gotten from the PHY will be masked to
117 * discard any bits which may change based on revision numbers
118 * unimportant to functionality
119 *
120 */
121struct phy_driver {
122	char *name;
123	unsigned int uid;
124	unsigned int mask;
125	unsigned int mmds;
126
127	uint32_t features;
128
129	/* Called to do any driver startup necessities */
130	/* Will be called during phy_connect */
131	int (*probe)(struct phy_device *phydev);
132
133	/* Called to configure the PHY, and modify the controller
134	 * based on the results.  Should be called after phy_connect */
135	int (*config)(struct phy_device *phydev);
136
137	/* Called when starting up the controller */
138	int (*startup)(struct phy_device *phydev);
139
140	/* Called when bringing down the controller */
141	int (*shutdown)(struct phy_device *phydev);
142
143	struct list_head list;
144};
145
146struct phy_device {
147	/* Information about the PHY type */
148	/* And management functions */
149	struct mii_dev *bus;
150	struct phy_driver *drv;
151	void *priv;
152
153	struct eth_device *dev;
154
155	/* forced speed & duplex (no autoneg)
156	 * partner speed & duplex & pause (autoneg)
157	 */
158	int speed;
159	int duplex;
160
161	/* The most recently read link state */
162	int link;
163	int port;
164	phy_interface_t interface;
165
166	uint32_t advertising;
167	uint32_t supported;
168	uint32_t mmds;
169
170	int autoneg;
171	int addr;
172	int pause;
173	int asym_pause;
174	uint32_t phy_id;
175	uint32_t flags;
176};
177
178static inline int phy_read(struct phy_device *phydev, int devad, int regnum)
179{
180	struct mii_dev *bus = phydev->bus;
181
182	return bus->read(bus, phydev->addr, devad, regnum);
183}
184
185static inline int phy_write(struct phy_device *phydev, int devad, int regnum,
186			uint16_t val)
187{
188	struct mii_dev *bus = phydev->bus;
189
190	return bus->write(bus, phydev->addr, devad, regnum, val);
191}
192
193#ifdef CONFIG_PHYLIB_10G
194extern struct phy_driver gen10g_driver;
195
196/* For now, XGMII is the only 10G interface */
197static inline int is_10g_interface(phy_interface_t interface)
198{
199	return interface == PHY_INTERFACE_MODE_XGMII;
200}
201
202#endif
203
204int phy_init(void);
205int phy_reset(struct phy_device *phydev);
206struct phy_device *phy_connect(struct mii_dev *bus, int addr,
207				struct eth_device *dev,
208				phy_interface_t interface);
209struct phy_device *phy_connect_by_mask(struct mii_dev *bus, unsigned phy_mask,
210		struct eth_device *dev, phy_interface_t interface);
211int phy_startup(struct phy_device *phydev);
212int phy_config(struct phy_device *phydev);
213int phy_shutdown(struct phy_device *phydev);
214int phy_register(struct phy_driver *drv);
215int genphy_config_aneg(struct phy_device *phydev);
216int genphy_restart_aneg(struct phy_device *phydev);
217int genphy_update_link(struct phy_device *phydev);
218int genphy_config(struct phy_device *phydev);
219int genphy_startup(struct phy_device *phydev);
220int genphy_shutdown(struct phy_device *phydev);
221int gen10g_config(struct phy_device *phydev);
222int gen10g_startup(struct phy_device *phydev);
223int gen10g_shutdown(struct phy_device *phydev);
224int gen10g_discover_mmds(struct phy_device *phydev);
225
226int phy_atheros_init(void);
227int phy_broadcom_init(void);
228int phy_davicom_init(void);
229int phy_lxt_init(void);
230int phy_marvell_init(void);
231int phy_micrel_init(void);
232int phy_natsemi_init(void);
233int phy_realtek_init(void);
234int phy_smsc_init(void);
235int phy_teranetics_init(void);
236int phy_vitesse_init(void);
237
238/* PHY UIDs for various PHYs that are referenced in external code */
239#define PHY_UID_TN2020	0x00a19410
240
241