1/* 2 * Atheros AR71xx built-in ethernet mac driver 3 * 4 * Copyright (C) 2010 Michael Kurz <michi.kurz@googlemail.com> 5 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> 6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 7 * 8 * Based on Atheros' AG7100 driver 9 * 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License version 2 as published 12 * by the Free Software Foundation. 13 */ 14 15#include <common.h> 16#include <malloc.h> 17#include <net.h> 18#include <miiphy.h> 19 20#include <asm/ar71xx.h> 21 22#include "ag71xx.h" 23 24#ifdef AG71XX_DEBUG 25#define DBG(fmt,args...) printf(fmt ,##args) 26#else 27#define DBG(fmt,args...) 28#endif 29 30 31static struct ag71xx agtable[] = { 32 { 33 .mac_base = KSEG1ADDR(AR71XX_GE0_BASE), 34 .mii_ctrl = KSEG1ADDR(AR71XX_MII_BASE + MII_REG_MII0_CTRL), 35 .mii_if = CONFIG_AG71XX_MII0_IIF, 36 } , { 37 .mac_base = KSEG1ADDR(AR71XX_GE1_BASE), 38 .mii_ctrl = KSEG1ADDR(AR71XX_MII_BASE + MII_REG_MII1_CTRL), 39 .mii_if = CONFIG_AG71XX_MII1_IIF, 40 } 41}; 42 43static int ag71xx_ring_alloc(struct ag71xx_ring *ring, unsigned int size) 44{ 45 int err; 46 int i; 47 int rsize; 48 49 ring->desc_size = sizeof(struct ag71xx_desc); 50 if (ring->desc_size % (CONFIG_SYS_CACHELINE_SIZE)) { 51 rsize = roundup(ring->desc_size, CONFIG_SYS_CACHELINE_SIZE); 52 DBG("ag71xx: ring %p, desc size %u rounded to %u\n", 53 ring, ring->desc_size, 54 rsize); 55 ring->desc_size = rsize; 56 } 57 58 ring->descs_cpu = (u8 *) malloc((size * ring->desc_size) 59 + CONFIG_SYS_CACHELINE_SIZE - 1); 60 if (!ring->descs_cpu) { 61 err = -1; 62 goto err; 63 } 64 ring->descs_cpu = (u8 *) UNCACHED_SDRAM((((u32) ring->descs_cpu + 65 CONFIG_SYS_CACHELINE_SIZE - 1) & ~(CONFIG_SYS_CACHELINE_SIZE - 1))); 66 ring->descs_dma = (u8 *) virt_to_phys(ring->descs_cpu); 67 68 ring->size = size; 69 70 ring->buf = malloc(size * sizeof(*ring->buf)); 71 if (!ring->buf) { 72 err = -1; 73 goto err; 74 } 75 memset(ring->buf, 0, size * sizeof(*ring->buf)); 76 77 for (i = 0; i < size; i++) { 78 ring->buf[i].desc = 79 (struct ag71xx_desc *)&ring->descs_cpu[i * ring->desc_size]; 80 DBG("ag71xx: ring %p, desc %d at %p\n", 81 ring, i, ring->buf[i].desc); 82 } 83 84 flush_cache( (u32) ring->buf, size * sizeof(*ring->buf)); 85 86 return 0; 87 88 err: 89 return err; 90} 91 92static void ag71xx_ring_tx_init(struct ag71xx *ag) 93{ 94 struct ag71xx_ring *ring = &ag->tx_ring; 95 int i; 96 97 for (i = 0; i < AG71XX_TX_RING_SIZE; i++) { 98 ring->buf[i].desc->next = (u32) virt_to_phys((ring->descs_dma + 99 ring->desc_size * ((i + 1) % AG71XX_TX_RING_SIZE))); 100 101 ring->buf[i].desc->ctrl = DESC_EMPTY; 102 ring->buf[i].skb = NULL; 103 } 104 105 ring->curr = 0; 106} 107 108static void ag71xx_ring_rx_clean(struct ag71xx *ag) 109{ 110 struct ag71xx_ring *ring = &ag->rx_ring; 111 int i; 112 113 if (!ring->buf) 114 return; 115 116 for (i = 0; i < AG71XX_RX_RING_SIZE; i++) { 117 ring->buf[i].desc->data = (u32) virt_to_phys(NetRxPackets[i]); 118 flush_cache((u32) NetRxPackets[i], PKTSIZE_ALIGN); 119 ring->buf[i].desc->ctrl = DESC_EMPTY; 120 } 121 122 ring->curr = 0; 123} 124 125static int ag71xx_ring_rx_init(struct ag71xx *ag) 126{ 127 struct ag71xx_ring *ring = &ag->rx_ring; 128 unsigned int i; 129 130 for (i = 0; i < AG71XX_RX_RING_SIZE; i++) { 131 ring->buf[i].desc->next = (u32) virt_to_phys((ring->descs_dma + 132 ring->desc_size * ((i + 1) % AG71XX_RX_RING_SIZE))); 133 134 DBG("ag71xx: RX desc at %p, next is %08x\n", 135 ring->buf[i].desc, 136 ring->buf[i].desc->next); 137 } 138 139 for (i = 0; i < AG71XX_RX_RING_SIZE; i++) { 140 ring->buf[i].desc->data = (u32) virt_to_phys(NetRxPackets[i]); 141 ring->buf[i].desc->ctrl = DESC_EMPTY; 142 } 143 144 ring->curr = 0; 145 146 return 0; 147} 148 149static int ag71xx_rings_init(struct ag71xx *ag) 150{ 151 int ret; 152 153 ret = ag71xx_ring_alloc(&ag->tx_ring, AG71XX_TX_RING_SIZE); 154 if (ret) 155 return ret; 156 157 ag71xx_ring_tx_init(ag); 158 159 ret = ag71xx_ring_alloc(&ag->rx_ring, AG71XX_RX_RING_SIZE); 160 if (ret) 161 return ret; 162 163 ret = ag71xx_ring_rx_init(ag); 164 return ret; 165} 166 167static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift) 168{ 169 uint32_t base = KSEG1ADDR(AR71XX_PLL_BASE); 170 u32 t; 171 172 t = readl(base + cfg_reg); 173 t &= ~(3 << shift); 174 t |= (2 << shift); 175 writel(t, base + cfg_reg); 176 udelay(100); 177 178 writel(pll_val, base + pll_reg); 179 180 t |= (3 << shift); 181 writel(t, base + cfg_reg); 182 udelay(100); 183 184 t &= ~(3 << shift); 185 writel(t, base + cfg_reg); 186 udelay(100); 187 188 debug("ar71xx: pll_reg %#x: %#x\n", (unsigned int)(base + pll_reg), 189 readl(base + pll_reg)); 190} 191 192static void ar91xx_set_pll_ge0(int speed) 193{ 194 //u32 val = ar71xx_get_eth_pll(0, speed); 195 u32 pll_val; 196 197 switch (speed) { 198 case SPEED_10: 199 pll_val = 0x00441099; 200 break; 201 case SPEED_100: 202 pll_val = 0x13000a44; 203 break; 204 case SPEED_1000: 205 pll_val = 0x1a000000; 206 break; 207 default: 208 BUG(); 209 } 210 211 ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK, 212 pll_val, AR91XX_ETH0_PLL_SHIFT); 213} 214 215static void ar91xx_set_pll_ge1(int speed) 216{ 217 //u32 val = ar71xx_get_eth_pll(1, speed); 218 u32 pll_val; 219 220 switch (speed) { 221 case SPEED_10: 222 pll_val = 0x00441099; 223 break; 224 case SPEED_100: 225 pll_val = 0x13000a44; 226 break; 227 case SPEED_1000: 228 pll_val = 0x1a000000; 229 break; 230 default: 231 BUG(); 232 } 233 234 ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK, 235 pll_val, AR91XX_ETH1_PLL_SHIFT); 236} 237 238static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) 239{ 240 u32 t; 241 242 t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16) 243 | (((u32) mac[3]) << 8) | ((u32) mac[2]); 244 245 ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t); 246 247 t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16); 248 ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t); 249} 250 251static void ag71xx_dma_reset(struct ag71xx *ag) 252{ 253 u32 val; 254 int i; 255 256 DBG("%s: txdesc reg: 0x%08x rxdesc reg: 0x%08x\n", 257 ag->dev->name, 258 ag71xx_rr(ag, AG71XX_REG_TX_DESC), 259 ag71xx_rr(ag, AG71XX_REG_RX_DESC)); 260 261 /* stop RX and TX */ 262 ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); 263 ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); 264 265 /* clear descriptor addresses */ 266 ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0); 267 ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0); 268 269 /* clear pending RX/TX interrupts */ 270 for (i = 0; i < 256; i++) { 271 ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); 272 ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); 273 } 274 275 /* clear pending errors */ 276 ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF); 277 ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR); 278 279 val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); 280 if (val) 281 printf("%s: unable to clear DMA Rx status: %08x\n", 282 ag->dev->name, val); 283 284 val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); 285 286 /* mask out reserved bits */ 287 val &= ~0xff000000; 288 289 if (val) 290 printf("%s: unable to clear DMA Tx status: %08x\n", 291 ag->dev->name, val); 292} 293 294static void ag71xx_halt(struct eth_device *dev) 295{ 296 struct ag71xx *ag = (struct ag71xx *) dev->priv; 297 298 /* stop RX engine */ 299 ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); 300 301 ag71xx_dma_reset(ag); 302} 303 304#define MAX_WAIT 1000 305 306static int ag71xx_send(struct eth_device *dev, volatile void *packet, 307 int length) 308{ 309 struct ag71xx *ag = (struct ag71xx *) dev->priv; 310 struct ag71xx_ring *ring = &ag->tx_ring; 311 struct ag71xx_desc *desc; 312 int i; 313 314 i = ring->curr % AG71XX_TX_RING_SIZE; 315 desc = ring->buf[i].desc; 316 317 if (!ag71xx_desc_empty(desc)) { 318 printf("%s: tx buffer full\n", ag->dev->name); 319 return 1; 320 } 321 322 flush_cache((u32) packet, length); 323 desc->data = (u32) virt_to_phys(packet); 324 desc->ctrl = (length & DESC_PKTLEN_M); 325 326 DBG("%s: sending %#08x length %#08x\n", 327 ag->dev->name, desc->data, desc->ctrl); 328 329 ring->curr++; 330 if (ring->curr >= AG71XX_TX_RING_SIZE){ 331 ring->curr = 0; 332 } 333 334 /* enable TX engine */ 335 ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE); 336 337 for (i = 0; i < MAX_WAIT; i++) 338 { 339 if (ag71xx_desc_empty(desc)) 340 break; 341 udelay(10); 342 } 343 if (i == MAX_WAIT) { 344 printf("%s: tx timed out!\n", ag->dev->name); 345 return -1; 346 } 347 348 /* disable TX engine */ 349 ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); 350 desc->data = 0; 351 desc->ctrl = DESC_EMPTY; 352 353 return 0; 354} 355 356static int ag71xx_recv(struct eth_device *dev) 357{ 358 struct ag71xx *ag = (struct ag71xx *) dev->priv; 359 struct ag71xx_ring *ring = &ag->rx_ring; 360 361 for (;;) { 362 unsigned int i = ring->curr % AG71XX_RX_RING_SIZE; 363 struct ag71xx_desc *desc = ring->buf[i].desc; 364 int pktlen; 365 366 if (ag71xx_desc_empty(desc)) 367 break; 368 369 DBG("%s: rx packets, curr=%u\n", dev->name, ring->curr); 370 371 pktlen = ag71xx_desc_pktlen(desc); 372 pktlen -= ETH_FCS_LEN; 373 374 375 NetReceive(NetRxPackets[i] , pktlen); 376 flush_cache( (u32) NetRxPackets[i], PKTSIZE_ALIGN); 377 378 ring->buf[i].desc->ctrl = DESC_EMPTY; 379 ring->curr++; 380 if (ring->curr >= AG71XX_RX_RING_SIZE){ 381 ring->curr = 0; 382 } 383 384 } 385 386 if ((ag71xx_rr(ag, AG71XX_REG_RX_CTRL) & RX_CTRL_RXE) == 0) { 387 /* start RX engine */ 388 ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); 389 } 390 391 return 0; 392} 393 394#ifdef AG71XX_DEBUG 395static char *ag71xx_speed_str(struct ag71xx *ag) 396{ 397 switch (ag->speed) { 398 case SPEED_1000: 399 return "1000"; 400 case SPEED_100: 401 return "100"; 402 case SPEED_10: 403 return "10"; 404 } 405 406 return "?"; 407} 408#endif 409 410void ag71xx_link_adjust(struct ag71xx *ag) 411{ 412 u32 cfg2; 413 u32 ifctl; 414 u32 fifo5; 415 u32 mii_speed; 416 417 if (!ag->link) { 418 DBG("%s: link down\n", ag->dev->name); 419 return; 420 } 421 422 cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2); 423 cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX); 424 cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0; 425 426 ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL); 427 ifctl &= ~(MAC_IFCTL_SPEED); 428 429 fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5); 430 fifo5 &= ~FIFO_CFG5_BM; 431 432 switch (ag->speed) { 433 case SPEED_1000: 434 mii_speed = MII_CTRL_SPEED_1000; 435 cfg2 |= MAC_CFG2_IF_1000; 436 fifo5 |= FIFO_CFG5_BM; 437 break; 438 case SPEED_100: 439 mii_speed = MII_CTRL_SPEED_100; 440 cfg2 |= MAC_CFG2_IF_10_100; 441 ifctl |= MAC_IFCTL_SPEED; 442 break; 443 case SPEED_10: 444 mii_speed = MII_CTRL_SPEED_10; 445 cfg2 |= MAC_CFG2_IF_10_100; 446 break; 447 default: 448 BUG(); 449 return; 450 } 451 452 ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff); 453 454 if (ag->macNum == 0) 455 ar91xx_set_pll_ge0(ag->speed); 456 else 457 ar91xx_set_pll_ge1(ag->speed); 458 459 ag71xx_mii_ctrl_set_speed(ag, mii_speed); 460 461 ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2); 462 ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5); 463 ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); 464 465 DBG("%s: link up (%sMbps/%s duplex)\n", 466 ag->dev->name, 467 ag71xx_speed_str(ag), 468 (1 == ag->duplex) ? "Full" : "Half"); 469 470 DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n", 471 ag->dev->name, 472 ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), 473 ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), 474 ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); 475 476 DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n", 477 ag->dev->name, 478 ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), 479 ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), 480 ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); 481 482 DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n", 483 ag->dev->name, 484 ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), 485 ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), 486 ag71xx_mii_ctrl_rr(ag)); 487} 488 489#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) 490static int ag71xx_getMiiSpeed(struct ag71xx *ag) 491{ 492 uint16_t phyreg, cap; 493 494 if (miiphy_read(ag->phyname, ag->phyid, 495 PHY_BMSR, &phyreg)) { 496 puts("PHY_BMSR read failed, assuming no link\n"); 497 return -1; 498 } 499 500 if ((phyreg & PHY_BMSR_LS) == 0) { 501 return -1; 502 } 503 504 if (miiphy_read(ag->phyname, ag->phyid, 505 PHY_1000BTSR, &phyreg)) 506 return -1; 507 508 if (phyreg & PHY_1000BTSR_1000FD) { 509 ag->speed = SPEED_1000; 510 ag->duplex = 1; 511 } else if (phyreg & PHY_1000BTSR_1000HD) { 512 ag->speed = SPEED_1000; 513 ag->duplex = 0; 514 } else { 515 if (miiphy_read(ag->phyname, ag->phyid, 516 PHY_ANAR, &cap)) 517 return -1; 518 519 if (miiphy_read(ag->phyname, ag->phyid, 520 PHY_ANLPAR, &phyreg)) 521 return -1; 522 523 cap &= phyreg; 524 if (cap & PHY_ANLPAR_TXFD) { 525 ag->speed = SPEED_100; 526 ag->duplex = 1; 527 } else if (cap & PHY_ANLPAR_TX) { 528 ag->speed = SPEED_100; 529 ag->duplex = 0; 530 } else if (cap & PHY_ANLPAR_10FD) { 531 ag->speed = SPEED_10; 532 ag->duplex = 1; 533 } else { 534 ag->speed = SPEED_10; 535 ag->duplex = 0; 536 } 537 } 538 539 ag->link = 1; 540 541 return 0; 542} 543#endif 544 545static int ag71xx_hw_start(struct eth_device *dev, bd_t * bd) 546{ 547 struct ag71xx *ag = (struct ag71xx *) dev->priv; 548 549 ag71xx_dma_reset(ag); 550 551 ag71xx_ring_rx_clean(ag); 552 ag71xx_ring_tx_init(ag); 553 554 ag71xx_wr(ag, AG71XX_REG_TX_DESC, 555 (u32) virt_to_phys(ag->tx_ring.descs_dma)); 556 ag71xx_wr(ag, AG71XX_REG_RX_DESC, 557 (u32) virt_to_phys(ag->rx_ring.descs_dma)); 558 559 ag71xx_hw_set_macaddr(ag, ag->dev->enetaddr); 560 561 if (ag->phyfixed) { 562 ag->link = 1; 563 ag->duplex = 1; 564 ag->speed = SPEED_1000; 565 } else { 566 567#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) 568 if (ag71xx_getMiiSpeed(ag)) 569 return -1; 570#else 571 /* only fixed, without mii */ 572 return -1; 573#endif 574 575 } 576 ag71xx_link_adjust(ag); 577 578 DBG("%s: txdesc reg: %#08x rxdesc reg: %#08x\n", 579 ag->dev->name, 580 ag71xx_rr(ag, AG71XX_REG_TX_DESC), 581 ag71xx_rr(ag, AG71XX_REG_RX_DESC)); 582 583 /* start RX engine */ 584 ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); 585 586 return 0; 587} 588 589#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT) 590 591#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \ 592 FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \ 593 FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \ 594 FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \ 595 FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \ 596 FIFO_CFG4_VT) 597 598#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \ 599 FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \ 600 FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \ 601 FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \ 602 FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \ 603 FIFO_CFG5_17 | FIFO_CFG5_SF) 604 605static int ag71xx_hw_init(struct ag71xx *ag) 606{ 607 int ret = 0; 608 uint32_t reg; 609 uint32_t mask, mii_type; 610 611 if (ag->macNum == 0) { 612 mask = (RESET_MODULE_GE0_MAC | RESET_MODULE_GE0_PHY); 613 mii_type = 0x13; 614 } else { 615 mask = (RESET_MODULE_GE1_MAC | RESET_MODULE_GE1_PHY); 616 mii_type = 0x11; 617 } 618 619 // mac soft reset 620 ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR); 621 udelay(20); 622 623 // device stop 624 reg = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); 625 ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, reg | mask); 626 udelay(100 * 1000); 627 628 // device start 629 reg = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); 630 ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, reg & ~mask); 631 udelay(100 * 1000); 632 633 /* setup MAC configuration registers */ 634 ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, (MAC_CFG1_RXE | MAC_CFG1_TXE)); 635 636 ag71xx_sb(ag, AG71XX_REG_MAC_CFG2, 637 MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK); 638 639 /* setup FIFO configuration register 0 */ 640 ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT); 641 642 /* setup MII interface type */ 643 ag71xx_mii_ctrl_set_if(ag, ag->mii_if); 644 645 /* setup mdio clock divisor */ 646 ag71xx_wr(ag, AG71XX_REG_MII_CFG, MII_CFG_CLK_DIV_20); 647 648 /* setup FIFO configuration registers */ 649 ag71xx_sb(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT); 650 ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000); 651 ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff); 652 ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT); 653 654 ag71xx_dma_reset(ag); 655 656 ret = ag71xx_rings_init(ag); 657 if (ret) 658 return -1; 659 660 ag71xx_wr(ag, AG71XX_REG_TX_DESC, 661 (u32) virt_to_phys(ag->tx_ring.descs_dma)); 662 ag71xx_wr(ag, AG71XX_REG_RX_DESC, 663 (u32) virt_to_phys(ag->rx_ring.descs_dma)); 664 665 ag71xx_hw_set_macaddr(ag, ag->dev->enetaddr); 666 667 return 0; 668} 669 670#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) 671#define AG71XX_MDIO_RETRY 1000 672#define AG71XX_MDIO_DELAY 5 673 674static inline struct ag71xx *ag71xx_name2mac(char *devname) 675{ 676 if (strcmp(devname, agtable[0].dev->name) == 0) 677 return &agtable[0]; 678 else if (strcmp(devname, agtable[1].dev->name) == 0) 679 return &agtable[1]; 680 else 681 return NULL; 682} 683 684static inline void ag71xx_mdio_wr(struct ag71xx *ag, unsigned reg, 685 u32 value) 686{ 687 uint32_t r; 688 689 r = ag->mac_base + reg; 690 writel(value, r); 691 692 /* flush write */ 693 (void) readl(r); 694} 695 696static inline u32 ag71xx_mdio_rr(struct ag71xx *ag, unsigned reg) 697{ 698 return readl(ag->mac_base + reg); 699} 700 701static int ag71xx_mdio_read(char *devname, unsigned char addr, 702 unsigned char reg, unsigned short *val) 703{ 704 struct ag71xx *ag = ag71xx_name2mac(devname); 705 uint16_t regData; 706 int i; 707 708 ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_WRITE); 709 ag71xx_mdio_wr(ag, AG71XX_REG_MII_ADDR, 710 ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); 711 ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_READ); 712 713 i = AG71XX_MDIO_RETRY; 714 while (ag71xx_mdio_rr(ag, AG71XX_REG_MII_IND) & MII_IND_BUSY) { 715 if (i-- == 0) { 716 printf("%s: mii_read timed out\n", 717 ag->dev->name); 718 return -1; 719 } 720 udelay(AG71XX_MDIO_DELAY); 721 } 722 723 regData = (uint16_t) ag71xx_mdio_rr(ag, AG71XX_REG_MII_STATUS) & 0xffff; 724 ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_WRITE); 725 726 DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, regData); 727 728 if (val) 729 *val = regData; 730 731 return 0; 732} 733 734static int ag71xx_mdio_write(char *devname, unsigned char addr, 735 unsigned char reg, unsigned short val) 736{ 737 struct ag71xx *ag = ag71xx_name2mac(devname); 738 int i; 739 740 if (ag == NULL) 741 return 1; 742 743 DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val); 744 745 ag71xx_mdio_wr(ag, AG71XX_REG_MII_ADDR, 746 ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); 747 ag71xx_mdio_wr(ag, AG71XX_REG_MII_CTRL, val); 748 749 i = AG71XX_MDIO_RETRY; 750 while (ag71xx_mdio_rr(ag, AG71XX_REG_MII_IND) & MII_IND_BUSY) { 751 if (i-- == 0) { 752 printf("%s: mii_write timed out\n", 753 ag->dev->name); 754 break; 755 } 756 udelay(AG71XX_MDIO_DELAY); 757 } 758 759 return 0; 760} 761#endif 762 763int ag71xx_register(bd_t * bis, char *phyname[], uint16_t phyid[], uint16_t phyfixed[]) 764{ 765 int i, num = 0; 766 u8 used_ports[MAX_AG71XX_DEVS] = CONFIG_AG71XX_PORTS; 767 768 for (i = 0; i < MAX_AG71XX_DEVS; i++) { 769 /*skip if port is configured not to use */ 770 if (used_ports[i] == 0) 771 continue; 772 773 agtable[i].dev = malloc(sizeof(struct eth_device)); 774 if (agtable[i].dev == NULL) { 775 puts("malloc failed\n"); 776 return 0; 777 } 778 memset(agtable[i].dev, 0, sizeof(struct eth_device)); 779 sprintf(agtable[i].dev->name, "eth%d", i); 780 781 agtable[i].dev->iobase = 0; 782 agtable[i].dev->init = ag71xx_hw_start; 783 agtable[i].dev->halt = ag71xx_halt; 784 agtable[i].dev->send = ag71xx_send; 785 agtable[i].dev->recv = ag71xx_recv; 786 agtable[i].dev->priv = (void *) (&agtable[i]); 787 agtable[i].macNum = i; 788 eth_register(agtable[i].dev); 789#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) 790 791 if ((phyname == NULL) || (phyid == NULL) || (phyfixed == NULL)) 792 return -1; 793 794 agtable[i].phyname = strdup(phyname[i]); 795 agtable[i].phyid = phyid[i]; 796 agtable[i].phyfixed = phyfixed[i]; 797 798 miiphy_register(agtable[i].dev->name, ag71xx_mdio_read, 799 ag71xx_mdio_write); 800#endif 801 802 if (ag71xx_hw_init(&agtable[i])) 803 continue; 804 805 num++; 806 } 807 808 return num; 809} 810