]> git.sur5r.net Git - u-boot/blob - common/miiphyutil.c
9cf845f605dca3940c821976247b647847a91636
[u-boot] / common / miiphyutil.c
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