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