1 /* 2 * Freescale Three Speed Ethernet Controller driver 3 * 4 * This software may be used and distributed according to the 5 * terms of the GNU Public License, Version 2, incorporated 6 * herein by reference. 7 * 8 * Copyright 2004-2010 Freescale Semiconductor, Inc. 9 * (C) Copyright 2003, Motorola, Inc. 10 * author Andy Fleming 11 * 12 */ 13 14 #include <config.h> 15 #include <common.h> 16 #include <malloc.h> 17 #include <net.h> 18 #include <command.h> 19 #include <tsec.h> 20 #include <asm/errno.h> 21 22 #include "miiphy.h" 23 24 DECLARE_GLOBAL_DATA_PTR; 25 26 #define TX_BUF_CNT 2 27 28 static uint rxIdx; /* index of the current RX buffer */ 29 static uint txIdx; /* index of the current TX buffer */ 30 31 typedef volatile struct rtxbd { 32 txbd8_t txbd[TX_BUF_CNT]; 33 rxbd8_t rxbd[PKTBUFSRX]; 34 } RTXBD; 35 36 #define MAXCONTROLLERS (8) 37 38 static struct tsec_private *privlist[MAXCONTROLLERS]; 39 static int num_tsecs = 0; 40 41 #ifdef __GNUC__ 42 static RTXBD rtx __attribute__ ((aligned(8))); 43 #else 44 #error "rtx must be 64-bit aligned" 45 #endif 46 47 static int tsec_send(struct eth_device *dev, 48 volatile void *packet, int length); 49 static int tsec_recv(struct eth_device *dev); 50 static int tsec_init(struct eth_device *dev, bd_t * bd); 51 static int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info); 52 static void tsec_halt(struct eth_device *dev); 53 static void init_registers(volatile tsec_t * regs); 54 static void startup_tsec(struct eth_device *dev); 55 static int init_phy(struct eth_device *dev); 56 void write_phy_reg(struct tsec_private *priv, uint regnum, uint value); 57 uint read_phy_reg(struct tsec_private *priv, uint regnum); 58 static struct phy_info *get_phy_info(struct eth_device *dev); 59 static void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd); 60 static void adjust_link(struct eth_device *dev); 61 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \ 62 && !defined(BITBANGMII) 63 static int tsec_miiphy_write(const char *devname, unsigned char addr, 64 unsigned char reg, unsigned short value); 65 static int tsec_miiphy_read(const char *devname, unsigned char addr, 66 unsigned char reg, unsigned short *value); 67 #endif 68 #ifdef CONFIG_MCAST_TFTP 69 static int tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set); 70 #endif 71 72 /* Default initializations for TSEC controllers. */ 73 74 static struct tsec_info_struct tsec_info[] = { 75 #ifdef CONFIG_TSEC1 76 STD_TSEC_INFO(1), /* TSEC1 */ 77 #endif 78 #ifdef CONFIG_TSEC2 79 STD_TSEC_INFO(2), /* TSEC2 */ 80 #endif 81 #ifdef CONFIG_MPC85XX_FEC 82 { 83 .regs = (tsec_t *)(TSEC_BASE_ADDR + 0x2000), 84 .miiregs = (tsec_mdio_t *)(MDIO_BASE_ADDR), 85 .devname = CONFIG_MPC85XX_FEC_NAME, 86 .phyaddr = FEC_PHY_ADDR, 87 .flags = FEC_FLAGS 88 }, /* FEC */ 89 #endif 90 #ifdef CONFIG_TSEC3 91 STD_TSEC_INFO(3), /* TSEC3 */ 92 #endif 93 #ifdef CONFIG_TSEC4 94 STD_TSEC_INFO(4), /* TSEC4 */ 95 #endif 96 }; 97 98 /* 99 * Initialize all the TSEC devices 100 * 101 * Returns the number of TSEC devices that were initialized 102 */ 103 int tsec_eth_init(bd_t *bis, struct tsec_info_struct *tsecs, int num) 104 { 105 int i; 106 int ret, count = 0; 107 108 for (i = 0; i < num; i++) { 109 ret = tsec_initialize(bis, &tsecs[i]); 110 if (ret > 0) 111 count += ret; 112 } 113 114 return count; 115 } 116 117 int tsec_standard_init(bd_t *bis) 118 { 119 return tsec_eth_init(bis, tsec_info, ARRAY_SIZE(tsec_info)); 120 } 121 122 /* Initialize device structure. Returns success if PHY 123 * initialization succeeded (i.e. if it recognizes the PHY) 124 */ 125 static int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info) 126 { 127 struct eth_device *dev; 128 int i; 129 struct tsec_private *priv; 130 131 dev = (struct eth_device *)malloc(sizeof *dev); 132 133 if (NULL == dev) 134 return 0; 135 136 memset(dev, 0, sizeof *dev); 137 138 priv = (struct tsec_private *)malloc(sizeof(*priv)); 139 140 if (NULL == priv) 141 return 0; 142 143 privlist[num_tsecs++] = priv; 144 priv->regs = tsec_info->regs; 145 priv->phyregs = tsec_info->miiregs; 146 priv->phyregs_sgmii = tsec_info->miiregs_sgmii; 147 148 priv->phyaddr = tsec_info->phyaddr; 149 priv->flags = tsec_info->flags; 150 151 sprintf(dev->name, tsec_info->devname); 152 dev->iobase = 0; 153 dev->priv = priv; 154 dev->init = tsec_init; 155 dev->halt = tsec_halt; 156 dev->send = tsec_send; 157 dev->recv = tsec_recv; 158 #ifdef CONFIG_MCAST_TFTP 159 dev->mcast = tsec_mcast_addr; 160 #endif 161 162 /* Tell u-boot to get the addr from the env */ 163 for (i = 0; i < 6; i++) 164 dev->enetaddr[i] = 0; 165 166 eth_register(dev); 167 168 /* Reset the MAC */ 169 priv->regs->maccfg1 |= MACCFG1_SOFT_RESET; 170 udelay(2); /* Soft Reset must be asserted for 3 TX clocks */ 171 priv->regs->maccfg1 &= ~(MACCFG1_SOFT_RESET); 172 173 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \ 174 && !defined(BITBANGMII) 175 miiphy_register(dev->name, tsec_miiphy_read, tsec_miiphy_write); 176 #endif 177 178 /* Try to initialize PHY here, and return */ 179 return init_phy(dev); 180 } 181 182 /* Initializes data structures and registers for the controller, 183 * and brings the interface up. Returns the link status, meaning 184 * that it returns success if the link is up, failure otherwise. 185 * This allows u-boot to find the first active controller. 186 */ 187 static int tsec_init(struct eth_device *dev, bd_t * bd) 188 { 189 uint tempval; 190 char tmpbuf[MAC_ADDR_LEN]; 191 int i; 192 struct tsec_private *priv = (struct tsec_private *)dev->priv; 193 volatile tsec_t *regs = priv->regs; 194 195 /* Make sure the controller is stopped */ 196 tsec_halt(dev); 197 198 /* Init MACCFG2. Defaults to GMII */ 199 regs->maccfg2 = MACCFG2_INIT_SETTINGS; 200 201 /* Init ECNTRL */ 202 regs->ecntrl = ECNTRL_INIT_SETTINGS; 203 204 /* Copy the station address into the address registers. 205 * Backwards, because little endian MACS are dumb */ 206 for (i = 0; i < MAC_ADDR_LEN; i++) { 207 tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->enetaddr[i]; 208 } 209 tempval = (tmpbuf[0] << 24) | (tmpbuf[1] << 16) | (tmpbuf[2] << 8) | 210 tmpbuf[3]; 211 212 regs->macstnaddr1 = tempval; 213 214 tempval = *((uint *) (tmpbuf + 4)); 215 216 regs->macstnaddr2 = tempval; 217 218 /* reset the indices to zero */ 219 rxIdx = 0; 220 txIdx = 0; 221 222 /* Clear out (for the most part) the other registers */ 223 init_registers(regs); 224 225 /* Ready the device for tx/rx */ 226 startup_tsec(dev); 227 228 /* If there's no link, fail */ 229 return (priv->link ? 0 : -1); 230 } 231 232 /* Writes the given phy's reg with value, using the specified MDIO regs */ 233 static void tsec_local_mdio_write(volatile tsec_mdio_t *phyregs, uint addr, 234 uint reg, uint value) 235 { 236 int timeout = 1000000; 237 238 phyregs->miimadd = (addr << 8) | reg; 239 phyregs->miimcon = value; 240 asm("sync"); 241 242 timeout = 1000000; 243 while ((phyregs->miimind & MIIMIND_BUSY) && timeout--) ; 244 } 245 246 247 /* Provide the default behavior of writing the PHY of this ethernet device */ 248 #define write_phy_reg(priv, regnum, value) \ 249 tsec_local_mdio_write(priv->phyregs,priv->phyaddr,regnum,value) 250 251 /* Reads register regnum on the device's PHY through the 252 * specified registers. It lowers and raises the read 253 * command, and waits for the data to become valid (miimind 254 * notvalid bit cleared), and the bus to cease activity (miimind 255 * busy bit cleared), and then returns the value 256 */ 257 static uint tsec_local_mdio_read(volatile tsec_mdio_t *phyregs, 258 uint phyid, uint regnum) 259 { 260 uint value; 261 262 /* Put the address of the phy, and the register 263 * number into MIIMADD */ 264 phyregs->miimadd = (phyid << 8) | regnum; 265 266 /* Clear the command register, and wait */ 267 phyregs->miimcom = 0; 268 asm("sync"); 269 270 /* Initiate a read command, and wait */ 271 phyregs->miimcom = MIIM_READ_COMMAND; 272 asm("sync"); 273 274 /* Wait for the the indication that the read is done */ 275 while ((phyregs->miimind & (MIIMIND_NOTVALID | MIIMIND_BUSY))) ; 276 277 /* Grab the value read from the PHY */ 278 value = phyregs->miimstat; 279 280 return value; 281 } 282 283 /* #define to provide old read_phy_reg functionality without duplicating code */ 284 #define read_phy_reg(priv,regnum) \ 285 tsec_local_mdio_read(priv->phyregs,priv->phyaddr,regnum) 286 287 #define TBIANA_SETTINGS ( \ 288 TBIANA_ASYMMETRIC_PAUSE \ 289 | TBIANA_SYMMETRIC_PAUSE \ 290 | TBIANA_FULL_DUPLEX \ 291 ) 292 293 /* By default force the TBI PHY into 1000Mbps full duplex when in SGMII mode */ 294 #ifndef CONFIG_TSEC_TBICR_SETTINGS 295 #define CONFIG_TSEC_TBICR_SETTINGS ( \ 296 TBICR_PHY_RESET \ 297 | TBICR_ANEG_ENABLE \ 298 | TBICR_FULL_DUPLEX \ 299 | TBICR_SPEED1_SET \ 300 ) 301 #endif /* CONFIG_TSEC_TBICR_SETTINGS */ 302 303 /* Configure the TBI for SGMII operation */ 304 static void tsec_configure_serdes(struct tsec_private *priv) 305 { 306 /* Access TBI PHY registers at given TSEC register offset as opposed 307 * to the register offset used for external PHY accesses */ 308 tsec_local_mdio_write(priv->phyregs_sgmii, priv->regs->tbipa, TBI_ANA, 309 TBIANA_SETTINGS); 310 tsec_local_mdio_write(priv->phyregs_sgmii, priv->regs->tbipa, TBI_TBICON, 311 TBICON_CLK_SELECT); 312 tsec_local_mdio_write(priv->phyregs_sgmii, priv->regs->tbipa, TBI_CR, 313 CONFIG_TSEC_TBICR_SETTINGS); 314 } 315 316 /* Discover which PHY is attached to the device, and configure it 317 * properly. If the PHY is not recognized, then return 0 318 * (failure). Otherwise, return 1 319 */ 320 static int init_phy(struct eth_device *dev) 321 { 322 struct tsec_private *priv = (struct tsec_private *)dev->priv; 323 struct phy_info *curphy; 324 volatile tsec_t *regs = priv->regs; 325 326 /* Assign a Physical address to the TBI */ 327 regs->tbipa = CONFIG_SYS_TBIPA_VALUE; 328 asm("sync"); 329 330 /* Reset MII (due to new addresses) */ 331 priv->phyregs->miimcfg = MIIMCFG_RESET; 332 asm("sync"); 333 priv->phyregs->miimcfg = MIIMCFG_INIT_VALUE; 334 asm("sync"); 335 while (priv->phyregs->miimind & MIIMIND_BUSY) ; 336 337 /* Get the cmd structure corresponding to the attached 338 * PHY */ 339 curphy = get_phy_info(dev); 340 341 if (curphy == NULL) { 342 priv->phyinfo = NULL; 343 printf("%s: No PHY found\n", dev->name); 344 345 return 0; 346 } 347 348 if (regs->ecntrl & ECNTRL_SGMII_MODE) 349 tsec_configure_serdes(priv); 350 351 priv->phyinfo = curphy; 352 353 phy_run_commands(priv, priv->phyinfo->config); 354 355 return 1; 356 } 357 358 /* 359 * Returns which value to write to the control register. 360 * For 10/100, the value is slightly different 361 */ 362 static uint mii_cr_init(uint mii_reg, struct tsec_private * priv) 363 { 364 if (priv->flags & TSEC_GIGABIT) 365 return MIIM_CONTROL_INIT; 366 else 367 return MIIM_CR_INIT; 368 } 369 370 /* 371 * Wait for auto-negotiation to complete, then determine link 372 */ 373 static uint mii_parse_sr(uint mii_reg, struct tsec_private * priv) 374 { 375 /* 376 * Wait if the link is up, and autonegotiation is in progress 377 * (ie - we're capable and it's not done) 378 */ 379 mii_reg = read_phy_reg(priv, MIIM_STATUS); 380 if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) { 381 int i = 0; 382 383 puts("Waiting for PHY auto negotiation to complete"); 384 while (!(mii_reg & BMSR_ANEGCOMPLETE)) { 385 /* 386 * Timeout reached ? 387 */ 388 if (i > PHY_AUTONEGOTIATE_TIMEOUT) { 389 puts(" TIMEOUT !\n"); 390 priv->link = 0; 391 return 0; 392 } 393 394 if (ctrlc()) { 395 puts("user interrupt!\n"); 396 priv->link = 0; 397 return -EINTR; 398 } 399 400 if ((i++ % 1000) == 0) { 401 putc('.'); 402 } 403 udelay(1000); /* 1 ms */ 404 mii_reg = read_phy_reg(priv, MIIM_STATUS); 405 } 406 puts(" done\n"); 407 408 /* Link status bit is latched low, read it again */ 409 mii_reg = read_phy_reg(priv, MIIM_STATUS); 410 411 udelay(500000); /* another 500 ms (results in faster booting) */ 412 } 413 414 priv->link = mii_reg & MIIM_STATUS_LINK ? 1 : 0; 415 416 return 0; 417 } 418 419 /* Generic function which updates the speed and duplex. If 420 * autonegotiation is enabled, it uses the AND of the link 421 * partner's advertised capabilities and our advertised 422 * capabilities. If autonegotiation is disabled, we use the 423 * appropriate bits in the control register. 424 * 425 * Stolen from Linux's mii.c and phy_device.c 426 */ 427 static uint mii_parse_link(uint mii_reg, struct tsec_private *priv) 428 { 429 /* We're using autonegotiation */ 430 if (mii_reg & BMSR_ANEGCAPABLE) { 431 uint lpa = 0; 432 uint gblpa = 0; 433 434 /* Check for gigabit capability */ 435 if (mii_reg & BMSR_ERCAP) { 436 /* We want a list of states supported by 437 * both PHYs in the link 438 */ 439 gblpa = read_phy_reg(priv, MII_STAT1000); 440 gblpa &= read_phy_reg(priv, MII_CTRL1000) << 2; 441 } 442 443 /* Set the baseline so we only have to set them 444 * if they're different 445 */ 446 priv->speed = 10; 447 priv->duplexity = 0; 448 449 /* Check the gigabit fields */ 450 if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) { 451 priv->speed = 1000; 452 453 if (gblpa & PHY_1000BTSR_1000FD) 454 priv->duplexity = 1; 455 456 /* We're done! */ 457 return 0; 458 } 459 460 lpa = read_phy_reg(priv, MII_ADVERTISE); 461 lpa &= read_phy_reg(priv, MII_LPA); 462 463 if (lpa & (LPA_100FULL | LPA_100HALF)) { 464 priv->speed = 100; 465 466 if (lpa & LPA_100FULL) 467 priv->duplexity = 1; 468 469 } else if (lpa & LPA_10FULL) 470 priv->duplexity = 1; 471 } else { 472 uint bmcr = read_phy_reg(priv, MII_BMCR); 473 474 priv->speed = 10; 475 priv->duplexity = 0; 476 477 if (bmcr & BMCR_FULLDPLX) 478 priv->duplexity = 1; 479 480 if (bmcr & BMCR_SPEED1000) 481 priv->speed = 1000; 482 else if (bmcr & BMCR_SPEED100) 483 priv->speed = 100; 484 } 485 486 return 0; 487 } 488 489 /* 490 * "Ethernet@Wirespeed" needs to be enabled to achieve link in certain 491 * circumstances. eg a gigabit TSEC connected to a gigabit switch with 492 * a 4-wire ethernet cable. Both ends advertise gigabit, but can't 493 * link. "Ethernet@Wirespeed" reduces advertised speed until link 494 * can be achieved. 495 */ 496 static uint mii_BCM54xx_wirespeed(uint mii_reg, struct tsec_private *priv) 497 { 498 return (read_phy_reg(priv, mii_reg) & 0x8FFF) | 0x8010; 499 } 500 501 /* 502 * Parse the BCM54xx status register for speed and duplex information. 503 * The linux sungem_phy has this information, but in a table format. 504 */ 505 static uint mii_parse_BCM54xx_sr(uint mii_reg, struct tsec_private *priv) 506 { 507 /* If there is no link, speed and duplex don't matter */ 508 if (!priv->link) 509 return 0; 510 511 switch ((mii_reg & MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK) >> 512 MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT) { 513 case 1: 514 priv->duplexity = 0; 515 priv->speed = 10; 516 break; 517 case 2: 518 priv->duplexity = 1; 519 priv->speed = 10; 520 break; 521 case 3: 522 priv->duplexity = 0; 523 priv->speed = 100; 524 break; 525 case 5: 526 priv->duplexity = 1; 527 priv->speed = 100; 528 break; 529 case 6: 530 priv->duplexity = 0; 531 priv->speed = 1000; 532 break; 533 case 7: 534 priv->duplexity = 1; 535 priv->speed = 1000; 536 break; 537 default: 538 printf("Auto-neg error, defaulting to 10BT/HD\n"); 539 priv->duplexity = 0; 540 priv->speed = 10; 541 break; 542 } 543 544 return 0; 545 } 546 547 /* 548 * Find out if PHY is in copper or serdes mode by looking at Expansion Reg 549 * 0x42 - "Operating Mode Status Register" 550 */ 551 static int BCM8482_is_serdes(struct tsec_private *priv) 552 { 553 u16 val; 554 int serdes = 0; 555 556 write_phy_reg(priv, MIIM_BCM54XX_EXP_SEL, MIIM_BCM54XX_EXP_SEL_ER | 0x42); 557 val = read_phy_reg(priv, MIIM_BCM54XX_EXP_DATA); 558 559 switch (val & 0x1f) { 560 case 0x0d: /* RGMII-to-100Base-FX */ 561 case 0x0e: /* RGMII-to-SGMII */ 562 case 0x0f: /* RGMII-to-SerDes */ 563 case 0x12: /* SGMII-to-SerDes */ 564 case 0x13: /* SGMII-to-100Base-FX */ 565 case 0x16: /* SerDes-to-Serdes */ 566 serdes = 1; 567 break; 568 case 0x6: /* RGMII-to-Copper */ 569 case 0x14: /* SGMII-to-Copper */ 570 case 0x17: /* SerDes-to-Copper */ 571 break; 572 default: 573 printf("ERROR, invalid PHY mode (0x%x\n)", val); 574 break; 575 } 576 577 return serdes; 578 } 579 580 /* 581 * Determine SerDes link speed and duplex from Expansion reg 0x42 "Operating 582 * Mode Status Register" 583 */ 584 uint mii_parse_BCM5482_serdes_sr(struct tsec_private *priv) 585 { 586 u16 val; 587 int i = 0; 588 589 /* Wait 1s for link - Clause 37 autonegotiation happens very fast */ 590 while (1) { 591 write_phy_reg(priv, MIIM_BCM54XX_EXP_SEL, 592 MIIM_BCM54XX_EXP_SEL_ER | 0x42); 593 val = read_phy_reg(priv, MIIM_BCM54XX_EXP_DATA); 594 595 if (val & 0x8000) 596 break; 597 598 if (i++ > 1000) { 599 priv->link = 0; 600 return 1; 601 } 602 603 udelay(1000); /* 1 ms */ 604 } 605 606 priv->link = 1; 607 switch ((val >> 13) & 0x3) { 608 case (0x00): 609 priv->speed = 10; 610 break; 611 case (0x01): 612 priv->speed = 100; 613 break; 614 case (0x02): 615 priv->speed = 1000; 616 break; 617 } 618 619 priv->duplexity = (val & 0x1000) == 0x1000; 620 621 return 0; 622 } 623 624 /* 625 * Figure out if BCM5482 is in serdes or copper mode and determine link 626 * configuration accordingly 627 */ 628 static uint mii_parse_BCM5482_sr(uint mii_reg, struct tsec_private *priv) 629 { 630 if (BCM8482_is_serdes(priv)) { 631 mii_parse_BCM5482_serdes_sr(priv); 632 priv->flags |= TSEC_FIBER; 633 } else { 634 /* Wait for auto-negotiation to complete or fail */ 635 mii_parse_sr(mii_reg, priv); 636 637 /* Parse BCM54xx copper aux status register */ 638 mii_reg = read_phy_reg(priv, MIIM_BCM54xx_AUXSTATUS); 639 mii_parse_BCM54xx_sr(mii_reg, priv); 640 } 641 642 return 0; 643 } 644 645 /* Parse the 88E1011's status register for speed and duplex 646 * information 647 */ 648 static uint mii_parse_88E1011_psr(uint mii_reg, struct tsec_private * priv) 649 { 650 uint speed; 651 652 mii_reg = read_phy_reg(priv, MIIM_88E1011_PHY_STATUS); 653 654 if ((mii_reg & MIIM_88E1011_PHYSTAT_LINK) && 655 !(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) { 656 int i = 0; 657 658 puts("Waiting for PHY realtime link"); 659 while (!(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) { 660 /* Timeout reached ? */ 661 if (i > PHY_AUTONEGOTIATE_TIMEOUT) { 662 puts(" TIMEOUT !\n"); 663 priv->link = 0; 664 break; 665 } 666 667 if ((i++ % 1000) == 0) { 668 putc('.'); 669 } 670 udelay(1000); /* 1 ms */ 671 mii_reg = read_phy_reg(priv, MIIM_88E1011_PHY_STATUS); 672 } 673 puts(" done\n"); 674 udelay(500000); /* another 500 ms (results in faster booting) */ 675 } else { 676 if (mii_reg & MIIM_88E1011_PHYSTAT_LINK) 677 priv->link = 1; 678 else 679 priv->link = 0; 680 } 681 682 if (mii_reg & MIIM_88E1011_PHYSTAT_DUPLEX) 683 priv->duplexity = 1; 684 else 685 priv->duplexity = 0; 686 687 speed = (mii_reg & MIIM_88E1011_PHYSTAT_SPEED); 688 689 switch (speed) { 690 case MIIM_88E1011_PHYSTAT_GBIT: 691 priv->speed = 1000; 692 break; 693 case MIIM_88E1011_PHYSTAT_100: 694 priv->speed = 100; 695 break; 696 default: 697 priv->speed = 10; 698 } 699 700 return 0; 701 } 702 703 /* Parse the RTL8211B's status register for speed and duplex 704 * information 705 */ 706 static uint mii_parse_RTL8211B_sr(uint mii_reg, struct tsec_private * priv) 707 { 708 uint speed; 709 710 mii_reg = read_phy_reg(priv, MIIM_RTL8211B_PHY_STATUS); 711 if (!(mii_reg & MIIM_RTL8211B_PHYSTAT_SPDDONE)) { 712 int i = 0; 713 714 /* in case of timeout ->link is cleared */ 715 priv->link = 1; 716 puts("Waiting for PHY realtime link"); 717 while (!(mii_reg & MIIM_RTL8211B_PHYSTAT_SPDDONE)) { 718 /* Timeout reached ? */ 719 if (i > PHY_AUTONEGOTIATE_TIMEOUT) { 720 puts(" TIMEOUT !\n"); 721 priv->link = 0; 722 break; 723 } 724 725 if ((i++ % 1000) == 0) { 726 putc('.'); 727 } 728 udelay(1000); /* 1 ms */ 729 mii_reg = read_phy_reg(priv, MIIM_RTL8211B_PHY_STATUS); 730 } 731 puts(" done\n"); 732 udelay(500000); /* another 500 ms (results in faster booting) */ 733 } else { 734 if (mii_reg & MIIM_RTL8211B_PHYSTAT_LINK) 735 priv->link = 1; 736 else 737 priv->link = 0; 738 } 739 740 if (mii_reg & MIIM_RTL8211B_PHYSTAT_DUPLEX) 741 priv->duplexity = 1; 742 else 743 priv->duplexity = 0; 744 745 speed = (mii_reg & MIIM_RTL8211B_PHYSTAT_SPEED); 746 747 switch (speed) { 748 case MIIM_RTL8211B_PHYSTAT_GBIT: 749 priv->speed = 1000; 750 break; 751 case MIIM_RTL8211B_PHYSTAT_100: 752 priv->speed = 100; 753 break; 754 default: 755 priv->speed = 10; 756 } 757 758 return 0; 759 } 760 761 /* Parse the cis8201's status register for speed and duplex 762 * information 763 */ 764 static uint mii_parse_cis8201(uint mii_reg, struct tsec_private * priv) 765 { 766 uint speed; 767 768 if (mii_reg & MIIM_CIS8201_AUXCONSTAT_DUPLEX) 769 priv->duplexity = 1; 770 else 771 priv->duplexity = 0; 772 773 speed = mii_reg & MIIM_CIS8201_AUXCONSTAT_SPEED; 774 switch (speed) { 775 case MIIM_CIS8201_AUXCONSTAT_GBIT: 776 priv->speed = 1000; 777 break; 778 case MIIM_CIS8201_AUXCONSTAT_100: 779 priv->speed = 100; 780 break; 781 default: 782 priv->speed = 10; 783 break; 784 } 785 786 return 0; 787 } 788 789 /* Parse the vsc8244's status register for speed and duplex 790 * information 791 */ 792 static uint mii_parse_vsc8244(uint mii_reg, struct tsec_private * priv) 793 { 794 uint speed; 795 796 if (mii_reg & MIIM_VSC8244_AUXCONSTAT_DUPLEX) 797 priv->duplexity = 1; 798 else 799 priv->duplexity = 0; 800 801 speed = mii_reg & MIIM_VSC8244_AUXCONSTAT_SPEED; 802 switch (speed) { 803 case MIIM_VSC8244_AUXCONSTAT_GBIT: 804 priv->speed = 1000; 805 break; 806 case MIIM_VSC8244_AUXCONSTAT_100: 807 priv->speed = 100; 808 break; 809 default: 810 priv->speed = 10; 811 break; 812 } 813 814 return 0; 815 } 816 817 /* Parse the DM9161's status register for speed and duplex 818 * information 819 */ 820 static uint mii_parse_dm9161_scsr(uint mii_reg, struct tsec_private * priv) 821 { 822 if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H)) 823 priv->speed = 100; 824 else 825 priv->speed = 10; 826 827 if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_10F)) 828 priv->duplexity = 1; 829 else 830 priv->duplexity = 0; 831 832 return 0; 833 } 834 835 /* 836 * Hack to write all 4 PHYs with the LED values 837 */ 838 static uint mii_cis8204_fixled(uint mii_reg, struct tsec_private * priv) 839 { 840 uint phyid; 841 volatile tsec_mdio_t *regbase = priv->phyregs; 842 int timeout = 1000000; 843 844 for (phyid = 0; phyid < 4; phyid++) { 845 regbase->miimadd = (phyid << 8) | mii_reg; 846 regbase->miimcon = MIIM_CIS8204_SLEDCON_INIT; 847 asm("sync"); 848 849 timeout = 1000000; 850 while ((regbase->miimind & MIIMIND_BUSY) && timeout--) ; 851 } 852 853 return MIIM_CIS8204_SLEDCON_INIT; 854 } 855 856 static uint mii_cis8204_setmode(uint mii_reg, struct tsec_private * priv) 857 { 858 if (priv->flags & TSEC_REDUCED) 859 return MIIM_CIS8204_EPHYCON_INIT | MIIM_CIS8204_EPHYCON_RGMII; 860 else 861 return MIIM_CIS8204_EPHYCON_INIT; 862 } 863 864 static uint mii_m88e1111s_setmode(uint mii_reg, struct tsec_private *priv) 865 { 866 uint mii_data = read_phy_reg(priv, mii_reg); 867 868 if (priv->flags & TSEC_REDUCED) 869 mii_data = (mii_data & 0xfff0) | 0x000b; 870 return mii_data; 871 } 872 873 /* Initialized required registers to appropriate values, zeroing 874 * those we don't care about (unless zero is bad, in which case, 875 * choose a more appropriate value) 876 */ 877 static void init_registers(volatile tsec_t * regs) 878 { 879 /* Clear IEVENT */ 880 regs->ievent = IEVENT_INIT_CLEAR; 881 882 regs->imask = IMASK_INIT_CLEAR; 883 884 regs->hash.iaddr0 = 0; 885 regs->hash.iaddr1 = 0; 886 regs->hash.iaddr2 = 0; 887 regs->hash.iaddr3 = 0; 888 regs->hash.iaddr4 = 0; 889 regs->hash.iaddr5 = 0; 890 regs->hash.iaddr6 = 0; 891 regs->hash.iaddr7 = 0; 892 893 regs->hash.gaddr0 = 0; 894 regs->hash.gaddr1 = 0; 895 regs->hash.gaddr2 = 0; 896 regs->hash.gaddr3 = 0; 897 regs->hash.gaddr4 = 0; 898 regs->hash.gaddr5 = 0; 899 regs->hash.gaddr6 = 0; 900 regs->hash.gaddr7 = 0; 901 902 regs->rctrl = 0x00000000; 903 904 /* Init RMON mib registers */ 905 memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t)); 906 907 regs->rmon.cam1 = 0xffffffff; 908 regs->rmon.cam2 = 0xffffffff; 909 910 regs->mrblr = MRBLR_INIT_SETTINGS; 911 912 regs->minflr = MINFLR_INIT_SETTINGS; 913 914 regs->attr = ATTR_INIT_SETTINGS; 915 regs->attreli = ATTRELI_INIT_SETTINGS; 916 917 } 918 919 /* Configure maccfg2 based on negotiated speed and duplex 920 * reported by PHY handling code 921 */ 922 static void adjust_link(struct eth_device *dev) 923 { 924 struct tsec_private *priv = (struct tsec_private *)dev->priv; 925 volatile tsec_t *regs = priv->regs; 926 927 if (priv->link) { 928 if (priv->duplexity != 0) 929 regs->maccfg2 |= MACCFG2_FULL_DUPLEX; 930 else 931 regs->maccfg2 &= ~(MACCFG2_FULL_DUPLEX); 932 933 switch (priv->speed) { 934 case 1000: 935 regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF)) 936 | MACCFG2_GMII); 937 break; 938 case 100: 939 case 10: 940 regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF)) 941 | MACCFG2_MII); 942 943 /* Set R100 bit in all modes although 944 * it is only used in RGMII mode 945 */ 946 if (priv->speed == 100) 947 regs->ecntrl |= ECNTRL_R100; 948 else 949 regs->ecntrl &= ~(ECNTRL_R100); 950 break; 951 default: 952 printf("%s: Speed was bad\n", dev->name); 953 break; 954 } 955 956 printf("Speed: %d, %s duplex%s\n", priv->speed, 957 (priv->duplexity) ? "full" : "half", 958 (priv->flags & TSEC_FIBER) ? ", fiber mode" : ""); 959 960 } else { 961 printf("%s: No link.\n", dev->name); 962 } 963 } 964 965 /* Set up the buffers and their descriptors, and bring up the 966 * interface 967 */ 968 static void startup_tsec(struct eth_device *dev) 969 { 970 int i; 971 struct tsec_private *priv = (struct tsec_private *)dev->priv; 972 volatile tsec_t *regs = priv->regs; 973 974 /* Point to the buffer descriptors */ 975 regs->tbase = (unsigned int)(&rtx.txbd[txIdx]); 976 regs->rbase = (unsigned int)(&rtx.rxbd[rxIdx]); 977 978 /* Initialize the Rx Buffer descriptors */ 979 for (i = 0; i < PKTBUFSRX; i++) { 980 rtx.rxbd[i].status = RXBD_EMPTY; 981 rtx.rxbd[i].length = 0; 982 rtx.rxbd[i].bufPtr = (uint) NetRxPackets[i]; 983 } 984 rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP; 985 986 /* Initialize the TX Buffer Descriptors */ 987 for (i = 0; i < TX_BUF_CNT; i++) { 988 rtx.txbd[i].status = 0; 989 rtx.txbd[i].length = 0; 990 rtx.txbd[i].bufPtr = 0; 991 } 992 rtx.txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP; 993 994 /* Start up the PHY */ 995 if(priv->phyinfo) 996 phy_run_commands(priv, priv->phyinfo->startup); 997 998 adjust_link(dev); 999 1000 /* Enable Transmit and Receive */ 1001 regs->maccfg1 |= (MACCFG1_RX_EN | MACCFG1_TX_EN); 1002 1003 /* Tell the DMA it is clear to go */ 1004 regs->dmactrl |= DMACTRL_INIT_SETTINGS; 1005 regs->tstat = TSTAT_CLEAR_THALT; 1006 regs->rstat = RSTAT_CLEAR_RHALT; 1007 regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS); 1008 } 1009 1010 /* This returns the status bits of the device. The return value 1011 * is never checked, and this is what the 8260 driver did, so we 1012 * do the same. Presumably, this would be zero if there were no 1013 * errors 1014 */ 1015 static int tsec_send(struct eth_device *dev, volatile void *packet, int length) 1016 { 1017 int i; 1018 int result = 0; 1019 struct tsec_private *priv = (struct tsec_private *)dev->priv; 1020 volatile tsec_t *regs = priv->regs; 1021 1022 /* Find an empty buffer descriptor */ 1023 for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) { 1024 if (i >= TOUT_LOOP) { 1025 debug("%s: tsec: tx buffers full\n", dev->name); 1026 return result; 1027 } 1028 } 1029 1030 rtx.txbd[txIdx].bufPtr = (uint) packet; 1031 rtx.txbd[txIdx].length = length; 1032 rtx.txbd[txIdx].status |= 1033 (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT); 1034 1035 /* Tell the DMA to go */ 1036 regs->tstat = TSTAT_CLEAR_THALT; 1037 1038 /* Wait for buffer to be transmitted */ 1039 for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) { 1040 if (i >= TOUT_LOOP) { 1041 debug("%s: tsec: tx error\n", dev->name); 1042 return result; 1043 } 1044 } 1045 1046 txIdx = (txIdx + 1) % TX_BUF_CNT; 1047 result = rtx.txbd[txIdx].status & TXBD_STATS; 1048 1049 return result; 1050 } 1051 1052 static int tsec_recv(struct eth_device *dev) 1053 { 1054 int length; 1055 struct tsec_private *priv = (struct tsec_private *)dev->priv; 1056 volatile tsec_t *regs = priv->regs; 1057 1058 while (!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) { 1059 1060 length = rtx.rxbd[rxIdx].length; 1061 1062 /* Send the packet up if there were no errors */ 1063 if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) { 1064 NetReceive(NetRxPackets[rxIdx], length - 4); 1065 } else { 1066 printf("Got error %x\n", 1067 (rtx.rxbd[rxIdx].status & RXBD_STATS)); 1068 } 1069 1070 rtx.rxbd[rxIdx].length = 0; 1071 1072 /* Set the wrap bit if this is the last element in the list */ 1073 rtx.rxbd[rxIdx].status = 1074 RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); 1075 1076 rxIdx = (rxIdx + 1) % PKTBUFSRX; 1077 } 1078 1079 if (regs->ievent & IEVENT_BSY) { 1080 regs->ievent = IEVENT_BSY; 1081 regs->rstat = RSTAT_CLEAR_RHALT; 1082 } 1083 1084 return -1; 1085 1086 } 1087 1088 /* Stop the interface */ 1089 static void tsec_halt(struct eth_device *dev) 1090 { 1091 struct tsec_private *priv = (struct tsec_private *)dev->priv; 1092 volatile tsec_t *regs = priv->regs; 1093 1094 regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS); 1095 regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS); 1096 1097 while ((regs->ievent & (IEVENT_GRSC | IEVENT_GTSC)) 1098 != (IEVENT_GRSC | IEVENT_GTSC)) ; 1099 1100 regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN); 1101 1102 /* Shut down the PHY, as needed */ 1103 if(priv->phyinfo) 1104 phy_run_commands(priv, priv->phyinfo->shutdown); 1105 } 1106 1107 static struct phy_info phy_info_M88E1149S = { 1108 0x1410ca, 1109 "Marvell 88E1149S", 1110 4, 1111 (struct phy_cmd[]) { /* config */ 1112 /* Reset and configure the PHY */ 1113 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1114 {0x1d, 0x1f, NULL}, 1115 {0x1e, 0x200c, NULL}, 1116 {0x1d, 0x5, NULL}, 1117 {0x1e, 0x0, NULL}, 1118 {0x1e, 0x100, NULL}, 1119 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1120 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1121 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1122 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1123 {miim_end,} 1124 }, 1125 (struct phy_cmd[]) { /* startup */ 1126 /* Status is read once to clear old link state */ 1127 {MIIM_STATUS, miim_read, NULL}, 1128 /* Auto-negotiate */ 1129 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1130 /* Read the status */ 1131 {MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr}, 1132 {miim_end,} 1133 }, 1134 (struct phy_cmd[]) { /* shutdown */ 1135 {miim_end,} 1136 }, 1137 }; 1138 1139 /* The 5411 id is 0x206070, the 5421 is 0x2060e0 */ 1140 static struct phy_info phy_info_BCM5461S = { 1141 0x02060c1, /* 5461 ID */ 1142 "Broadcom BCM5461S", 1143 0, /* not clear to me what minor revisions we can shift away */ 1144 (struct phy_cmd[]) { /* config */ 1145 /* Reset and configure the PHY */ 1146 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1147 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1148 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1149 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1150 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1151 {miim_end,} 1152 }, 1153 (struct phy_cmd[]) { /* startup */ 1154 /* Status is read once to clear old link state */ 1155 {MIIM_STATUS, miim_read, NULL}, 1156 /* Auto-negotiate */ 1157 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1158 /* Read the status */ 1159 {MIIM_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr}, 1160 {miim_end,} 1161 }, 1162 (struct phy_cmd[]) { /* shutdown */ 1163 {miim_end,} 1164 }, 1165 }; 1166 1167 static struct phy_info phy_info_BCM5464S = { 1168 0x02060b1, /* 5464 ID */ 1169 "Broadcom BCM5464S", 1170 0, /* not clear to me what minor revisions we can shift away */ 1171 (struct phy_cmd[]) { /* config */ 1172 /* Reset and configure the PHY */ 1173 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1174 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1175 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1176 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1177 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1178 {miim_end,} 1179 }, 1180 (struct phy_cmd[]) { /* startup */ 1181 /* Status is read once to clear old link state */ 1182 {MIIM_STATUS, miim_read, NULL}, 1183 /* Auto-negotiate */ 1184 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1185 /* Read the status */ 1186 {MIIM_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr}, 1187 {miim_end,} 1188 }, 1189 (struct phy_cmd[]) { /* shutdown */ 1190 {miim_end,} 1191 }, 1192 }; 1193 1194 static struct phy_info phy_info_BCM5482S = { 1195 0x0143bcb, 1196 "Broadcom BCM5482S", 1197 4, 1198 (struct phy_cmd[]) { /* config */ 1199 /* Reset and configure the PHY */ 1200 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1201 /* Setup read from auxilary control shadow register 7 */ 1202 {MIIM_BCM54xx_AUXCNTL, MIIM_BCM54xx_AUXCNTL_ENCODE(7), NULL}, 1203 /* Read Misc Control register and or in Ethernet@Wirespeed */ 1204 {MIIM_BCM54xx_AUXCNTL, 0, &mii_BCM54xx_wirespeed}, 1205 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1206 /* Initial config/enable of secondary SerDes interface */ 1207 {MIIM_BCM54XX_SHD, MIIM_BCM54XX_SHD_WR_ENCODE(0x14, 0xf), NULL}, 1208 /* Write intial value to secondary SerDes Contol */ 1209 {MIIM_BCM54XX_EXP_SEL, MIIM_BCM54XX_EXP_SEL_SSD | 0, NULL}, 1210 {MIIM_BCM54XX_EXP_DATA, MIIM_CONTROL_RESTART, NULL}, 1211 /* Enable copper/fiber auto-detect */ 1212 {MIIM_BCM54XX_SHD, MIIM_BCM54XX_SHD_WR_ENCODE(0x1e, 0x201)}, 1213 {miim_end,} 1214 }, 1215 (struct phy_cmd[]) { /* startup */ 1216 /* Status is read once to clear old link state */ 1217 {MIIM_STATUS, miim_read, NULL}, 1218 /* Determine copper/fiber, auto-negotiate, and read the result */ 1219 {MIIM_STATUS, miim_read, &mii_parse_BCM5482_sr}, 1220 {miim_end,} 1221 }, 1222 (struct phy_cmd[]) { /* shutdown */ 1223 {miim_end,} 1224 }, 1225 }; 1226 1227 static struct phy_info phy_info_M88E1011S = { 1228 0x01410c6, 1229 "Marvell 88E1011S", 1230 4, 1231 (struct phy_cmd[]) { /* config */ 1232 /* Reset and configure the PHY */ 1233 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1234 {0x1d, 0x1f, NULL}, 1235 {0x1e, 0x200c, NULL}, 1236 {0x1d, 0x5, NULL}, 1237 {0x1e, 0x0, NULL}, 1238 {0x1e, 0x100, NULL}, 1239 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1240 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1241 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1242 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1243 {miim_end,} 1244 }, 1245 (struct phy_cmd[]) { /* startup */ 1246 /* Status is read once to clear old link state */ 1247 {MIIM_STATUS, miim_read, NULL}, 1248 /* Auto-negotiate */ 1249 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1250 /* Read the status */ 1251 {MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr}, 1252 {miim_end,} 1253 }, 1254 (struct phy_cmd[]) { /* shutdown */ 1255 {miim_end,} 1256 }, 1257 }; 1258 1259 static struct phy_info phy_info_M88E1111S = { 1260 0x01410cc, 1261 "Marvell 88E1111S", 1262 4, 1263 (struct phy_cmd[]) { /* config */ 1264 /* Reset and configure the PHY */ 1265 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1266 {0x1b, 0x848f, &mii_m88e1111s_setmode}, 1267 {0x14, 0x0cd2, NULL}, /* Delay RGMII TX and RX */ 1268 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1269 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1270 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1271 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1272 {miim_end,} 1273 }, 1274 (struct phy_cmd[]) { /* startup */ 1275 /* Status is read once to clear old link state */ 1276 {MIIM_STATUS, miim_read, NULL}, 1277 /* Auto-negotiate */ 1278 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1279 /* Read the status */ 1280 {MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr}, 1281 {miim_end,} 1282 }, 1283 (struct phy_cmd[]) { /* shutdown */ 1284 {miim_end,} 1285 }, 1286 }; 1287 1288 static struct phy_info phy_info_M88E1118 = { 1289 0x01410e1, 1290 "Marvell 88E1118", 1291 4, 1292 (struct phy_cmd[]) { /* config */ 1293 /* Reset and configure the PHY */ 1294 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1295 {0x16, 0x0002, NULL}, /* Change Page Number */ 1296 {0x15, 0x1070, NULL}, /* Delay RGMII TX and RX */ 1297 {0x16, 0x0003, NULL}, /* Change Page Number */ 1298 {0x10, 0x021e, NULL}, /* Adjust LED control */ 1299 {0x16, 0x0000, NULL}, /* Change Page Number */ 1300 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1301 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1302 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1303 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1304 {miim_end,} 1305 }, 1306 (struct phy_cmd[]) { /* startup */ 1307 {0x16, 0x0000, NULL}, /* Change Page Number */ 1308 /* Status is read once to clear old link state */ 1309 {MIIM_STATUS, miim_read, NULL}, 1310 /* Auto-negotiate */ 1311 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1312 /* Read the status */ 1313 {MIIM_88E1011_PHY_STATUS, miim_read, 1314 &mii_parse_88E1011_psr}, 1315 {miim_end,} 1316 }, 1317 (struct phy_cmd[]) { /* shutdown */ 1318 {miim_end,} 1319 }, 1320 }; 1321 1322 /* 1323 * Since to access LED register we need do switch the page, we 1324 * do LED configuring in the miim_read-like function as follows 1325 */ 1326 static uint mii_88E1121_set_led (uint mii_reg, struct tsec_private *priv) 1327 { 1328 uint pg; 1329 1330 /* Switch the page to access the led register */ 1331 pg = read_phy_reg(priv, MIIM_88E1121_PHY_PAGE); 1332 write_phy_reg(priv, MIIM_88E1121_PHY_PAGE, MIIM_88E1121_PHY_LED_PAGE); 1333 1334 /* Configure leds */ 1335 write_phy_reg(priv, MIIM_88E1121_PHY_LED_CTRL, 1336 MIIM_88E1121_PHY_LED_DEF); 1337 1338 /* Restore the page pointer */ 1339 write_phy_reg(priv, MIIM_88E1121_PHY_PAGE, pg); 1340 return 0; 1341 } 1342 1343 static struct phy_info phy_info_M88E1121R = { 1344 0x01410cb, 1345 "Marvell 88E1121R", 1346 4, 1347 (struct phy_cmd[]) { /* config */ 1348 /* Reset and configure the PHY */ 1349 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1350 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1351 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1352 /* Configure leds */ 1353 {MIIM_88E1121_PHY_LED_CTRL, miim_read, &mii_88E1121_set_led}, 1354 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1355 /* Disable IRQs and de-assert interrupt */ 1356 {MIIM_88E1121_PHY_IRQ_EN, 0, NULL}, 1357 {MIIM_88E1121_PHY_IRQ_STATUS, miim_read, NULL}, 1358 {miim_end,} 1359 }, 1360 (struct phy_cmd[]) { /* startup */ 1361 /* Status is read once to clear old link state */ 1362 {MIIM_STATUS, miim_read, NULL}, 1363 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1364 {MIIM_STATUS, miim_read, &mii_parse_link}, 1365 {miim_end,} 1366 }, 1367 (struct phy_cmd[]) { /* shutdown */ 1368 {miim_end,} 1369 }, 1370 }; 1371 1372 static unsigned int m88e1145_setmode(uint mii_reg, struct tsec_private *priv) 1373 { 1374 uint mii_data = read_phy_reg(priv, mii_reg); 1375 1376 /* Setting MIIM_88E1145_PHY_EXT_CR */ 1377 if (priv->flags & TSEC_REDUCED) 1378 return mii_data | 1379 MIIM_M88E1145_RGMII_RX_DELAY | MIIM_M88E1145_RGMII_TX_DELAY; 1380 else 1381 return mii_data; 1382 } 1383 1384 static struct phy_info phy_info_M88E1145 = { 1385 0x01410cd, 1386 "Marvell 88E1145", 1387 4, 1388 (struct phy_cmd[]) { /* config */ 1389 /* Reset the PHY */ 1390 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1391 1392 /* Errata E0, E1 */ 1393 {29, 0x001b, NULL}, 1394 {30, 0x418f, NULL}, 1395 {29, 0x0016, NULL}, 1396 {30, 0xa2da, NULL}, 1397 1398 /* Configure the PHY */ 1399 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1400 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1401 {MIIM_88E1011_PHY_SCR, MIIM_88E1011_PHY_MDI_X_AUTO, NULL}, 1402 {MIIM_88E1145_PHY_EXT_CR, 0, &m88e1145_setmode}, 1403 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1404 {MIIM_CONTROL, MIIM_CONTROL_INIT, NULL}, 1405 {miim_end,} 1406 }, 1407 (struct phy_cmd[]) { /* startup */ 1408 /* Status is read once to clear old link state */ 1409 {MIIM_STATUS, miim_read, NULL}, 1410 /* Auto-negotiate */ 1411 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1412 {MIIM_88E1111_PHY_LED_CONTROL, MIIM_88E1111_PHY_LED_DIRECT, NULL}, 1413 /* Read the Status */ 1414 {MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr}, 1415 {miim_end,} 1416 }, 1417 (struct phy_cmd[]) { /* shutdown */ 1418 {miim_end,} 1419 }, 1420 }; 1421 1422 static struct phy_info phy_info_cis8204 = { 1423 0x3f11, 1424 "Cicada Cis8204", 1425 6, 1426 (struct phy_cmd[]) { /* config */ 1427 /* Override PHY config settings */ 1428 {MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL}, 1429 /* Configure some basic stuff */ 1430 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1431 {MIIM_CIS8204_SLED_CON, MIIM_CIS8204_SLEDCON_INIT, 1432 &mii_cis8204_fixled}, 1433 {MIIM_CIS8204_EPHY_CON, MIIM_CIS8204_EPHYCON_INIT, 1434 &mii_cis8204_setmode}, 1435 {miim_end,} 1436 }, 1437 (struct phy_cmd[]) { /* startup */ 1438 /* Read the Status (2x to make sure link is right) */ 1439 {MIIM_STATUS, miim_read, NULL}, 1440 /* Auto-negotiate */ 1441 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1442 /* Read the status */ 1443 {MIIM_CIS8201_AUX_CONSTAT, miim_read, &mii_parse_cis8201}, 1444 {miim_end,} 1445 }, 1446 (struct phy_cmd[]) { /* shutdown */ 1447 {miim_end,} 1448 }, 1449 }; 1450 1451 /* Cicada 8201 */ 1452 static struct phy_info phy_info_cis8201 = { 1453 0xfc41, 1454 "CIS8201", 1455 4, 1456 (struct phy_cmd[]) { /* config */ 1457 /* Override PHY config settings */ 1458 {MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL}, 1459 /* Set up the interface mode */ 1460 {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL}, 1461 /* Configure some basic stuff */ 1462 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1463 {miim_end,} 1464 }, 1465 (struct phy_cmd[]) { /* startup */ 1466 /* Read the Status (2x to make sure link is right) */ 1467 {MIIM_STATUS, miim_read, NULL}, 1468 /* Auto-negotiate */ 1469 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1470 /* Read the status */ 1471 {MIIM_CIS8201_AUX_CONSTAT, miim_read, &mii_parse_cis8201}, 1472 {miim_end,} 1473 }, 1474 (struct phy_cmd[]) { /* shutdown */ 1475 {miim_end,} 1476 }, 1477 }; 1478 1479 static struct phy_info phy_info_VSC8211 = { 1480 0xfc4b, 1481 "Vitesse VSC8211", 1482 4, 1483 (struct phy_cmd[]) { /* config */ 1484 /* Override PHY config settings */ 1485 {MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL}, 1486 /* Set up the interface mode */ 1487 {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL}, 1488 /* Configure some basic stuff */ 1489 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1490 {miim_end,} 1491 }, 1492 (struct phy_cmd[]) { /* startup */ 1493 /* Read the Status (2x to make sure link is right) */ 1494 {MIIM_STATUS, miim_read, NULL}, 1495 /* Auto-negotiate */ 1496 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1497 /* Read the status */ 1498 {MIIM_CIS8201_AUX_CONSTAT, miim_read, &mii_parse_cis8201}, 1499 {miim_end,} 1500 }, 1501 (struct phy_cmd[]) { /* shutdown */ 1502 {miim_end,} 1503 }, 1504 }; 1505 1506 static struct phy_info phy_info_VSC8244 = { 1507 0x3f1b, 1508 "Vitesse VSC8244", 1509 6, 1510 (struct phy_cmd[]) { /* config */ 1511 /* Override PHY config settings */ 1512 /* Configure some basic stuff */ 1513 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1514 {miim_end,} 1515 }, 1516 (struct phy_cmd[]) { /* startup */ 1517 /* Read the Status (2x to make sure link is right) */ 1518 {MIIM_STATUS, miim_read, NULL}, 1519 /* Auto-negotiate */ 1520 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1521 /* Read the status */ 1522 {MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244}, 1523 {miim_end,} 1524 }, 1525 (struct phy_cmd[]) { /* shutdown */ 1526 {miim_end,} 1527 }, 1528 }; 1529 1530 static struct phy_info phy_info_VSC8641 = { 1531 0x7043, 1532 "Vitesse VSC8641", 1533 4, 1534 (struct phy_cmd[]) { /* config */ 1535 /* Configure some basic stuff */ 1536 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1537 {miim_end,} 1538 }, 1539 (struct phy_cmd[]) { /* startup */ 1540 /* Read the Status (2x to make sure link is right) */ 1541 {MIIM_STATUS, miim_read, NULL}, 1542 /* Auto-negotiate */ 1543 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1544 /* Read the status */ 1545 {MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244}, 1546 {miim_end,} 1547 }, 1548 (struct phy_cmd[]) { /* shutdown */ 1549 {miim_end,} 1550 }, 1551 }; 1552 1553 static struct phy_info phy_info_VSC8221 = { 1554 0xfc55, 1555 "Vitesse VSC8221", 1556 4, 1557 (struct phy_cmd[]) { /* config */ 1558 /* Configure some basic stuff */ 1559 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1560 {miim_end,} 1561 }, 1562 (struct phy_cmd[]) { /* startup */ 1563 /* Read the Status (2x to make sure link is right) */ 1564 {MIIM_STATUS, miim_read, NULL}, 1565 /* Auto-negotiate */ 1566 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1567 /* Read the status */ 1568 {MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244}, 1569 {miim_end,} 1570 }, 1571 (struct phy_cmd[]) { /* shutdown */ 1572 {miim_end,} 1573 }, 1574 }; 1575 1576 static struct phy_info phy_info_VSC8601 = { 1577 0x00007042, 1578 "Vitesse VSC8601", 1579 4, 1580 (struct phy_cmd[]) { /* config */ 1581 /* Override PHY config settings */ 1582 /* Configure some basic stuff */ 1583 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1584 #ifdef CONFIG_SYS_VSC8601_SKEWFIX 1585 {MIIM_VSC8601_EPHY_CON,MIIM_VSC8601_EPHY_CON_INIT_SKEW,NULL}, 1586 #if defined(CONFIG_SYS_VSC8601_SKEW_TX) && defined(CONFIG_SYS_VSC8601_SKEW_RX) 1587 {MIIM_EXT_PAGE_ACCESS,1,NULL}, 1588 #define VSC8101_SKEW \ 1589 (CONFIG_SYS_VSC8601_SKEW_TX << 14) | (CONFIG_SYS_VSC8601_SKEW_RX << 12) 1590 {MIIM_VSC8601_SKEW_CTRL,VSC8101_SKEW,NULL}, 1591 {MIIM_EXT_PAGE_ACCESS,0,NULL}, 1592 #endif 1593 #endif 1594 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1595 {MIIM_CONTROL, MIIM_CONTROL_RESTART, &mii_cr_init}, 1596 {miim_end,} 1597 }, 1598 (struct phy_cmd[]) { /* startup */ 1599 /* Read the Status (2x to make sure link is right) */ 1600 {MIIM_STATUS, miim_read, NULL}, 1601 /* Auto-negotiate */ 1602 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1603 /* Read the status */ 1604 {MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244}, 1605 {miim_end,} 1606 }, 1607 (struct phy_cmd[]) { /* shutdown */ 1608 {miim_end,} 1609 }, 1610 }; 1611 1612 static struct phy_info phy_info_dm9161 = { 1613 0x0181b88, 1614 "Davicom DM9161E", 1615 4, 1616 (struct phy_cmd[]) { /* config */ 1617 {MIIM_CONTROL, MIIM_DM9161_CR_STOP, NULL}, 1618 /* Do not bypass the scrambler/descrambler */ 1619 {MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT, NULL}, 1620 /* Clear 10BTCSR to default */ 1621 {MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT, NULL}, 1622 /* Configure some basic stuff */ 1623 {MIIM_CONTROL, MIIM_CR_INIT, NULL}, 1624 /* Restart Auto Negotiation */ 1625 {MIIM_CONTROL, MIIM_DM9161_CR_RSTAN, NULL}, 1626 {miim_end,} 1627 }, 1628 (struct phy_cmd[]) { /* startup */ 1629 /* Status is read once to clear old link state */ 1630 {MIIM_STATUS, miim_read, NULL}, 1631 /* Auto-negotiate */ 1632 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1633 /* Read the status */ 1634 {MIIM_DM9161_SCSR, miim_read, &mii_parse_dm9161_scsr}, 1635 {miim_end,} 1636 }, 1637 (struct phy_cmd[]) { /* shutdown */ 1638 {miim_end,} 1639 }, 1640 }; 1641 1642 /* micrel KSZ804 */ 1643 static struct phy_info phy_info_ksz804 = { 1644 0x0022151, 1645 "Micrel KSZ804 PHY", 1646 4, 1647 (struct phy_cmd[]) { /* config */ 1648 {MII_BMCR, BMCR_RESET, NULL}, 1649 {MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART, NULL}, 1650 {miim_end,} 1651 }, 1652 (struct phy_cmd[]) { /* startup */ 1653 {MII_BMSR, miim_read, NULL}, 1654 {MII_BMSR, miim_read, &mii_parse_sr}, 1655 {MII_BMSR, miim_read, &mii_parse_link}, 1656 {miim_end,} 1657 }, 1658 (struct phy_cmd[]) { /* shutdown */ 1659 {miim_end,} 1660 } 1661 }; 1662 1663 /* a generic flavor. */ 1664 static struct phy_info phy_info_generic = { 1665 0, 1666 "Unknown/Generic PHY", 1667 32, 1668 (struct phy_cmd[]) { /* config */ 1669 {MII_BMCR, BMCR_RESET, NULL}, 1670 {MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART, NULL}, 1671 {miim_end,} 1672 }, 1673 (struct phy_cmd[]) { /* startup */ 1674 {MII_BMSR, miim_read, NULL}, 1675 {MII_BMSR, miim_read, &mii_parse_sr}, 1676 {MII_BMSR, miim_read, &mii_parse_link}, 1677 {miim_end,} 1678 }, 1679 (struct phy_cmd[]) { /* shutdown */ 1680 {miim_end,} 1681 } 1682 }; 1683 1684 static uint mii_parse_lxt971_sr2(uint mii_reg, struct tsec_private *priv) 1685 { 1686 unsigned int speed; 1687 if (priv->link) { 1688 speed = mii_reg & MIIM_LXT971_SR2_SPEED_MASK; 1689 1690 switch (speed) { 1691 case MIIM_LXT971_SR2_10HDX: 1692 priv->speed = 10; 1693 priv->duplexity = 0; 1694 break; 1695 case MIIM_LXT971_SR2_10FDX: 1696 priv->speed = 10; 1697 priv->duplexity = 1; 1698 break; 1699 case MIIM_LXT971_SR2_100HDX: 1700 priv->speed = 100; 1701 priv->duplexity = 0; 1702 break; 1703 default: 1704 priv->speed = 100; 1705 priv->duplexity = 1; 1706 } 1707 } else { 1708 priv->speed = 0; 1709 priv->duplexity = 0; 1710 } 1711 1712 return 0; 1713 } 1714 1715 static struct phy_info phy_info_lxt971 = { 1716 0x0001378e, 1717 "LXT971", 1718 4, 1719 (struct phy_cmd[]) { /* config */ 1720 {MIIM_CR, MIIM_CR_INIT, mii_cr_init}, /* autonegotiate */ 1721 {miim_end,} 1722 }, 1723 (struct phy_cmd[]) { /* startup - enable interrupts */ 1724 /* { 0x12, 0x00f2, NULL }, */ 1725 {MIIM_STATUS, miim_read, NULL}, 1726 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1727 {MIIM_LXT971_SR2, miim_read, &mii_parse_lxt971_sr2}, 1728 {miim_end,} 1729 }, 1730 (struct phy_cmd[]) { /* shutdown - disable interrupts */ 1731 {miim_end,} 1732 }, 1733 }; 1734 1735 /* Parse the DP83865's link and auto-neg status register for speed and duplex 1736 * information 1737 */ 1738 static uint mii_parse_dp83865_lanr(uint mii_reg, struct tsec_private *priv) 1739 { 1740 switch (mii_reg & MIIM_DP83865_SPD_MASK) { 1741 1742 case MIIM_DP83865_SPD_1000: 1743 priv->speed = 1000; 1744 break; 1745 1746 case MIIM_DP83865_SPD_100: 1747 priv->speed = 100; 1748 break; 1749 1750 default: 1751 priv->speed = 10; 1752 break; 1753 1754 } 1755 1756 if (mii_reg & MIIM_DP83865_DPX_FULL) 1757 priv->duplexity = 1; 1758 else 1759 priv->duplexity = 0; 1760 1761 return 0; 1762 } 1763 1764 static struct phy_info phy_info_dp83865 = { 1765 0x20005c7, 1766 "NatSemi DP83865", 1767 4, 1768 (struct phy_cmd[]) { /* config */ 1769 {MIIM_CONTROL, MIIM_DP83865_CR_INIT, NULL}, 1770 {miim_end,} 1771 }, 1772 (struct phy_cmd[]) { /* startup */ 1773 /* Status is read once to clear old link state */ 1774 {MIIM_STATUS, miim_read, NULL}, 1775 /* Auto-negotiate */ 1776 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1777 /* Read the link and auto-neg status */ 1778 {MIIM_DP83865_LANR, miim_read, &mii_parse_dp83865_lanr}, 1779 {miim_end,} 1780 }, 1781 (struct phy_cmd[]) { /* shutdown */ 1782 {miim_end,} 1783 }, 1784 }; 1785 1786 static struct phy_info phy_info_rtl8211b = { 1787 0x001cc91, 1788 "RealTek RTL8211B", 1789 4, 1790 (struct phy_cmd[]) { /* config */ 1791 /* Reset and configure the PHY */ 1792 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1793 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1794 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1795 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1796 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1797 {miim_end,} 1798 }, 1799 (struct phy_cmd[]) { /* startup */ 1800 /* Status is read once to clear old link state */ 1801 {MIIM_STATUS, miim_read, NULL}, 1802 /* Auto-negotiate */ 1803 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1804 /* Read the status */ 1805 {MIIM_RTL8211B_PHY_STATUS, miim_read, &mii_parse_RTL8211B_sr}, 1806 {miim_end,} 1807 }, 1808 (struct phy_cmd[]) { /* shutdown */ 1809 {miim_end,} 1810 }, 1811 }; 1812 1813 static struct phy_info *phy_info[] = { 1814 &phy_info_cis8204, 1815 &phy_info_cis8201, 1816 &phy_info_BCM5461S, 1817 &phy_info_BCM5464S, 1818 &phy_info_BCM5482S, 1819 &phy_info_M88E1011S, 1820 &phy_info_M88E1111S, 1821 &phy_info_M88E1118, 1822 &phy_info_M88E1121R, 1823 &phy_info_M88E1145, 1824 &phy_info_M88E1149S, 1825 &phy_info_dm9161, 1826 &phy_info_ksz804, 1827 &phy_info_lxt971, 1828 &phy_info_VSC8211, 1829 &phy_info_VSC8244, 1830 &phy_info_VSC8601, 1831 &phy_info_VSC8641, 1832 &phy_info_VSC8221, 1833 &phy_info_dp83865, 1834 &phy_info_rtl8211b, 1835 &phy_info_generic, /* must be last; has ID 0 and 32 bit mask */ 1836 NULL 1837 }; 1838 1839 /* Grab the identifier of the device's PHY, and search through 1840 * all of the known PHYs to see if one matches. If so, return 1841 * it, if not, return NULL 1842 */ 1843 static struct phy_info *get_phy_info(struct eth_device *dev) 1844 { 1845 struct tsec_private *priv = (struct tsec_private *)dev->priv; 1846 uint phy_reg, phy_ID; 1847 int i; 1848 struct phy_info *theInfo = NULL; 1849 1850 /* Grab the bits from PHYIR1, and put them in the upper half */ 1851 phy_reg = read_phy_reg(priv, MIIM_PHYIR1); 1852 phy_ID = (phy_reg & 0xffff) << 16; 1853 1854 /* Grab the bits from PHYIR2, and put them in the lower half */ 1855 phy_reg = read_phy_reg(priv, MIIM_PHYIR2); 1856 phy_ID |= (phy_reg & 0xffff); 1857 1858 /* loop through all the known PHY types, and find one that */ 1859 /* matches the ID we read from the PHY. */ 1860 for (i = 0; phy_info[i]; i++) { 1861 if (phy_info[i]->id == (phy_ID >> phy_info[i]->shift)) { 1862 theInfo = phy_info[i]; 1863 break; 1864 } 1865 } 1866 1867 if (theInfo == &phy_info_generic) { 1868 printf("%s: No support for PHY id %x; assuming generic\n", 1869 dev->name, phy_ID); 1870 } else { 1871 debug("%s: PHY is %s (%x)\n", dev->name, theInfo->name, phy_ID); 1872 } 1873 1874 return theInfo; 1875 } 1876 1877 /* Execute the given series of commands on the given device's 1878 * PHY, running functions as necessary 1879 */ 1880 static void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd) 1881 { 1882 int i; 1883 uint result; 1884 volatile tsec_mdio_t *phyregs = priv->phyregs; 1885 1886 phyregs->miimcfg = MIIMCFG_RESET; 1887 1888 phyregs->miimcfg = MIIMCFG_INIT_VALUE; 1889 1890 while (phyregs->miimind & MIIMIND_BUSY) ; 1891 1892 for (i = 0; cmd->mii_reg != miim_end; i++) { 1893 if (cmd->mii_data == miim_read) { 1894 result = read_phy_reg(priv, cmd->mii_reg); 1895 1896 if (cmd->funct != NULL) 1897 (*(cmd->funct)) (result, priv); 1898 1899 } else { 1900 if (cmd->funct != NULL) 1901 result = (*(cmd->funct)) (cmd->mii_reg, priv); 1902 else 1903 result = cmd->mii_data; 1904 1905 write_phy_reg(priv, cmd->mii_reg, result); 1906 1907 } 1908 cmd++; 1909 } 1910 } 1911 1912 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \ 1913 && !defined(BITBANGMII) 1914 1915 /* 1916 * Read a MII PHY register. 1917 * 1918 * Returns: 1919 * 0 on success 1920 */ 1921 static int tsec_miiphy_read(const char *devname, unsigned char addr, 1922 unsigned char reg, unsigned short *value) 1923 { 1924 unsigned short ret; 1925 struct tsec_private *priv = privlist[0]; 1926 1927 if (NULL == priv) { 1928 printf("Can't read PHY at address %d\n", addr); 1929 return -1; 1930 } 1931 1932 ret = (unsigned short)tsec_local_mdio_read(priv->phyregs, addr, reg); 1933 *value = ret; 1934 1935 return 0; 1936 } 1937 1938 /* 1939 * Write a MII PHY register. 1940 * 1941 * Returns: 1942 * 0 on success 1943 */ 1944 static int tsec_miiphy_write(const char *devname, unsigned char addr, 1945 unsigned char reg, unsigned short value) 1946 { 1947 struct tsec_private *priv = privlist[0]; 1948 1949 if (NULL == priv) { 1950 printf("Can't write PHY at address %d\n", addr); 1951 return -1; 1952 } 1953 1954 tsec_local_mdio_write(priv->phyregs, addr, reg, value); 1955 1956 return 0; 1957 } 1958 1959 #endif 1960 1961 #ifdef CONFIG_MCAST_TFTP 1962 1963 /* CREDITS: linux gianfar driver, slightly adjusted... thanx. */ 1964 1965 /* Set the appropriate hash bit for the given addr */ 1966 1967 /* The algorithm works like so: 1968 * 1) Take the Destination Address (ie the multicast address), and 1969 * do a CRC on it (little endian), and reverse the bits of the 1970 * result. 1971 * 2) Use the 8 most significant bits as a hash into a 256-entry 1972 * table. The table is controlled through 8 32-bit registers: 1973 * gaddr0-7. gaddr0's MSB is entry 0, and gaddr7's LSB is 1974 * gaddr7. This means that the 3 most significant bits in the 1975 * hash index which gaddr register to use, and the 5 other bits 1976 * indicate which bit (assuming an IBM numbering scheme, which 1977 * for PowerPC (tm) is usually the case) in the tregister holds 1978 * the entry. */ 1979 static int 1980 tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set) 1981 { 1982 struct tsec_private *priv = privlist[1]; 1983 volatile tsec_t *regs = priv->regs; 1984 volatile u32 *reg_array, value; 1985 u8 result, whichbit, whichreg; 1986 1987 result = (u8)((ether_crc(MAC_ADDR_LEN,mcast_mac) >> 24) & 0xff); 1988 whichbit = result & 0x1f; /* the 5 LSB = which bit to set */ 1989 whichreg = result >> 5; /* the 3 MSB = which reg to set it in */ 1990 value = (1 << (31-whichbit)); 1991 1992 reg_array = &(regs->hash.gaddr0); 1993 1994 if (set) { 1995 reg_array[whichreg] |= value; 1996 } else { 1997 reg_array[whichreg] &= ~value; 1998 } 1999 return 0; 2000 } 2001 #endif /* Multicast TFTP ? */ 2002