Commit a8f9cd1893bef05b92f63242228607b45821c4a7
Committed by
Joe Hershberger
1 parent
c4775476d2
Exists in
master
and in
53 other branches
net: update FTGMAC100 for MMU/D-cache support
Signed-off-by: Kuo-Jung Su <dantesu@faraday-tech.com> CC: Joe Hershberger <joe.hershberger@gmail.com> CC: Tom Rini <trini@ti.com>
Showing 1 changed file with 49 additions and 21 deletions Side-by-side Diff
drivers/net/ftgmac100.c
... | ... | @@ -27,11 +27,13 @@ |
27 | 27 | #include <malloc.h> |
28 | 28 | #include <net.h> |
29 | 29 | #include <asm/io.h> |
30 | +#include <asm/dma-mapping.h> | |
30 | 31 | #include <linux/mii.h> |
31 | 32 | |
32 | 33 | #include "ftgmac100.h" |
33 | 34 | |
34 | 35 | #define ETH_ZLEN 60 |
36 | +#define CFG_XBUF_SIZE 1536 | |
35 | 37 | |
36 | 38 | /* RBSR - hw default init value is also 0x640 */ |
37 | 39 | #define RBSR_DEFAULT_VALUE 0x640 |
... | ... | @@ -40,8 +42,10 @@ |
40 | 42 | #define PKTBUFSTX 4 /* must be power of 2 */ |
41 | 43 | |
42 | 44 | struct ftgmac100_data { |
43 | - struct ftgmac100_txdes txdes[PKTBUFSTX]; | |
44 | - struct ftgmac100_rxdes rxdes[PKTBUFSRX]; | |
45 | + ulong txdes_dma; | |
46 | + struct ftgmac100_txdes *txdes; | |
47 | + ulong rxdes_dma; | |
48 | + struct ftgmac100_rxdes *rxdes; | |
45 | 49 | int tx_index; |
46 | 50 | int rx_index; |
47 | 51 | int phy_addr; |
48 | 52 | |
49 | 53 | |
... | ... | @@ -375,13 +379,34 @@ |
375 | 379 | { |
376 | 380 | struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; |
377 | 381 | struct ftgmac100_data *priv = dev->priv; |
378 | - struct ftgmac100_txdes *txdes = priv->txdes; | |
379 | - struct ftgmac100_rxdes *rxdes = priv->rxdes; | |
382 | + struct ftgmac100_txdes *txdes; | |
383 | + struct ftgmac100_rxdes *rxdes; | |
380 | 384 | unsigned int maccr; |
385 | + void *buf; | |
381 | 386 | int i; |
382 | 387 | |
383 | 388 | debug("%s()\n", __func__); |
384 | 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 | + | |
385 | 410 | /* set the ethernet address */ |
386 | 411 | ftgmac100_set_mac_from_env(dev); |
387 | 412 | |
388 | 413 | |
389 | 414 | |
390 | 415 | |
... | ... | @@ -397,21 +422,31 @@ |
397 | 422 | |
398 | 423 | for (i = 0; i < PKTBUFSTX; i++) { |
399 | 424 | /* TXBUF_BADR */ |
400 | - txdes[i].txdes3 = 0; | |
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 | + } | |
401 | 432 | txdes[i].txdes1 = 0; |
402 | 433 | } |
403 | 434 | |
404 | 435 | for (i = 0; i < PKTBUFSRX; i++) { |
405 | 436 | /* RXBUF_BADR */ |
406 | - rxdes[i].rxdes3 = (unsigned int)NetRxPackets[i]; | |
437 | + if (!rxdes[i].rxdes2) { | |
438 | + buf = NetRxPackets[i]; | |
439 | + rxdes[i].rxdes3 = virt_to_phys(buf); | |
440 | + rxdes[i].rxdes2 = (uint)buf; | |
441 | + } | |
407 | 442 | rxdes[i].rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY; |
408 | 443 | } |
409 | 444 | |
410 | 445 | /* transmit ring */ |
411 | - writel((unsigned int)txdes, &ftgmac100->txr_badr); | |
446 | + writel(priv->txdes_dma, &ftgmac100->txr_badr); | |
412 | 447 | |
413 | 448 | /* receive ring */ |
414 | - writel((unsigned int)rxdes, &ftgmac100->rxr_badr); | |
449 | + writel(priv->rxdes_dma, &ftgmac100->rxr_badr); | |
415 | 450 | |
416 | 451 | /* poll receive descriptor automatically */ |
417 | 452 | writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc); |
418 | 453 | |
... | ... | @@ -466,8 +501,11 @@ |
466 | 501 | debug("%s(): RX buffer %d, %x received\n", |
467 | 502 | __func__, priv->rx_index, rxlen); |
468 | 503 | |
504 | + /* invalidate d-cache */ | |
505 | + dma_map_single((void *)curr_des->rxdes2, rxlen, DMA_FROM_DEVICE); | |
506 | + | |
469 | 507 | /* pass the packet up to the protocol layers. */ |
470 | - NetReceive((void *)curr_des->rxdes3, rxlen); | |
508 | + NetReceive((void *)curr_des->rxdes2, rxlen); | |
471 | 509 | |
472 | 510 | /* release buffer to DMA */ |
473 | 511 | curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY; |
... | ... | @@ -485,7 +523,6 @@ |
485 | 523 | struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; |
486 | 524 | struct ftgmac100_data *priv = dev->priv; |
487 | 525 | struct ftgmac100_txdes *curr_des = &priv->txdes[priv->tx_index]; |
488 | - int start; | |
489 | 526 | |
490 | 527 | if (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) { |
491 | 528 | debug("%s(): no TX descriptor available\n", __func__); |
... | ... | @@ -496,8 +533,8 @@ |
496 | 533 | |
497 | 534 | length = (length < ETH_ZLEN) ? ETH_ZLEN : length; |
498 | 535 | |
499 | - /* initiate a transmit sequence */ | |
500 | - curr_des->txdes3 = (unsigned int)packet; /* TXBUF_BADR */ | |
536 | + memcpy((void *)curr_des->txdes2, (void *)packet, length); | |
537 | + dma_map_single((void *)curr_des->txdes2, length, DMA_TO_DEVICE); | |
501 | 538 | |
502 | 539 | /* only one descriptor on TXBUF */ |
503 | 540 | curr_des->txdes0 &= FTGMAC100_TXDES0_EDOTR; |
... | ... | @@ -508,15 +545,6 @@ |
508 | 545 | |
509 | 546 | /* start transmit */ |
510 | 547 | writel(1, &ftgmac100->txpd); |
511 | - | |
512 | - /* wait for transfer to succeed */ | |
513 | - start = get_timer(0); | |
514 | - while (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) { | |
515 | - if (get_timer(0) >= 5) { | |
516 | - debug("%s(): timed out\n", __func__); | |
517 | - return -1; | |
518 | - } | |
519 | - } | |
520 | 548 | |
521 | 549 | debug("%s(): packet sent\n", __func__); |
522 | 550 |