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 #if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) 33 #include <asm/types.h> 34 #include <linux/list.h> 35 #include <malloc.h> 36 #include <net.h> 37 38 /* local debug macro */ 39 #define MII_DEBUG 40 #undef MII_DEBUG 41 42 #undef debug 43 #ifdef MII_DEBUG 44 #define debug(fmt,args...) printf (fmt ,##args) 45 #else 46 #define debug(fmt,args...) 47 #endif /* MII_DEBUG */ 48 49 struct mii_dev { 50 struct list_head link; 51 char *name; 52 int (* read)(char *devname, unsigned char addr, 53 unsigned char reg, unsigned short *value); 54 int (* write)(char *devname, unsigned char addr, 55 unsigned char reg, unsigned short value); 56 }; 57 58 static struct list_head mii_devs; 59 static struct mii_dev *current_mii; 60 61 /***************************************************************************** 62 * 63 * Register read and write MII access routines for the device <name>. 64 */ 65 void miiphy_register(char *name, 66 int (* read)(char *devname, unsigned char addr, 67 unsigned char reg, unsigned short *value), 68 int (* write)(char *devname, unsigned char addr, 69 unsigned char reg, unsigned short value)) 70 { 71 struct list_head *entry; 72 struct mii_dev *new_dev; 73 struct mii_dev *miidev; 74 static int head_initialized = 0; 75 unsigned int name_len; 76 77 if (head_initialized == 0) { 78 INIT_LIST_HEAD(&mii_devs); 79 current_mii = NULL; 80 head_initialized = 1; 81 } 82 83 /* check if we have unique name */ 84 list_for_each(entry, &mii_devs) { 85 miidev = list_entry(entry, struct mii_dev, link); 86 if (strcmp(miidev->name, name) == 0) { 87 printf("miiphy_register: non unique device name '%s'\n", 88 name); 89 return; 90 } 91 } 92 93 /* allocate memory */ 94 name_len = strlen(name); 95 new_dev = (struct mii_dev *)malloc(sizeof(struct mii_dev) + name_len + 1); 96 97 if(new_dev == NULL) { 98 printf("miiphy_register: cannot allocate memory for '%s'\n", 99 name); 100 return; 101 } 102 memset(new_dev, 0, sizeof(struct mii_dev) + name_len); 103 104 /* initalize mii_dev struct fields */ 105 INIT_LIST_HEAD(&new_dev->link); 106 new_dev->read = read; 107 new_dev->write = write; 108 new_dev->name = (char *)(new_dev + 1); 109 strncpy(new_dev->name, name, name_len); 110 new_dev->name[name_len] = '\0'; 111 112 debug("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n", 113 new_dev->name, new_dev->read, new_dev->write); 114 115 /* add it to the list */ 116 list_add_tail(&new_dev->link, &mii_devs); 117 118 if (!current_mii) 119 current_mii = new_dev; 120 } 121 122 int miiphy_set_current_dev(char *devname) 123 { 124 struct list_head *entry; 125 struct mii_dev *dev; 126 127 list_for_each(entry, &mii_devs) { 128 dev = list_entry(entry, struct mii_dev, link); 129 130 if (strcmp(devname, dev->name) == 0) { 131 current_mii = dev; 132 return 0; 133 } 134 } 135 136 printf("No such device: %s\n", devname); 137 return 1; 138 } 139 140 char *miiphy_get_current_dev() 141 { 142 if (current_mii) 143 return current_mii->name; 144 145 return NULL; 146 } 147 148 /***************************************************************************** 149 * 150 * Read to variable <value> from the PHY attached to device <devname>, 151 * use PHY address <addr> and register <reg>. 152 * 153 * Returns: 154 * 0 on success 155 */ 156 int miiphy_read(char *devname, unsigned char addr, unsigned char reg, 157 unsigned short *value) 158 { 159 struct list_head *entry; 160 struct mii_dev *dev; 161 int found_dev = 0; 162 int read_ret = 0; 163 164 if (!devname) { 165 printf("NULL device name!\n"); 166 return 1; 167 } 168 169 list_for_each(entry, &mii_devs) { 170 dev = list_entry(entry, struct mii_dev, link); 171 172 if (strcmp(devname, dev->name) == 0) { 173 found_dev = 1; 174 read_ret = dev->read(devname, addr, reg, value); 175 break; 176 } 177 } 178 179 if (found_dev == 0) 180 printf("No such device: %s\n", devname); 181 182 return ((found_dev) ? read_ret : 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(char *devname, unsigned char addr, unsigned char reg, 194 unsigned short value) 195 { 196 struct list_head *entry; 197 struct mii_dev *dev; 198 int found_dev = 0; 199 int write_ret = 0; 200 201 if (!devname) { 202 printf("NULL device name!\n"); 203 return 1; 204 } 205 206 list_for_each(entry, &mii_devs) { 207 dev = list_entry(entry, struct mii_dev, link); 208 209 if (strcmp(devname, dev->name) == 0) { 210 found_dev = 1; 211 write_ret = dev->write(devname, addr, reg, value); 212 break; 213 } 214 } 215 216 if (found_dev == 0) 217 printf("No such device: %s\n", devname); 218 219 return ((found_dev) ? write_ret : 1); 220 } 221 222 /***************************************************************************** 223 * 224 * Print out list of registered MII capable devices. 225 */ 226 void miiphy_listdev(void) 227 { 228 struct list_head *entry; 229 struct mii_dev *dev; 230 231 puts("MII devices: "); 232 list_for_each(entry, &mii_devs) { 233 dev = list_entry(entry, struct mii_dev, link); 234 printf("'%s' ", dev->name); 235 } 236 puts("\n"); 237 238 if (current_mii) 239 printf("Current device: '%s'\n", current_mii->name); 240 } 241 242 243 /***************************************************************************** 244 * 245 * Read the OUI, manufacture's model number, and revision number. 246 * 247 * OUI: 22 bits (unsigned int) 248 * Model: 6 bits (unsigned char) 249 * Revision: 4 bits (unsigned char) 250 * 251 * Returns: 252 * 0 on success 253 */ 254 int miiphy_info (char *devname, 255 unsigned char addr, 256 unsigned int *oui, 257 unsigned char *model, unsigned char *rev) 258 { 259 unsigned int reg = 0; 260 unsigned short tmp; 261 262 if (miiphy_read (devname, addr, PHY_PHYIDR2, &tmp) != 0) { 263 #ifdef DEBUG 264 puts ("PHY ID register 2 read failed\n"); 265 #endif 266 return (-1); 267 } 268 reg = tmp; 269 270 #ifdef DEBUG 271 printf ("PHY_PHYIDR2 @ 0x%x = 0x%04x\n", addr, reg); 272 #endif 273 if (reg == 0xFFFF) { 274 /* No physical device present at this address */ 275 return (-1); 276 } 277 278 if (miiphy_read (devname, addr, PHY_PHYIDR1, &tmp) != 0) { 279 #ifdef DEBUG 280 puts ("PHY ID register 1 read failed\n"); 281 #endif 282 return (-1); 283 } 284 reg |= tmp << 16; 285 #ifdef DEBUG 286 printf ("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg); 287 #endif 288 *oui = ( reg >> 10); 289 *model = (unsigned char) ((reg >> 4) & 0x0000003F); 290 *rev = (unsigned char) ( reg & 0x0000000F); 291 return (0); 292 } 293 294 295 /***************************************************************************** 296 * 297 * Reset the PHY. 298 * Returns: 299 * 0 on success 300 */ 301 int miiphy_reset (char *devname, unsigned char addr) 302 { 303 unsigned short reg; 304 int loop_cnt; 305 306 if (miiphy_read (devname, addr, PHY_BMCR, ®) != 0) { 307 #ifdef DEBUG 308 printf ("PHY status read failed\n"); 309 #endif 310 return (-1); 311 } 312 if (miiphy_write (devname, addr, PHY_BMCR, reg | 0x8000) != 0) { 313 #ifdef DEBUG 314 puts ("PHY reset failed\n"); 315 #endif 316 return (-1); 317 } 318 #ifdef CONFIG_PHY_RESET_DELAY 319 udelay (CONFIG_PHY_RESET_DELAY); /* Intel LXT971A needs this */ 320 #endif 321 /* 322 * Poll the control register for the reset bit to go to 0 (it is 323 * auto-clearing). This should happen within 0.5 seconds per the 324 * IEEE spec. 325 */ 326 loop_cnt = 0; 327 reg = 0x8000; 328 while (((reg & 0x8000) != 0) && (loop_cnt++ < 1000000)) { 329 if (miiphy_read (devname, addr, PHY_BMCR, ®) != 0) { 330 # ifdef DEBUG 331 puts ("PHY status read failed\n"); 332 # endif 333 return (-1); 334 } 335 } 336 if ((reg & 0x8000) == 0) { 337 return (0); 338 } else { 339 puts ("PHY reset timed out\n"); 340 return (-1); 341 } 342 return (0); 343 } 344 345 346 /***************************************************************************** 347 * 348 * Determine the ethernet speed (10/100). 349 */ 350 int miiphy_speed (char *devname, unsigned char addr) 351 { 352 unsigned short reg; 353 354 #if defined(CONFIG_PHY_GIGE) 355 if (miiphy_read (devname, addr, PHY_1000BTSR, ®)) { 356 printf ("PHY 1000BT Status read failed\n"); 357 } else { 358 if (reg != 0xFFFF) { 359 if ((reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) !=0) { 360 return (_1000BASET); 361 } 362 } 363 } 364 #endif /* CONFIG_PHY_GIGE */ 365 366 /* Check Basic Management Control Register first. */ 367 if (miiphy_read (devname, addr, PHY_BMCR, ®)) { 368 puts ("PHY speed read failed, assuming 10bT\n"); 369 return (_10BASET); 370 } 371 /* Check if auto-negotiation is on. */ 372 if ((reg & PHY_BMCR_AUTON) != 0) { 373 /* Get auto-negotiation results. */ 374 if (miiphy_read (devname, addr, PHY_ANLPAR, ®)) { 375 puts ("PHY AN speed read failed, assuming 10bT\n"); 376 return (_10BASET); 377 } 378 if ((reg & PHY_ANLPAR_100) != 0) { 379 return (_100BASET); 380 } else { 381 return (_10BASET); 382 } 383 } 384 /* Get speed from basic control settings. */ 385 else if (reg & PHY_BMCR_100MB) { 386 return (_100BASET); 387 } else { 388 return (_10BASET); 389 } 390 391 } 392 393 394 /***************************************************************************** 395 * 396 * Determine full/half duplex. 397 */ 398 int miiphy_duplex (char *devname, unsigned char addr) 399 { 400 unsigned short reg; 401 402 #if defined(CONFIG_PHY_GIGE) 403 if (miiphy_read (devname, addr, PHY_1000BTSR, ®)) { 404 printf ("PHY 1000BT Status read failed\n"); 405 } else { 406 if ( (reg != 0xFFFF) && 407 (reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) ) { 408 if ((reg & PHY_1000BTSR_1000FD) !=0) { 409 return (FULL); 410 } else { 411 return (HALF); 412 } 413 } 414 } 415 #endif /* CONFIG_PHY_GIGE */ 416 417 /* Check Basic Management Control Register first. */ 418 if (miiphy_read (devname, addr, PHY_BMCR, ®)) { 419 puts ("PHY duplex read failed, assuming half duplex\n"); 420 return (HALF); 421 } 422 /* Check if auto-negotiation is on. */ 423 if ((reg & PHY_BMCR_AUTON) != 0) { 424 /* Get auto-negotiation results. */ 425 if (miiphy_read (devname, addr, PHY_ANLPAR, ®)) { 426 puts ("PHY AN duplex read failed, assuming half duplex\n"); 427 return (HALF); 428 } 429 430 if ((reg & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) != 0) { 431 return (FULL); 432 } else { 433 return (HALF); 434 } 435 } 436 /* Get speed from basic control settings. */ 437 else if (reg & PHY_BMCR_DPLX) { 438 return (FULL); 439 } else { 440 return (HALF); 441 } 442 443 } 444 445 #ifdef CFG_FAULT_ECHO_LINK_DOWN 446 /***************************************************************************** 447 * 448 * Determine link status 449 */ 450 int miiphy_link (char *devname, unsigned char addr) 451 { 452 unsigned short reg; 453 454 /* dummy read; needed to latch some phys */ 455 (void)miiphy_read(devname, addr, PHY_BMSR, ®); 456 if (miiphy_read (devname, addr, PHY_BMSR, ®)) { 457 puts ("PHY_BMSR read failed, assuming no link\n"); 458 return (0); 459 } 460 461 /* Determine if a link is active */ 462 if ((reg & PHY_BMSR_LS) != 0) { 463 return (1); 464 } else { 465 return (0); 466 } 467 } 468 #endif 469 470 #endif /* CONFIG_MII || (CONFIG_COMMANDS & CFG_CMD_MII) */ 471