xref: /openbmc/u-boot/common/miiphyutil.c (revision d4562e09)
1 /*
2  * (C) Copyright 2001
3  * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23 
24 /*
25  * This provides a bit-banged interface to the ethernet MII management
26  * channel.
27  */
28 
29 #include <common.h>
30 #include <miiphy.h>
31 
32 #include <asm/types.h>
33 #include <linux/list.h>
34 #include <malloc.h>
35 #include <net.h>
36 
37 /* local debug macro */
38 #undef MII_DEBUG
39 
40 #undef debug
41 #ifdef MII_DEBUG
42 #define debug(fmt,args...)	printf (fmt ,##args)
43 #else
44 #define debug(fmt,args...)
45 #endif /* MII_DEBUG */
46 
47 struct mii_dev {
48 	struct list_head link;
49 	const char *name;
50 	int (*read) (const char *devname, unsigned char addr,
51 		     unsigned char reg, unsigned short *value);
52 	int (*write) (const char *devname, unsigned char addr,
53 		      unsigned char reg, unsigned short value);
54 };
55 
56 static struct list_head mii_devs;
57 static struct mii_dev *current_mii;
58 
59 /*
60  * Lookup the mii_dev struct by the registered device name.
61  */
62 static struct mii_dev *miiphy_get_dev_by_name(const char *devname, int quiet)
63 {
64 	struct list_head *entry;
65 	struct mii_dev *dev;
66 
67 	if (!devname) {
68 		printf("NULL device name!\n");
69 		return NULL;
70 	}
71 
72 	list_for_each(entry, &mii_devs) {
73 		dev = list_entry(entry, struct mii_dev, link);
74 		if (strcmp(dev->name, devname) == 0)
75 			return dev;
76 	}
77 
78 	if (!quiet)
79 		printf("No such device: %s\n", devname);
80 	return NULL;
81 }
82 
83 /*****************************************************************************
84  *
85  * Initialize global data. Need to be called before any other miiphy routine.
86  */
87 void miiphy_init(void)
88 {
89 	INIT_LIST_HEAD (&mii_devs);
90 	current_mii = NULL;
91 }
92 
93 /*****************************************************************************
94  *
95  * Register read and write MII access routines for the device <name>.
96  */
97 void miiphy_register(const char *name,
98 		      int (*read) (const char *devname, unsigned char addr,
99 				   unsigned char reg, unsigned short *value),
100 		      int (*write) (const char *devname, unsigned char addr,
101 				    unsigned char reg, unsigned short value))
102 {
103 	struct mii_dev *new_dev;
104 	unsigned int name_len;
105 	char *new_name;
106 
107 	/* check if we have unique name */
108 	new_dev = miiphy_get_dev_by_name(name, 1);
109 	if (new_dev) {
110 		printf("miiphy_register: non unique device name '%s'\n", name);
111 		return;
112 	}
113 
114 	/* allocate memory */
115 	name_len = strlen (name);
116 	new_dev =
117 	    (struct mii_dev *)malloc (sizeof (struct mii_dev) + name_len + 1);
118 
119 	if (new_dev == NULL) {
120 		printf ("miiphy_register: cannot allocate memory for '%s'\n",
121 			name);
122 		return;
123 	}
124 	memset (new_dev, 0, sizeof (struct mii_dev) + name_len);
125 
126 	/* initalize mii_dev struct fields */
127 	INIT_LIST_HEAD (&new_dev->link);
128 	new_dev->read = read;
129 	new_dev->write = write;
130 	new_dev->name = new_name = (char *)(new_dev + 1);
131 	strncpy (new_name, name, name_len);
132 	new_name[name_len] = '\0';
133 
134 	debug ("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n",
135 	       new_dev->name, new_dev->read, new_dev->write);
136 
137 	/* add it to the list */
138 	list_add_tail (&new_dev->link, &mii_devs);
139 
140 	if (!current_mii)
141 		current_mii = new_dev;
142 }
143 
144 int miiphy_set_current_dev(const char *devname)
145 {
146 	struct mii_dev *dev;
147 
148 	dev = miiphy_get_dev_by_name(devname, 0);
149 	if (dev) {
150 		current_mii = dev;
151 		return 0;
152 	}
153 
154 	return 1;
155 }
156 
157 const char *miiphy_get_current_dev(void)
158 {
159 	if (current_mii)
160 		return current_mii->name;
161 
162 	return NULL;
163 }
164 
165 static struct mii_dev *miiphy_get_active_dev(const char *devname)
166 {
167 	/* If the current mii is the one we want, return it */
168 	if (current_mii)
169 		if (strcmp(current_mii->name, devname) == 0)
170 			return current_mii;
171 
172 	/* Otherwise, set the active one to the one we want */
173 	if (miiphy_set_current_dev(devname))
174 		return NULL;
175 	else
176 		return current_mii;
177 }
178 
179 /*****************************************************************************
180  *
181  * Read to variable <value> from the PHY attached to device <devname>,
182  * use PHY address <addr> and register <reg>.
183  *
184  * Returns:
185  *   0 on success
186  */
187 int miiphy_read(const char *devname, unsigned char addr, unsigned char reg,
188 		 unsigned short *value)
189 {
190 	struct mii_dev *dev;
191 
192 	dev = miiphy_get_active_dev(devname);
193 	if (dev)
194 		return dev->read(devname, addr, reg, value);
195 
196 	return 1;
197 }
198 
199 /*****************************************************************************
200  *
201  * Write <value> to the PHY attached to device <devname>,
202  * use PHY address <addr> and register <reg>.
203  *
204  * Returns:
205  *   0 on success
206  */
207 int miiphy_write(const char *devname, unsigned char addr, unsigned char reg,
208 		  unsigned short value)
209 {
210 	struct mii_dev *dev;
211 
212 	dev = miiphy_get_active_dev(devname);
213 	if (dev)
214 		return dev->write(devname, addr, reg, value);
215 
216 	return 1;
217 }
218 
219 /*****************************************************************************
220  *
221  * Print out list of registered MII capable devices.
222  */
223 void miiphy_listdev (void)
224 {
225 	struct list_head *entry;
226 	struct mii_dev *dev;
227 
228 	puts ("MII devices: ");
229 	list_for_each (entry, &mii_devs) {
230 		dev = list_entry (entry, struct mii_dev, link);
231 		printf ("'%s' ", dev->name);
232 	}
233 	puts ("\n");
234 
235 	if (current_mii)
236 		printf ("Current device: '%s'\n", current_mii->name);
237 }
238 
239 /*****************************************************************************
240  *
241  * Read the OUI, manufacture's model number, and revision number.
242  *
243  * OUI:     22 bits (unsigned int)
244  * Model:    6 bits (unsigned char)
245  * Revision: 4 bits (unsigned char)
246  *
247  * Returns:
248  *   0 on success
249  */
250 int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui,
251 		 unsigned char *model, unsigned char *rev)
252 {
253 	unsigned int reg = 0;
254 	unsigned short tmp;
255 
256 	if (miiphy_read (devname, addr, PHY_PHYIDR2, &tmp) != 0) {
257 		debug ("PHY ID register 2 read failed\n");
258 		return (-1);
259 	}
260 	reg = tmp;
261 
262 	debug ("PHY_PHYIDR2 @ 0x%x = 0x%04x\n", addr, reg);
263 
264 	if (reg == 0xFFFF) {
265 		/* No physical device present at this address */
266 		return (-1);
267 	}
268 
269 	if (miiphy_read (devname, addr, PHY_PHYIDR1, &tmp) != 0) {
270 		debug ("PHY ID register 1 read failed\n");
271 		return (-1);
272 	}
273 	reg |= tmp << 16;
274 	debug ("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);
275 
276 	*oui = (reg >> 10);
277 	*model = (unsigned char)((reg >> 4) & 0x0000003F);
278 	*rev = (unsigned char)(reg & 0x0000000F);
279 	return (0);
280 }
281 
282 /*****************************************************************************
283  *
284  * Reset the PHY.
285  * Returns:
286  *   0 on success
287  */
288 int miiphy_reset(const char *devname, unsigned char addr)
289 {
290 	unsigned short reg;
291 	int timeout = 500;
292 
293 	if (miiphy_read (devname, addr, PHY_BMCR, &reg) != 0) {
294 		debug ("PHY status read failed\n");
295 		return (-1);
296 	}
297 	if (miiphy_write (devname, addr, PHY_BMCR, reg | PHY_BMCR_RESET) != 0) {
298 		debug ("PHY reset failed\n");
299 		return (-1);
300 	}
301 #ifdef CONFIG_PHY_RESET_DELAY
302 	udelay (CONFIG_PHY_RESET_DELAY);	/* Intel LXT971A needs this */
303 #endif
304 	/*
305 	 * Poll the control register for the reset bit to go to 0 (it is
306 	 * auto-clearing).  This should happen within 0.5 seconds per the
307 	 * IEEE spec.
308 	 */
309 	reg = 0x8000;
310 	while (((reg & 0x8000) != 0) && timeout--) {
311 		if (miiphy_read(devname, addr, PHY_BMCR, &reg) != 0) {
312 			debug("PHY status read failed\n");
313 			return -1;
314 		}
315 		udelay(1000);
316 	}
317 	if ((reg & 0x8000) == 0) {
318 		return (0);
319 	} else {
320 		puts ("PHY reset timed out\n");
321 		return (-1);
322 	}
323 	return (0);
324 }
325 
326 /*****************************************************************************
327  *
328  * Determine the ethernet speed (10/100/1000).  Return 10 on error.
329  */
330 int miiphy_speed(const char *devname, unsigned char addr)
331 {
332 	u16 bmcr, anlpar;
333 
334 #if defined(CONFIG_PHY_GIGE)
335 	u16 btsr;
336 
337 	/*
338 	 * Check for 1000BASE-X.  If it is supported, then assume that the speed
339 	 * is 1000.
340 	 */
341 	if (miiphy_is_1000base_x (devname, addr)) {
342 		return _1000BASET;
343 	}
344 	/*
345 	 * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
346 	 */
347 	/* Check for 1000BASE-T. */
348 	if (miiphy_read (devname, addr, PHY_1000BTSR, &btsr)) {
349 		printf ("PHY 1000BT status");
350 		goto miiphy_read_failed;
351 	}
352 	if (btsr != 0xFFFF &&
353 	    (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD))) {
354 		return _1000BASET;
355 	}
356 #endif /* CONFIG_PHY_GIGE */
357 
358 	/* Check Basic Management Control Register first. */
359 	if (miiphy_read (devname, addr, PHY_BMCR, &bmcr)) {
360 		printf ("PHY speed");
361 		goto miiphy_read_failed;
362 	}
363 	/* Check if auto-negotiation is on. */
364 	if (bmcr & PHY_BMCR_AUTON) {
365 		/* Get auto-negotiation results. */
366 		if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
367 			printf ("PHY AN speed");
368 			goto miiphy_read_failed;
369 		}
370 		return (anlpar & PHY_ANLPAR_100) ? _100BASET : _10BASET;
371 	}
372 	/* Get speed from basic control settings. */
373 	return (bmcr & PHY_BMCR_100MB) ? _100BASET : _10BASET;
374 
375 miiphy_read_failed:
376 	printf (" read failed, assuming 10BASE-T\n");
377 	return _10BASET;
378 }
379 
380 /*****************************************************************************
381  *
382  * Determine full/half duplex.  Return half on error.
383  */
384 int miiphy_duplex(const char *devname, unsigned char addr)
385 {
386 	u16 bmcr, anlpar;
387 
388 #if defined(CONFIG_PHY_GIGE)
389 	u16 btsr;
390 
391 	/* Check for 1000BASE-X. */
392 	if (miiphy_is_1000base_x (devname, addr)) {
393 		/* 1000BASE-X */
394 		if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
395 			printf ("1000BASE-X PHY AN duplex");
396 			goto miiphy_read_failed;
397 		}
398 	}
399 	/*
400 	 * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
401 	 */
402 	/* Check for 1000BASE-T. */
403 	if (miiphy_read (devname, addr, PHY_1000BTSR, &btsr)) {
404 		printf ("PHY 1000BT status");
405 		goto miiphy_read_failed;
406 	}
407 	if (btsr != 0xFFFF) {
408 		if (btsr & PHY_1000BTSR_1000FD) {
409 			return FULL;
410 		} else if (btsr & PHY_1000BTSR_1000HD) {
411 			return HALF;
412 		}
413 	}
414 #endif /* CONFIG_PHY_GIGE */
415 
416 	/* Check Basic Management Control Register first. */
417 	if (miiphy_read (devname, addr, PHY_BMCR, &bmcr)) {
418 		puts ("PHY duplex");
419 		goto miiphy_read_failed;
420 	}
421 	/* Check if auto-negotiation is on. */
422 	if (bmcr & PHY_BMCR_AUTON) {
423 		/* Get auto-negotiation results. */
424 		if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
425 			puts ("PHY AN duplex");
426 			goto miiphy_read_failed;
427 		}
428 		return (anlpar & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) ?
429 		    FULL : HALF;
430 	}
431 	/* Get speed from basic control settings. */
432 	return (bmcr & PHY_BMCR_DPLX) ? FULL : HALF;
433 
434 miiphy_read_failed:
435 	printf (" read failed, assuming half duplex\n");
436 	return HALF;
437 }
438 
439 /*****************************************************************************
440  *
441  * Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/
442  * 1000BASE-T, or on error.
443  */
444 int miiphy_is_1000base_x(const char *devname, unsigned char addr)
445 {
446 #if defined(CONFIG_PHY_GIGE)
447 	u16 exsr;
448 
449 	if (miiphy_read (devname, addr, PHY_EXSR, &exsr)) {
450 		printf ("PHY extended status read failed, assuming no "
451 			"1000BASE-X\n");
452 		return 0;
453 	}
454 	return 0 != (exsr & (PHY_EXSR_1000XF | PHY_EXSR_1000XH));
455 #else
456 	return 0;
457 #endif
458 }
459 
460 #ifdef CONFIG_SYS_FAULT_ECHO_LINK_DOWN
461 /*****************************************************************************
462  *
463  * Determine link status
464  */
465 int miiphy_link(const char *devname, unsigned char addr)
466 {
467 	unsigned short reg;
468 
469 	/* dummy read; needed to latch some phys */
470 	(void)miiphy_read (devname, addr, PHY_BMSR, &reg);
471 	if (miiphy_read (devname, addr, PHY_BMSR, &reg)) {
472 		puts ("PHY_BMSR read failed, assuming no link\n");
473 		return (0);
474 	}
475 
476 	/* Determine if a link is active */
477 	if ((reg & PHY_BMSR_LS) != 0) {
478 		return (1);
479 	} else {
480 		return (0);
481 	}
482 }
483 #endif
484