1/*
2 * drivers/net/ibm_emac/ibm_emac_phy.c
3 *
4 * Driver for PowerPC 4xx on-chip ethernet controller, PHY support.
5 * Borrowed from sungem_phy.c, though I only kept the generic MII
6 * driver for now.
7 *
8 * This file should be shared with other drivers or eventually
9 * merged as the "low level" part of miilib
10 *
11 * (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org)
12 * (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net>
13 *
14 */
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/types.h>
18#include <linux/netdevice.h>
19#include <linux/mii.h>
20#include <linux/ethtool.h>
21#include <linux/delay.h>
22
23#include <asm/ocp.h>
24
25#include "ibm_emac_core.h"
26#include "ibm_emac_phy.h"
27
28static inline int phy_read(struct mii_phy *phy, int reg)
29{
30	return phy->mdio_read(phy->dev, phy->address, reg);
31}
32
33static inline void phy_write(struct mii_phy *phy, int reg, int val)
34{
35	phy->mdio_write(phy->dev, phy->address, reg, val);
36}
37
38/*
39 * polls MII_BMCR until BMCR_RESET bit clears or operation times out.
40 *
41 * returns:
42 *	>= 0 => success, value in BMCR returned to caller
43 *	-EBUSY => failure, RESET bit never cleared
44 *	otherwise => failure, lower level PHY read failed
45 */
46static int mii_spin_reset_complete(struct mii_phy *phy)
47{
48	int val;
49	int limit = 10000;
50
51	while (limit--) {
52		val = phy_read(phy, MII_BMCR);
53		if (val >= 0 && !(val & BMCR_RESET))
54			return val;	/* success */
55		udelay(10);
56	}
57	if (val & BMCR_RESET)
58		val = -EBUSY;
59
60	if (net_ratelimit())
61		printk(KERN_ERR "emac%d: PHY reset timeout (%d)\n",
62		       ((struct ocp_enet_private *)phy->dev->priv)->def->index,
63		       val);
64	return val;
65}
66
67int mii_reset_phy(struct mii_phy *phy)
68{
69	int val;
70
71	val = phy_read(phy, MII_BMCR);
72	val &= ~BMCR_ISOLATE;
73	val |= BMCR_RESET;
74	phy_write(phy, MII_BMCR, val);
75
76	udelay(300);
77
78	val = mii_spin_reset_complete(phy);
79	if (val >= 0 && (val & BMCR_ISOLATE))
80		phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
81
82	return val < 0;
83}
84
85static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
86{
87	int ctl, adv;
88
89	phy->autoneg = AUTONEG_ENABLE;
90	phy->speed = SPEED_10;
91	phy->duplex = DUPLEX_HALF;
92	phy->pause = phy->asym_pause = 0;
93	phy->advertising = advertise;
94
95	/* Setup standard advertise */
96	adv = phy_read(phy, MII_ADVERTISE);
97	if (adv < 0)
98		return adv;
99	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
100		 ADVERTISE_PAUSE_ASYM);
101	if (advertise & ADVERTISED_10baseT_Half)
102		adv |= ADVERTISE_10HALF;
103	if (advertise & ADVERTISED_10baseT_Full)
104		adv |= ADVERTISE_10FULL;
105	if (advertise & ADVERTISED_100baseT_Half)
106		adv |= ADVERTISE_100HALF;
107	if (advertise & ADVERTISED_100baseT_Full)
108		adv |= ADVERTISE_100FULL;
109	if (advertise & ADVERTISED_Pause)
110		adv |= ADVERTISE_PAUSE_CAP;
111	if (advertise & ADVERTISED_Asym_Pause)
112		adv |= ADVERTISE_PAUSE_ASYM;
113	phy_write(phy, MII_ADVERTISE, adv);
114
115	if (phy->features &
116	    (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
117		adv = phy_read(phy, MII_CTRL1000);
118		if (adv < 0)
119			return adv;
120		adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
121		if (advertise & ADVERTISED_1000baseT_Full)
122			adv |= ADVERTISE_1000FULL;
123		if (advertise & ADVERTISED_1000baseT_Half)
124			adv |= ADVERTISE_1000HALF;
125		phy_write(phy, MII_CTRL1000, adv);
126	}
127
128	/* Start/Restart aneg */
129	/* on some PHYs (e.g. National DP83843) a write to MII_ADVERTISE
130	 * causes BMCR_RESET to be set on the next read of MII_BMCR, which
131	 * if not checked for causes the PHY to be reset below */
132	ctl = mii_spin_reset_complete(phy);
133	if (ctl < 0)
134		return ctl;
135
136	ctl |= BMCR_ANENABLE | BMCR_ANRESTART;
137	phy_write(phy, MII_BMCR, ctl);
138
139	return 0;
140}
141
142static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
143{
144	int ctl;
145
146	phy->autoneg = AUTONEG_DISABLE;
147	phy->speed = speed;
148	phy->duplex = fd;
149	phy->pause = phy->asym_pause = 0;
150
151	/* First reset the PHY */
152	mii_reset_phy(phy);
153
154	ctl = phy_read(phy, MII_BMCR);
155	if (ctl < 0)
156		return ctl;
157	ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE | BMCR_SPEED1000);
158
159	/* Select speed & duplex */
160	switch (speed) {
161	case SPEED_10:
162		break;
163	case SPEED_100:
164		ctl |= BMCR_SPEED100;
165		break;
166	case SPEED_1000:
167		ctl |= BMCR_SPEED1000;
168		break;
169	default:
170		return -EINVAL;
171	}
172	if (fd == DUPLEX_FULL)
173		ctl |= BMCR_FULLDPLX;
174	phy_write(phy, MII_BMCR, ctl);
175
176	return 0;
177}
178
179static int genmii_poll_link(struct mii_phy *phy)
180{
181	int status;
182
183	/* Clear latched value with dummy read */
184	phy_read(phy, MII_BMSR);
185	status = phy_read(phy, MII_BMSR);
186	if (status < 0 || (status & BMSR_LSTATUS) == 0)
187		return 0;
188	if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE))
189		return 0;
190	return 1;
191}
192
193static int genmii_read_link(struct mii_phy *phy)
194{
195	if (phy->autoneg == AUTONEG_ENABLE) {
196		int glpa = 0;
197		int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
198		if (lpa < 0)
199			return lpa;
200
201		if (phy->features &
202		    (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
203			int adv = phy_read(phy, MII_CTRL1000);
204			glpa = phy_read(phy, MII_STAT1000);
205
206			if (glpa < 0 || adv < 0)
207				return adv;
208
209			glpa &= adv << 2;
210		}
211
212		phy->speed = SPEED_10;
213		phy->duplex = DUPLEX_HALF;
214		phy->pause = phy->asym_pause = 0;
215
216		if (glpa & (LPA_1000FULL | LPA_1000HALF)) {
217			phy->speed = SPEED_1000;
218			if (glpa & LPA_1000FULL)
219				phy->duplex = DUPLEX_FULL;
220		} else if (lpa & (LPA_100FULL | LPA_100HALF)) {
221			phy->speed = SPEED_100;
222			if (lpa & LPA_100FULL)
223				phy->duplex = DUPLEX_FULL;
224		} else if (lpa & LPA_10FULL)
225			phy->duplex = DUPLEX_FULL;
226
227		if (phy->duplex == DUPLEX_FULL) {
228			phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
229			phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
230		}
231	} else {
232		int bmcr = phy_read(phy, MII_BMCR);
233		if (bmcr < 0)
234			return bmcr;
235
236		if (bmcr & BMCR_FULLDPLX)
237			phy->duplex = DUPLEX_FULL;
238		else
239			phy->duplex = DUPLEX_HALF;
240		if (bmcr & BMCR_SPEED1000)
241			phy->speed = SPEED_1000;
242		else if (bmcr & BMCR_SPEED100)
243			phy->speed = SPEED_100;
244		else
245			phy->speed = SPEED_10;
246
247		phy->pause = phy->asym_pause = 0;
248	}
249	return 0;
250}
251
252/* Generic implementation for most 10/100/1000 PHYs */
253static struct mii_phy_ops generic_phy_ops = {
254	.setup_aneg	= genmii_setup_aneg,
255	.setup_forced	= genmii_setup_forced,
256	.poll_link	= genmii_poll_link,
257	.read_link	= genmii_read_link
258};
259
260static struct mii_phy_def genmii_phy_def = {
261	.phy_id		= 0x00000000,
262	.phy_id_mask	= 0x00000000,
263	.name		= "Generic MII",
264	.ops		= &generic_phy_ops
265};
266
267/* CIS8201 */
268#define MII_CIS8201_10BTCSR	0x16
269#define  TENBTCSR_ECHO_DISABLE	0x2000
270#define MII_CIS8201_EPCR	0x17
271#define  EPCR_MODE_MASK		0x3000
272#define  EPCR_GMII_MODE		0x0000
273#define  EPCR_RGMII_MODE	0x1000
274#define  EPCR_TBI_MODE		0x2000
275#define  EPCR_RTBI_MODE		0x3000
276#define MII_CIS8201_ACSR	0x1c
277#define  ACSR_PIN_PRIO_SELECT	0x0004
278
279static int cis8201_init(struct mii_phy *phy)
280{
281	int epcr;
282
283	epcr = phy_read(phy, MII_CIS8201_EPCR);
284	if (epcr < 0)
285		return epcr;
286
287	epcr &= ~EPCR_MODE_MASK;
288
289	switch (phy->mode) {
290	case PHY_MODE_TBI:
291		epcr |= EPCR_TBI_MODE;
292		break;
293	case PHY_MODE_RTBI:
294		epcr |= EPCR_RTBI_MODE;
295		break;
296	case PHY_MODE_GMII:
297		epcr |= EPCR_GMII_MODE;
298		break;
299	case PHY_MODE_RGMII:
300	default:
301		epcr |= EPCR_RGMII_MODE;
302	}
303
304	phy_write(phy, MII_CIS8201_EPCR, epcr);
305
306	/* MII regs override strap pins */
307	phy_write(phy, MII_CIS8201_ACSR,
308		  phy_read(phy, MII_CIS8201_ACSR) | ACSR_PIN_PRIO_SELECT);
309
310	/* Disable TX_EN -> CRS echo mode, otherwise 10/HDX doesn't work */
311	phy_write(phy, MII_CIS8201_10BTCSR,
312		  phy_read(phy, MII_CIS8201_10BTCSR) | TENBTCSR_ECHO_DISABLE);
313
314	return 0;
315}
316
317static struct mii_phy_ops cis8201_phy_ops = {
318	.init		= cis8201_init,
319	.setup_aneg	= genmii_setup_aneg,
320	.setup_forced	= genmii_setup_forced,
321	.poll_link	= genmii_poll_link,
322	.read_link	= genmii_read_link
323};
324
325static struct mii_phy_def cis8201_phy_def = {
326	.phy_id		= 0x000fc410,
327	.phy_id_mask	= 0x000ffff0,
328	.name		= "CIS8201 Gigabit Ethernet",
329	.ops		= &cis8201_phy_ops
330};
331
332static struct mii_phy_def *mii_phy_table[] = {
333	&cis8201_phy_def,
334	&genmii_phy_def,
335	NULL
336};
337
338int mii_phy_probe(struct mii_phy *phy, int address)
339{
340	struct mii_phy_def *def;
341	int i;
342	int id;
343
344	phy->autoneg = AUTONEG_DISABLE;
345	phy->advertising = 0;
346	phy->address = address;
347	phy->speed = SPEED_10;
348	phy->duplex = DUPLEX_HALF;
349	phy->pause = phy->asym_pause = 0;
350
351	/* Take PHY out of isolate mode and reset it. */
352	if (mii_reset_phy(phy))
353		return -ENODEV;
354
355	/* Read ID and find matching entry */
356	id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2);
357	if (id < 0)
358		return -ENODEV;
359	for (i = 0; (def = mii_phy_table[i]) != NULL; i++)
360		if ((id & def->phy_id_mask) == def->phy_id)
361			break;
362	/* Should never be NULL (we have a generic entry), but... */
363	if (!def)
364		return -ENODEV;
365
366	phy->def = def;
367
368	/* Determine PHY features if needed */
369	phy->features = def->features;
370	if (!phy->features) {
371		u16 bmsr = phy_read(phy, MII_BMSR);
372		if (bmsr & BMSR_ANEGCAPABLE)
373			phy->features |= SUPPORTED_Autoneg;
374		if (bmsr & BMSR_10HALF)
375			phy->features |= SUPPORTED_10baseT_Half;
376		if (bmsr & BMSR_10FULL)
377			phy->features |= SUPPORTED_10baseT_Full;
378		if (bmsr & BMSR_100HALF)
379			phy->features |= SUPPORTED_100baseT_Half;
380		if (bmsr & BMSR_100FULL)
381			phy->features |= SUPPORTED_100baseT_Full;
382		if (bmsr & BMSR_ESTATEN) {
383			u16 esr = phy_read(phy, MII_ESTATUS);
384			if (esr & ESTATUS_1000_TFULL)
385				phy->features |= SUPPORTED_1000baseT_Full;
386			if (esr & ESTATUS_1000_THALF)
387				phy->features |= SUPPORTED_1000baseT_Half;
388		}
389		phy->features |= SUPPORTED_MII;
390	}
391
392	/* Setup default advertising */
393	phy->advertising = phy->features;
394
395	return 0;
396}
397
398MODULE_LICENSE("GPL");
399