1 /* 2 * Copyright (C) 2005-2006 Atmel Corporation 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 #include <common.h> 19 20 /* 21 * The u-boot networking stack is a little weird. It seems like the 22 * networking core allocates receive buffers up front without any 23 * regard to the hardware that's supposed to actually receive those 24 * packets. 25 * 26 * The MACB receives packets into 128-byte receive buffers, so the 27 * buffers allocated by the core isn't very practical to use. We'll 28 * allocate our own, but we need one such buffer in case a packet 29 * wraps around the DMA ring so that we have to copy it. 30 * 31 * Therefore, define CONFIG_SYS_RX_ETH_BUFFER to 1 in the board-specific 32 * configuration header. This way, the core allocates one RX buffer 33 * and one TX buffer, each of which can hold a ethernet packet of 34 * maximum size. 35 * 36 * For some reason, the networking core unconditionally specifies a 37 * 32-byte packet "alignment" (which really should be called 38 * "padding"). MACB shouldn't need that, but we'll refrain from any 39 * core modifications here... 40 */ 41 42 #include <net.h> 43 #include <netdev.h> 44 #include <malloc.h> 45 #include <miiphy.h> 46 47 #include <linux/mii.h> 48 #include <asm/io.h> 49 #include <asm/dma-mapping.h> 50 #include <asm/arch/clk.h> 51 52 #include "macb.h" 53 54 #define CONFIG_SYS_MACB_RX_BUFFER_SIZE 4096 55 #define CONFIG_SYS_MACB_RX_RING_SIZE (CONFIG_SYS_MACB_RX_BUFFER_SIZE / 128) 56 #define CONFIG_SYS_MACB_TX_RING_SIZE 16 57 #define CONFIG_SYS_MACB_TX_TIMEOUT 1000 58 #define CONFIG_SYS_MACB_AUTONEG_TIMEOUT 5000000 59 60 struct macb_dma_desc { 61 u32 addr; 62 u32 ctrl; 63 }; 64 65 #define RXADDR_USED 0x00000001 66 #define RXADDR_WRAP 0x00000002 67 68 #define RXBUF_FRMLEN_MASK 0x00000fff 69 #define RXBUF_FRAME_START 0x00004000 70 #define RXBUF_FRAME_END 0x00008000 71 #define RXBUF_TYPEID_MATCH 0x00400000 72 #define RXBUF_ADDR4_MATCH 0x00800000 73 #define RXBUF_ADDR3_MATCH 0x01000000 74 #define RXBUF_ADDR2_MATCH 0x02000000 75 #define RXBUF_ADDR1_MATCH 0x04000000 76 #define RXBUF_BROADCAST 0x80000000 77 78 #define TXBUF_FRMLEN_MASK 0x000007ff 79 #define TXBUF_FRAME_END 0x00008000 80 #define TXBUF_NOCRC 0x00010000 81 #define TXBUF_EXHAUSTED 0x08000000 82 #define TXBUF_UNDERRUN 0x10000000 83 #define TXBUF_MAXRETRY 0x20000000 84 #define TXBUF_WRAP 0x40000000 85 #define TXBUF_USED 0x80000000 86 87 struct macb_device { 88 void *regs; 89 90 unsigned int rx_tail; 91 unsigned int tx_head; 92 unsigned int tx_tail; 93 94 void *rx_buffer; 95 void *tx_buffer; 96 struct macb_dma_desc *rx_ring; 97 struct macb_dma_desc *tx_ring; 98 99 unsigned long rx_buffer_dma; 100 unsigned long rx_ring_dma; 101 unsigned long tx_ring_dma; 102 103 const struct device *dev; 104 struct eth_device netdev; 105 unsigned short phy_addr; 106 }; 107 #define to_macb(_nd) container_of(_nd, struct macb_device, netdev) 108 109 static void macb_mdio_write(struct macb_device *macb, u8 reg, u16 value) 110 { 111 unsigned long netctl; 112 unsigned long netstat; 113 unsigned long frame; 114 115 netctl = macb_readl(macb, NCR); 116 netctl |= MACB_BIT(MPE); 117 macb_writel(macb, NCR, netctl); 118 119 frame = (MACB_BF(SOF, 1) 120 | MACB_BF(RW, 1) 121 | MACB_BF(PHYA, macb->phy_addr) 122 | MACB_BF(REGA, reg) 123 | MACB_BF(CODE, 2) 124 | MACB_BF(DATA, value)); 125 macb_writel(macb, MAN, frame); 126 127 do { 128 netstat = macb_readl(macb, NSR); 129 } while (!(netstat & MACB_BIT(IDLE))); 130 131 netctl = macb_readl(macb, NCR); 132 netctl &= ~MACB_BIT(MPE); 133 macb_writel(macb, NCR, netctl); 134 } 135 136 static u16 macb_mdio_read(struct macb_device *macb, u8 reg) 137 { 138 unsigned long netctl; 139 unsigned long netstat; 140 unsigned long frame; 141 142 netctl = macb_readl(macb, NCR); 143 netctl |= MACB_BIT(MPE); 144 macb_writel(macb, NCR, netctl); 145 146 frame = (MACB_BF(SOF, 1) 147 | MACB_BF(RW, 2) 148 | MACB_BF(PHYA, macb->phy_addr) 149 | MACB_BF(REGA, reg) 150 | MACB_BF(CODE, 2)); 151 macb_writel(macb, MAN, frame); 152 153 do { 154 netstat = macb_readl(macb, NSR); 155 } while (!(netstat & MACB_BIT(IDLE))); 156 157 frame = macb_readl(macb, MAN); 158 159 netctl = macb_readl(macb, NCR); 160 netctl &= ~MACB_BIT(MPE); 161 macb_writel(macb, NCR, netctl); 162 163 return MACB_BFEXT(DATA, frame); 164 } 165 166 #if defined(CONFIG_CMD_MII) 167 168 int macb_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value) 169 { 170 struct eth_device *dev = eth_get_dev_by_name(devname); 171 struct macb_device *macb = to_macb(dev); 172 173 if ( macb->phy_addr != phy_adr ) 174 return -1; 175 176 *value = macb_mdio_read(macb, reg); 177 178 return 0; 179 } 180 181 int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value) 182 { 183 struct eth_device *dev = eth_get_dev_by_name(devname); 184 struct macb_device *macb = to_macb(dev); 185 186 if ( macb->phy_addr != phy_adr ) 187 return -1; 188 189 macb_mdio_write(macb, reg, value); 190 191 return 0; 192 } 193 #endif 194 195 196 #if defined(CONFIG_CMD_NET) 197 198 static int macb_send(struct eth_device *netdev, void *packet, int length) 199 { 200 struct macb_device *macb = to_macb(netdev); 201 unsigned long paddr, ctrl; 202 unsigned int tx_head = macb->tx_head; 203 int i; 204 205 paddr = dma_map_single(packet, length, DMA_TO_DEVICE); 206 207 ctrl = length & TXBUF_FRMLEN_MASK; 208 ctrl |= TXBUF_FRAME_END; 209 if (tx_head == (CONFIG_SYS_MACB_TX_RING_SIZE - 1)) { 210 ctrl |= TXBUF_WRAP; 211 macb->tx_head = 0; 212 } else 213 macb->tx_head++; 214 215 macb->tx_ring[tx_head].ctrl = ctrl; 216 macb->tx_ring[tx_head].addr = paddr; 217 barrier(); 218 macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART)); 219 220 /* 221 * I guess this is necessary because the networking core may 222 * re-use the transmit buffer as soon as we return... 223 */ 224 for (i = 0; i <= CONFIG_SYS_MACB_TX_TIMEOUT; i++) { 225 barrier(); 226 ctrl = macb->tx_ring[tx_head].ctrl; 227 if (ctrl & TXBUF_USED) 228 break; 229 udelay(1); 230 } 231 232 dma_unmap_single(packet, length, paddr); 233 234 if (i <= CONFIG_SYS_MACB_TX_TIMEOUT) { 235 if (ctrl & TXBUF_UNDERRUN) 236 printf("%s: TX underrun\n", netdev->name); 237 if (ctrl & TXBUF_EXHAUSTED) 238 printf("%s: TX buffers exhausted in mid frame\n", 239 netdev->name); 240 } else { 241 printf("%s: TX timeout\n", netdev->name); 242 } 243 244 /* No one cares anyway */ 245 return 0; 246 } 247 248 static void reclaim_rx_buffers(struct macb_device *macb, 249 unsigned int new_tail) 250 { 251 unsigned int i; 252 253 i = macb->rx_tail; 254 while (i > new_tail) { 255 macb->rx_ring[i].addr &= ~RXADDR_USED; 256 i++; 257 if (i > CONFIG_SYS_MACB_RX_RING_SIZE) 258 i = 0; 259 } 260 261 while (i < new_tail) { 262 macb->rx_ring[i].addr &= ~RXADDR_USED; 263 i++; 264 } 265 266 barrier(); 267 macb->rx_tail = new_tail; 268 } 269 270 static int macb_recv(struct eth_device *netdev) 271 { 272 struct macb_device *macb = to_macb(netdev); 273 unsigned int rx_tail = macb->rx_tail; 274 void *buffer; 275 int length; 276 int wrapped = 0; 277 u32 status; 278 279 for (;;) { 280 if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED)) 281 return -1; 282 283 status = macb->rx_ring[rx_tail].ctrl; 284 if (status & RXBUF_FRAME_START) { 285 if (rx_tail != macb->rx_tail) 286 reclaim_rx_buffers(macb, rx_tail); 287 wrapped = 0; 288 } 289 290 if (status & RXBUF_FRAME_END) { 291 buffer = macb->rx_buffer + 128 * macb->rx_tail; 292 length = status & RXBUF_FRMLEN_MASK; 293 if (wrapped) { 294 unsigned int headlen, taillen; 295 296 headlen = 128 * (CONFIG_SYS_MACB_RX_RING_SIZE 297 - macb->rx_tail); 298 taillen = length - headlen; 299 memcpy((void *)NetRxPackets[0], 300 buffer, headlen); 301 memcpy((void *)NetRxPackets[0] + headlen, 302 macb->rx_buffer, taillen); 303 buffer = (void *)NetRxPackets[0]; 304 } 305 306 NetReceive(buffer, length); 307 if (++rx_tail >= CONFIG_SYS_MACB_RX_RING_SIZE) 308 rx_tail = 0; 309 reclaim_rx_buffers(macb, rx_tail); 310 } else { 311 if (++rx_tail >= CONFIG_SYS_MACB_RX_RING_SIZE) { 312 wrapped = 1; 313 rx_tail = 0; 314 } 315 } 316 barrier(); 317 } 318 319 return 0; 320 } 321 322 static void macb_phy_reset(struct macb_device *macb) 323 { 324 struct eth_device *netdev = &macb->netdev; 325 int i; 326 u16 status, adv; 327 328 adv = ADVERTISE_CSMA | ADVERTISE_ALL; 329 macb_mdio_write(macb, MII_ADVERTISE, adv); 330 printf("%s: Starting autonegotiation...\n", netdev->name); 331 macb_mdio_write(macb, MII_BMCR, (BMCR_ANENABLE 332 | BMCR_ANRESTART)); 333 334 for (i = 0; i < CONFIG_SYS_MACB_AUTONEG_TIMEOUT / 100; i++) { 335 status = macb_mdio_read(macb, MII_BMSR); 336 if (status & BMSR_ANEGCOMPLETE) 337 break; 338 udelay(100); 339 } 340 341 if (status & BMSR_ANEGCOMPLETE) 342 printf("%s: Autonegotiation complete\n", netdev->name); 343 else 344 printf("%s: Autonegotiation timed out (status=0x%04x)\n", 345 netdev->name, status); 346 } 347 348 #ifdef CONFIG_MACB_SEARCH_PHY 349 static int macb_phy_find(struct macb_device *macb) 350 { 351 int i; 352 u16 phy_id; 353 354 /* Search for PHY... */ 355 for (i = 0; i < 32; i++) { 356 macb->phy_addr = i; 357 phy_id = macb_mdio_read(macb, MII_PHYSID1); 358 if (phy_id != 0xffff) { 359 printf("%s: PHY present at %d\n", macb->netdev.name, i); 360 return 1; 361 } 362 } 363 364 /* PHY isn't up to snuff */ 365 printf("%s: PHY not found\n", macb->netdev.name); 366 367 return 0; 368 } 369 #endif /* CONFIG_MACB_SEARCH_PHY */ 370 371 372 static int macb_phy_init(struct macb_device *macb) 373 { 374 struct eth_device *netdev = &macb->netdev; 375 u32 ncfgr; 376 u16 phy_id, status, adv, lpa; 377 int media, speed, duplex; 378 int i; 379 380 #ifdef CONFIG_MACB_SEARCH_PHY 381 /* Auto-detect phy_addr */ 382 if (!macb_phy_find(macb)) { 383 return 0; 384 } 385 #endif /* CONFIG_MACB_SEARCH_PHY */ 386 387 /* Check if the PHY is up to snuff... */ 388 phy_id = macb_mdio_read(macb, MII_PHYSID1); 389 if (phy_id == 0xffff) { 390 printf("%s: No PHY present\n", netdev->name); 391 return 0; 392 } 393 394 status = macb_mdio_read(macb, MII_BMSR); 395 if (!(status & BMSR_LSTATUS)) { 396 /* Try to re-negotiate if we don't have link already. */ 397 macb_phy_reset(macb); 398 399 for (i = 0; i < CONFIG_SYS_MACB_AUTONEG_TIMEOUT / 100; i++) { 400 status = macb_mdio_read(macb, MII_BMSR); 401 if (status & BMSR_LSTATUS) 402 break; 403 udelay(100); 404 } 405 } 406 407 if (!(status & BMSR_LSTATUS)) { 408 printf("%s: link down (status: 0x%04x)\n", 409 netdev->name, status); 410 return 0; 411 } else { 412 adv = macb_mdio_read(macb, MII_ADVERTISE); 413 lpa = macb_mdio_read(macb, MII_LPA); 414 media = mii_nway_result(lpa & adv); 415 speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) 416 ? 1 : 0); 417 duplex = (media & ADVERTISE_FULL) ? 1 : 0; 418 printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n", 419 netdev->name, 420 speed ? "100" : "10", 421 duplex ? "full" : "half", 422 lpa); 423 424 ncfgr = macb_readl(macb, NCFGR); 425 ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); 426 if (speed) 427 ncfgr |= MACB_BIT(SPD); 428 if (duplex) 429 ncfgr |= MACB_BIT(FD); 430 macb_writel(macb, NCFGR, ncfgr); 431 return 1; 432 } 433 } 434 435 static int macb_init(struct eth_device *netdev, bd_t *bd) 436 { 437 struct macb_device *macb = to_macb(netdev); 438 unsigned long paddr; 439 int i; 440 441 /* 442 * macb_halt should have been called at some point before now, 443 * so we'll assume the controller is idle. 444 */ 445 446 /* initialize DMA descriptors */ 447 paddr = macb->rx_buffer_dma; 448 for (i = 0; i < CONFIG_SYS_MACB_RX_RING_SIZE; i++) { 449 if (i == (CONFIG_SYS_MACB_RX_RING_SIZE - 1)) 450 paddr |= RXADDR_WRAP; 451 macb->rx_ring[i].addr = paddr; 452 macb->rx_ring[i].ctrl = 0; 453 paddr += 128; 454 } 455 for (i = 0; i < CONFIG_SYS_MACB_TX_RING_SIZE; i++) { 456 macb->tx_ring[i].addr = 0; 457 if (i == (CONFIG_SYS_MACB_TX_RING_SIZE - 1)) 458 macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP; 459 else 460 macb->tx_ring[i].ctrl = TXBUF_USED; 461 } 462 macb->rx_tail = macb->tx_head = macb->tx_tail = 0; 463 464 macb_writel(macb, RBQP, macb->rx_ring_dma); 465 macb_writel(macb, TBQP, macb->tx_ring_dma); 466 467 /* choose RMII or MII mode. This depends on the board */ 468 #ifdef CONFIG_RMII 469 #if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \ 470 defined(CONFIG_AT91SAM9263) || defined(CONFIG_AT91SAM9G20) || \ 471 defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) || \ 472 defined(CONFIG_AT91SAM9XE) || defined(CONFIG_AT91SAM9X5) 473 macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN)); 474 #else 475 macb_writel(macb, USRIO, 0); 476 #endif 477 #else 478 #if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \ 479 defined(CONFIG_AT91SAM9263) || defined(CONFIG_AT91SAM9G20) || \ 480 defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) || \ 481 defined(CONFIG_AT91SAM9XE) || defined(CONFIG_AT91SAM9X5) 482 macb_writel(macb, USRIO, MACB_BIT(CLKEN)); 483 #else 484 macb_writel(macb, USRIO, MACB_BIT(MII)); 485 #endif 486 #endif /* CONFIG_RMII */ 487 488 if (!macb_phy_init(macb)) 489 return -1; 490 491 /* Enable TX and RX */ 492 macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE)); 493 494 return 0; 495 } 496 497 static void macb_halt(struct eth_device *netdev) 498 { 499 struct macb_device *macb = to_macb(netdev); 500 u32 ncr, tsr; 501 502 /* Halt the controller and wait for any ongoing transmission to end. */ 503 ncr = macb_readl(macb, NCR); 504 ncr |= MACB_BIT(THALT); 505 macb_writel(macb, NCR, ncr); 506 507 do { 508 tsr = macb_readl(macb, TSR); 509 } while (tsr & MACB_BIT(TGO)); 510 511 /* Disable TX and RX, and clear statistics */ 512 macb_writel(macb, NCR, MACB_BIT(CLRSTAT)); 513 } 514 515 static int macb_write_hwaddr(struct eth_device *dev) 516 { 517 struct macb_device *macb = to_macb(dev); 518 u32 hwaddr_bottom; 519 u16 hwaddr_top; 520 521 /* set hardware address */ 522 hwaddr_bottom = dev->enetaddr[0] | dev->enetaddr[1] << 8 | 523 dev->enetaddr[2] << 16 | dev->enetaddr[3] << 24; 524 macb_writel(macb, SA1B, hwaddr_bottom); 525 hwaddr_top = dev->enetaddr[4] | dev->enetaddr[5] << 8; 526 macb_writel(macb, SA1T, hwaddr_top); 527 return 0; 528 } 529 530 int macb_eth_initialize(int id, void *regs, unsigned int phy_addr) 531 { 532 struct macb_device *macb; 533 struct eth_device *netdev; 534 unsigned long macb_hz; 535 u32 ncfgr; 536 537 macb = malloc(sizeof(struct macb_device)); 538 if (!macb) { 539 printf("Error: Failed to allocate memory for MACB%d\n", id); 540 return -1; 541 } 542 memset(macb, 0, sizeof(struct macb_device)); 543 544 netdev = &macb->netdev; 545 546 macb->rx_buffer = dma_alloc_coherent(CONFIG_SYS_MACB_RX_BUFFER_SIZE, 547 &macb->rx_buffer_dma); 548 macb->rx_ring = dma_alloc_coherent(CONFIG_SYS_MACB_RX_RING_SIZE 549 * sizeof(struct macb_dma_desc), 550 &macb->rx_ring_dma); 551 macb->tx_ring = dma_alloc_coherent(CONFIG_SYS_MACB_TX_RING_SIZE 552 * sizeof(struct macb_dma_desc), 553 &macb->tx_ring_dma); 554 555 macb->regs = regs; 556 macb->phy_addr = phy_addr; 557 558 sprintf(netdev->name, "macb%d", id); 559 netdev->init = macb_init; 560 netdev->halt = macb_halt; 561 netdev->send = macb_send; 562 netdev->recv = macb_recv; 563 netdev->write_hwaddr = macb_write_hwaddr; 564 565 /* 566 * Do some basic initialization so that we at least can talk 567 * to the PHY 568 */ 569 macb_hz = get_macb_pclk_rate(id); 570 if (macb_hz < 20000000) 571 ncfgr = MACB_BF(CLK, MACB_CLK_DIV8); 572 else if (macb_hz < 40000000) 573 ncfgr = MACB_BF(CLK, MACB_CLK_DIV16); 574 else if (macb_hz < 80000000) 575 ncfgr = MACB_BF(CLK, MACB_CLK_DIV32); 576 else 577 ncfgr = MACB_BF(CLK, MACB_CLK_DIV64); 578 579 macb_writel(macb, NCFGR, ncfgr); 580 581 eth_register(netdev); 582 583 #if defined(CONFIG_CMD_MII) 584 miiphy_register(netdev->name, macb_miiphy_read, macb_miiphy_write); 585 #endif 586 return 0; 587 } 588 589 #endif 590