1/*
2 * @TAG(OTHER_GPL)
3 */
4
5/*
6 * (C) Copyright 2001
7 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
8 *
9 * See file CREDITS for list of people who contributed to this
10 * project.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 * MA 02111-1307 USA
26 */
27
28/*
29 * This provides a bit-banged interface to the ethernet MII management
30 * channel.
31 */
32
33#include "common.h"
34#include "miiphy.h"
35#include "phy.h"
36
37#include "list.h"
38#include "fec_mxc.h"
39#include <stdlib.h>
40#include <string.h>
41#include "../unimplemented.h"
42
43#define BUG_ON(x) do {} while(0)
44
45/* local debug macro */
46#undef MII_DEBUG
47
48#undef debug
49#ifdef MII_DEBUG
50#define debug(fmt, args...)	printf(fmt, ##args)
51#else
52#define debug(fmt, args...)
53#endif /* MII_DEBUG */
54
55static struct list_head mii_devs;
56static struct mii_dev *current_mii;
57
58/*
59 * Lookup the mii_dev struct by the registered device name.
60 */
61struct mii_dev *miiphy_get_dev_by_name(const char *devname)
62{
63	struct list_head *entry;
64	struct mii_dev *dev;
65
66	if (!devname) {
67		printf("NULL device name!\n");
68		return NULL;
69	}
70
71	list_for_each(entry, &mii_devs) {
72		dev = list_entry(entry, struct mii_dev, link);
73		if (strcmp(dev->name, devname) == 0)
74			return dev;
75	}
76
77	return NULL;
78}
79
80/*****************************************************************************
81 *
82 * Initialize global data. Need to be called before any other miiphy routine.
83 */
84void miiphy_init(void)
85{
86	mii_devs.next = &mii_devs;
87	mii_devs.prev = &mii_devs;
88	current_mii = NULL;
89}
90
91static int legacy_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
92{
93	unsigned short val;
94	int ret;
95	struct legacy_mii_dev *ldev = bus->priv;
96
97	ret = ldev->read(bus->name, addr, reg, &val);
98
99	return ret ? -1 : (int)val;
100}
101
102static int legacy_miiphy_write(struct mii_dev *bus, int addr, int devad,
103				int reg, u16 val)
104{
105	struct legacy_mii_dev *ldev = bus->priv;
106
107	return ldev->write(bus->name, addr, reg, val);
108}
109
110/*****************************************************************************
111 *
112 * Register read and write MII access routines for the device <name>.
113 * This API is now deprecated. Please use mdio_alloc and mdio_register, instead.
114 */
115void miiphy_register(const char *name,
116		      int (*read)(const char *devname, unsigned char addr,
117				   unsigned char reg, unsigned short *value),
118		      int (*write)(const char *devname, unsigned char addr,
119				    unsigned char reg, unsigned short value))
120{
121	struct mii_dev *new_dev;
122	struct legacy_mii_dev *ldev;
123
124	BUG_ON(strlen(name) >= MDIO_NAME_LEN);
125
126	/* check if we have unique name */
127	new_dev = miiphy_get_dev_by_name(name);
128	if (new_dev) {
129		printf("miiphy_register: non unique device name '%s'\n", name);
130		return;
131	}
132
133	/* allocate memory */
134	new_dev = mdio_alloc();
135	ldev = malloc(sizeof(*ldev));
136
137	if (new_dev == NULL || ldev == NULL) {
138		printf("miiphy_register: cannot allocate memory for '%s'\n",
139			name);
140		return;
141	}
142
143	/* initalize mii_dev struct fields */
144	new_dev->read = legacy_miiphy_read;
145	new_dev->write = legacy_miiphy_write;
146	strncpy(new_dev->name, name, MDIO_NAME_LEN);
147	new_dev->name[MDIO_NAME_LEN - 1] = 0;
148	ldev->read = read;
149	ldev->write = write;
150	new_dev->priv = ldev;
151
152	debug("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n",
153	       new_dev->name, ldev->read, ldev->write);
154
155	/* add it to the list */
156	list_add_tail(&new_dev->link, &mii_devs);
157
158	if (!current_mii)
159		current_mii = new_dev;
160}
161
162struct mii_dev *mdio_alloc(void)
163{
164	struct mii_dev *bus;
165
166	bus = malloc(sizeof(*bus));
167	if (!bus)
168		return bus;
169
170	memset(bus, 0, sizeof(*bus));
171
172	/* initalize mii_dev struct fields */
173	INIT_LIST_HEAD(&bus->link);
174
175	return bus;
176}
177
178int mdio_register(struct mii_dev *bus)
179{
180	if (!bus || !bus->name || !bus->read || !bus->write)
181		return -1;
182
183	/* check if we have unique name */
184	if (miiphy_get_dev_by_name(bus->name)) {
185		printf("mdio_register: non unique device name '%s'\n",
186			bus->name);
187		return -1;
188	}
189
190	/* add it to the list */
191	list_add_tail(&bus->link, &mii_devs);
192
193	if (!current_mii)
194		current_mii = bus;
195
196	return 0;
197}
198
199void mdio_list_devices(void)
200{
201	struct list_head *entry;
202
203	list_for_each(entry, &mii_devs) {
204		int i;
205		struct mii_dev *bus = list_entry(entry, struct mii_dev, link);
206
207		printf("%s:\n", bus->name);
208
209		for (i = 0; i < PHY_MAX_ADDR; i++) {
210			struct phy_device *phydev = bus->phymap[i];
211
212			if (phydev) {
213				printf("%d - %s", i, phydev->drv->name);
214
215				if (phydev->dev)
216					printf(" <--> %s\n", phydev->dev->name);
217				else
218					printf("\n");
219			}
220		}
221	}
222}
223
224int miiphy_set_current_dev(const char *devname)
225{
226	struct mii_dev *dev;
227
228	dev = miiphy_get_dev_by_name(devname);
229	if (dev) {
230		current_mii = dev;
231		return 0;
232	}
233
234	printf("No such device: %s\n", devname);
235
236	return 1;
237}
238
239struct mii_dev *mdio_get_current_dev(void)
240{
241	return current_mii;
242}
243
244struct phy_device *mdio_phydev_for_ethname(const char *ethname)
245{
246	struct list_head *entry;
247	struct mii_dev *bus;
248
249	list_for_each(entry, &mii_devs) {
250		int i;
251		bus = list_entry(entry, struct mii_dev, link);
252
253		for (i = 0; i < PHY_MAX_ADDR; i++) {
254			if (!bus->phymap[i] || !bus->phymap[i]->dev)
255				continue;
256
257			if (strcmp(bus->phymap[i]->dev->name, ethname) == 0)
258				return bus->phymap[i];
259		}
260	}
261
262	printf("%s is not a known ethernet\n", ethname);
263	return NULL;
264}
265
266const char *miiphy_get_current_dev(void)
267{
268	if (current_mii)
269		return current_mii->name;
270
271	return NULL;
272}
273
274static struct mii_dev *miiphy_get_active_dev(const char *devname)
275{
276	/* If the current mii is the one we want, return it */
277	if (current_mii)
278		if (strcmp(current_mii->name, devname) == 0)
279			return current_mii;
280
281	/* Otherwise, set the active one to the one we want */
282	if (miiphy_set_current_dev(devname))
283		return NULL;
284	else
285		return current_mii;
286}
287
288/*****************************************************************************
289 *
290 * Read to variable <value> from the PHY attached to device <devname>,
291 * use PHY address <addr> and register <reg>.
292 *
293 * This API is deprecated. Use phy_read on a phy_device found via phy_connect
294 *
295 * Returns:
296 *   0 on success
297 */
298int miiphy_read(const char *devname, unsigned char addr, unsigned char reg,
299		 unsigned short *value)
300{
301	struct mii_dev *bus;
302	int ret;
303
304	bus = miiphy_get_active_dev(devname);
305	if (!bus)
306		return 1;
307
308	ret = bus->read(bus, addr, MDIO_DEVAD_NONE, reg);
309	if (ret < 0)
310		return 1;
311
312	*value = (unsigned short)ret;
313	return 0;
314}
315
316/*****************************************************************************
317 *
318 * Write <value> to the PHY attached to device <devname>,
319 * use PHY address <addr> and register <reg>.
320 *
321 * This API is deprecated. Use phy_write on a phy_device found by phy_connect
322 *
323 * Returns:
324 *   0 on success
325 */
326int miiphy_write(const char *devname, unsigned char addr, unsigned char reg,
327		  unsigned short value)
328{
329	struct mii_dev *bus;
330
331	bus = miiphy_get_active_dev(devname);
332	if (bus)
333		return bus->write(bus, addr, MDIO_DEVAD_NONE, reg, value);
334
335	return 1;
336}
337
338/*****************************************************************************
339 *
340 * Print out list of registered MII capable devices.
341 */
342void miiphy_listdev(void)
343{
344	struct list_head *entry;
345	struct mii_dev *dev;
346
347	puts("MII devices: ");
348	list_for_each(entry, &mii_devs) {
349		dev = list_entry(entry, struct mii_dev, link);
350		printf("'%s' ", dev->name);
351	}
352	puts("\n");
353
354	if (current_mii)
355		printf("Current device: '%s'\n", current_mii->name);
356}
357
358/*****************************************************************************
359 *
360 * Read the OUI, manufacture's model number, and revision number.
361 *
362 * OUI:     22 bits (unsigned int)
363 * Model:    6 bits (unsigned char)
364 * Revision: 4 bits (unsigned char)
365 *
366 * This API is deprecated.
367 *
368 * Returns:
369 *   0 on success
370 */
371int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui,
372		 unsigned char *model, unsigned char *rev)
373{
374	unsigned int reg = 0;
375	unsigned short tmp;
376
377	if (miiphy_read(devname, addr, MII_PHYSID2, &tmp) != 0) {
378		debug("PHY ID register 2 read failed\n");
379		return -1;
380	}
381	reg = tmp;
382
383	debug("MII_PHYSID2 @ 0x%x = 0x%04x\n", addr, reg);
384
385	if (reg == 0xFFFF) {
386		/* No physical device present at this address */
387		return -1;
388	}
389
390	if (miiphy_read(devname, addr, MII_PHYSID1, &tmp) != 0) {
391		debug("PHY ID register 1 read failed\n");
392		return -1;
393	}
394	reg |= tmp << 16;
395	debug("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);
396
397	*oui = (reg >> 10);
398	*model = (unsigned char)((reg >> 4) & 0x0000003F);
399	*rev = (unsigned char)(reg & 0x0000000F);
400	return 0;
401}
402
403#ifndef CONFIG_PHYLIB
404/*****************************************************************************
405 *
406 * Reset the PHY.
407 *
408 * This API is deprecated. Use PHYLIB.
409 *
410 * Returns:
411 *   0 on success
412 */
413int miiphy_reset(const char *devname, unsigned char addr)
414{
415	unsigned short reg;
416	int timeout = 500;
417
418	if (miiphy_read(devname, addr, MII_BMCR, &reg) != 0) {
419		debug("PHY status read failed\n");
420		return -1;
421	}
422	if (miiphy_write(devname, addr, MII_BMCR, reg | BMCR_RESET) != 0) {
423		debug("PHY reset failed\n");
424		return -1;
425	}
426#ifdef CONFIG_PHY_RESET_DELAY
427	udelay(CONFIG_PHY_RESET_DELAY);	/* Intel LXT971A needs this */
428#endif
429	/*
430	 * Poll the control register for the reset bit to go to 0 (it is
431	 * auto-clearing).  This should happen within 0.5 seconds per the
432	 * IEEE spec.
433	 */
434	reg = 0x8000;
435	while (((reg & 0x8000) != 0) && timeout--) {
436		if (miiphy_read(devname, addr, MII_BMCR, &reg) != 0) {
437			debug("PHY status read failed\n");
438			return -1;
439		}
440		udelay(1000);
441	}
442	if ((reg & 0x8000) == 0) {
443		return 0;
444	} else {
445		puts("PHY reset timed out\n");
446		return -1;
447	}
448	return 0;
449}
450#endif /* !PHYLIB */
451
452/*****************************************************************************
453 *
454 * Determine the ethernet speed (10/100/1000).  Return 10 on error.
455 */
456int miiphy_speed(const char *devname, unsigned char addr)
457{
458	u16 bmcr, anlpar;
459
460#if defined(CONFIG_PHY_GIGE)
461	u16 btsr;
462
463	/*
464	 * Check for 1000BASE-X.  If it is supported, then assume that the speed
465	 * is 1000.
466	 */
467	if (miiphy_is_1000base_x(devname, addr))
468		return _1000BASET;
469
470	/*
471	 * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
472	 */
473	/* Check for 1000BASE-T. */
474	if (miiphy_read(devname, addr, MII_STAT1000, &btsr)) {
475		printf("PHY 1000BT status");
476		goto miiphy_read_failed;
477	}
478	if (btsr != 0xFFFF &&
479			(btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)))
480		return _1000BASET;
481#endif /* CONFIG_PHY_GIGE */
482
483	/* Check Basic Management Control Register first. */
484	if (miiphy_read(devname, addr, MII_BMCR, &bmcr)) {
485		printf("PHY speed");
486		goto miiphy_read_failed;
487	}
488	/* Check if auto-negotiation is on. */
489	if (bmcr & BMCR_ANENABLE) {
490		/* Get auto-negotiation results. */
491		if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
492			printf("PHY AN speed");
493			goto miiphy_read_failed;
494		}
495		return (anlpar & LPA_100) ? _100BASET : _10BASET;
496	}
497	/* Get speed from basic control settings. */
498	return (bmcr & BMCR_SPEED100) ? _100BASET : _10BASET;
499
500miiphy_read_failed:
501	printf(" read failed, assuming 10BASE-T\n");
502	return _10BASET;
503}
504
505/*****************************************************************************
506 *
507 * Determine full/half duplex.  Return half on error.
508 */
509int miiphy_duplex(const char *devname, unsigned char addr)
510{
511	u16 bmcr, anlpar;
512
513#if defined(CONFIG_PHY_GIGE)
514	u16 btsr;
515
516	/* Check for 1000BASE-X. */
517	if (miiphy_is_1000base_x(devname, addr)) {
518		/* 1000BASE-X */
519		if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
520			printf("1000BASE-X PHY AN duplex");
521			goto miiphy_read_failed;
522		}
523	}
524	/*
525	 * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
526	 */
527	/* Check for 1000BASE-T. */
528	if (miiphy_read(devname, addr, MII_STAT1000, &btsr)) {
529		printf("PHY 1000BT status");
530		goto miiphy_read_failed;
531	}
532	if (btsr != 0xFFFF) {
533		if (btsr & PHY_1000BTSR_1000FD) {
534			return FULL;
535		} else if (btsr & PHY_1000BTSR_1000HD) {
536			return HALF;
537		}
538	}
539#endif /* CONFIG_PHY_GIGE */
540
541	/* Check Basic Management Control Register first. */
542	if (miiphy_read(devname, addr, MII_BMCR, &bmcr)) {
543		puts("PHY duplex");
544		goto miiphy_read_failed;
545	}
546	/* Check if auto-negotiation is on. */
547	if (bmcr & BMCR_ANENABLE) {
548		/* Get auto-negotiation results. */
549		if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
550			puts("PHY AN duplex");
551			goto miiphy_read_failed;
552		}
553		return (anlpar & (LPA_10FULL | LPA_100FULL)) ?
554		    FULL : HALF;
555	}
556	/* Get speed from basic control settings. */
557	return (bmcr & BMCR_FULLDPLX) ? FULL : HALF;
558
559miiphy_read_failed:
560	printf(" read failed, assuming half duplex\n");
561	return HALF;
562}
563
564/*****************************************************************************
565 *
566 * Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/
567 * 1000BASE-T, or on error.
568 */
569int miiphy_is_1000base_x(const char *devname, unsigned char addr)
570{
571#if defined(CONFIG_PHY_GIGE)
572	u16 exsr;
573
574	if (miiphy_read(devname, addr, MII_ESTATUS, &exsr)) {
575		printf("PHY extended status read failed, assuming no "
576			"1000BASE-X\n");
577		return 0;
578	}
579	return 0 != (exsr & (ESTATUS_1000XF | ESTATUS_1000XH));
580#else
581	return 0;
582#endif
583}
584
585#ifdef CONFIG_SYS_FAULT_ECHO_LINK_DOWN
586/*****************************************************************************
587 *
588 * Determine link status
589 */
590int miiphy_link(const char *devname, unsigned char addr)
591{
592	unsigned short reg;
593
594	/* dummy read; needed to latch some phys */
595	(void)miiphy_read(devname, addr, MII_BMSR, &reg);
596	if (miiphy_read(devname, addr, MII_BMSR, &reg)) {
597		puts("MII_BMSR read failed, assuming no link\n");
598		return 0;
599	}
600
601	/* Determine if a link is active */
602	if ((reg & BMSR_LSTATUS) != 0) {
603		return 1;
604	} else {
605		return 0;
606	}
607}
608#endif
609