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, 2007 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 20 #if defined(CONFIG_TSEC_ENET) 21 #include "tsec.h" 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 struct tsec_info_struct { 37 unsigned int phyaddr; 38 u32 flags; 39 unsigned int phyregidx; 40 }; 41 42 /* The tsec_info structure contains 3 values which the 43 * driver uses to determine how to operate a given ethernet 44 * device. The information needed is: 45 * phyaddr - The address of the PHY which is attached to 46 * the given device. 47 * 48 * flags - This variable indicates whether the device 49 * supports gigabit speed ethernet, and whether it should be 50 * in reduced mode. 51 * 52 * phyregidx - This variable specifies which ethernet device 53 * controls the MII Management registers which are connected 54 * to the PHY. For now, only TSEC1 (index 0) has 55 * access to the PHYs, so all of the entries have "0". 56 * 57 * The values specified in the table are taken from the board's 58 * config file in include/configs/. When implementing a new 59 * board with ethernet capability, it is necessary to define: 60 * TSECn_PHY_ADDR 61 * TSECn_PHYIDX 62 * 63 * for n = 1,2,3, etc. And for FEC: 64 * FEC_PHY_ADDR 65 * FEC_PHYIDX 66 */ 67 static struct tsec_info_struct tsec_info[] = { 68 #ifdef CONFIG_TSEC1 69 {TSEC1_PHY_ADDR, TSEC1_FLAGS, TSEC1_PHYIDX}, 70 #else 71 {0, 0, 0}, 72 #endif 73 #ifdef CONFIG_TSEC2 74 {TSEC2_PHY_ADDR, TSEC2_FLAGS, TSEC2_PHYIDX}, 75 #else 76 {0, 0, 0}, 77 #endif 78 #ifdef CONFIG_MPC85XX_FEC 79 {FEC_PHY_ADDR, FEC_FLAGS, FEC_PHYIDX}, 80 #else 81 #ifdef CONFIG_TSEC3 82 {TSEC3_PHY_ADDR, TSEC3_FLAGS, TSEC3_PHYIDX}, 83 #else 84 {0, 0, 0}, 85 #endif 86 #ifdef CONFIG_TSEC4 87 {TSEC4_PHY_ADDR, TSEC4_FLAGS, TSEC4_PHYIDX}, 88 #else 89 {0, 0, 0}, 90 #endif /* CONFIG_TSEC4 */ 91 #endif /* CONFIG_MPC85XX_FEC */ 92 }; 93 94 #define MAXCONTROLLERS (4) 95 96 static int relocated = 0; 97 98 static struct tsec_private *privlist[MAXCONTROLLERS]; 99 100 #ifdef __GNUC__ 101 static RTXBD rtx __attribute__ ((aligned(8))); 102 #else 103 #error "rtx must be 64-bit aligned" 104 #endif 105 106 static int tsec_send(struct eth_device *dev, 107 volatile void *packet, int length); 108 static int tsec_recv(struct eth_device *dev); 109 static int tsec_init(struct eth_device *dev, bd_t * bd); 110 static void tsec_halt(struct eth_device *dev); 111 static void init_registers(volatile tsec_t * regs); 112 static void startup_tsec(struct eth_device *dev); 113 static int init_phy(struct eth_device *dev); 114 void write_phy_reg(struct tsec_private *priv, uint regnum, uint value); 115 uint read_phy_reg(struct tsec_private *priv, uint regnum); 116 struct phy_info *get_phy_info(struct eth_device *dev); 117 void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd); 118 static void adjust_link(struct eth_device *dev); 119 static void relocate_cmds(void); 120 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \ 121 && !defined(BITBANGMII) 122 static int tsec_miiphy_write(char *devname, unsigned char addr, 123 unsigned char reg, unsigned short value); 124 static int tsec_miiphy_read(char *devname, unsigned char addr, 125 unsigned char reg, unsigned short *value); 126 #endif 127 #ifdef CONFIG_MCAST_TFTP 128 static int tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set); 129 #endif 130 131 /* Initialize device structure. Returns success if PHY 132 * initialization succeeded (i.e. if it recognizes the PHY) 133 */ 134 int tsec_initialize(bd_t * bis, int index, char *devname) 135 { 136 struct eth_device *dev; 137 int i; 138 struct tsec_private *priv; 139 140 dev = (struct eth_device *)malloc(sizeof *dev); 141 142 if (NULL == dev) 143 return 0; 144 145 memset(dev, 0, sizeof *dev); 146 147 priv = (struct tsec_private *)malloc(sizeof(*priv)); 148 149 if (NULL == priv) 150 return 0; 151 152 privlist[index] = priv; 153 priv->regs = (volatile tsec_t *)(TSEC_BASE_ADDR + index * TSEC_SIZE); 154 priv->phyregs = (volatile tsec_t *)(TSEC_BASE_ADDR + 155 tsec_info[index].phyregidx * 156 TSEC_SIZE); 157 158 priv->phyaddr = tsec_info[index].phyaddr; 159 priv->flags = tsec_info[index].flags; 160 161 sprintf(dev->name, devname); 162 dev->iobase = 0; 163 dev->priv = priv; 164 dev->init = tsec_init; 165 dev->halt = tsec_halt; 166 dev->send = tsec_send; 167 dev->recv = tsec_recv; 168 #ifdef CONFIG_MCAST_TFTP 169 dev->mcast = tsec_mcast_addr; 170 #endif 171 172 /* Tell u-boot to get the addr from the env */ 173 for (i = 0; i < 6; i++) 174 dev->enetaddr[i] = 0; 175 176 eth_register(dev); 177 178 /* Reset the MAC */ 179 priv->regs->maccfg1 |= MACCFG1_SOFT_RESET; 180 priv->regs->maccfg1 &= ~(MACCFG1_SOFT_RESET); 181 182 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \ 183 && !defined(BITBANGMII) 184 miiphy_register(dev->name, tsec_miiphy_read, tsec_miiphy_write); 185 #endif 186 187 /* Try to initialize PHY here, and return */ 188 return init_phy(dev); 189 } 190 191 /* Initializes data structures and registers for the controller, 192 * and brings the interface up. Returns the link status, meaning 193 * that it returns success if the link is up, failure otherwise. 194 * This allows u-boot to find the first active controller. 195 */ 196 int tsec_init(struct eth_device *dev, bd_t * bd) 197 { 198 uint tempval; 199 char tmpbuf[MAC_ADDR_LEN]; 200 int i; 201 struct tsec_private *priv = (struct tsec_private *)dev->priv; 202 volatile tsec_t *regs = priv->regs; 203 204 /* Make sure the controller is stopped */ 205 tsec_halt(dev); 206 207 /* Init MACCFG2. Defaults to GMII */ 208 regs->maccfg2 = MACCFG2_INIT_SETTINGS; 209 210 /* Init ECNTRL */ 211 regs->ecntrl = ECNTRL_INIT_SETTINGS; 212 213 /* Copy the station address into the address registers. 214 * Backwards, because little endian MACS are dumb */ 215 for (i = 0; i < MAC_ADDR_LEN; i++) { 216 tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->enetaddr[i]; 217 } 218 regs->macstnaddr1 = *((uint *) (tmpbuf)); 219 220 tempval = *((uint *) (tmpbuf + 4)); 221 222 regs->macstnaddr2 = tempval; 223 224 /* reset the indices to zero */ 225 rxIdx = 0; 226 txIdx = 0; 227 228 /* Clear out (for the most part) the other registers */ 229 init_registers(regs); 230 231 /* Ready the device for tx/rx */ 232 startup_tsec(dev); 233 234 /* If there's no link, fail */ 235 return priv->link; 236 237 } 238 239 /* Write value to the device's PHY through the registers 240 * specified in priv, modifying the register specified in regnum. 241 * It will wait for the write to be done (or for a timeout to 242 * expire) before exiting 243 */ 244 void write_phy_reg(struct tsec_private *priv, uint regnum, uint value) 245 { 246 volatile tsec_t *regbase = priv->phyregs; 247 uint phyid = priv->phyaddr; 248 int timeout = 1000000; 249 250 regbase->miimadd = (phyid << 8) | regnum; 251 regbase->miimcon = value; 252 asm("sync"); 253 254 timeout = 1000000; 255 while ((regbase->miimind & MIIMIND_BUSY) && timeout--) ; 256 } 257 258 /* Reads register regnum on the device's PHY through the 259 * registers specified in priv. It lowers and raises the read 260 * command, and waits for the data to become valid (miimind 261 * notvalid bit cleared), and the bus to cease activity (miimind 262 * busy bit cleared), and then returns the value 263 */ 264 uint read_phy_reg(struct tsec_private *priv, uint regnum) 265 { 266 uint value; 267 volatile tsec_t *regbase = priv->phyregs; 268 uint phyid = priv->phyaddr; 269 270 /* Put the address of the phy, and the register 271 * number into MIIMADD */ 272 regbase->miimadd = (phyid << 8) | regnum; 273 274 /* Clear the command register, and wait */ 275 regbase->miimcom = 0; 276 asm("sync"); 277 278 /* Initiate a read command, and wait */ 279 regbase->miimcom = MIIM_READ_COMMAND; 280 asm("sync"); 281 282 /* Wait for the the indication that the read is done */ 283 while ((regbase->miimind & (MIIMIND_NOTVALID | MIIMIND_BUSY))) ; 284 285 /* Grab the value read from the PHY */ 286 value = regbase->miimstat; 287 288 return value; 289 } 290 291 /* Discover which PHY is attached to the device, and configure it 292 * properly. If the PHY is not recognized, then return 0 293 * (failure). Otherwise, return 1 294 */ 295 static int init_phy(struct eth_device *dev) 296 { 297 struct tsec_private *priv = (struct tsec_private *)dev->priv; 298 struct phy_info *curphy; 299 volatile tsec_t *regs = (volatile tsec_t *)(TSEC_BASE_ADDR); 300 301 /* Assign a Physical address to the TBI */ 302 regs->tbipa = CFG_TBIPA_VALUE; 303 regs = (volatile tsec_t *)(TSEC_BASE_ADDR + TSEC_SIZE); 304 regs->tbipa = CFG_TBIPA_VALUE; 305 asm("sync"); 306 307 /* Reset MII (due to new addresses) */ 308 priv->phyregs->miimcfg = MIIMCFG_RESET; 309 asm("sync"); 310 priv->phyregs->miimcfg = MIIMCFG_INIT_VALUE; 311 asm("sync"); 312 while (priv->phyregs->miimind & MIIMIND_BUSY) ; 313 314 if (0 == relocated) 315 relocate_cmds(); 316 317 /* Get the cmd structure corresponding to the attached 318 * PHY */ 319 curphy = get_phy_info(dev); 320 321 if (curphy == NULL) { 322 priv->phyinfo = NULL; 323 printf("%s: No PHY found\n", dev->name); 324 325 return 0; 326 } 327 328 priv->phyinfo = curphy; 329 330 phy_run_commands(priv, priv->phyinfo->config); 331 332 return 1; 333 } 334 335 /* 336 * Returns which value to write to the control register. 337 * For 10/100, the value is slightly different 338 */ 339 uint mii_cr_init(uint mii_reg, struct tsec_private * priv) 340 { 341 if (priv->flags & TSEC_GIGABIT) 342 return MIIM_CONTROL_INIT; 343 else 344 return MIIM_CR_INIT; 345 } 346 347 /* Parse the status register for link, and then do 348 * auto-negotiation 349 */ 350 uint mii_parse_sr(uint mii_reg, struct tsec_private * priv) 351 { 352 /* 353 * Wait if the link is up, and autonegotiation is in progress 354 * (ie - we're capable and it's not done) 355 */ 356 mii_reg = read_phy_reg(priv, MIIM_STATUS); 357 if ((mii_reg & MIIM_STATUS_LINK) && (mii_reg & PHY_BMSR_AUTN_ABLE) 358 && !(mii_reg & PHY_BMSR_AUTN_COMP)) { 359 int i = 0; 360 361 puts("Waiting for PHY auto negotiation to complete"); 362 while (!(mii_reg & PHY_BMSR_AUTN_COMP)) { 363 /* 364 * Timeout reached ? 365 */ 366 if (i > PHY_AUTONEGOTIATE_TIMEOUT) { 367 puts(" TIMEOUT !\n"); 368 priv->link = 0; 369 return 0; 370 } 371 372 if ((i++ % 1000) == 0) { 373 putc('.'); 374 } 375 udelay(1000); /* 1 ms */ 376 mii_reg = read_phy_reg(priv, MIIM_STATUS); 377 } 378 puts(" done\n"); 379 priv->link = 1; 380 udelay(500000); /* another 500 ms (results in faster booting) */ 381 } else { 382 if (mii_reg & MIIM_STATUS_LINK) 383 priv->link = 1; 384 else 385 priv->link = 0; 386 } 387 388 return 0; 389 } 390 391 /* Generic function which updates the speed and duplex. If 392 * autonegotiation is enabled, it uses the AND of the link 393 * partner's advertised capabilities and our advertised 394 * capabilities. If autonegotiation is disabled, we use the 395 * appropriate bits in the control register. 396 * 397 * Stolen from Linux's mii.c and phy_device.c 398 */ 399 uint mii_parse_link(uint mii_reg, struct tsec_private *priv) 400 { 401 /* We're using autonegotiation */ 402 if (mii_reg & PHY_BMSR_AUTN_ABLE) { 403 uint lpa = 0; 404 uint gblpa = 0; 405 406 /* Check for gigabit capability */ 407 if (mii_reg & PHY_BMSR_EXT) { 408 /* We want a list of states supported by 409 * both PHYs in the link 410 */ 411 gblpa = read_phy_reg(priv, PHY_1000BTSR); 412 gblpa &= read_phy_reg(priv, PHY_1000BTCR) << 2; 413 } 414 415 /* Set the baseline so we only have to set them 416 * if they're different 417 */ 418 priv->speed = 10; 419 priv->duplexity = 0; 420 421 /* Check the gigabit fields */ 422 if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) { 423 priv->speed = 1000; 424 425 if (gblpa & PHY_1000BTSR_1000FD) 426 priv->duplexity = 1; 427 428 /* We're done! */ 429 return 0; 430 } 431 432 lpa = read_phy_reg(priv, PHY_ANAR); 433 lpa &= read_phy_reg(priv, PHY_ANLPAR); 434 435 if (lpa & (PHY_ANLPAR_TXFD | PHY_ANLPAR_TX)) { 436 priv->speed = 100; 437 438 if (lpa & PHY_ANLPAR_TXFD) 439 priv->duplexity = 1; 440 441 } else if (lpa & PHY_ANLPAR_10FD) 442 priv->duplexity = 1; 443 } else { 444 uint bmcr = read_phy_reg(priv, PHY_BMCR); 445 446 priv->speed = 10; 447 priv->duplexity = 0; 448 449 if (bmcr & PHY_BMCR_DPLX) 450 priv->duplexity = 1; 451 452 if (bmcr & PHY_BMCR_1000_MBPS) 453 priv->speed = 1000; 454 else if (bmcr & PHY_BMCR_100_MBPS) 455 priv->speed = 100; 456 } 457 458 return 0; 459 } 460 461 /* 462 * Parse the BCM54xx status register for speed and duplex information. 463 * The linux sungem_phy has this information, but in a table format. 464 */ 465 uint mii_parse_BCM54xx_sr(uint mii_reg, struct tsec_private *priv) 466 { 467 468 switch((mii_reg & MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK) >> MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT){ 469 470 case 1: 471 printf("Enet starting in 10BT/HD\n"); 472 priv->duplexity = 0; 473 priv->speed = 10; 474 break; 475 476 case 2: 477 printf("Enet starting in 10BT/FD\n"); 478 priv->duplexity = 1; 479 priv->speed = 10; 480 break; 481 482 case 3: 483 printf("Enet starting in 100BT/HD\n"); 484 priv->duplexity = 0; 485 priv->speed = 100; 486 break; 487 488 case 5: 489 printf("Enet starting in 100BT/FD\n"); 490 priv->duplexity = 1; 491 priv->speed = 100; 492 break; 493 494 case 6: 495 printf("Enet starting in 1000BT/HD\n"); 496 priv->duplexity = 0; 497 priv->speed = 1000; 498 break; 499 500 case 7: 501 printf("Enet starting in 1000BT/FD\n"); 502 priv->duplexity = 1; 503 priv->speed = 1000; 504 break; 505 506 default: 507 printf("Auto-neg error, defaulting to 10BT/HD\n"); 508 priv->duplexity = 0; 509 priv->speed = 10; 510 break; 511 } 512 513 return 0; 514 515 } 516 /* Parse the 88E1011's status register for speed and duplex 517 * information 518 */ 519 uint mii_parse_88E1011_psr(uint mii_reg, struct tsec_private * priv) 520 { 521 uint speed; 522 523 mii_reg = read_phy_reg(priv, MIIM_88E1011_PHY_STATUS); 524 525 if ((mii_reg & MIIM_88E1011_PHYSTAT_LINK) && 526 !(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) { 527 int i = 0; 528 529 puts("Waiting for PHY realtime link"); 530 while (!(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) { 531 /* Timeout reached ? */ 532 if (i > PHY_AUTONEGOTIATE_TIMEOUT) { 533 puts(" TIMEOUT !\n"); 534 priv->link = 0; 535 break; 536 } 537 538 if ((i++ % 1000) == 0) { 539 putc('.'); 540 } 541 udelay(1000); /* 1 ms */ 542 mii_reg = read_phy_reg(priv, MIIM_88E1011_PHY_STATUS); 543 } 544 puts(" done\n"); 545 udelay(500000); /* another 500 ms (results in faster booting) */ 546 } else { 547 if (mii_reg & MIIM_88E1011_PHYSTAT_LINK) 548 priv->link = 1; 549 else 550 priv->link = 0; 551 } 552 553 if (mii_reg & MIIM_88E1011_PHYSTAT_DUPLEX) 554 priv->duplexity = 1; 555 else 556 priv->duplexity = 0; 557 558 speed = (mii_reg & MIIM_88E1011_PHYSTAT_SPEED); 559 560 switch (speed) { 561 case MIIM_88E1011_PHYSTAT_GBIT: 562 priv->speed = 1000; 563 break; 564 case MIIM_88E1011_PHYSTAT_100: 565 priv->speed = 100; 566 break; 567 default: 568 priv->speed = 10; 569 } 570 571 return 0; 572 } 573 574 /* Parse the cis8201's status register for speed and duplex 575 * information 576 */ 577 uint mii_parse_cis8201(uint mii_reg, struct tsec_private * priv) 578 { 579 uint speed; 580 581 if (mii_reg & MIIM_CIS8201_AUXCONSTAT_DUPLEX) 582 priv->duplexity = 1; 583 else 584 priv->duplexity = 0; 585 586 speed = mii_reg & MIIM_CIS8201_AUXCONSTAT_SPEED; 587 switch (speed) { 588 case MIIM_CIS8201_AUXCONSTAT_GBIT: 589 priv->speed = 1000; 590 break; 591 case MIIM_CIS8201_AUXCONSTAT_100: 592 priv->speed = 100; 593 break; 594 default: 595 priv->speed = 10; 596 break; 597 } 598 599 return 0; 600 } 601 602 /* Parse the vsc8244's status register for speed and duplex 603 * information 604 */ 605 uint mii_parse_vsc8244(uint mii_reg, struct tsec_private * priv) 606 { 607 uint speed; 608 609 if (mii_reg & MIIM_VSC8244_AUXCONSTAT_DUPLEX) 610 priv->duplexity = 1; 611 else 612 priv->duplexity = 0; 613 614 speed = mii_reg & MIIM_VSC8244_AUXCONSTAT_SPEED; 615 switch (speed) { 616 case MIIM_VSC8244_AUXCONSTAT_GBIT: 617 priv->speed = 1000; 618 break; 619 case MIIM_VSC8244_AUXCONSTAT_100: 620 priv->speed = 100; 621 break; 622 default: 623 priv->speed = 10; 624 break; 625 } 626 627 return 0; 628 } 629 630 /* Parse the DM9161's status register for speed and duplex 631 * information 632 */ 633 uint mii_parse_dm9161_scsr(uint mii_reg, struct tsec_private * priv) 634 { 635 if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H)) 636 priv->speed = 100; 637 else 638 priv->speed = 10; 639 640 if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_10F)) 641 priv->duplexity = 1; 642 else 643 priv->duplexity = 0; 644 645 return 0; 646 } 647 648 /* 649 * Hack to write all 4 PHYs with the LED values 650 */ 651 uint mii_cis8204_fixled(uint mii_reg, struct tsec_private * priv) 652 { 653 uint phyid; 654 volatile tsec_t *regbase = priv->phyregs; 655 int timeout = 1000000; 656 657 for (phyid = 0; phyid < 4; phyid++) { 658 regbase->miimadd = (phyid << 8) | mii_reg; 659 regbase->miimcon = MIIM_CIS8204_SLEDCON_INIT; 660 asm("sync"); 661 662 timeout = 1000000; 663 while ((regbase->miimind & MIIMIND_BUSY) && timeout--) ; 664 } 665 666 return MIIM_CIS8204_SLEDCON_INIT; 667 } 668 669 uint mii_cis8204_setmode(uint mii_reg, struct tsec_private * priv) 670 { 671 if (priv->flags & TSEC_REDUCED) 672 return MIIM_CIS8204_EPHYCON_INIT | MIIM_CIS8204_EPHYCON_RGMII; 673 else 674 return MIIM_CIS8204_EPHYCON_INIT; 675 } 676 677 /* Initialized required registers to appropriate values, zeroing 678 * those we don't care about (unless zero is bad, in which case, 679 * choose a more appropriate value) 680 */ 681 static void init_registers(volatile tsec_t * regs) 682 { 683 /* Clear IEVENT */ 684 regs->ievent = IEVENT_INIT_CLEAR; 685 686 regs->imask = IMASK_INIT_CLEAR; 687 688 regs->hash.iaddr0 = 0; 689 regs->hash.iaddr1 = 0; 690 regs->hash.iaddr2 = 0; 691 regs->hash.iaddr3 = 0; 692 regs->hash.iaddr4 = 0; 693 regs->hash.iaddr5 = 0; 694 regs->hash.iaddr6 = 0; 695 regs->hash.iaddr7 = 0; 696 697 regs->hash.gaddr0 = 0; 698 regs->hash.gaddr1 = 0; 699 regs->hash.gaddr2 = 0; 700 regs->hash.gaddr3 = 0; 701 regs->hash.gaddr4 = 0; 702 regs->hash.gaddr5 = 0; 703 regs->hash.gaddr6 = 0; 704 regs->hash.gaddr7 = 0; 705 706 regs->rctrl = 0x00000000; 707 708 /* Init RMON mib registers */ 709 memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t)); 710 711 regs->rmon.cam1 = 0xffffffff; 712 regs->rmon.cam2 = 0xffffffff; 713 714 regs->mrblr = MRBLR_INIT_SETTINGS; 715 716 regs->minflr = MINFLR_INIT_SETTINGS; 717 718 regs->attr = ATTR_INIT_SETTINGS; 719 regs->attreli = ATTRELI_INIT_SETTINGS; 720 721 } 722 723 /* Configure maccfg2 based on negotiated speed and duplex 724 * reported by PHY handling code 725 */ 726 static void adjust_link(struct eth_device *dev) 727 { 728 struct tsec_private *priv = (struct tsec_private *)dev->priv; 729 volatile tsec_t *regs = priv->regs; 730 731 if (priv->link) { 732 if (priv->duplexity != 0) 733 regs->maccfg2 |= MACCFG2_FULL_DUPLEX; 734 else 735 regs->maccfg2 &= ~(MACCFG2_FULL_DUPLEX); 736 737 switch (priv->speed) { 738 case 1000: 739 regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF)) 740 | MACCFG2_GMII); 741 break; 742 case 100: 743 case 10: 744 regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF)) 745 | MACCFG2_MII); 746 747 /* Set R100 bit in all modes although 748 * it is only used in RGMII mode 749 */ 750 if (priv->speed == 100) 751 regs->ecntrl |= ECNTRL_R100; 752 else 753 regs->ecntrl &= ~(ECNTRL_R100); 754 break; 755 default: 756 printf("%s: Speed was bad\n", dev->name); 757 break; 758 } 759 760 printf("Speed: %d, %s duplex\n", priv->speed, 761 (priv->duplexity) ? "full" : "half"); 762 763 } else { 764 printf("%s: No link.\n", dev->name); 765 } 766 } 767 768 /* Set up the buffers and their descriptors, and bring up the 769 * interface 770 */ 771 static void startup_tsec(struct eth_device *dev) 772 { 773 int i; 774 struct tsec_private *priv = (struct tsec_private *)dev->priv; 775 volatile tsec_t *regs = priv->regs; 776 777 /* Point to the buffer descriptors */ 778 regs->tbase = (unsigned int)(&rtx.txbd[txIdx]); 779 regs->rbase = (unsigned int)(&rtx.rxbd[rxIdx]); 780 781 /* Initialize the Rx Buffer descriptors */ 782 for (i = 0; i < PKTBUFSRX; i++) { 783 rtx.rxbd[i].status = RXBD_EMPTY; 784 rtx.rxbd[i].length = 0; 785 rtx.rxbd[i].bufPtr = (uint) NetRxPackets[i]; 786 } 787 rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP; 788 789 /* Initialize the TX Buffer Descriptors */ 790 for (i = 0; i < TX_BUF_CNT; i++) { 791 rtx.txbd[i].status = 0; 792 rtx.txbd[i].length = 0; 793 rtx.txbd[i].bufPtr = 0; 794 } 795 rtx.txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP; 796 797 /* Start up the PHY */ 798 if(priv->phyinfo) 799 phy_run_commands(priv, priv->phyinfo->startup); 800 801 adjust_link(dev); 802 803 /* Enable Transmit and Receive */ 804 regs->maccfg1 |= (MACCFG1_RX_EN | MACCFG1_TX_EN); 805 806 /* Tell the DMA it is clear to go */ 807 regs->dmactrl |= DMACTRL_INIT_SETTINGS; 808 regs->tstat = TSTAT_CLEAR_THALT; 809 regs->rstat = RSTAT_CLEAR_RHALT; 810 regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS); 811 } 812 813 /* This returns the status bits of the device. The return value 814 * is never checked, and this is what the 8260 driver did, so we 815 * do the same. Presumably, this would be zero if there were no 816 * errors 817 */ 818 static int tsec_send(struct eth_device *dev, volatile void *packet, int length) 819 { 820 int i; 821 int result = 0; 822 struct tsec_private *priv = (struct tsec_private *)dev->priv; 823 volatile tsec_t *regs = priv->regs; 824 825 /* Find an empty buffer descriptor */ 826 for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) { 827 if (i >= TOUT_LOOP) { 828 debug("%s: tsec: tx buffers full\n", dev->name); 829 return result; 830 } 831 } 832 833 rtx.txbd[txIdx].bufPtr = (uint) packet; 834 rtx.txbd[txIdx].length = length; 835 rtx.txbd[txIdx].status |= 836 (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT); 837 838 /* Tell the DMA to go */ 839 regs->tstat = TSTAT_CLEAR_THALT; 840 841 /* Wait for buffer to be transmitted */ 842 for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) { 843 if (i >= TOUT_LOOP) { 844 debug("%s: tsec: tx error\n", dev->name); 845 return result; 846 } 847 } 848 849 txIdx = (txIdx + 1) % TX_BUF_CNT; 850 result = rtx.txbd[txIdx].status & TXBD_STATS; 851 852 return result; 853 } 854 855 static int tsec_recv(struct eth_device *dev) 856 { 857 int length; 858 struct tsec_private *priv = (struct tsec_private *)dev->priv; 859 volatile tsec_t *regs = priv->regs; 860 861 while (!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) { 862 863 length = rtx.rxbd[rxIdx].length; 864 865 /* Send the packet up if there were no errors */ 866 if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) { 867 NetReceive(NetRxPackets[rxIdx], length - 4); 868 } else { 869 printf("Got error %x\n", 870 (rtx.rxbd[rxIdx].status & RXBD_STATS)); 871 } 872 873 rtx.rxbd[rxIdx].length = 0; 874 875 /* Set the wrap bit if this is the last element in the list */ 876 rtx.rxbd[rxIdx].status = 877 RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); 878 879 rxIdx = (rxIdx + 1) % PKTBUFSRX; 880 } 881 882 if (regs->ievent & IEVENT_BSY) { 883 regs->ievent = IEVENT_BSY; 884 regs->rstat = RSTAT_CLEAR_RHALT; 885 } 886 887 return -1; 888 889 } 890 891 /* Stop the interface */ 892 static void tsec_halt(struct eth_device *dev) 893 { 894 struct tsec_private *priv = (struct tsec_private *)dev->priv; 895 volatile tsec_t *regs = priv->regs; 896 897 regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS); 898 regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS); 899 900 while (!(regs->ievent & (IEVENT_GRSC | IEVENT_GTSC))) ; 901 902 regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN); 903 904 /* Shut down the PHY, as needed */ 905 if(priv->phyinfo) 906 phy_run_commands(priv, priv->phyinfo->shutdown); 907 } 908 909 struct phy_info phy_info_M88E1149S = { 910 0x1410ca, 911 "Marvell 88E1149S", 912 4, 913 (struct phy_cmd[]){ /* config */ 914 /* Reset and configure the PHY */ 915 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 916 {0x1d, 0x1f, NULL}, 917 {0x1e, 0x200c, NULL}, 918 {0x1d, 0x5, NULL}, 919 {0x1e, 0x0, NULL}, 920 {0x1e, 0x100, NULL}, 921 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 922 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 923 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 924 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 925 {miim_end,} 926 }, 927 (struct phy_cmd[]){ /* startup */ 928 /* Status is read once to clear old link state */ 929 {MIIM_STATUS, miim_read, NULL}, 930 /* Auto-negotiate */ 931 {MIIM_STATUS, miim_read, &mii_parse_sr}, 932 /* Read the status */ 933 {MIIM_88E1011_PHY_STATUS, miim_read, 934 &mii_parse_88E1011_psr}, 935 {miim_end,} 936 }, 937 (struct phy_cmd[]){ /* shutdown */ 938 {miim_end,} 939 }, 940 }; 941 942 /* The 5411 id is 0x206070, the 5421 is 0x2060e0 */ 943 struct phy_info phy_info_BCM5461S = { 944 0x02060c1, /* 5461 ID */ 945 "Broadcom BCM5461S", 946 0, /* not clear to me what minor revisions we can shift away */ 947 (struct phy_cmd[]) { /* config */ 948 /* Reset and configure the PHY */ 949 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 950 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 951 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 952 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 953 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 954 {miim_end,} 955 }, 956 (struct phy_cmd[]) { /* startup */ 957 /* Status is read once to clear old link state */ 958 {MIIM_STATUS, miim_read, NULL}, 959 /* Auto-negotiate */ 960 {MIIM_STATUS, miim_read, &mii_parse_sr}, 961 /* Read the status */ 962 {MIIM_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr}, 963 {miim_end,} 964 }, 965 (struct phy_cmd[]) { /* shutdown */ 966 {miim_end,} 967 }, 968 }; 969 970 struct phy_info phy_info_BCM5464S = { 971 0x02060b1, /* 5464 ID */ 972 "Broadcom BCM5464S", 973 0, /* not clear to me what minor revisions we can shift away */ 974 (struct phy_cmd[]) { /* config */ 975 /* Reset and configure the PHY */ 976 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 977 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 978 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 979 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 980 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 981 {miim_end,} 982 }, 983 (struct phy_cmd[]) { /* startup */ 984 /* Status is read once to clear old link state */ 985 {MIIM_STATUS, miim_read, NULL}, 986 /* Auto-negotiate */ 987 {MIIM_STATUS, miim_read, &mii_parse_sr}, 988 /* Read the status */ 989 {MIIM_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr}, 990 {miim_end,} 991 }, 992 (struct phy_cmd[]) { /* shutdown */ 993 {miim_end,} 994 }, 995 }; 996 997 struct phy_info phy_info_M88E1011S = { 998 0x01410c6, 999 "Marvell 88E1011S", 1000 4, 1001 (struct phy_cmd[]){ /* config */ 1002 /* Reset and configure the PHY */ 1003 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1004 {0x1d, 0x1f, NULL}, 1005 {0x1e, 0x200c, NULL}, 1006 {0x1d, 0x5, NULL}, 1007 {0x1e, 0x0, NULL}, 1008 {0x1e, 0x100, NULL}, 1009 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1010 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1011 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1012 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1013 {miim_end,} 1014 }, 1015 (struct phy_cmd[]){ /* startup */ 1016 /* Status is read once to clear old link state */ 1017 {MIIM_STATUS, miim_read, NULL}, 1018 /* Auto-negotiate */ 1019 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1020 /* Read the status */ 1021 {MIIM_88E1011_PHY_STATUS, miim_read, 1022 &mii_parse_88E1011_psr}, 1023 {miim_end,} 1024 }, 1025 (struct phy_cmd[]){ /* shutdown */ 1026 {miim_end,} 1027 }, 1028 }; 1029 1030 struct phy_info phy_info_M88E1111S = { 1031 0x01410cc, 1032 "Marvell 88E1111S", 1033 4, 1034 (struct phy_cmd[]){ /* config */ 1035 /* Reset and configure the PHY */ 1036 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1037 {0x14, 0x0cd2, NULL}, /* Delay RGMII TX and RX */ 1038 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1039 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1040 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1041 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1042 {miim_end,} 1043 }, 1044 (struct phy_cmd[]){ /* startup */ 1045 /* Status is read once to clear old link state */ 1046 {MIIM_STATUS, miim_read, NULL}, 1047 /* Auto-negotiate */ 1048 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1049 /* Read the status */ 1050 {MIIM_88E1011_PHY_STATUS, miim_read, 1051 &mii_parse_88E1011_psr}, 1052 {miim_end,} 1053 }, 1054 (struct phy_cmd[]){ /* shutdown */ 1055 {miim_end,} 1056 }, 1057 }; 1058 1059 static unsigned int m88e1145_setmode(uint mii_reg, struct tsec_private *priv) 1060 { 1061 uint mii_data = read_phy_reg(priv, mii_reg); 1062 1063 /* Setting MIIM_88E1145_PHY_EXT_CR */ 1064 if (priv->flags & TSEC_REDUCED) 1065 return mii_data | 1066 MIIM_M88E1145_RGMII_RX_DELAY | MIIM_M88E1145_RGMII_TX_DELAY; 1067 else 1068 return mii_data; 1069 } 1070 1071 static struct phy_info phy_info_M88E1145 = { 1072 0x01410cd, 1073 "Marvell 88E1145", 1074 4, 1075 (struct phy_cmd[]){ /* config */ 1076 /* Reset the PHY */ 1077 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1078 1079 /* Errata E0, E1 */ 1080 {29, 0x001b, NULL}, 1081 {30, 0x418f, NULL}, 1082 {29, 0x0016, NULL}, 1083 {30, 0xa2da, NULL}, 1084 1085 /* Configure the PHY */ 1086 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1087 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1088 {MIIM_88E1011_PHY_SCR, MIIM_88E1011_PHY_MDI_X_AUTO, 1089 NULL}, 1090 {MIIM_88E1145_PHY_EXT_CR, 0, &m88e1145_setmode}, 1091 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1092 {MIIM_CONTROL, MIIM_CONTROL_INIT, NULL}, 1093 {miim_end,} 1094 }, 1095 (struct phy_cmd[]){ /* startup */ 1096 /* Status is read once to clear old link state */ 1097 {MIIM_STATUS, miim_read, NULL}, 1098 /* Auto-negotiate */ 1099 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1100 {MIIM_88E1111_PHY_LED_CONTROL, 1101 MIIM_88E1111_PHY_LED_DIRECT, NULL}, 1102 /* Read the Status */ 1103 {MIIM_88E1011_PHY_STATUS, miim_read, 1104 &mii_parse_88E1011_psr}, 1105 {miim_end,} 1106 }, 1107 (struct phy_cmd[]){ /* shutdown */ 1108 {miim_end,} 1109 }, 1110 }; 1111 1112 struct phy_info phy_info_cis8204 = { 1113 0x3f11, 1114 "Cicada Cis8204", 1115 6, 1116 (struct phy_cmd[]){ /* config */ 1117 /* Override PHY config settings */ 1118 {MIIM_CIS8201_AUX_CONSTAT, 1119 MIIM_CIS8201_AUXCONSTAT_INIT, NULL}, 1120 /* Configure some basic stuff */ 1121 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1122 {MIIM_CIS8204_SLED_CON, MIIM_CIS8204_SLEDCON_INIT, 1123 &mii_cis8204_fixled}, 1124 {MIIM_CIS8204_EPHY_CON, MIIM_CIS8204_EPHYCON_INIT, 1125 &mii_cis8204_setmode}, 1126 {miim_end,} 1127 }, 1128 (struct phy_cmd[]){ /* startup */ 1129 /* Read the Status (2x to make sure link is right) */ 1130 {MIIM_STATUS, miim_read, NULL}, 1131 /* Auto-negotiate */ 1132 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1133 /* Read the status */ 1134 {MIIM_CIS8201_AUX_CONSTAT, miim_read, 1135 &mii_parse_cis8201}, 1136 {miim_end,} 1137 }, 1138 (struct phy_cmd[]){ /* shutdown */ 1139 {miim_end,} 1140 }, 1141 }; 1142 1143 /* Cicada 8201 */ 1144 struct phy_info phy_info_cis8201 = { 1145 0xfc41, 1146 "CIS8201", 1147 4, 1148 (struct phy_cmd[]){ /* config */ 1149 /* Override PHY config settings */ 1150 {MIIM_CIS8201_AUX_CONSTAT, 1151 MIIM_CIS8201_AUXCONSTAT_INIT, NULL}, 1152 /* Set up the interface mode */ 1153 {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, 1154 NULL}, 1155 /* Configure some basic stuff */ 1156 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1157 {miim_end,} 1158 }, 1159 (struct phy_cmd[]){ /* startup */ 1160 /* Read the Status (2x to make sure link is right) */ 1161 {MIIM_STATUS, miim_read, NULL}, 1162 /* Auto-negotiate */ 1163 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1164 /* Read the status */ 1165 {MIIM_CIS8201_AUX_CONSTAT, miim_read, 1166 &mii_parse_cis8201}, 1167 {miim_end,} 1168 }, 1169 (struct phy_cmd[]){ /* shutdown */ 1170 {miim_end,} 1171 }, 1172 }; 1173 struct phy_info phy_info_VSC8244 = { 1174 0x3f1b, 1175 "Vitesse VSC8244", 1176 6, 1177 (struct phy_cmd[]){ /* config */ 1178 /* Override PHY config settings */ 1179 /* Configure some basic stuff */ 1180 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1181 {miim_end,} 1182 }, 1183 (struct phy_cmd[]){ /* startup */ 1184 /* Read the Status (2x to make sure link is right) */ 1185 {MIIM_STATUS, miim_read, NULL}, 1186 /* Auto-negotiate */ 1187 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1188 /* Read the status */ 1189 {MIIM_VSC8244_AUX_CONSTAT, miim_read, 1190 &mii_parse_vsc8244}, 1191 {miim_end,} 1192 }, 1193 (struct phy_cmd[]){ /* shutdown */ 1194 {miim_end,} 1195 }, 1196 }; 1197 1198 struct phy_info phy_info_dm9161 = { 1199 0x0181b88, 1200 "Davicom DM9161E", 1201 4, 1202 (struct phy_cmd[]){ /* config */ 1203 {MIIM_CONTROL, MIIM_DM9161_CR_STOP, NULL}, 1204 /* Do not bypass the scrambler/descrambler */ 1205 {MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT, NULL}, 1206 /* Clear 10BTCSR to default */ 1207 {MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT, 1208 NULL}, 1209 /* Configure some basic stuff */ 1210 {MIIM_CONTROL, MIIM_CR_INIT, NULL}, 1211 /* Restart Auto Negotiation */ 1212 {MIIM_CONTROL, MIIM_DM9161_CR_RSTAN, NULL}, 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 /* Auto-negotiate */ 1219 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1220 /* Read the status */ 1221 {MIIM_DM9161_SCSR, miim_read, 1222 &mii_parse_dm9161_scsr}, 1223 {miim_end,} 1224 }, 1225 (struct phy_cmd[]){ /* shutdown */ 1226 {miim_end,} 1227 }, 1228 }; 1229 /* a generic flavor. */ 1230 struct phy_info phy_info_generic = { 1231 0, 1232 "Unknown/Generic PHY", 1233 32, 1234 (struct phy_cmd[]) { /* config */ 1235 {PHY_BMCR, PHY_BMCR_RESET, NULL}, 1236 {PHY_BMCR, PHY_BMCR_AUTON|PHY_BMCR_RST_NEG, NULL}, 1237 {miim_end,} 1238 }, 1239 (struct phy_cmd[]) { /* startup */ 1240 {PHY_BMSR, miim_read, NULL}, 1241 {PHY_BMSR, miim_read, &mii_parse_sr}, 1242 {PHY_BMSR, miim_read, &mii_parse_link}, 1243 {miim_end,} 1244 }, 1245 (struct phy_cmd[]) { /* shutdown */ 1246 {miim_end,} 1247 } 1248 }; 1249 1250 1251 uint mii_parse_lxt971_sr2(uint mii_reg, struct tsec_private *priv) 1252 { 1253 unsigned int speed; 1254 if (priv->link) { 1255 speed = mii_reg & MIIM_LXT971_SR2_SPEED_MASK; 1256 1257 switch (speed) { 1258 case MIIM_LXT971_SR2_10HDX: 1259 priv->speed = 10; 1260 priv->duplexity = 0; 1261 break; 1262 case MIIM_LXT971_SR2_10FDX: 1263 priv->speed = 10; 1264 priv->duplexity = 1; 1265 break; 1266 case MIIM_LXT971_SR2_100HDX: 1267 priv->speed = 100; 1268 priv->duplexity = 0; 1269 break; 1270 default: 1271 priv->speed = 100; 1272 priv->duplexity = 1; 1273 } 1274 } else { 1275 priv->speed = 0; 1276 priv->duplexity = 0; 1277 } 1278 1279 return 0; 1280 } 1281 1282 static struct phy_info phy_info_lxt971 = { 1283 0x0001378e, 1284 "LXT971", 1285 4, 1286 (struct phy_cmd[]){ /* config */ 1287 {MIIM_CR, MIIM_CR_INIT, mii_cr_init}, /* autonegotiate */ 1288 {miim_end,} 1289 }, 1290 (struct phy_cmd[]){ /* startup - enable interrupts */ 1291 /* { 0x12, 0x00f2, NULL }, */ 1292 {MIIM_STATUS, miim_read, NULL}, 1293 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1294 {MIIM_LXT971_SR2, miim_read, &mii_parse_lxt971_sr2}, 1295 {miim_end,} 1296 }, 1297 (struct phy_cmd[]){ /* shutdown - disable interrupts */ 1298 {miim_end,} 1299 }, 1300 }; 1301 1302 /* Parse the DP83865's link and auto-neg status register for speed and duplex 1303 * information 1304 */ 1305 uint mii_parse_dp83865_lanr(uint mii_reg, struct tsec_private *priv) 1306 { 1307 switch (mii_reg & MIIM_DP83865_SPD_MASK) { 1308 1309 case MIIM_DP83865_SPD_1000: 1310 priv->speed = 1000; 1311 break; 1312 1313 case MIIM_DP83865_SPD_100: 1314 priv->speed = 100; 1315 break; 1316 1317 default: 1318 priv->speed = 10; 1319 break; 1320 1321 } 1322 1323 if (mii_reg & MIIM_DP83865_DPX_FULL) 1324 priv->duplexity = 1; 1325 else 1326 priv->duplexity = 0; 1327 1328 return 0; 1329 } 1330 1331 struct phy_info phy_info_dp83865 = { 1332 0x20005c7, 1333 "NatSemi DP83865", 1334 4, 1335 (struct phy_cmd[]){ /* config */ 1336 {MIIM_CONTROL, MIIM_DP83865_CR_INIT, NULL}, 1337 {miim_end,} 1338 }, 1339 (struct phy_cmd[]){ /* startup */ 1340 /* Status is read once to clear old link state */ 1341 {MIIM_STATUS, miim_read, NULL}, 1342 /* Auto-negotiate */ 1343 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1344 /* Read the link and auto-neg status */ 1345 {MIIM_DP83865_LANR, miim_read, 1346 &mii_parse_dp83865_lanr}, 1347 {miim_end,} 1348 }, 1349 (struct phy_cmd[]){ /* shutdown */ 1350 {miim_end,} 1351 }, 1352 }; 1353 1354 struct phy_info *phy_info[] = { 1355 &phy_info_cis8204, 1356 &phy_info_cis8201, 1357 &phy_info_BCM5461S, 1358 &phy_info_BCM5464S, 1359 &phy_info_M88E1011S, 1360 &phy_info_M88E1111S, 1361 &phy_info_M88E1145, 1362 &phy_info_M88E1149S, 1363 &phy_info_dm9161, 1364 &phy_info_lxt971, 1365 &phy_info_VSC8244, 1366 &phy_info_dp83865, 1367 &phy_info_generic, 1368 NULL 1369 }; 1370 1371 /* Grab the identifier of the device's PHY, and search through 1372 * all of the known PHYs to see if one matches. If so, return 1373 * it, if not, return NULL 1374 */ 1375 struct phy_info *get_phy_info(struct eth_device *dev) 1376 { 1377 struct tsec_private *priv = (struct tsec_private *)dev->priv; 1378 uint phy_reg, phy_ID; 1379 int i; 1380 struct phy_info *theInfo = NULL; 1381 1382 /* Grab the bits from PHYIR1, and put them in the upper half */ 1383 phy_reg = read_phy_reg(priv, MIIM_PHYIR1); 1384 phy_ID = (phy_reg & 0xffff) << 16; 1385 1386 /* Grab the bits from PHYIR2, and put them in the lower half */ 1387 phy_reg = read_phy_reg(priv, MIIM_PHYIR2); 1388 phy_ID |= (phy_reg & 0xffff); 1389 1390 /* loop through all the known PHY types, and find one that */ 1391 /* matches the ID we read from the PHY. */ 1392 for (i = 0; phy_info[i]; i++) { 1393 if (phy_info[i]->id == (phy_ID >> phy_info[i]->shift)) { 1394 theInfo = phy_info[i]; 1395 break; 1396 } 1397 } 1398 1399 if (theInfo == NULL) { 1400 printf("%s: PHY id %x is not supported!\n", dev->name, phy_ID); 1401 return NULL; 1402 } else { 1403 debug("%s: PHY is %s (%x)\n", dev->name, theInfo->name, phy_ID); 1404 } 1405 1406 return theInfo; 1407 } 1408 1409 /* Execute the given series of commands on the given device's 1410 * PHY, running functions as necessary 1411 */ 1412 void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd) 1413 { 1414 int i; 1415 uint result; 1416 volatile tsec_t *phyregs = priv->phyregs; 1417 1418 phyregs->miimcfg = MIIMCFG_RESET; 1419 1420 phyregs->miimcfg = MIIMCFG_INIT_VALUE; 1421 1422 while (phyregs->miimind & MIIMIND_BUSY) ; 1423 1424 for (i = 0; cmd->mii_reg != miim_end; i++) { 1425 if (cmd->mii_data == miim_read) { 1426 result = read_phy_reg(priv, cmd->mii_reg); 1427 1428 if (cmd->funct != NULL) 1429 (*(cmd->funct)) (result, priv); 1430 1431 } else { 1432 if (cmd->funct != NULL) 1433 result = (*(cmd->funct)) (cmd->mii_reg, priv); 1434 else 1435 result = cmd->mii_data; 1436 1437 write_phy_reg(priv, cmd->mii_reg, result); 1438 1439 } 1440 cmd++; 1441 } 1442 } 1443 1444 /* Relocate the function pointers in the phy cmd lists */ 1445 static void relocate_cmds(void) 1446 { 1447 struct phy_cmd **cmdlistptr; 1448 struct phy_cmd *cmd; 1449 int i, j, k; 1450 1451 for (i = 0; phy_info[i]; i++) { 1452 /* First thing's first: relocate the pointers to the 1453 * PHY command structures (the structs were done) */ 1454 phy_info[i] = (struct phy_info *)((uint) phy_info[i] 1455 + gd->reloc_off); 1456 phy_info[i]->name += gd->reloc_off; 1457 phy_info[i]->config = 1458 (struct phy_cmd *)((uint) phy_info[i]->config 1459 + gd->reloc_off); 1460 phy_info[i]->startup = 1461 (struct phy_cmd *)((uint) phy_info[i]->startup 1462 + gd->reloc_off); 1463 phy_info[i]->shutdown = 1464 (struct phy_cmd *)((uint) phy_info[i]->shutdown 1465 + gd->reloc_off); 1466 1467 cmdlistptr = &phy_info[i]->config; 1468 j = 0; 1469 for (; cmdlistptr <= &phy_info[i]->shutdown; cmdlistptr++) { 1470 k = 0; 1471 for (cmd = *cmdlistptr; 1472 cmd->mii_reg != miim_end; 1473 cmd++) { 1474 /* Only relocate non-NULL pointers */ 1475 if (cmd->funct) 1476 cmd->funct += gd->reloc_off; 1477 1478 k++; 1479 } 1480 j++; 1481 } 1482 } 1483 1484 relocated = 1; 1485 } 1486 1487 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \ 1488 && !defined(BITBANGMII) 1489 1490 struct tsec_private *get_priv_for_phy(unsigned char phyaddr) 1491 { 1492 int i; 1493 1494 for (i = 0; i < MAXCONTROLLERS; i++) { 1495 if (privlist[i]->phyaddr == phyaddr) 1496 return privlist[i]; 1497 } 1498 1499 return NULL; 1500 } 1501 1502 /* 1503 * Read a MII PHY register. 1504 * 1505 * Returns: 1506 * 0 on success 1507 */ 1508 static int tsec_miiphy_read(char *devname, unsigned char addr, 1509 unsigned char reg, unsigned short *value) 1510 { 1511 unsigned short ret; 1512 struct tsec_private *priv = get_priv_for_phy(addr); 1513 1514 if (NULL == priv) { 1515 printf("Can't read PHY at address %d\n", addr); 1516 return -1; 1517 } 1518 1519 ret = (unsigned short)read_phy_reg(priv, reg); 1520 *value = ret; 1521 1522 return 0; 1523 } 1524 1525 /* 1526 * Write a MII PHY register. 1527 * 1528 * Returns: 1529 * 0 on success 1530 */ 1531 static int tsec_miiphy_write(char *devname, unsigned char addr, 1532 unsigned char reg, unsigned short value) 1533 { 1534 struct tsec_private *priv = get_priv_for_phy(addr); 1535 1536 if (NULL == priv) { 1537 printf("Can't write PHY at address %d\n", addr); 1538 return -1; 1539 } 1540 1541 write_phy_reg(priv, reg, value); 1542 1543 return 0; 1544 } 1545 1546 #endif 1547 1548 #ifdef CONFIG_MCAST_TFTP 1549 1550 /* CREDITS: linux gianfar driver, slightly adjusted... thanx. */ 1551 1552 /* Set the appropriate hash bit for the given addr */ 1553 1554 /* The algorithm works like so: 1555 * 1) Take the Destination Address (ie the multicast address), and 1556 * do a CRC on it (little endian), and reverse the bits of the 1557 * result. 1558 * 2) Use the 8 most significant bits as a hash into a 256-entry 1559 * table. The table is controlled through 8 32-bit registers: 1560 * gaddr0-7. gaddr0's MSB is entry 0, and gaddr7's LSB is 1561 * gaddr7. This means that the 3 most significant bits in the 1562 * hash index which gaddr register to use, and the 5 other bits 1563 * indicate which bit (assuming an IBM numbering scheme, which 1564 * for PowerPC (tm) is usually the case) in the tregister holds 1565 * the entry. */ 1566 static int 1567 tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set) 1568 { 1569 struct tsec_private *priv = privlist[1]; 1570 volatile tsec_t *regs = priv->regs; 1571 volatile u32 *reg_array, value; 1572 u8 result, whichbit, whichreg; 1573 1574 result = (u8)((ether_crc(MAC_ADDR_LEN,mcast_mac) >> 24) & 0xff); 1575 whichbit = result & 0x1f; /* the 5 LSB = which bit to set */ 1576 whichreg = result >> 5; /* the 3 MSB = which reg to set it in */ 1577 value = (1 << (31-whichbit)); 1578 1579 reg_array = &(regs->hash.gaddr0); 1580 1581 if (set) { 1582 reg_array[whichreg] |= value; 1583 } else { 1584 reg_array[whichreg] &= ~value; 1585 } 1586 return 0; 1587 } 1588 #endif /* Multicast TFTP ? */ 1589 1590 #endif /* CONFIG_TSEC_ENET */ 1591