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