]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - common/miiphyutil.c
miiphy: unify device list lookup
[karo-tx-uboot.git] / 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 /*****************************************************************************
166  *
167  * Read to variable <value> from the PHY attached to device <devname>,
168  * use PHY address <addr> and register <reg>.
169  *
170  * Returns:
171  *   0 on success
172  */
173 int miiphy_read(const char *devname, unsigned char addr, unsigned char reg,
174                  unsigned short *value)
175 {
176         struct mii_dev *dev;
177
178         dev = miiphy_get_dev_by_name(devname, 0);
179         if (dev)
180                 return dev->read(devname, addr, reg, value);
181
182         return 1;
183 }
184
185 /*****************************************************************************
186  *
187  * Write <value> to the PHY attached to device <devname>,
188  * use PHY address <addr> and register <reg>.
189  *
190  * Returns:
191  *   0 on success
192  */
193 int miiphy_write(const char *devname, unsigned char addr, unsigned char reg,
194                   unsigned short value)
195 {
196         struct mii_dev *dev;
197
198         dev = miiphy_get_dev_by_name(devname, 0);
199         if (dev)
200                 return dev->write(devname, addr, reg, value);
201
202         return 1;
203 }
204
205 /*****************************************************************************
206  *
207  * Print out list of registered MII capable devices.
208  */
209 void miiphy_listdev (void)
210 {
211         struct list_head *entry;
212         struct mii_dev *dev;
213
214         puts ("MII devices: ");
215         list_for_each (entry, &mii_devs) {
216                 dev = list_entry (entry, struct mii_dev, link);
217                 printf ("'%s' ", dev->name);
218         }
219         puts ("\n");
220
221         if (current_mii)
222                 printf ("Current device: '%s'\n", current_mii->name);
223 }
224
225 /*****************************************************************************
226  *
227  * Read the OUI, manufacture's model number, and revision number.
228  *
229  * OUI:     22 bits (unsigned int)
230  * Model:    6 bits (unsigned char)
231  * Revision: 4 bits (unsigned char)
232  *
233  * Returns:
234  *   0 on success
235  */
236 int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui,
237                  unsigned char *model, unsigned char *rev)
238 {
239         unsigned int reg = 0;
240         unsigned short tmp;
241
242         if (miiphy_read (devname, addr, PHY_PHYIDR2, &tmp) != 0) {
243                 debug ("PHY ID register 2 read failed\n");
244                 return (-1);
245         }
246         reg = tmp;
247
248         debug ("PHY_PHYIDR2 @ 0x%x = 0x%04x\n", addr, reg);
249
250         if (reg == 0xFFFF) {
251                 /* No physical device present at this address */
252                 return (-1);
253         }
254
255         if (miiphy_read (devname, addr, PHY_PHYIDR1, &tmp) != 0) {
256                 debug ("PHY ID register 1 read failed\n");
257                 return (-1);
258         }
259         reg |= tmp << 16;
260         debug ("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);
261
262         *oui = (reg >> 10);
263         *model = (unsigned char)((reg >> 4) & 0x0000003F);
264         *rev = (unsigned char)(reg & 0x0000000F);
265         return (0);
266 }
267
268 /*****************************************************************************
269  *
270  * Reset the PHY.
271  * Returns:
272  *   0 on success
273  */
274 int miiphy_reset(const char *devname, unsigned char addr)
275 {
276         unsigned short reg;
277         int timeout = 500;
278
279         if (miiphy_read (devname, addr, PHY_BMCR, &reg) != 0) {
280                 debug ("PHY status read failed\n");
281                 return (-1);
282         }
283         if (miiphy_write (devname, addr, PHY_BMCR, reg | PHY_BMCR_RESET) != 0) {
284                 debug ("PHY reset failed\n");
285                 return (-1);
286         }
287 #ifdef CONFIG_PHY_RESET_DELAY
288         udelay (CONFIG_PHY_RESET_DELAY);        /* Intel LXT971A needs this */
289 #endif
290         /*
291          * Poll the control register for the reset bit to go to 0 (it is
292          * auto-clearing).  This should happen within 0.5 seconds per the
293          * IEEE spec.
294          */
295         reg = 0x8000;
296         while (((reg & 0x8000) != 0) && timeout--) {
297                 if (miiphy_read(devname, addr, PHY_BMCR, &reg) != 0) {
298                         debug("PHY status read failed\n");
299                         return -1;
300                 }
301                 udelay(1000);
302         }
303         if ((reg & 0x8000) == 0) {
304                 return (0);
305         } else {
306                 puts ("PHY reset timed out\n");
307                 return (-1);
308         }
309         return (0);
310 }
311
312 /*****************************************************************************
313  *
314  * Determine the ethernet speed (10/100/1000).  Return 10 on error.
315  */
316 int miiphy_speed(const char *devname, unsigned char addr)
317 {
318         u16 bmcr, anlpar;
319
320 #if defined(CONFIG_PHY_GIGE)
321         u16 btsr;
322
323         /*
324          * Check for 1000BASE-X.  If it is supported, then assume that the speed
325          * is 1000.
326          */
327         if (miiphy_is_1000base_x (devname, addr)) {
328                 return _1000BASET;
329         }
330         /*
331          * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
332          */
333         /* Check for 1000BASE-T. */
334         if (miiphy_read (devname, addr, PHY_1000BTSR, &btsr)) {
335                 printf ("PHY 1000BT status");
336                 goto miiphy_read_failed;
337         }
338         if (btsr != 0xFFFF &&
339             (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD))) {
340                 return _1000BASET;
341         }
342 #endif /* CONFIG_PHY_GIGE */
343
344         /* Check Basic Management Control Register first. */
345         if (miiphy_read (devname, addr, PHY_BMCR, &bmcr)) {
346                 printf ("PHY speed");
347                 goto miiphy_read_failed;
348         }
349         /* Check if auto-negotiation is on. */
350         if (bmcr & PHY_BMCR_AUTON) {
351                 /* Get auto-negotiation results. */
352                 if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
353                         printf ("PHY AN speed");
354                         goto miiphy_read_failed;
355                 }
356                 return (anlpar & PHY_ANLPAR_100) ? _100BASET : _10BASET;
357         }
358         /* Get speed from basic control settings. */
359         return (bmcr & PHY_BMCR_100MB) ? _100BASET : _10BASET;
360
361 miiphy_read_failed:
362         printf (" read failed, assuming 10BASE-T\n");
363         return _10BASET;
364 }
365
366 /*****************************************************************************
367  *
368  * Determine full/half duplex.  Return half on error.
369  */
370 int miiphy_duplex(const char *devname, unsigned char addr)
371 {
372         u16 bmcr, anlpar;
373
374 #if defined(CONFIG_PHY_GIGE)
375         u16 btsr;
376
377         /* Check for 1000BASE-X. */
378         if (miiphy_is_1000base_x (devname, addr)) {
379                 /* 1000BASE-X */
380                 if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
381                         printf ("1000BASE-X PHY AN duplex");
382                         goto miiphy_read_failed;
383                 }
384         }
385         /*
386          * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
387          */
388         /* Check for 1000BASE-T. */
389         if (miiphy_read (devname, addr, PHY_1000BTSR, &btsr)) {
390                 printf ("PHY 1000BT status");
391                 goto miiphy_read_failed;
392         }
393         if (btsr != 0xFFFF) {
394                 if (btsr & PHY_1000BTSR_1000FD) {
395                         return FULL;
396                 } else if (btsr & PHY_1000BTSR_1000HD) {
397                         return HALF;
398                 }
399         }
400 #endif /* CONFIG_PHY_GIGE */
401
402         /* Check Basic Management Control Register first. */
403         if (miiphy_read (devname, addr, PHY_BMCR, &bmcr)) {
404                 puts ("PHY duplex");
405                 goto miiphy_read_failed;
406         }
407         /* Check if auto-negotiation is on. */
408         if (bmcr & PHY_BMCR_AUTON) {
409                 /* Get auto-negotiation results. */
410                 if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) {
411                         puts ("PHY AN duplex");
412                         goto miiphy_read_failed;
413                 }
414                 return (anlpar & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) ?
415                     FULL : HALF;
416         }
417         /* Get speed from basic control settings. */
418         return (bmcr & PHY_BMCR_DPLX) ? FULL : HALF;
419
420 miiphy_read_failed:
421         printf (" read failed, assuming half duplex\n");
422         return HALF;
423 }
424
425 /*****************************************************************************
426  *
427  * Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/
428  * 1000BASE-T, or on error.
429  */
430 int miiphy_is_1000base_x(const char *devname, unsigned char addr)
431 {
432 #if defined(CONFIG_PHY_GIGE)
433         u16 exsr;
434
435         if (miiphy_read (devname, addr, PHY_EXSR, &exsr)) {
436                 printf ("PHY extended status read failed, assuming no "
437                         "1000BASE-X\n");
438                 return 0;
439         }
440         return 0 != (exsr & (PHY_EXSR_1000XF | PHY_EXSR_1000XH));
441 #else
442         return 0;
443 #endif
444 }
445
446 #ifdef CONFIG_SYS_FAULT_ECHO_LINK_DOWN
447 /*****************************************************************************
448  *
449  * Determine link status
450  */
451 int miiphy_link(const char *devname, unsigned char addr)
452 {
453         unsigned short reg;
454
455         /* dummy read; needed to latch some phys */
456         (void)miiphy_read (devname, addr, PHY_BMSR, &reg);
457         if (miiphy_read (devname, addr, PHY_BMSR, &reg)) {
458                 puts ("PHY_BMSR read failed, assuming no link\n");
459                 return (0);
460         }
461
462         /* Determine if a link is active */
463         if ((reg & PHY_BMSR_LS) != 0) {
464                 return (1);
465         } else {
466                 return (0);
467         }
468 }
469 #endif