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 uint mii_m88e1111s_setmode(uint mii_reg, struct tsec_private *priv) 678 { 679 uint mii_data = read_phy_reg(priv, mii_reg); 680 681 if (priv->flags & TSEC_REDUCED) 682 mii_data = (mii_data & 0xfff0) | 0x000b; 683 return mii_data; 684 } 685 686 /* Initialized required registers to appropriate values, zeroing 687 * those we don't care about (unless zero is bad, in which case, 688 * choose a more appropriate value) 689 */ 690 static void init_registers(volatile tsec_t * regs) 691 { 692 /* Clear IEVENT */ 693 regs->ievent = IEVENT_INIT_CLEAR; 694 695 regs->imask = IMASK_INIT_CLEAR; 696 697 regs->hash.iaddr0 = 0; 698 regs->hash.iaddr1 = 0; 699 regs->hash.iaddr2 = 0; 700 regs->hash.iaddr3 = 0; 701 regs->hash.iaddr4 = 0; 702 regs->hash.iaddr5 = 0; 703 regs->hash.iaddr6 = 0; 704 regs->hash.iaddr7 = 0; 705 706 regs->hash.gaddr0 = 0; 707 regs->hash.gaddr1 = 0; 708 regs->hash.gaddr2 = 0; 709 regs->hash.gaddr3 = 0; 710 regs->hash.gaddr4 = 0; 711 regs->hash.gaddr5 = 0; 712 regs->hash.gaddr6 = 0; 713 regs->hash.gaddr7 = 0; 714 715 regs->rctrl = 0x00000000; 716 717 /* Init RMON mib registers */ 718 memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t)); 719 720 regs->rmon.cam1 = 0xffffffff; 721 regs->rmon.cam2 = 0xffffffff; 722 723 regs->mrblr = MRBLR_INIT_SETTINGS; 724 725 regs->minflr = MINFLR_INIT_SETTINGS; 726 727 regs->attr = ATTR_INIT_SETTINGS; 728 regs->attreli = ATTRELI_INIT_SETTINGS; 729 730 } 731 732 /* Configure maccfg2 based on negotiated speed and duplex 733 * reported by PHY handling code 734 */ 735 static void adjust_link(struct eth_device *dev) 736 { 737 struct tsec_private *priv = (struct tsec_private *)dev->priv; 738 volatile tsec_t *regs = priv->regs; 739 740 if (priv->link) { 741 if (priv->duplexity != 0) 742 regs->maccfg2 |= MACCFG2_FULL_DUPLEX; 743 else 744 regs->maccfg2 &= ~(MACCFG2_FULL_DUPLEX); 745 746 switch (priv->speed) { 747 case 1000: 748 regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF)) 749 | MACCFG2_GMII); 750 break; 751 case 100: 752 case 10: 753 regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF)) 754 | MACCFG2_MII); 755 756 /* Set R100 bit in all modes although 757 * it is only used in RGMII mode 758 */ 759 if (priv->speed == 100) 760 regs->ecntrl |= ECNTRL_R100; 761 else 762 regs->ecntrl &= ~(ECNTRL_R100); 763 break; 764 default: 765 printf("%s: Speed was bad\n", dev->name); 766 break; 767 } 768 769 printf("Speed: %d, %s duplex\n", priv->speed, 770 (priv->duplexity) ? "full" : "half"); 771 772 } else { 773 printf("%s: No link.\n", dev->name); 774 } 775 } 776 777 /* Set up the buffers and their descriptors, and bring up the 778 * interface 779 */ 780 static void startup_tsec(struct eth_device *dev) 781 { 782 int i; 783 struct tsec_private *priv = (struct tsec_private *)dev->priv; 784 volatile tsec_t *regs = priv->regs; 785 786 /* Point to the buffer descriptors */ 787 regs->tbase = (unsigned int)(&rtx.txbd[txIdx]); 788 regs->rbase = (unsigned int)(&rtx.rxbd[rxIdx]); 789 790 /* Initialize the Rx Buffer descriptors */ 791 for (i = 0; i < PKTBUFSRX; i++) { 792 rtx.rxbd[i].status = RXBD_EMPTY; 793 rtx.rxbd[i].length = 0; 794 rtx.rxbd[i].bufPtr = (uint) NetRxPackets[i]; 795 } 796 rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP; 797 798 /* Initialize the TX Buffer Descriptors */ 799 for (i = 0; i < TX_BUF_CNT; i++) { 800 rtx.txbd[i].status = 0; 801 rtx.txbd[i].length = 0; 802 rtx.txbd[i].bufPtr = 0; 803 } 804 rtx.txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP; 805 806 /* Start up the PHY */ 807 if(priv->phyinfo) 808 phy_run_commands(priv, priv->phyinfo->startup); 809 810 adjust_link(dev); 811 812 /* Enable Transmit and Receive */ 813 regs->maccfg1 |= (MACCFG1_RX_EN | MACCFG1_TX_EN); 814 815 /* Tell the DMA it is clear to go */ 816 regs->dmactrl |= DMACTRL_INIT_SETTINGS; 817 regs->tstat = TSTAT_CLEAR_THALT; 818 regs->rstat = RSTAT_CLEAR_RHALT; 819 regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS); 820 } 821 822 /* This returns the status bits of the device. The return value 823 * is never checked, and this is what the 8260 driver did, so we 824 * do the same. Presumably, this would be zero if there were no 825 * errors 826 */ 827 static int tsec_send(struct eth_device *dev, volatile void *packet, int length) 828 { 829 int i; 830 int result = 0; 831 struct tsec_private *priv = (struct tsec_private *)dev->priv; 832 volatile tsec_t *regs = priv->regs; 833 834 /* Find an empty buffer descriptor */ 835 for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) { 836 if (i >= TOUT_LOOP) { 837 debug("%s: tsec: tx buffers full\n", dev->name); 838 return result; 839 } 840 } 841 842 rtx.txbd[txIdx].bufPtr = (uint) packet; 843 rtx.txbd[txIdx].length = length; 844 rtx.txbd[txIdx].status |= 845 (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT); 846 847 /* Tell the DMA to go */ 848 regs->tstat = TSTAT_CLEAR_THALT; 849 850 /* Wait for buffer to be transmitted */ 851 for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) { 852 if (i >= TOUT_LOOP) { 853 debug("%s: tsec: tx error\n", dev->name); 854 return result; 855 } 856 } 857 858 txIdx = (txIdx + 1) % TX_BUF_CNT; 859 result = rtx.txbd[txIdx].status & TXBD_STATS; 860 861 return result; 862 } 863 864 static int tsec_recv(struct eth_device *dev) 865 { 866 int length; 867 struct tsec_private *priv = (struct tsec_private *)dev->priv; 868 volatile tsec_t *regs = priv->regs; 869 870 while (!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) { 871 872 length = rtx.rxbd[rxIdx].length; 873 874 /* Send the packet up if there were no errors */ 875 if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) { 876 NetReceive(NetRxPackets[rxIdx], length - 4); 877 } else { 878 printf("Got error %x\n", 879 (rtx.rxbd[rxIdx].status & RXBD_STATS)); 880 } 881 882 rtx.rxbd[rxIdx].length = 0; 883 884 /* Set the wrap bit if this is the last element in the list */ 885 rtx.rxbd[rxIdx].status = 886 RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); 887 888 rxIdx = (rxIdx + 1) % PKTBUFSRX; 889 } 890 891 if (regs->ievent & IEVENT_BSY) { 892 regs->ievent = IEVENT_BSY; 893 regs->rstat = RSTAT_CLEAR_RHALT; 894 } 895 896 return -1; 897 898 } 899 900 /* Stop the interface */ 901 static void tsec_halt(struct eth_device *dev) 902 { 903 struct tsec_private *priv = (struct tsec_private *)dev->priv; 904 volatile tsec_t *regs = priv->regs; 905 906 regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS); 907 regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS); 908 909 while (!(regs->ievent & (IEVENT_GRSC | IEVENT_GTSC))) ; 910 911 regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN); 912 913 /* Shut down the PHY, as needed */ 914 if(priv->phyinfo) 915 phy_run_commands(priv, priv->phyinfo->shutdown); 916 } 917 918 struct phy_info phy_info_M88E1149S = { 919 0x1410ca, 920 "Marvell 88E1149S", 921 4, 922 (struct phy_cmd[]){ /* config */ 923 /* Reset and configure the PHY */ 924 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 925 {0x1d, 0x1f, NULL}, 926 {0x1e, 0x200c, NULL}, 927 {0x1d, 0x5, NULL}, 928 {0x1e, 0x0, NULL}, 929 {0x1e, 0x100, NULL}, 930 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 931 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 932 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 933 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 934 {miim_end,} 935 }, 936 (struct phy_cmd[]){ /* startup */ 937 /* Status is read once to clear old link state */ 938 {MIIM_STATUS, miim_read, NULL}, 939 /* Auto-negotiate */ 940 {MIIM_STATUS, miim_read, &mii_parse_sr}, 941 /* Read the status */ 942 {MIIM_88E1011_PHY_STATUS, miim_read, 943 &mii_parse_88E1011_psr}, 944 {miim_end,} 945 }, 946 (struct phy_cmd[]){ /* shutdown */ 947 {miim_end,} 948 }, 949 }; 950 951 /* The 5411 id is 0x206070, the 5421 is 0x2060e0 */ 952 struct phy_info phy_info_BCM5461S = { 953 0x02060c1, /* 5461 ID */ 954 "Broadcom BCM5461S", 955 0, /* not clear to me what minor revisions we can shift away */ 956 (struct phy_cmd[]) { /* config */ 957 /* Reset and configure the PHY */ 958 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 959 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 960 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 961 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 962 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 963 {miim_end,} 964 }, 965 (struct phy_cmd[]) { /* startup */ 966 /* Status is read once to clear old link state */ 967 {MIIM_STATUS, miim_read, NULL}, 968 /* Auto-negotiate */ 969 {MIIM_STATUS, miim_read, &mii_parse_sr}, 970 /* Read the status */ 971 {MIIM_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr}, 972 {miim_end,} 973 }, 974 (struct phy_cmd[]) { /* shutdown */ 975 {miim_end,} 976 }, 977 }; 978 979 struct phy_info phy_info_BCM5464S = { 980 0x02060b1, /* 5464 ID */ 981 "Broadcom BCM5464S", 982 0, /* not clear to me what minor revisions we can shift away */ 983 (struct phy_cmd[]) { /* config */ 984 /* Reset and configure the PHY */ 985 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 986 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 987 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 988 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 989 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 990 {miim_end,} 991 }, 992 (struct phy_cmd[]) { /* startup */ 993 /* Status is read once to clear old link state */ 994 {MIIM_STATUS, miim_read, NULL}, 995 /* Auto-negotiate */ 996 {MIIM_STATUS, miim_read, &mii_parse_sr}, 997 /* Read the status */ 998 {MIIM_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr}, 999 {miim_end,} 1000 }, 1001 (struct phy_cmd[]) { /* shutdown */ 1002 {miim_end,} 1003 }, 1004 }; 1005 1006 struct phy_info phy_info_M88E1011S = { 1007 0x01410c6, 1008 "Marvell 88E1011S", 1009 4, 1010 (struct phy_cmd[]){ /* config */ 1011 /* Reset and configure the PHY */ 1012 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1013 {0x1d, 0x1f, NULL}, 1014 {0x1e, 0x200c, NULL}, 1015 {0x1d, 0x5, NULL}, 1016 {0x1e, 0x0, NULL}, 1017 {0x1e, 0x100, NULL}, 1018 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1019 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1020 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1021 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1022 {miim_end,} 1023 }, 1024 (struct phy_cmd[]){ /* startup */ 1025 /* Status is read once to clear old link state */ 1026 {MIIM_STATUS, miim_read, NULL}, 1027 /* Auto-negotiate */ 1028 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1029 /* Read the status */ 1030 {MIIM_88E1011_PHY_STATUS, miim_read, 1031 &mii_parse_88E1011_psr}, 1032 {miim_end,} 1033 }, 1034 (struct phy_cmd[]){ /* shutdown */ 1035 {miim_end,} 1036 }, 1037 }; 1038 1039 struct phy_info phy_info_M88E1111S = { 1040 0x01410cc, 1041 "Marvell 88E1111S", 1042 4, 1043 (struct phy_cmd[]){ /* config */ 1044 /* Reset and configure the PHY */ 1045 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1046 {0x1b, 0x848f, &mii_m88e1111s_setmode}, 1047 {0x14, 0x0cd2, NULL}, /* Delay RGMII TX and RX */ 1048 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1049 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1050 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1051 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1052 {miim_end,} 1053 }, 1054 (struct phy_cmd[]){ /* startup */ 1055 /* Status is read once to clear old link state */ 1056 {MIIM_STATUS, miim_read, NULL}, 1057 /* Auto-negotiate */ 1058 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1059 /* Read the status */ 1060 {MIIM_88E1011_PHY_STATUS, miim_read, 1061 &mii_parse_88E1011_psr}, 1062 {miim_end,} 1063 }, 1064 (struct phy_cmd[]){ /* shutdown */ 1065 {miim_end,} 1066 }, 1067 }; 1068 1069 static unsigned int m88e1145_setmode(uint mii_reg, struct tsec_private *priv) 1070 { 1071 uint mii_data = read_phy_reg(priv, mii_reg); 1072 1073 /* Setting MIIM_88E1145_PHY_EXT_CR */ 1074 if (priv->flags & TSEC_REDUCED) 1075 return mii_data | 1076 MIIM_M88E1145_RGMII_RX_DELAY | MIIM_M88E1145_RGMII_TX_DELAY; 1077 else 1078 return mii_data; 1079 } 1080 1081 static struct phy_info phy_info_M88E1145 = { 1082 0x01410cd, 1083 "Marvell 88E1145", 1084 4, 1085 (struct phy_cmd[]){ /* config */ 1086 /* Reset the PHY */ 1087 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1088 1089 /* Errata E0, E1 */ 1090 {29, 0x001b, NULL}, 1091 {30, 0x418f, NULL}, 1092 {29, 0x0016, NULL}, 1093 {30, 0xa2da, NULL}, 1094 1095 /* Configure the PHY */ 1096 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, 1097 {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, 1098 {MIIM_88E1011_PHY_SCR, MIIM_88E1011_PHY_MDI_X_AUTO, 1099 NULL}, 1100 {MIIM_88E1145_PHY_EXT_CR, 0, &m88e1145_setmode}, 1101 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, 1102 {MIIM_CONTROL, MIIM_CONTROL_INIT, NULL}, 1103 {miim_end,} 1104 }, 1105 (struct phy_cmd[]){ /* startup */ 1106 /* Status is read once to clear old link state */ 1107 {MIIM_STATUS, miim_read, NULL}, 1108 /* Auto-negotiate */ 1109 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1110 {MIIM_88E1111_PHY_LED_CONTROL, 1111 MIIM_88E1111_PHY_LED_DIRECT, NULL}, 1112 /* Read the Status */ 1113 {MIIM_88E1011_PHY_STATUS, miim_read, 1114 &mii_parse_88E1011_psr}, 1115 {miim_end,} 1116 }, 1117 (struct phy_cmd[]){ /* shutdown */ 1118 {miim_end,} 1119 }, 1120 }; 1121 1122 struct phy_info phy_info_cis8204 = { 1123 0x3f11, 1124 "Cicada Cis8204", 1125 6, 1126 (struct phy_cmd[]){ /* config */ 1127 /* Override PHY config settings */ 1128 {MIIM_CIS8201_AUX_CONSTAT, 1129 MIIM_CIS8201_AUXCONSTAT_INIT, NULL}, 1130 /* Configure some basic stuff */ 1131 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1132 {MIIM_CIS8204_SLED_CON, MIIM_CIS8204_SLEDCON_INIT, 1133 &mii_cis8204_fixled}, 1134 {MIIM_CIS8204_EPHY_CON, MIIM_CIS8204_EPHYCON_INIT, 1135 &mii_cis8204_setmode}, 1136 {miim_end,} 1137 }, 1138 (struct phy_cmd[]){ /* startup */ 1139 /* Read the Status (2x to make sure link is right) */ 1140 {MIIM_STATUS, miim_read, NULL}, 1141 /* Auto-negotiate */ 1142 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1143 /* Read the status */ 1144 {MIIM_CIS8201_AUX_CONSTAT, miim_read, 1145 &mii_parse_cis8201}, 1146 {miim_end,} 1147 }, 1148 (struct phy_cmd[]){ /* shutdown */ 1149 {miim_end,} 1150 }, 1151 }; 1152 1153 /* Cicada 8201 */ 1154 struct phy_info phy_info_cis8201 = { 1155 0xfc41, 1156 "CIS8201", 1157 4, 1158 (struct phy_cmd[]){ /* config */ 1159 /* Override PHY config settings */ 1160 {MIIM_CIS8201_AUX_CONSTAT, 1161 MIIM_CIS8201_AUXCONSTAT_INIT, NULL}, 1162 /* Set up the interface mode */ 1163 {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, 1164 NULL}, 1165 /* Configure some basic stuff */ 1166 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1167 {miim_end,} 1168 }, 1169 (struct phy_cmd[]){ /* startup */ 1170 /* Read the Status (2x to make sure link is right) */ 1171 {MIIM_STATUS, miim_read, NULL}, 1172 /* Auto-negotiate */ 1173 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1174 /* Read the status */ 1175 {MIIM_CIS8201_AUX_CONSTAT, miim_read, 1176 &mii_parse_cis8201}, 1177 {miim_end,} 1178 }, 1179 (struct phy_cmd[]){ /* shutdown */ 1180 {miim_end,} 1181 }, 1182 }; 1183 struct phy_info phy_info_VSC8244 = { 1184 0x3f1b, 1185 "Vitesse VSC8244", 1186 6, 1187 (struct phy_cmd[]){ /* config */ 1188 /* Override PHY config settings */ 1189 /* Configure some basic stuff */ 1190 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, 1191 {miim_end,} 1192 }, 1193 (struct phy_cmd[]){ /* startup */ 1194 /* Read the Status (2x to make sure link is right) */ 1195 {MIIM_STATUS, miim_read, NULL}, 1196 /* Auto-negotiate */ 1197 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1198 /* Read the status */ 1199 {MIIM_VSC8244_AUX_CONSTAT, miim_read, 1200 &mii_parse_vsc8244}, 1201 {miim_end,} 1202 }, 1203 (struct phy_cmd[]){ /* shutdown */ 1204 {miim_end,} 1205 }, 1206 }; 1207 1208 struct phy_info phy_info_dm9161 = { 1209 0x0181b88, 1210 "Davicom DM9161E", 1211 4, 1212 (struct phy_cmd[]){ /* config */ 1213 {MIIM_CONTROL, MIIM_DM9161_CR_STOP, NULL}, 1214 /* Do not bypass the scrambler/descrambler */ 1215 {MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT, NULL}, 1216 /* Clear 10BTCSR to default */ 1217 {MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT, 1218 NULL}, 1219 /* Configure some basic stuff */ 1220 {MIIM_CONTROL, MIIM_CR_INIT, NULL}, 1221 /* Restart Auto Negotiation */ 1222 {MIIM_CONTROL, MIIM_DM9161_CR_RSTAN, NULL}, 1223 {miim_end,} 1224 }, 1225 (struct phy_cmd[]){ /* startup */ 1226 /* Status is read once to clear old link state */ 1227 {MIIM_STATUS, miim_read, NULL}, 1228 /* Auto-negotiate */ 1229 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1230 /* Read the status */ 1231 {MIIM_DM9161_SCSR, miim_read, 1232 &mii_parse_dm9161_scsr}, 1233 {miim_end,} 1234 }, 1235 (struct phy_cmd[]){ /* shutdown */ 1236 {miim_end,} 1237 }, 1238 }; 1239 /* a generic flavor. */ 1240 struct phy_info phy_info_generic = { 1241 0, 1242 "Unknown/Generic PHY", 1243 32, 1244 (struct phy_cmd[]) { /* config */ 1245 {PHY_BMCR, PHY_BMCR_RESET, NULL}, 1246 {PHY_BMCR, PHY_BMCR_AUTON|PHY_BMCR_RST_NEG, NULL}, 1247 {miim_end,} 1248 }, 1249 (struct phy_cmd[]) { /* startup */ 1250 {PHY_BMSR, miim_read, NULL}, 1251 {PHY_BMSR, miim_read, &mii_parse_sr}, 1252 {PHY_BMSR, miim_read, &mii_parse_link}, 1253 {miim_end,} 1254 }, 1255 (struct phy_cmd[]) { /* shutdown */ 1256 {miim_end,} 1257 } 1258 }; 1259 1260 1261 uint mii_parse_lxt971_sr2(uint mii_reg, struct tsec_private *priv) 1262 { 1263 unsigned int speed; 1264 if (priv->link) { 1265 speed = mii_reg & MIIM_LXT971_SR2_SPEED_MASK; 1266 1267 switch (speed) { 1268 case MIIM_LXT971_SR2_10HDX: 1269 priv->speed = 10; 1270 priv->duplexity = 0; 1271 break; 1272 case MIIM_LXT971_SR2_10FDX: 1273 priv->speed = 10; 1274 priv->duplexity = 1; 1275 break; 1276 case MIIM_LXT971_SR2_100HDX: 1277 priv->speed = 100; 1278 priv->duplexity = 0; 1279 break; 1280 default: 1281 priv->speed = 100; 1282 priv->duplexity = 1; 1283 } 1284 } else { 1285 priv->speed = 0; 1286 priv->duplexity = 0; 1287 } 1288 1289 return 0; 1290 } 1291 1292 static struct phy_info phy_info_lxt971 = { 1293 0x0001378e, 1294 "LXT971", 1295 4, 1296 (struct phy_cmd[]){ /* config */ 1297 {MIIM_CR, MIIM_CR_INIT, mii_cr_init}, /* autonegotiate */ 1298 {miim_end,} 1299 }, 1300 (struct phy_cmd[]){ /* startup - enable interrupts */ 1301 /* { 0x12, 0x00f2, NULL }, */ 1302 {MIIM_STATUS, miim_read, NULL}, 1303 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1304 {MIIM_LXT971_SR2, miim_read, &mii_parse_lxt971_sr2}, 1305 {miim_end,} 1306 }, 1307 (struct phy_cmd[]){ /* shutdown - disable interrupts */ 1308 {miim_end,} 1309 }, 1310 }; 1311 1312 /* Parse the DP83865's link and auto-neg status register for speed and duplex 1313 * information 1314 */ 1315 uint mii_parse_dp83865_lanr(uint mii_reg, struct tsec_private *priv) 1316 { 1317 switch (mii_reg & MIIM_DP83865_SPD_MASK) { 1318 1319 case MIIM_DP83865_SPD_1000: 1320 priv->speed = 1000; 1321 break; 1322 1323 case MIIM_DP83865_SPD_100: 1324 priv->speed = 100; 1325 break; 1326 1327 default: 1328 priv->speed = 10; 1329 break; 1330 1331 } 1332 1333 if (mii_reg & MIIM_DP83865_DPX_FULL) 1334 priv->duplexity = 1; 1335 else 1336 priv->duplexity = 0; 1337 1338 return 0; 1339 } 1340 1341 struct phy_info phy_info_dp83865 = { 1342 0x20005c7, 1343 "NatSemi DP83865", 1344 4, 1345 (struct phy_cmd[]){ /* config */ 1346 {MIIM_CONTROL, MIIM_DP83865_CR_INIT, NULL}, 1347 {miim_end,} 1348 }, 1349 (struct phy_cmd[]){ /* startup */ 1350 /* Status is read once to clear old link state */ 1351 {MIIM_STATUS, miim_read, NULL}, 1352 /* Auto-negotiate */ 1353 {MIIM_STATUS, miim_read, &mii_parse_sr}, 1354 /* Read the link and auto-neg status */ 1355 {MIIM_DP83865_LANR, miim_read, 1356 &mii_parse_dp83865_lanr}, 1357 {miim_end,} 1358 }, 1359 (struct phy_cmd[]){ /* shutdown */ 1360 {miim_end,} 1361 }, 1362 }; 1363 1364 struct phy_info *phy_info[] = { 1365 &phy_info_cis8204, 1366 &phy_info_cis8201, 1367 &phy_info_BCM5461S, 1368 &phy_info_BCM5464S, 1369 &phy_info_M88E1011S, 1370 &phy_info_M88E1111S, 1371 &phy_info_M88E1145, 1372 &phy_info_M88E1149S, 1373 &phy_info_dm9161, 1374 &phy_info_lxt971, 1375 &phy_info_VSC8244, 1376 &phy_info_dp83865, 1377 &phy_info_generic, 1378 NULL 1379 }; 1380 1381 /* Grab the identifier of the device's PHY, and search through 1382 * all of the known PHYs to see if one matches. If so, return 1383 * it, if not, return NULL 1384 */ 1385 struct phy_info *get_phy_info(struct eth_device *dev) 1386 { 1387 struct tsec_private *priv = (struct tsec_private *)dev->priv; 1388 uint phy_reg, phy_ID; 1389 int i; 1390 struct phy_info *theInfo = NULL; 1391 1392 /* Grab the bits from PHYIR1, and put them in the upper half */ 1393 phy_reg = read_phy_reg(priv, MIIM_PHYIR1); 1394 phy_ID = (phy_reg & 0xffff) << 16; 1395 1396 /* Grab the bits from PHYIR2, and put them in the lower half */ 1397 phy_reg = read_phy_reg(priv, MIIM_PHYIR2); 1398 phy_ID |= (phy_reg & 0xffff); 1399 1400 /* loop through all the known PHY types, and find one that */ 1401 /* matches the ID we read from the PHY. */ 1402 for (i = 0; phy_info[i]; i++) { 1403 if (phy_info[i]->id == (phy_ID >> phy_info[i]->shift)) { 1404 theInfo = phy_info[i]; 1405 break; 1406 } 1407 } 1408 1409 if (theInfo == NULL) { 1410 printf("%s: PHY id %x is not supported!\n", dev->name, phy_ID); 1411 return NULL; 1412 } else { 1413 debug("%s: PHY is %s (%x)\n", dev->name, theInfo->name, phy_ID); 1414 } 1415 1416 return theInfo; 1417 } 1418 1419 /* Execute the given series of commands on the given device's 1420 * PHY, running functions as necessary 1421 */ 1422 void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd) 1423 { 1424 int i; 1425 uint result; 1426 volatile tsec_t *phyregs = priv->phyregs; 1427 1428 phyregs->miimcfg = MIIMCFG_RESET; 1429 1430 phyregs->miimcfg = MIIMCFG_INIT_VALUE; 1431 1432 while (phyregs->miimind & MIIMIND_BUSY) ; 1433 1434 for (i = 0; cmd->mii_reg != miim_end; i++) { 1435 if (cmd->mii_data == miim_read) { 1436 result = read_phy_reg(priv, cmd->mii_reg); 1437 1438 if (cmd->funct != NULL) 1439 (*(cmd->funct)) (result, priv); 1440 1441 } else { 1442 if (cmd->funct != NULL) 1443 result = (*(cmd->funct)) (cmd->mii_reg, priv); 1444 else 1445 result = cmd->mii_data; 1446 1447 write_phy_reg(priv, cmd->mii_reg, result); 1448 1449 } 1450 cmd++; 1451 } 1452 } 1453 1454 /* Relocate the function pointers in the phy cmd lists */ 1455 static void relocate_cmds(void) 1456 { 1457 struct phy_cmd **cmdlistptr; 1458 struct phy_cmd *cmd; 1459 int i, j, k; 1460 1461 for (i = 0; phy_info[i]; i++) { 1462 /* First thing's first: relocate the pointers to the 1463 * PHY command structures (the structs were done) */ 1464 phy_info[i] = (struct phy_info *)((uint) phy_info[i] 1465 + gd->reloc_off); 1466 phy_info[i]->name += gd->reloc_off; 1467 phy_info[i]->config = 1468 (struct phy_cmd *)((uint) phy_info[i]->config 1469 + gd->reloc_off); 1470 phy_info[i]->startup = 1471 (struct phy_cmd *)((uint) phy_info[i]->startup 1472 + gd->reloc_off); 1473 phy_info[i]->shutdown = 1474 (struct phy_cmd *)((uint) phy_info[i]->shutdown 1475 + gd->reloc_off); 1476 1477 cmdlistptr = &phy_info[i]->config; 1478 j = 0; 1479 for (; cmdlistptr <= &phy_info[i]->shutdown; cmdlistptr++) { 1480 k = 0; 1481 for (cmd = *cmdlistptr; 1482 cmd->mii_reg != miim_end; 1483 cmd++) { 1484 /* Only relocate non-NULL pointers */ 1485 if (cmd->funct) 1486 cmd->funct += gd->reloc_off; 1487 1488 k++; 1489 } 1490 j++; 1491 } 1492 } 1493 1494 relocated = 1; 1495 } 1496 1497 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \ 1498 && !defined(BITBANGMII) 1499 1500 struct tsec_private *get_priv_for_phy(unsigned char phyaddr) 1501 { 1502 int i; 1503 1504 for (i = 0; i < MAXCONTROLLERS; i++) { 1505 if (privlist[i]->phyaddr == phyaddr) 1506 return privlist[i]; 1507 } 1508 1509 return NULL; 1510 } 1511 1512 /* 1513 * Read a MII PHY register. 1514 * 1515 * Returns: 1516 * 0 on success 1517 */ 1518 static int tsec_miiphy_read(char *devname, unsigned char addr, 1519 unsigned char reg, unsigned short *value) 1520 { 1521 unsigned short ret; 1522 struct tsec_private *priv = get_priv_for_phy(addr); 1523 1524 if (NULL == priv) { 1525 printf("Can't read PHY at address %d\n", addr); 1526 return -1; 1527 } 1528 1529 ret = (unsigned short)read_phy_reg(priv, reg); 1530 *value = ret; 1531 1532 return 0; 1533 } 1534 1535 /* 1536 * Write a MII PHY register. 1537 * 1538 * Returns: 1539 * 0 on success 1540 */ 1541 static int tsec_miiphy_write(char *devname, unsigned char addr, 1542 unsigned char reg, unsigned short value) 1543 { 1544 struct tsec_private *priv = get_priv_for_phy(addr); 1545 1546 if (NULL == priv) { 1547 printf("Can't write PHY at address %d\n", addr); 1548 return -1; 1549 } 1550 1551 write_phy_reg(priv, reg, value); 1552 1553 return 0; 1554 } 1555 1556 #endif 1557 1558 #ifdef CONFIG_MCAST_TFTP 1559 1560 /* CREDITS: linux gianfar driver, slightly adjusted... thanx. */ 1561 1562 /* Set the appropriate hash bit for the given addr */ 1563 1564 /* The algorithm works like so: 1565 * 1) Take the Destination Address (ie the multicast address), and 1566 * do a CRC on it (little endian), and reverse the bits of the 1567 * result. 1568 * 2) Use the 8 most significant bits as a hash into a 256-entry 1569 * table. The table is controlled through 8 32-bit registers: 1570 * gaddr0-7. gaddr0's MSB is entry 0, and gaddr7's LSB is 1571 * gaddr7. This means that the 3 most significant bits in the 1572 * hash index which gaddr register to use, and the 5 other bits 1573 * indicate which bit (assuming an IBM numbering scheme, which 1574 * for PowerPC (tm) is usually the case) in the tregister holds 1575 * the entry. */ 1576 static int 1577 tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set) 1578 { 1579 struct tsec_private *priv = privlist[1]; 1580 volatile tsec_t *regs = priv->regs; 1581 volatile u32 *reg_array, value; 1582 u8 result, whichbit, whichreg; 1583 1584 result = (u8)((ether_crc(MAC_ADDR_LEN,mcast_mac) >> 24) & 0xff); 1585 whichbit = result & 0x1f; /* the 5 LSB = which bit to set */ 1586 whichreg = result >> 5; /* the 3 MSB = which reg to set it in */ 1587 value = (1 << (31-whichbit)); 1588 1589 reg_array = &(regs->hash.gaddr0); 1590 1591 if (set) { 1592 reg_array[whichreg] |= value; 1593 } else { 1594 reg_array[whichreg] &= ~value; 1595 } 1596 return 0; 1597 } 1598 #endif /* Multicast TFTP ? */ 1599 1600 #endif /* CONFIG_TSEC_ENET */ 1601