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