1 /* 2 * Faraday FTGMAC100 Ethernet 3 * 4 * (C) Copyright 2009 Faraday Technology 5 * Po-Yu Chuang <ratbert@faraday-tech.com> 6 * 7 * (C) Copyright 2010 Andes Technology 8 * Macpaul Lin <macpaul@andestech.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 */ 24 25 #include <config.h> 26 #include <common.h> 27 #include <malloc.h> 28 #include <net.h> 29 #include <asm/io.h> 30 #include <asm/dma-mapping.h> 31 #include <linux/mii.h> 32 33 #include "ftgmac100.h" 34 35 #define ETH_ZLEN 60 36 #define CFG_XBUF_SIZE 1536 37 38 /* RBSR - hw default init value is also 0x640 */ 39 #define RBSR_DEFAULT_VALUE 0x640 40 41 /* PKTBUFSTX/PKTBUFSRX must both be power of 2 */ 42 #define PKTBUFSTX 4 /* must be power of 2 */ 43 44 struct ftgmac100_data { 45 ulong txdes_dma; 46 struct ftgmac100_txdes *txdes; 47 ulong rxdes_dma; 48 struct ftgmac100_rxdes *rxdes; 49 int tx_index; 50 int rx_index; 51 int phy_addr; 52 }; 53 54 /* 55 * struct mii_bus functions 56 */ 57 static int ftgmac100_mdiobus_read(struct eth_device *dev, int phy_addr, 58 int regnum) 59 { 60 struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; 61 int phycr; 62 int i; 63 64 phycr = readl(&ftgmac100->phycr); 65 66 /* preserve MDC cycle threshold */ 67 phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK; 68 69 phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr) 70 | FTGMAC100_PHYCR_REGAD(regnum) 71 | FTGMAC100_PHYCR_MIIRD; 72 73 writel(phycr, &ftgmac100->phycr); 74 75 for (i = 0; i < 10; i++) { 76 phycr = readl(&ftgmac100->phycr); 77 78 if ((phycr & FTGMAC100_PHYCR_MIIRD) == 0) { 79 int data; 80 81 data = readl(&ftgmac100->phydata); 82 return FTGMAC100_PHYDATA_MIIRDATA(data); 83 } 84 85 mdelay(10); 86 } 87 88 debug("mdio read timed out\n"); 89 return -1; 90 } 91 92 static int ftgmac100_mdiobus_write(struct eth_device *dev, int phy_addr, 93 int regnum, u16 value) 94 { 95 struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; 96 int phycr; 97 int data; 98 int i; 99 100 phycr = readl(&ftgmac100->phycr); 101 102 /* preserve MDC cycle threshold */ 103 phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK; 104 105 phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr) 106 | FTGMAC100_PHYCR_REGAD(regnum) 107 | FTGMAC100_PHYCR_MIIWR; 108 109 data = FTGMAC100_PHYDATA_MIIWDATA(value); 110 111 writel(data, &ftgmac100->phydata); 112 writel(phycr, &ftgmac100->phycr); 113 114 for (i = 0; i < 10; i++) { 115 phycr = readl(&ftgmac100->phycr); 116 117 if ((phycr & FTGMAC100_PHYCR_MIIWR) == 0) { 118 debug("(phycr & FTGMAC100_PHYCR_MIIWR) == 0: " \ 119 "phy_addr: %x\n", phy_addr); 120 return 0; 121 } 122 123 mdelay(1); 124 } 125 126 debug("mdio write timed out\n"); 127 return -1; 128 } 129 130 int ftgmac100_phy_read(struct eth_device *dev, int addr, int reg, u16 *value) 131 { 132 *value = ftgmac100_mdiobus_read(dev , addr, reg); 133 134 if (*value == -1) 135 return -1; 136 137 return 0; 138 } 139 140 int ftgmac100_phy_write(struct eth_device *dev, int addr, int reg, u16 value) 141 { 142 if (ftgmac100_mdiobus_write(dev, addr, reg, value) == -1) 143 return -1; 144 145 return 0; 146 } 147 148 static int ftgmac100_phy_reset(struct eth_device *dev) 149 { 150 struct ftgmac100_data *priv = dev->priv; 151 int i; 152 u16 status, adv; 153 154 adv = ADVERTISE_CSMA | ADVERTISE_ALL; 155 156 ftgmac100_phy_write(dev, priv->phy_addr, MII_ADVERTISE, adv); 157 158 printf("%s: Starting autonegotiation...\n", dev->name); 159 160 ftgmac100_phy_write(dev, priv->phy_addr, 161 MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART)); 162 163 for (i = 0; i < 100000 / 100; i++) { 164 ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &status); 165 166 if (status & BMSR_ANEGCOMPLETE) 167 break; 168 mdelay(1); 169 } 170 171 if (status & BMSR_ANEGCOMPLETE) { 172 printf("%s: Autonegotiation complete\n", dev->name); 173 } else { 174 printf("%s: Autonegotiation timed out (status=0x%04x)\n", 175 dev->name, status); 176 return 0; 177 } 178 179 return 1; 180 } 181 182 static int ftgmac100_phy_init(struct eth_device *dev) 183 { 184 struct ftgmac100_data *priv = dev->priv; 185 186 int phy_addr; 187 u16 phy_id, status, adv, lpa, stat_ge; 188 int media, speed, duplex; 189 int i; 190 191 /* Check if the PHY is up to snuff... */ 192 for (phy_addr = 0; phy_addr < CONFIG_PHY_MAX_ADDR; phy_addr++) { 193 194 ftgmac100_phy_read(dev, phy_addr, MII_PHYSID1, &phy_id); 195 196 /* 197 * When it is unable to found PHY, 198 * the interface usually return 0xffff or 0x0000 199 */ 200 if (phy_id != 0xffff && phy_id != 0x0) { 201 printf("%s: found PHY at 0x%02x\n", 202 dev->name, phy_addr); 203 priv->phy_addr = phy_addr; 204 break; 205 } 206 } 207 208 if (phy_id == 0xffff || phy_id == 0x0) { 209 printf("%s: no PHY present\n", dev->name); 210 return 0; 211 } 212 213 ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &status); 214 215 if (!(status & BMSR_LSTATUS)) { 216 /* Try to re-negotiate if we don't have link already. */ 217 ftgmac100_phy_reset(dev); 218 219 for (i = 0; i < 100000 / 100; i++) { 220 ftgmac100_phy_read(dev, priv->phy_addr, 221 MII_BMSR, &status); 222 if (status & BMSR_LSTATUS) 223 break; 224 udelay(100); 225 } 226 } 227 228 if (!(status & BMSR_LSTATUS)) { 229 printf("%s: link down\n", dev->name); 230 return 0; 231 } 232 233 #ifdef CONFIG_FTGMAC100_EGIGA 234 /* 1000 Base-T Status Register */ 235 ftgmac100_phy_read(dev, priv->phy_addr, 236 MII_STAT1000, &stat_ge); 237 238 speed = (stat_ge & (LPA_1000FULL | LPA_1000HALF) 239 ? 1 : 0); 240 241 duplex = ((stat_ge & LPA_1000FULL) 242 ? 1 : 0); 243 244 if (speed) { /* Speed is 1000 */ 245 printf("%s: link up, 1000bps %s-duplex\n", 246 dev->name, duplex ? "full" : "half"); 247 return 0; 248 } 249 #endif 250 251 ftgmac100_phy_read(dev, priv->phy_addr, MII_ADVERTISE, &adv); 252 ftgmac100_phy_read(dev, priv->phy_addr, MII_LPA, &lpa); 253 254 media = mii_nway_result(lpa & adv); 255 speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 1 : 0); 256 duplex = (media & ADVERTISE_FULL) ? 1 : 0; 257 258 printf("%s: link up, %sMbps %s-duplex\n", 259 dev->name, speed ? "100" : "10", duplex ? "full" : "half"); 260 261 return 1; 262 } 263 264 static int ftgmac100_update_link_speed(struct eth_device *dev) 265 { 266 struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; 267 struct ftgmac100_data *priv = dev->priv; 268 269 unsigned short stat_fe; 270 unsigned short stat_ge; 271 unsigned int maccr; 272 273 #ifdef CONFIG_FTGMAC100_EGIGA 274 /* 1000 Base-T Status Register */ 275 ftgmac100_phy_read(dev, priv->phy_addr, MII_STAT1000, &stat_ge); 276 #endif 277 278 ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &stat_fe); 279 280 if (!(stat_fe & BMSR_LSTATUS)) /* link status up? */ 281 return 0; 282 283 /* read MAC control register and clear related bits */ 284 maccr = readl(&ftgmac100->maccr) & 285 ~(FTGMAC100_MACCR_GIGA_MODE | 286 FTGMAC100_MACCR_FAST_MODE | 287 FTGMAC100_MACCR_FULLDUP); 288 289 #ifdef CONFIG_FTGMAC100_EGIGA 290 if (stat_ge & LPA_1000FULL) { 291 /* set gmac for 1000BaseTX and Full Duplex */ 292 maccr |= FTGMAC100_MACCR_GIGA_MODE | FTGMAC100_MACCR_FULLDUP; 293 } 294 295 if (stat_ge & LPA_1000HALF) { 296 /* set gmac for 1000BaseTX and Half Duplex */ 297 maccr |= FTGMAC100_MACCR_GIGA_MODE; 298 } 299 #endif 300 301 if (stat_fe & BMSR_100FULL) { 302 /* set MII for 100BaseTX and Full Duplex */ 303 maccr |= FTGMAC100_MACCR_FAST_MODE | FTGMAC100_MACCR_FULLDUP; 304 } 305 306 if (stat_fe & BMSR_10FULL) { 307 /* set MII for 10BaseT and Full Duplex */ 308 maccr |= FTGMAC100_MACCR_FULLDUP; 309 } 310 311 if (stat_fe & BMSR_100HALF) { 312 /* set MII for 100BaseTX and Half Duplex */ 313 maccr |= FTGMAC100_MACCR_FAST_MODE; 314 } 315 316 if (stat_fe & BMSR_10HALF) { 317 /* set MII for 10BaseT and Half Duplex */ 318 /* we have already clear these bits, do nothing */ 319 ; 320 } 321 322 /* update MII config into maccr */ 323 writel(maccr, &ftgmac100->maccr); 324 325 return 1; 326 } 327 328 /* 329 * Reset MAC 330 */ 331 static void ftgmac100_reset(struct eth_device *dev) 332 { 333 struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; 334 335 debug("%s()\n", __func__); 336 337 writel(FTGMAC100_MACCR_SW_RST, &ftgmac100->maccr); 338 339 while (readl(&ftgmac100->maccr) & FTGMAC100_MACCR_SW_RST) 340 ; 341 } 342 343 /* 344 * Set MAC address 345 */ 346 static void ftgmac100_set_mac(struct eth_device *dev, 347 const unsigned char *mac) 348 { 349 struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; 350 unsigned int maddr = mac[0] << 8 | mac[1]; 351 unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; 352 353 debug("%s(%x %x)\n", __func__, maddr, laddr); 354 355 writel(maddr, &ftgmac100->mac_madr); 356 writel(laddr, &ftgmac100->mac_ladr); 357 } 358 359 static void ftgmac100_set_mac_from_env(struct eth_device *dev) 360 { 361 eth_getenv_enetaddr("ethaddr", dev->enetaddr); 362 363 ftgmac100_set_mac(dev, dev->enetaddr); 364 } 365 366 /* 367 * disable transmitter, receiver 368 */ 369 static void ftgmac100_halt(struct eth_device *dev) 370 { 371 struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; 372 373 debug("%s()\n", __func__); 374 375 writel(0, &ftgmac100->maccr); 376 } 377 378 static int ftgmac100_init(struct eth_device *dev, bd_t *bd) 379 { 380 struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; 381 struct ftgmac100_data *priv = dev->priv; 382 struct ftgmac100_txdes *txdes; 383 struct ftgmac100_rxdes *rxdes; 384 unsigned int maccr; 385 void *buf; 386 int i; 387 388 debug("%s()\n", __func__); 389 390 if (!priv->txdes) { 391 txdes = dma_alloc_coherent( 392 sizeof(*txdes) * PKTBUFSTX, &priv->txdes_dma); 393 if (!txdes) 394 panic("ftgmac100: out of memory\n"); 395 memset(txdes, 0, sizeof(*txdes) * PKTBUFSTX); 396 priv->txdes = txdes; 397 } 398 txdes = priv->txdes; 399 400 if (!priv->rxdes) { 401 rxdes = dma_alloc_coherent( 402 sizeof(*rxdes) * PKTBUFSRX, &priv->rxdes_dma); 403 if (!rxdes) 404 panic("ftgmac100: out of memory\n"); 405 memset(rxdes, 0, sizeof(*rxdes) * PKTBUFSRX); 406 priv->rxdes = rxdes; 407 } 408 rxdes = priv->rxdes; 409 410 /* set the ethernet address */ 411 ftgmac100_set_mac_from_env(dev); 412 413 /* disable all interrupts */ 414 writel(0, &ftgmac100->ier); 415 416 /* initialize descriptors */ 417 priv->tx_index = 0; 418 priv->rx_index = 0; 419 420 txdes[PKTBUFSTX - 1].txdes0 = FTGMAC100_TXDES0_EDOTR; 421 rxdes[PKTBUFSRX - 1].rxdes0 = FTGMAC100_RXDES0_EDORR; 422 423 for (i = 0; i < PKTBUFSTX; i++) { 424 /* TXBUF_BADR */ 425 if (!txdes[i].txdes2) { 426 buf = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE); 427 if (!buf) 428 panic("ftgmac100: out of memory\n"); 429 txdes[i].txdes3 = virt_to_phys(buf); 430 txdes[i].txdes2 = (uint)buf; 431 } 432 txdes[i].txdes1 = 0; 433 } 434 435 for (i = 0; i < PKTBUFSRX; i++) { 436 /* RXBUF_BADR */ 437 if (!rxdes[i].rxdes2) { 438 buf = NetRxPackets[i]; 439 rxdes[i].rxdes3 = virt_to_phys(buf); 440 rxdes[i].rxdes2 = (uint)buf; 441 } 442 rxdes[i].rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY; 443 } 444 445 /* transmit ring */ 446 writel(priv->txdes_dma, &ftgmac100->txr_badr); 447 448 /* receive ring */ 449 writel(priv->rxdes_dma, &ftgmac100->rxr_badr); 450 451 /* poll receive descriptor automatically */ 452 writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc); 453 454 /* config receive buffer size register */ 455 writel(FTGMAC100_RBSR_SIZE(RBSR_DEFAULT_VALUE), &ftgmac100->rbsr); 456 457 /* enable transmitter, receiver */ 458 maccr = FTGMAC100_MACCR_TXMAC_EN | 459 FTGMAC100_MACCR_RXMAC_EN | 460 FTGMAC100_MACCR_TXDMA_EN | 461 FTGMAC100_MACCR_RXDMA_EN | 462 FTGMAC100_MACCR_CRC_APD | 463 FTGMAC100_MACCR_FULLDUP | 464 FTGMAC100_MACCR_RX_RUNT | 465 FTGMAC100_MACCR_RX_BROADPKT; 466 467 writel(maccr, &ftgmac100->maccr); 468 469 if (!ftgmac100_phy_init(dev)) { 470 if (!ftgmac100_update_link_speed(dev)) 471 return -1; 472 } 473 474 return 0; 475 } 476 477 /* 478 * Get a data block via Ethernet 479 */ 480 static int ftgmac100_recv(struct eth_device *dev) 481 { 482 struct ftgmac100_data *priv = dev->priv; 483 struct ftgmac100_rxdes *curr_des; 484 unsigned short rxlen; 485 486 curr_des = &priv->rxdes[priv->rx_index]; 487 488 if (!(curr_des->rxdes0 & FTGMAC100_RXDES0_RXPKT_RDY)) 489 return -1; 490 491 if (curr_des->rxdes0 & (FTGMAC100_RXDES0_RX_ERR | 492 FTGMAC100_RXDES0_CRC_ERR | 493 FTGMAC100_RXDES0_FTL | 494 FTGMAC100_RXDES0_RUNT | 495 FTGMAC100_RXDES0_RX_ODD_NB)) { 496 return -1; 497 } 498 499 rxlen = FTGMAC100_RXDES0_VDBC(curr_des->rxdes0); 500 501 debug("%s(): RX buffer %d, %x received\n", 502 __func__, priv->rx_index, rxlen); 503 504 /* invalidate d-cache */ 505 dma_map_single((void *)curr_des->rxdes2, rxlen, DMA_FROM_DEVICE); 506 507 /* pass the packet up to the protocol layers. */ 508 NetReceive((void *)curr_des->rxdes2, rxlen); 509 510 /* release buffer to DMA */ 511 curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY; 512 513 priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX; 514 515 return 0; 516 } 517 518 /* 519 * Send a data block via Ethernet 520 */ 521 static int ftgmac100_send(struct eth_device *dev, void *packet, int length) 522 { 523 struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; 524 struct ftgmac100_data *priv = dev->priv; 525 struct ftgmac100_txdes *curr_des = &priv->txdes[priv->tx_index]; 526 527 if (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) { 528 debug("%s(): no TX descriptor available\n", __func__); 529 return -1; 530 } 531 532 debug("%s(%x, %x)\n", __func__, (int)packet, length); 533 534 length = (length < ETH_ZLEN) ? ETH_ZLEN : length; 535 536 memcpy((void *)curr_des->txdes2, (void *)packet, length); 537 dma_map_single((void *)curr_des->txdes2, length, DMA_TO_DEVICE); 538 539 /* only one descriptor on TXBUF */ 540 curr_des->txdes0 &= FTGMAC100_TXDES0_EDOTR; 541 curr_des->txdes0 |= FTGMAC100_TXDES0_FTS | 542 FTGMAC100_TXDES0_LTS | 543 FTGMAC100_TXDES0_TXBUF_SIZE(length) | 544 FTGMAC100_TXDES0_TXDMA_OWN ; 545 546 /* start transmit */ 547 writel(1, &ftgmac100->txpd); 548 549 debug("%s(): packet sent\n", __func__); 550 551 priv->tx_index = (priv->tx_index + 1) % PKTBUFSTX; 552 553 return 0; 554 } 555 556 int ftgmac100_initialize(bd_t *bd) 557 { 558 struct eth_device *dev; 559 struct ftgmac100_data *priv; 560 561 dev = malloc(sizeof *dev); 562 if (!dev) { 563 printf("%s(): failed to allocate dev\n", __func__); 564 goto out; 565 } 566 567 /* Transmit and receive descriptors should align to 16 bytes */ 568 priv = memalign(16, sizeof(struct ftgmac100_data)); 569 if (!priv) { 570 printf("%s(): failed to allocate priv\n", __func__); 571 goto free_dev; 572 } 573 574 memset(dev, 0, sizeof(*dev)); 575 memset(priv, 0, sizeof(*priv)); 576 577 sprintf(dev->name, "FTGMAC100"); 578 dev->iobase = CONFIG_FTGMAC100_BASE; 579 dev->init = ftgmac100_init; 580 dev->halt = ftgmac100_halt; 581 dev->send = ftgmac100_send; 582 dev->recv = ftgmac100_recv; 583 dev->priv = priv; 584 585 eth_register(dev); 586 587 ftgmac100_reset(dev); 588 589 return 1; 590 591 free_dev: 592 free(dev); 593 out: 594 return 0; 595 } 596