1 /* 2 * Cirrus Logic EP93xx ethernet MAC / MII driver. 3 * 4 * Copyright (C) 2010, 2009 5 * Matthias Kaehlcke <matthias@kaehlcke.net> 6 * 7 * Copyright (C) 2004, 2005 8 * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com> 9 * 10 * Based on the original eth.[ch] Cirrus Logic EP93xx Rev D. Ethernet Driver, 11 * which is 12 * 13 * (C) Copyright 2002 2003 14 * Adam Bezanson, Network Audio Technologies, Inc. 15 * <bezanson@netaudiotech.com> 16 * 17 * See file CREDITS for list of people who contributed to this project. 18 * 19 * This program is free software; you can redistribute it and/or modify 20 * it under the terms of the GNU General Public License as published by 21 * the Free Software Foundation; either version 2 of the License, or 22 * (at your option) any later version. 23 * 24 * This program is distributed in the hope that it will be useful, but 25 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 26 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 27 * for more details. 28 * 29 * You should have received a copy of the GNU General Public License along 30 * with this program; if not, write to the Free Software Foundation, Inc., 31 * 675 Mass Ave, Cambridge, MA 02139, USA. 32 */ 33 34 #include <command.h> 35 #include <common.h> 36 #include <asm/arch/ep93xx.h> 37 #include <asm/io.h> 38 #include <malloc.h> 39 #include <miiphy.h> 40 #include <linux/types.h> 41 #include "ep93xx_eth.h" 42 43 #define GET_PRIV(eth_dev) ((struct ep93xx_priv *)(eth_dev)->priv) 44 #define GET_REGS(eth_dev) (GET_PRIV(eth_dev)->regs) 45 46 /* ep93xx_miiphy ops forward declarations */ 47 static int ep93xx_miiphy_read(char * const dev, unsigned char const addr, 48 unsigned char const reg, unsigned short * const value); 49 static int ep93xx_miiphy_write(char * const dev, unsigned char const addr, 50 unsigned char const reg, unsigned short const value); 51 52 #if defined(EP93XX_MAC_DEBUG) 53 /** 54 * Dump ep93xx_mac values to the terminal. 55 */ 56 static void dump_dev(struct eth_device *dev) 57 { 58 struct ep93xx_priv *priv = GET_PRIV(dev); 59 int i; 60 61 printf("\ndump_dev()\n"); 62 printf(" rx_dq.base %p\n", priv->rx_dq.base); 63 printf(" rx_dq.current %p\n", priv->rx_dq.current); 64 printf(" rx_dq.end %p\n", priv->rx_dq.end); 65 printf(" rx_sq.base %p\n", priv->rx_sq.base); 66 printf(" rx_sq.current %p\n", priv->rx_sq.current); 67 printf(" rx_sq.end %p\n", priv->rx_sq.end); 68 69 for (i = 0; i < NUMRXDESC; i++) 70 printf(" rx_buffer[%2.d] %p\n", i, NetRxPackets[i]); 71 72 printf(" tx_dq.base %p\n", priv->tx_dq.base); 73 printf(" tx_dq.current %p\n", priv->tx_dq.current); 74 printf(" tx_dq.end %p\n", priv->tx_dq.end); 75 printf(" tx_sq.base %p\n", priv->tx_sq.base); 76 printf(" tx_sq.current %p\n", priv->tx_sq.current); 77 printf(" tx_sq.end %p\n", priv->tx_sq.end); 78 } 79 80 /** 81 * Dump all RX status queue entries to the terminal. 82 */ 83 static void dump_rx_status_queue(struct eth_device *dev) 84 { 85 struct ep93xx_priv *priv = GET_PRIV(dev); 86 int i; 87 88 printf("\ndump_rx_status_queue()\n"); 89 printf(" descriptor address word1 word2\n"); 90 for (i = 0; i < NUMRXDESC; i++) { 91 printf(" [ %p ] %08X %08X\n", 92 priv->rx_sq.base + i, 93 (priv->rx_sq.base + i)->word1, 94 (priv->rx_sq.base + i)->word2); 95 } 96 } 97 98 /** 99 * Dump all RX descriptor queue entries to the terminal. 100 */ 101 static void dump_rx_descriptor_queue(struct eth_device *dev) 102 { 103 struct ep93xx_priv *priv = GET_PRIV(dev); 104 int i; 105 106 printf("\ndump_rx_descriptor_queue()\n"); 107 printf(" descriptor address word1 word2\n"); 108 for (i = 0; i < NUMRXDESC; i++) { 109 printf(" [ %p ] %08X %08X\n", 110 priv->rx_dq.base + i, 111 (priv->rx_dq.base + i)->word1, 112 (priv->rx_dq.base + i)->word2); 113 } 114 } 115 116 /** 117 * Dump all TX descriptor queue entries to the terminal. 118 */ 119 static void dump_tx_descriptor_queue(struct eth_device *dev) 120 { 121 struct ep93xx_priv *priv = GET_PRIV(dev); 122 int i; 123 124 printf("\ndump_tx_descriptor_queue()\n"); 125 printf(" descriptor address word1 word2\n"); 126 for (i = 0; i < NUMTXDESC; i++) { 127 printf(" [ %p ] %08X %08X\n", 128 priv->tx_dq.base + i, 129 (priv->tx_dq.base + i)->word1, 130 (priv->tx_dq.base + i)->word2); 131 } 132 } 133 134 /** 135 * Dump all TX status queue entries to the terminal. 136 */ 137 static void dump_tx_status_queue(struct eth_device *dev) 138 { 139 struct ep93xx_priv *priv = GET_PRIV(dev); 140 int i; 141 142 printf("\ndump_tx_status_queue()\n"); 143 printf(" descriptor address word1\n"); 144 for (i = 0; i < NUMTXDESC; i++) { 145 printf(" [ %p ] %08X\n", 146 priv->rx_sq.base + i, 147 (priv->rx_sq.base + i)->word1); 148 } 149 } 150 #else 151 #define dump_dev(x) 152 #define dump_rx_descriptor_queue(x) 153 #define dump_rx_status_queue(x) 154 #define dump_tx_descriptor_queue(x) 155 #define dump_tx_status_queue(x) 156 #endif /* defined(EP93XX_MAC_DEBUG) */ 157 158 /** 159 * Reset the EP93xx MAC by twiddling the soft reset bit and spinning until 160 * it's cleared. 161 */ 162 static void ep93xx_mac_reset(struct eth_device *dev) 163 { 164 struct mac_regs *mac = GET_REGS(dev); 165 uint32_t value; 166 167 debug("+ep93xx_mac_reset"); 168 169 value = readl(&mac->selfctl); 170 value |= SELFCTL_RESET; 171 writel(value, &mac->selfctl); 172 173 while (readl(&mac->selfctl) & SELFCTL_RESET) 174 ; /* noop */ 175 176 debug("-ep93xx_mac_reset"); 177 } 178 179 /* Eth device open */ 180 static int ep93xx_eth_open(struct eth_device *dev, bd_t *bd) 181 { 182 struct ep93xx_priv *priv = GET_PRIV(dev); 183 struct mac_regs *mac = GET_REGS(dev); 184 uchar *mac_addr = dev->enetaddr; 185 int i; 186 187 debug("+ep93xx_eth_open"); 188 189 /* Reset the MAC */ 190 ep93xx_mac_reset(dev); 191 192 /* Reset the descriptor queues' current and end address values */ 193 priv->tx_dq.current = priv->tx_dq.base; 194 priv->tx_dq.end = (priv->tx_dq.base + NUMTXDESC); 195 196 priv->tx_sq.current = priv->tx_sq.base; 197 priv->tx_sq.end = (priv->tx_sq.base + NUMTXDESC); 198 199 priv->rx_dq.current = priv->rx_dq.base; 200 priv->rx_dq.end = (priv->rx_dq.base + NUMRXDESC); 201 202 priv->rx_sq.current = priv->rx_sq.base; 203 priv->rx_sq.end = (priv->rx_sq.base + NUMRXDESC); 204 205 /* 206 * Set the transmit descriptor and status queues' base address, 207 * current address, and length registers. Set the maximum frame 208 * length and threshold. Enable the transmit descriptor processor. 209 */ 210 writel((uint32_t)priv->tx_dq.base, &mac->txdq.badd); 211 writel((uint32_t)priv->tx_dq.base, &mac->txdq.curadd); 212 writel(sizeof(struct tx_descriptor) * NUMTXDESC, &mac->txdq.blen); 213 214 writel((uint32_t)priv->tx_sq.base, &mac->txstsq.badd); 215 writel((uint32_t)priv->tx_sq.base, &mac->txstsq.curadd); 216 writel(sizeof(struct tx_status) * NUMTXDESC, &mac->txstsq.blen); 217 218 writel(0x00040000, &mac->txdthrshld); 219 writel(0x00040000, &mac->txststhrshld); 220 221 writel((TXSTARTMAX << 0) | (PKTSIZE_ALIGN << 16), &mac->maxfrmlen); 222 writel(BMCTL_TXEN, &mac->bmctl); 223 224 /* 225 * Set the receive descriptor and status queues' base address, 226 * current address, and length registers. Enable the receive 227 * descriptor processor. 228 */ 229 writel((uint32_t)priv->rx_dq.base, &mac->rxdq.badd); 230 writel((uint32_t)priv->rx_dq.base, &mac->rxdq.curadd); 231 writel(sizeof(struct rx_descriptor) * NUMRXDESC, &mac->rxdq.blen); 232 233 writel((uint32_t)priv->rx_sq.base, &mac->rxstsq.badd); 234 writel((uint32_t)priv->rx_sq.base, &mac->rxstsq.curadd); 235 writel(sizeof(struct rx_status) * NUMRXDESC, &mac->rxstsq.blen); 236 237 writel(0x00040000, &mac->rxdthrshld); 238 239 writel(BMCTL_RXEN, &mac->bmctl); 240 241 writel(0x00040000, &mac->rxststhrshld); 242 243 /* Wait until the receive descriptor processor is active */ 244 while (!(readl(&mac->bmsts) & BMSTS_RXACT)) 245 ; /* noop */ 246 247 /* 248 * Initialize the RX descriptor queue. Clear the TX descriptor queue. 249 * Clear the RX and TX status queues. Enqueue the RX descriptor and 250 * status entries to the MAC. 251 */ 252 for (i = 0; i < NUMRXDESC; i++) { 253 /* set buffer address */ 254 (priv->rx_dq.base + i)->word1 = (uint32_t)NetRxPackets[i]; 255 256 /* set buffer length, clear buffer index and NSOF */ 257 (priv->rx_dq.base + i)->word2 = PKTSIZE_ALIGN; 258 } 259 260 memset(priv->tx_dq.base, 0, 261 (sizeof(struct tx_descriptor) * NUMTXDESC)); 262 memset(priv->rx_sq.base, 0, 263 (sizeof(struct rx_status) * NUMRXDESC)); 264 memset(priv->tx_sq.base, 0, 265 (sizeof(struct tx_status) * NUMTXDESC)); 266 267 writel(NUMRXDESC, &mac->rxdqenq); 268 writel(NUMRXDESC, &mac->rxstsqenq); 269 270 /* Set the primary MAC address */ 271 writel(AFP_IAPRIMARY, &mac->afp); 272 writel(mac_addr[0] | (mac_addr[1] << 8) | 273 (mac_addr[2] << 16) | (mac_addr[3] << 24), 274 &mac->indad); 275 writel(mac_addr[4] | (mac_addr[5] << 8), &mac->indad_upper); 276 277 /* Turn on RX and TX */ 278 writel(RXCTL_IA0 | RXCTL_BA | RXCTL_SRXON | 279 RXCTL_RCRCA | RXCTL_MA, &mac->rxctl); 280 writel(TXCTL_STXON, &mac->txctl); 281 282 /* Dump data structures if we're debugging */ 283 dump_dev(dev); 284 dump_rx_descriptor_queue(dev); 285 dump_rx_status_queue(dev); 286 dump_tx_descriptor_queue(dev); 287 dump_tx_status_queue(dev); 288 289 debug("-ep93xx_eth_open"); 290 291 return 1; 292 } 293 294 /** 295 * Halt EP93xx MAC transmit and receive by clearing the TxCTL and RxCTL 296 * registers. 297 */ 298 static void ep93xx_eth_close(struct eth_device *dev) 299 { 300 struct mac_regs *mac = GET_REGS(dev); 301 302 debug("+ep93xx_eth_close"); 303 304 writel(0x00000000, &mac->rxctl); 305 writel(0x00000000, &mac->txctl); 306 307 debug("-ep93xx_eth_close"); 308 } 309 310 /** 311 * Copy a frame of data from the MAC into the protocol layer for further 312 * processing. 313 */ 314 static int ep93xx_eth_rcv_packet(struct eth_device *dev) 315 { 316 struct mac_regs *mac = GET_REGS(dev); 317 struct ep93xx_priv *priv = GET_PRIV(dev); 318 int len = -1; 319 320 debug("+ep93xx_eth_rcv_packet"); 321 322 if (RX_STATUS_RFP(priv->rx_sq.current)) { 323 if (RX_STATUS_RWE(priv->rx_sq.current)) { 324 /* 325 * We have a good frame. Extract the frame's length 326 * from the current rx_status_queue entry, and copy 327 * the frame's data into NetRxPackets[] of the 328 * protocol stack. We track the total number of 329 * bytes in the frame (nbytes_frame) which will be 330 * used when we pass the data off to the protocol 331 * layer via NetReceive(). 332 */ 333 len = RX_STATUS_FRAME_LEN(priv->rx_sq.current); 334 335 NetReceive((uchar *)priv->rx_dq.current->word1, len); 336 337 debug("reporting %d bytes...\n", len); 338 } else { 339 /* Do we have an erroneous packet? */ 340 error("packet rx error, status %08X %08X", 341 priv->rx_sq.current->word1, 342 priv->rx_sq.current->word2); 343 dump_rx_descriptor_queue(dev); 344 dump_rx_status_queue(dev); 345 } 346 347 /* 348 * Clear the associated status queue entry, and 349 * increment our current pointers to the next RX 350 * descriptor and status queue entries (making sure 351 * we wrap properly). 352 */ 353 memset((void *)priv->rx_sq.current, 0, 354 sizeof(struct rx_status)); 355 356 priv->rx_sq.current++; 357 if (priv->rx_sq.current >= priv->rx_sq.end) 358 priv->rx_sq.current = priv->rx_sq.base; 359 360 priv->rx_dq.current++; 361 if (priv->rx_dq.current >= priv->rx_dq.end) 362 priv->rx_dq.current = priv->rx_dq.base; 363 364 /* 365 * Finally, return the RX descriptor and status entries 366 * back to the MAC engine, and loop again, checking for 367 * more descriptors to process. 368 */ 369 writel(1, &mac->rxdqenq); 370 writel(1, &mac->rxstsqenq); 371 } else { 372 len = 0; 373 } 374 375 debug("-ep93xx_eth_rcv_packet %d", len); 376 return len; 377 } 378 379 /** 380 * Send a block of data via ethernet. 381 */ 382 static int ep93xx_eth_send_packet(struct eth_device *dev, 383 volatile void * const packet, int const length) 384 { 385 struct mac_regs *mac = GET_REGS(dev); 386 struct ep93xx_priv *priv = GET_PRIV(dev); 387 int ret = -1; 388 389 debug("+ep93xx_eth_send_packet"); 390 391 /* Parameter check */ 392 BUG_ON(packet == NULL); 393 394 /* 395 * Initialize the TX descriptor queue with the new packet's info. 396 * Clear the associated status queue entry. Enqueue the packet 397 * to the MAC for transmission. 398 */ 399 400 /* set buffer address */ 401 priv->tx_dq.current->word1 = (uint32_t)packet; 402 403 /* set buffer length and EOF bit */ 404 priv->tx_dq.current->word2 = length | TX_DESC_EOF; 405 406 /* clear tx status */ 407 priv->tx_sq.current->word1 = 0; 408 409 /* enqueue the TX descriptor */ 410 writel(1, &mac->txdqenq); 411 412 /* wait for the frame to become processed */ 413 while (!TX_STATUS_TXFP(priv->tx_sq.current)) 414 ; /* noop */ 415 416 if (!TX_STATUS_TXWE(priv->tx_sq.current)) { 417 error("packet tx error, status %08X", 418 priv->tx_sq.current->word1); 419 dump_tx_descriptor_queue(dev); 420 dump_tx_status_queue(dev); 421 422 /* TODO: Add better error handling? */ 423 goto eth_send_out; 424 } 425 426 ret = 0; 427 /* Fall through */ 428 429 eth_send_out: 430 debug("-ep93xx_eth_send_packet %d", ret); 431 return ret; 432 } 433 434 #if defined(CONFIG_MII) 435 int ep93xx_miiphy_initialize(bd_t * const bd) 436 { 437 miiphy_register("ep93xx_eth0", ep93xx_miiphy_read, ep93xx_miiphy_write); 438 return 0; 439 } 440 #endif 441 442 /** 443 * Initialize the EP93xx MAC. The MAC hardware is reset. Buffers are 444 * allocated, if necessary, for the TX and RX descriptor and status queues, 445 * as well as for received packets. The EP93XX MAC hardware is initialized. 446 * Transmit and receive operations are enabled. 447 */ 448 int ep93xx_eth_initialize(u8 dev_num, int base_addr) 449 { 450 int ret = -1; 451 struct eth_device *dev; 452 struct ep93xx_priv *priv; 453 454 debug("+ep93xx_eth_initialize"); 455 456 priv = malloc(sizeof(*priv)); 457 if (!priv) { 458 error("malloc() failed"); 459 goto eth_init_failed_0; 460 } 461 memset(priv, 0, sizeof(*priv)); 462 463 priv->regs = (struct mac_regs *)base_addr; 464 465 priv->tx_dq.base = calloc(NUMTXDESC, 466 sizeof(struct tx_descriptor)); 467 if (priv->tx_dq.base == NULL) { 468 error("calloc() failed"); 469 goto eth_init_failed_1; 470 } 471 472 priv->tx_sq.base = calloc(NUMTXDESC, 473 sizeof(struct tx_status)); 474 if (priv->tx_sq.base == NULL) { 475 error("calloc() failed"); 476 goto eth_init_failed_2; 477 } 478 479 priv->rx_dq.base = calloc(NUMRXDESC, 480 sizeof(struct rx_descriptor)); 481 if (priv->rx_dq.base == NULL) { 482 error("calloc() failed"); 483 goto eth_init_failed_3; 484 } 485 486 priv->rx_sq.base = calloc(NUMRXDESC, 487 sizeof(struct rx_status)); 488 if (priv->rx_sq.base == NULL) { 489 error("calloc() failed"); 490 goto eth_init_failed_4; 491 } 492 493 dev = malloc(sizeof *dev); 494 if (dev == NULL) { 495 error("malloc() failed"); 496 goto eth_init_failed_5; 497 } 498 memset(dev, 0, sizeof *dev); 499 500 dev->iobase = base_addr; 501 dev->priv = priv; 502 dev->init = ep93xx_eth_open; 503 dev->halt = ep93xx_eth_close; 504 dev->send = ep93xx_eth_send_packet; 505 dev->recv = ep93xx_eth_rcv_packet; 506 507 sprintf(dev->name, "ep93xx_eth-%hu", dev_num); 508 509 eth_register(dev); 510 511 /* Done! */ 512 ret = 1; 513 goto eth_init_done; 514 515 eth_init_failed_5: 516 free(priv->rx_sq.base); 517 /* Fall through */ 518 519 eth_init_failed_4: 520 free(priv->rx_dq.base); 521 /* Fall through */ 522 523 eth_init_failed_3: 524 free(priv->tx_sq.base); 525 /* Fall through */ 526 527 eth_init_failed_2: 528 free(priv->tx_dq.base); 529 /* Fall through */ 530 531 eth_init_failed_1: 532 free(priv); 533 /* Fall through */ 534 535 eth_init_failed_0: 536 /* Fall through */ 537 538 eth_init_done: 539 debug("-ep93xx_eth_initialize %d", ret); 540 return ret; 541 } 542 543 #if defined(CONFIG_MII) 544 545 /** 546 * Maximum MII address we support 547 */ 548 #define MII_ADDRESS_MAX 31 549 550 /** 551 * Maximum MII register address we support 552 */ 553 #define MII_REGISTER_MAX 31 554 555 /** 556 * Read a 16-bit value from an MII register. 557 */ 558 static int ep93xx_miiphy_read(char * const dev, unsigned char const addr, 559 unsigned char const reg, unsigned short * const value) 560 { 561 struct mac_regs *mac = (struct mac_regs *)MAC_BASE; 562 int ret = -1; 563 uint32_t self_ctl; 564 565 debug("+ep93xx_miiphy_read"); 566 567 /* Parameter checks */ 568 BUG_ON(dev == NULL); 569 BUG_ON(addr > MII_ADDRESS_MAX); 570 BUG_ON(reg > MII_REGISTER_MAX); 571 BUG_ON(value == NULL); 572 573 /* 574 * Save the current SelfCTL register value. Set MAC to suppress 575 * preamble bits. Wait for any previous MII command to complete 576 * before issuing the new command. 577 */ 578 self_ctl = readl(&mac->selfctl); 579 #if defined(CONFIG_MII_SUPPRESS_PREAMBLE) 580 writel(self_ctl & ~(1 << 8), &mac->selfctl); 581 #endif /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */ 582 583 while (readl(&mac->miists) & MIISTS_BUSY) 584 ; /* noop */ 585 586 /* 587 * Issue the MII 'read' command. Wait for the command to complete. 588 * Read the MII data value. 589 */ 590 writel(MIICMD_OPCODE_READ | ((uint32_t)addr << 5) | (uint32_t)reg, 591 &mac->miicmd); 592 while (readl(&mac->miists) & MIISTS_BUSY) 593 ; /* noop */ 594 595 *value = (unsigned short)readl(&mac->miidata); 596 597 /* Restore the saved SelfCTL value and return. */ 598 writel(self_ctl, &mac->selfctl); 599 600 ret = 0; 601 /* Fall through */ 602 603 debug("-ep93xx_miiphy_read"); 604 return ret; 605 } 606 607 /** 608 * Write a 16-bit value to an MII register. 609 */ 610 static int ep93xx_miiphy_write(char * const dev, unsigned char const addr, 611 unsigned char const reg, unsigned short const value) 612 { 613 struct mac_regs *mac = (struct mac_regs *)MAC_BASE; 614 int ret = -1; 615 uint32_t self_ctl; 616 617 debug("+ep93xx_miiphy_write"); 618 619 /* Parameter checks */ 620 BUG_ON(dev == NULL); 621 BUG_ON(addr > MII_ADDRESS_MAX); 622 BUG_ON(reg > MII_REGISTER_MAX); 623 624 /* 625 * Save the current SelfCTL register value. Set MAC to suppress 626 * preamble bits. Wait for any previous MII command to complete 627 * before issuing the new command. 628 */ 629 self_ctl = readl(&mac->selfctl); 630 #if defined(CONFIG_MII_SUPPRESS_PREAMBLE) 631 writel(self_ctl & ~(1 << 8), &mac->selfctl); 632 #endif /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */ 633 634 while (readl(&mac->miists) & MIISTS_BUSY) 635 ; /* noop */ 636 637 /* Issue the MII 'write' command. Wait for the command to complete. */ 638 writel((uint32_t)value, &mac->miidata); 639 writel(MIICMD_OPCODE_WRITE | ((uint32_t)addr << 5) | (uint32_t)reg, 640 &mac->miicmd); 641 while (readl(&mac->miists) & MIISTS_BUSY) 642 ; /* noop */ 643 644 /* Restore the saved SelfCTL value and return. */ 645 writel(self_ctl, &mac->selfctl); 646 647 ret = 0; 648 /* Fall through */ 649 650 debug("-ep93xx_miiphy_write"); 651 return ret; 652 } 653 #endif /* defined(CONFIG_MII) */ 654