Commit b3dbf4a51f3891c16315b038cd3b7a87f4182e0d

Authored by Macpaul Lin
Committed by Wolfgang Denk
1 parent 3474741c8d

ftgmac100: support of gigabit eth ftgmac100

Add Faraday's ftgmac100 (gigabit ethernet)
MAC controller's driver.

Signed-off-by: Macpaul Lin <macpaul@andestech.com>

Showing 5 changed files with 839 additions and 0 deletions Side-by-side Diff

... ... @@ -861,6 +861,18 @@
861 861 Define this to use i/o functions instead of macros
862 862 (some hardware wont work with macros)
863 863  
  864 + CONFIG_FTGMAC100
  865 + Support for Faraday's FTGMAC100 Gigabit SoC Ethernet
  866 +
  867 + CONFIG_FTGMAC100_EGIGA
  868 + Define this to use GE link update with gigabit PHY.
  869 + Define this if FTGMAC100 is connected to gigabit PHY.
  870 + If your system has 10/100 PHY only, it might not occur
  871 + wrong behavior. Because PHY usually return timeout or
  872 + useless data when polling gigabit status and gigabit
  873 + control registers. This behavior won't affect the
  874 + correctnessof 10/100 link speed update.
  875 +
864 876 CONFIG_SMC911X
865 877 Support for SMSC's LAN911x and LAN921x chips
866 878  
drivers/net/Makefile
... ... @@ -47,6 +47,7 @@
47 47 COBJS-$(CONFIG_ETHOC) += ethoc.o
48 48 COBJS-$(CONFIG_FEC_MXC) += fec_mxc.o
49 49 COBJS-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o
  50 +COBJS-$(CONFIG_FTGMAC100) += ftgmac100.o
50 51 COBJS-$(CONFIG_FTMAC100) += ftmac100.o
51 52 COBJS-$(CONFIG_GRETH) += greth.o
52 53 COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
drivers/net/ftgmac100.c
  1 +/*
  2 + * Faraday FTGMAC100 Ethernet
  3 + *
  4 + * (C) Copyright 2009 Faraday Technology
  5 + * Po-Yu Chuang <ratbert@faraday-tech.com>
  6 + *
  7 + * (C) Copyright 2010 Andes Technology
  8 + * Macpaul Lin <macpaul@andestech.com>
  9 + *
  10 + * This program is free software; you can redistribute it and/or modify
  11 + * it under the terms of the GNU General Public License as published by
  12 + * the Free Software Foundation; either version 2 of the License, or
  13 + * (at your option) any later version.
  14 + *
  15 + * This program is distributed in the hope that it will be useful,
  16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18 + * GNU General Public License for more details.
  19 + *
  20 + * You should have received a copy of the GNU General Public License
  21 + * along with this program; if not, write to the Free Software
  22 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23 + */
  24 +
  25 +#include <config.h>
  26 +#include <common.h>
  27 +#include <malloc.h>
  28 +#include <net.h>
  29 +#include <asm/io.h>
  30 +#include <linux/mii.h>
  31 +
  32 +#include "ftgmac100.h"
  33 +
  34 +#define ETH_ZLEN 60
  35 +
  36 +#define mdelay(n) ({unsigned long msec = (n); while (msec--) udelay(1000); })
  37 +
  38 +/* RBSR - hw default init value is also 0x640 */
  39 +#define RBSR_DEFAULT_VALUE 0x640
  40 +
  41 +/* PKTBUFSTX/PKTBUFSRX must both be power of 2 */
  42 +#define PKTBUFSTX 4 /* must be power of 2 */
  43 +
  44 +struct ftgmac100_data {
  45 + struct ftgmac100_txdes txdes[PKTBUFSTX];
  46 + struct ftgmac100_rxdes rxdes[PKTBUFSRX];
  47 + int tx_index;
  48 + int rx_index;
  49 + int phy_addr;
  50 +};
  51 +
  52 +/*
  53 + * struct mii_bus functions
  54 + */
  55 +static int ftgmac100_mdiobus_read(struct eth_device *dev, int phy_addr,
  56 + int regnum)
  57 +{
  58 + struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
  59 + int phycr;
  60 + int i;
  61 +
  62 + phycr = readl(&ftgmac100->phycr);
  63 +
  64 + /* preserve MDC cycle threshold */
  65 + phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK;
  66 +
  67 + phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr)
  68 + | FTGMAC100_PHYCR_REGAD(regnum)
  69 + | FTGMAC100_PHYCR_MIIRD;
  70 +
  71 + writel(phycr, &ftgmac100->phycr);
  72 +
  73 + for (i = 0; i < 10; i++) {
  74 + phycr = readl(&ftgmac100->phycr);
  75 +
  76 + if ((phycr & FTGMAC100_PHYCR_MIIRD) == 0) {
  77 + int data;
  78 +
  79 + data = readl(&ftgmac100->phydata);
  80 + return FTGMAC100_PHYDATA_MIIRDATA(data);
  81 + }
  82 +
  83 + mdelay(10);
  84 + }
  85 +
  86 + debug("mdio read timed out\n");
  87 + return -1;
  88 +}
  89 +
  90 +static int ftgmac100_mdiobus_write(struct eth_device *dev, int phy_addr,
  91 + int regnum, u16 value)
  92 +{
  93 + struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
  94 + int phycr;
  95 + int data;
  96 + int i;
  97 +
  98 + phycr = readl(&ftgmac100->phycr);
  99 +
  100 + /* preserve MDC cycle threshold */
  101 + phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK;
  102 +
  103 + phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr)
  104 + | FTGMAC100_PHYCR_REGAD(regnum)
  105 + | FTGMAC100_PHYCR_MIIWR;
  106 +
  107 + data = FTGMAC100_PHYDATA_MIIWDATA(value);
  108 +
  109 + writel(data, &ftgmac100->phydata);
  110 + writel(phycr, &ftgmac100->phycr);
  111 +
  112 + for (i = 0; i < 10; i++) {
  113 + phycr = readl(&ftgmac100->phycr);
  114 +
  115 + if ((phycr & FTGMAC100_PHYCR_MIIWR) == 0) {
  116 + debug("(phycr & FTGMAC100_PHYCR_MIIWR) == 0: " \
  117 + "phy_addr: %x\n", phy_addr);
  118 + return 0;
  119 + }
  120 +
  121 + mdelay(1);
  122 + }
  123 +
  124 + debug("mdio write timed out\n");
  125 + return -1;
  126 +}
  127 +
  128 +int ftgmac100_phy_read(struct eth_device *dev, int addr, int reg, u16 *value)
  129 +{
  130 + *value = ftgmac100_mdiobus_read(dev , addr, reg);
  131 +
  132 + if (*value == -1)
  133 + return -1;
  134 +
  135 + return 0;
  136 +}
  137 +
  138 +int ftgmac100_phy_write(struct eth_device *dev, int addr, int reg, u16 value)
  139 +{
  140 + if (ftgmac100_mdiobus_write(dev, addr, reg, value) == -1)
  141 + return -1;
  142 +
  143 + return 0;
  144 +}
  145 +
  146 +static int ftgmac100_phy_reset(struct eth_device *dev)
  147 +{
  148 + struct ftgmac100_data *priv = dev->priv;
  149 + int i;
  150 + u16 status, adv;
  151 +
  152 + adv = ADVERTISE_CSMA | ADVERTISE_ALL;
  153 +
  154 + ftgmac100_phy_write(dev, priv->phy_addr, MII_ADVERTISE, adv);
  155 +
  156 + printf("%s: Starting autonegotiation...\n", dev->name);
  157 +
  158 + ftgmac100_phy_write(dev, priv->phy_addr,
  159 + MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART));
  160 +
  161 + for (i = 0; i < 100000 / 100; i++) {
  162 + ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &status);
  163 +
  164 + if (status & BMSR_ANEGCOMPLETE)
  165 + break;
  166 + mdelay(1);
  167 + }
  168 +
  169 + if (status & BMSR_ANEGCOMPLETE) {
  170 + printf("%s: Autonegotiation complete\n", dev->name);
  171 + } else {
  172 + printf("%s: Autonegotiation timed out (status=0x%04x)\n",
  173 + dev->name, status);
  174 + return 0;
  175 + }
  176 +
  177 + return 1;
  178 +}
  179 +
  180 +static int ftgmac100_phy_init(struct eth_device *dev)
  181 +{
  182 + struct ftgmac100_data *priv = dev->priv;
  183 +
  184 + int phy_addr;
  185 + u16 phy_id, status, adv, lpa, stat_ge;
  186 + int media, speed, duplex;
  187 + int i;
  188 +
  189 + /* Check if the PHY is up to snuff... */
  190 + for (phy_addr = 0; phy_addr < CONFIG_PHY_MAX_ADDR; phy_addr++) {
  191 +
  192 + ftgmac100_phy_read(dev, phy_addr, MII_PHYSID1, &phy_id);
  193 +
  194 + /*
  195 + * When it is unable to found PHY,
  196 + * the interface usually return 0xffff or 0x0000
  197 + */
  198 + if (phy_id != 0xffff && phy_id != 0x0) {
  199 + printf("%s: found PHY at 0x%02x\n",
  200 + dev->name, phy_addr);
  201 + priv->phy_addr = phy_addr;
  202 + break;
  203 + }
  204 + }
  205 +
  206 + if (phy_id == 0xffff || phy_id == 0x0) {
  207 + printf("%s: no PHY present\n", dev->name);
  208 + return 0;
  209 + }
  210 +
  211 + ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &status);
  212 +
  213 + if (!(status & BMSR_LSTATUS)) {
  214 + /* Try to re-negotiate if we don't have link already. */
  215 + ftgmac100_phy_reset(dev);
  216 +
  217 + for (i = 0; i < 100000 / 100; i++) {
  218 + ftgmac100_phy_read(dev, priv->phy_addr,
  219 + MII_BMSR, &status);
  220 + if (status & BMSR_LSTATUS)
  221 + break;
  222 + udelay(100);
  223 + }
  224 + }
  225 +
  226 + if (!(status & BMSR_LSTATUS)) {
  227 + printf("%s: link down\n", dev->name);
  228 + return 0;
  229 + }
  230 +
  231 +#ifdef CONFIG_FTGMAC100_EGIGA
  232 + /* 1000 Base-T Status Register */
  233 + ftgmac100_phy_read(dev, priv->phy_addr,
  234 + MII_STAT1000, &stat_ge);
  235 +
  236 + speed = (stat_ge & (LPA_1000FULL | LPA_1000HALF)
  237 + ? 1 : 0);
  238 +
  239 + duplex = ((stat_ge & LPA_1000FULL)
  240 + ? 1 : 0);
  241 +
  242 + if (speed) { /* Speed is 1000 */
  243 + printf("%s: link up, 1000bps %s-duplex\n",
  244 + dev->name, duplex ? "full" : "half");
  245 + return 0;
  246 + }
  247 +#endif
  248 +
  249 + ftgmac100_phy_read(dev, priv->phy_addr, MII_ADVERTISE, &adv);
  250 + ftgmac100_phy_read(dev, priv->phy_addr, MII_LPA, &lpa);
  251 +
  252 + media = mii_nway_result(lpa & adv);
  253 + speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 1 : 0);
  254 + duplex = (media & ADVERTISE_FULL) ? 1 : 0;
  255 +
  256 + printf("%s: link up, %sMbps %s-duplex\n",
  257 + dev->name, speed ? "100" : "10", duplex ? "full" : "half");
  258 +
  259 + return 1;
  260 +}
  261 +
  262 +static int ftgmac100_update_link_speed(struct eth_device *dev)
  263 +{
  264 + struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
  265 + struct ftgmac100_data *priv = dev->priv;
  266 +
  267 + unsigned short stat_fe;
  268 + unsigned short stat_ge;
  269 + unsigned int maccr;
  270 +
  271 +#ifdef CONFIG_FTGMAC100_EGIGA
  272 + /* 1000 Base-T Status Register */
  273 + ftgmac100_phy_read(dev, priv->phy_addr, MII_STAT1000, &stat_ge);
  274 +#endif
  275 +
  276 + ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &stat_fe);
  277 +
  278 + if (!(stat_fe & BMSR_LSTATUS)) /* link status up? */
  279 + return 0;
  280 +
  281 + /* read MAC control register and clear related bits */
  282 + maccr = readl(&ftgmac100->maccr) &
  283 + ~(FTGMAC100_MACCR_GIGA_MODE |
  284 + FTGMAC100_MACCR_FAST_MODE |
  285 + FTGMAC100_MACCR_FULLDUP);
  286 +
  287 +#ifdef CONFIG_FTGMAC100_EGIGA
  288 + if (stat_ge & LPA_1000FULL) {
  289 + /* set gmac for 1000BaseTX and Full Duplex */
  290 + maccr |= FTGMAC100_MACCR_GIGA_MODE | FTGMAC100_MACCR_FULLDUP;
  291 + }
  292 +
  293 + if (stat_ge & LPA_1000HALF) {
  294 + /* set gmac for 1000BaseTX and Half Duplex */
  295 + maccr |= FTGMAC100_MACCR_GIGA_MODE;
  296 + }
  297 +#endif
  298 +
  299 + if (stat_fe & BMSR_100FULL) {
  300 + /* set MII for 100BaseTX and Full Duplex */
  301 + maccr |= FTGMAC100_MACCR_FAST_MODE | FTGMAC100_MACCR_FULLDUP;
  302 + }
  303 +
  304 + if (stat_fe & BMSR_10FULL) {
  305 + /* set MII for 10BaseT and Full Duplex */
  306 + maccr |= FTGMAC100_MACCR_FULLDUP;
  307 + }
  308 +
  309 + if (stat_fe & BMSR_100HALF) {
  310 + /* set MII for 100BaseTX and Half Duplex */
  311 + maccr |= FTGMAC100_MACCR_FAST_MODE;
  312 + }
  313 +
  314 + if (stat_fe & BMSR_10HALF) {
  315 + /* set MII for 10BaseT and Half Duplex */
  316 + /* we have already clear these bits, do nothing */
  317 + ;
  318 + }
  319 +
  320 + /* update MII config into maccr */
  321 + writel(maccr, &ftgmac100->maccr);
  322 +
  323 + return 1;
  324 +}
  325 +
  326 +/*
  327 + * Reset MAC
  328 + */
  329 +static void ftgmac100_reset(struct eth_device *dev)
  330 +{
  331 + struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
  332 +
  333 + debug("%s()\n", __func__);
  334 +
  335 + writel(FTGMAC100_MACCR_SW_RST, &ftgmac100->maccr);
  336 +
  337 + while (readl(&ftgmac100->maccr) & FTGMAC100_MACCR_SW_RST)
  338 + ;
  339 +}
  340 +
  341 +/*
  342 + * Set MAC address
  343 + */
  344 +static void ftgmac100_set_mac(struct eth_device *dev,
  345 + const unsigned char *mac)
  346 +{
  347 + struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
  348 + unsigned int maddr = mac[0] << 8 | mac[1];
  349 + unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
  350 +
  351 + debug("%s(%x %x)\n", __func__, maddr, laddr);
  352 +
  353 + writel(maddr, &ftgmac100->mac_madr);
  354 + writel(laddr, &ftgmac100->mac_ladr);
  355 +}
  356 +
  357 +static void ftgmac100_set_mac_from_env(struct eth_device *dev)
  358 +{
  359 + eth_getenv_enetaddr("ethaddr", dev->enetaddr);
  360 +
  361 + ftgmac100_set_mac(dev, dev->enetaddr);
  362 +}
  363 +
  364 +/*
  365 + * disable transmitter, receiver
  366 + */
  367 +static void ftgmac100_halt(struct eth_device *dev)
  368 +{
  369 + struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
  370 +
  371 + debug("%s()\n", __func__);
  372 +
  373 + writel(0, &ftgmac100->maccr);
  374 +}
  375 +
  376 +static int ftgmac100_init(struct eth_device *dev, bd_t *bd)
  377 +{
  378 + struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
  379 + struct ftgmac100_data *priv = dev->priv;
  380 + struct ftgmac100_txdes *txdes = priv->txdes;
  381 + struct ftgmac100_rxdes *rxdes = priv->rxdes;
  382 + unsigned int maccr;
  383 + int i;
  384 +
  385 + debug("%s()\n", __func__);
  386 +
  387 + ftgmac100_reset(dev);
  388 +
  389 + /* set the ethernet address */
  390 + ftgmac100_set_mac_from_env(dev);
  391 +
  392 + /* disable all interrupts */
  393 + writel(0, &ftgmac100->ier);
  394 +
  395 + /* initialize descriptors */
  396 + priv->tx_index = 0;
  397 + priv->rx_index = 0;
  398 +
  399 + txdes[PKTBUFSTX - 1].txdes0 = FTGMAC100_TXDES0_EDOTR;
  400 + rxdes[PKTBUFSRX - 1].rxdes0 = FTGMAC100_RXDES0_EDORR;
  401 +
  402 + for (i = 0; i < PKTBUFSTX; i++) {
  403 + /* TXBUF_BADR */
  404 + txdes[i].txdes3 = 0;
  405 + txdes[i].txdes1 = 0;
  406 + }
  407 +
  408 + for (i = 0; i < PKTBUFSRX; i++) {
  409 + /* RXBUF_BADR */
  410 + rxdes[i].rxdes3 = (unsigned int)NetRxPackets[i];
  411 + rxdes[i].rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
  412 + }
  413 +
  414 + /* transmit ring */
  415 + writel((unsigned int)txdes, &ftgmac100->txr_badr);
  416 +
  417 + /* receive ring */
  418 + writel((unsigned int)rxdes, &ftgmac100->rxr_badr);
  419 +
  420 + /* poll receive descriptor automatically */
  421 + writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc);
  422 +
  423 + /* config receive buffer size register */
  424 + writel(FTGMAC100_RBSR_SIZE(RBSR_DEFAULT_VALUE), &ftgmac100->rbsr);
  425 +
  426 + /* enable transmitter, receiver */
  427 + maccr = FTGMAC100_MACCR_TXMAC_EN |
  428 + FTGMAC100_MACCR_RXMAC_EN |
  429 + FTGMAC100_MACCR_TXDMA_EN |
  430 + FTGMAC100_MACCR_RXDMA_EN |
  431 + FTGMAC100_MACCR_CRC_APD |
  432 + FTGMAC100_MACCR_FULLDUP |
  433 + FTGMAC100_MACCR_RX_RUNT |
  434 + FTGMAC100_MACCR_RX_BROADPKT;
  435 +
  436 + writel(maccr, &ftgmac100->maccr);
  437 +
  438 + if (!ftgmac100_phy_init(dev)) {
  439 + if (!ftgmac100_update_link_speed(dev))
  440 + return -1;
  441 + }
  442 +
  443 + return 0;
  444 +}
  445 +
  446 +/*
  447 + * Get a data block via Ethernet
  448 + */
  449 +static int ftgmac100_recv(struct eth_device *dev)
  450 +{
  451 + struct ftgmac100_data *priv = dev->priv;
  452 + struct ftgmac100_rxdes *curr_des;
  453 + unsigned short rxlen;
  454 +
  455 + curr_des = &priv->rxdes[priv->rx_index];
  456 +
  457 + if (!(curr_des->rxdes0 & FTGMAC100_RXDES0_RXPKT_RDY))
  458 + return -1;
  459 +
  460 + if (curr_des->rxdes0 & (FTGMAC100_RXDES0_RX_ERR |
  461 + FTGMAC100_RXDES0_CRC_ERR |
  462 + FTGMAC100_RXDES0_FTL |
  463 + FTGMAC100_RXDES0_RUNT |
  464 + FTGMAC100_RXDES0_RX_ODD_NB)) {
  465 + return -1;
  466 + }
  467 +
  468 + rxlen = FTGMAC100_RXDES0_VDBC(curr_des->rxdes0);
  469 +
  470 + debug("%s(): RX buffer %d, %x received\n",
  471 + __func__, priv->rx_index, rxlen);
  472 +
  473 + /* pass the packet up to the protocol layers. */
  474 + NetReceive((void *)curr_des->rxdes3, rxlen);
  475 +
  476 + /* release buffer to DMA */
  477 + curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
  478 +
  479 + priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX;
  480 +
  481 + return 0;
  482 +}
  483 +
  484 +/*
  485 + * Send a data block via Ethernet
  486 + */
  487 +static int
  488 +ftgmac100_send(struct eth_device *dev, void *packet, int length)
  489 +{
  490 + struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
  491 + struct ftgmac100_data *priv = dev->priv;
  492 + struct ftgmac100_txdes *curr_des = &priv->txdes[priv->tx_index];
  493 + int start;
  494 +
  495 + if (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) {
  496 + debug("%s(): no TX descriptor available\n", __func__);
  497 + return -1;
  498 + }
  499 +
  500 + debug("%s(%x, %x)\n", __func__, (int)packet, length);
  501 +
  502 + length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
  503 +
  504 + /* initiate a transmit sequence */
  505 + curr_des->txdes3 = (unsigned int)packet; /* TXBUF_BADR */
  506 +
  507 + /* only one descriptor on TXBUF */
  508 + curr_des->txdes0 &= FTGMAC100_TXDES0_EDOTR;
  509 + curr_des->txdes0 |= FTGMAC100_TXDES0_FTS |
  510 + FTGMAC100_TXDES0_LTS |
  511 + FTGMAC100_TXDES0_TXBUF_SIZE(length) |
  512 + FTGMAC100_TXDES0_TXDMA_OWN ;
  513 +
  514 + /* start transmit */
  515 + writel(1, &ftgmac100->txpd);
  516 +
  517 + /* wait for transfer to succeed */
  518 + start = get_timer(0);
  519 + while (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) {
  520 + if (get_timer(0) >= 5) {
  521 + debug("%s(): timed out\n", __func__);
  522 + return -1;
  523 + }
  524 + }
  525 +
  526 + debug("%s(): packet sent\n", __func__);
  527 +
  528 + priv->tx_index = (priv->tx_index + 1) % PKTBUFSTX;
  529 +
  530 + return 0;
  531 +}
  532 +
  533 +int ftgmac100_initialize(bd_t *bd)
  534 +{
  535 + struct eth_device *dev;
  536 + struct ftgmac100_data *priv;
  537 +
  538 + dev = malloc(sizeof *dev);
  539 + if (!dev) {
  540 + printf("%s(): failed to allocate dev\n", __func__);
  541 + goto out;
  542 + }
  543 +
  544 + /* Transmit and receive descriptors should align to 16 bytes */
  545 + priv = memalign(16, sizeof(struct ftgmac100_data));
  546 + if (!priv) {
  547 + printf("%s(): failed to allocate priv\n", __func__);
  548 + goto free_dev;
  549 + }
  550 +
  551 + memset(dev, 0, sizeof(*dev));
  552 + memset(priv, 0, sizeof(*priv));
  553 +
  554 + sprintf(dev->name, "FTGMAC100");
  555 + dev->iobase = CONFIG_FTGMAC100_BASE;
  556 + dev->init = ftgmac100_init;
  557 + dev->halt = ftgmac100_halt;
  558 + dev->send = ftgmac100_send;
  559 + dev->recv = ftgmac100_recv;
  560 + dev->priv = priv;
  561 +
  562 + eth_register(dev);
  563 +
  564 + return 1;
  565 +
  566 +free_dev:
  567 + free(dev);
  568 +out:
  569 + return 0;
  570 +}
drivers/net/ftgmac100.h
  1 +/*
  2 + * Faraday FTGMAC100 Ethernet
  3 + *
  4 + * (C) Copyright 2010 Faraday Technology
  5 + * Po-Yu Chuang <ratbert@faraday-tech.com>
  6 + *
  7 + * (C) Copyright 2010 Andes Technology
  8 + * Macpaul Lin <macpaul@andestech.com>
  9 + *
  10 + * This program is free software; you can redistribute it and/or modify
  11 + * it under the terms of the GNU General Public License as published by
  12 + * the Free Software Foundation; either version 2 of the License, or
  13 + * (at your option) any later version.
  14 + *
  15 + * This program is distributed in the hope that it will be useful,
  16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18 + * GNU General Public License for more details.
  19 + *
  20 + * You should have received a copy of the GNU General Public License
  21 + * along with this program; if not, write to the Free Software
  22 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23 + */
  24 +
  25 +#ifndef __FTGMAC100_H
  26 +#define __FTGMAC100_H
  27 +
  28 +/* The registers offset table of ftgmac100 */
  29 +struct ftgmac100 {
  30 + unsigned int isr; /* 0x00 */
  31 + unsigned int ier; /* 0x04 */
  32 + unsigned int mac_madr; /* 0x08 */
  33 + unsigned int mac_ladr; /* 0x0c */
  34 + unsigned int maht0; /* 0x10 */
  35 + unsigned int maht1; /* 0x14 */
  36 + unsigned int txpd; /* 0x18 */
  37 + unsigned int rxpd; /* 0x1c */
  38 + unsigned int txr_badr; /* 0x20 */
  39 + unsigned int rxr_badr; /* 0x24 */
  40 + unsigned int hptxpd; /* 0x28 */
  41 + unsigned int hptxpd_badr; /* 0x2c */
  42 + unsigned int itc; /* 0x30 */
  43 + unsigned int aptc; /* 0x34 */
  44 + unsigned int dblac; /* 0x38 */
  45 + unsigned int dmafifos; /* 0x3c */
  46 + unsigned int revr; /* 0x40 */
  47 + unsigned int fear; /* 0x44 */
  48 + unsigned int tpafcr; /* 0x48 */
  49 + unsigned int rbsr; /* 0x4c */
  50 + unsigned int maccr; /* 0x50 */
  51 + unsigned int macsr; /* 0x54 */
  52 + unsigned int tm; /* 0x58 */
  53 + unsigned int resv1; /* 0x5c */ /* not defined in spec */
  54 + unsigned int phycr; /* 0x60 */
  55 + unsigned int phydata; /* 0x64 */
  56 + unsigned int fcr; /* 0x68 */
  57 + unsigned int bpr; /* 0x6c */
  58 + unsigned int wolcr; /* 0x70 */
  59 + unsigned int wolsr; /* 0x74 */
  60 + unsigned int wfcrc; /* 0x78 */
  61 + unsigned int resv2; /* 0x7c */ /* not defined in spec */
  62 + unsigned int wfbm1; /* 0x80 */
  63 + unsigned int wfbm2; /* 0x84 */
  64 + unsigned int wfbm3; /* 0x88 */
  65 + unsigned int wfbm4; /* 0x8c */
  66 + unsigned int nptxr_ptr; /* 0x90 */
  67 + unsigned int hptxr_ptr; /* 0x94 */
  68 + unsigned int rxr_ptr; /* 0x98 */
  69 + unsigned int resv3; /* 0x9c */ /* not defined in spec */
  70 + unsigned int tx; /* 0xa0 */
  71 + unsigned int tx_mcol_scol; /* 0xa4 */
  72 + unsigned int tx_ecol_fail; /* 0xa8 */
  73 + unsigned int tx_lcol_und; /* 0xac */
  74 + unsigned int rx; /* 0xb0 */
  75 + unsigned int rx_bc; /* 0xb4 */
  76 + unsigned int rx_mc; /* 0xb8 */
  77 + unsigned int rx_pf_aep; /* 0xbc */
  78 + unsigned int rx_runt; /* 0xc0 */
  79 + unsigned int rx_crcer_ftl; /* 0xc4 */
  80 + unsigned int rx_col_lost; /* 0xc8 */
  81 +};
  82 +
  83 +/*
  84 + * Interrupt status register & interrupt enable register
  85 + */
  86 +#define FTGMAC100_INT_RPKT_BUF (1 << 0)
  87 +#define FTGMAC100_INT_RPKT_FIFO (1 << 1)
  88 +#define FTGMAC100_INT_NO_RXBUF (1 << 2)
  89 +#define FTGMAC100_INT_RPKT_LOST (1 << 3)
  90 +#define FTGMAC100_INT_XPKT_ETH (1 << 4)
  91 +#define FTGMAC100_INT_XPKT_FIFO (1 << 5)
  92 +#define FTGMAC100_INT_NO_NPTXBUF (1 << 6)
  93 +#define FTGMAC100_INT_XPKT_LOST (1 << 7)
  94 +#define FTGMAC100_INT_AHB_ERR (1 << 8)
  95 +#define FTGMAC100_INT_PHYSTS_CHG (1 << 9)
  96 +#define FTGMAC100_INT_NO_HPTXBUF (1 << 10)
  97 +
  98 +/*
  99 + * Interrupt timer control register
  100 + */
  101 +#define FTGMAC100_ITC_RXINT_CNT(x) (((x) & 0xf) << 0)
  102 +#define FTGMAC100_ITC_RXINT_THR(x) (((x) & 0x7) << 4)
  103 +#define FTGMAC100_ITC_RXINT_TIME_SEL (1 << 7)
  104 +#define FTGMAC100_ITC_TXINT_CNT(x) (((x) & 0xf) << 8)
  105 +#define FTGMAC100_ITC_TXINT_THR(x) (((x) & 0x7) << 12)
  106 +#define FTGMAC100_ITC_TXINT_TIME_SEL (1 << 15)
  107 +
  108 +/*
  109 + * Automatic polling timer control register
  110 + */
  111 +#define FTGMAC100_APTC_RXPOLL_CNT(x) (((x) & 0xf) << 0)
  112 +#define FTGMAC100_APTC_RXPOLL_TIME_SEL (1 << 4)
  113 +#define FTGMAC100_APTC_TXPOLL_CNT(x) (((x) & 0xf) << 8)
  114 +#define FTGMAC100_APTC_TXPOLL_TIME_SEL (1 << 12)
  115 +
  116 +/*
  117 + * DMA burst length and arbitration control register
  118 + */
  119 +#define FTGMAC100_DBLAC_RXFIFO_LTHR(x) (((x) & 0x7) << 0)
  120 +#define FTGMAC100_DBLAC_RXFIFO_HTHR(x) (((x) & 0x7) << 3)
  121 +#define FTGMAC100_DBLAC_RX_THR_EN (1 << 6)
  122 +#define FTGMAC100_DBLAC_RXBURST_SIZE(x) (((x) & 0x3) << 8)
  123 +#define FTGMAC100_DBLAC_TXBURST_SIZE(x) (((x) & 0x3) << 10)
  124 +#define FTGMAC100_DBLAC_RXDES_SIZE(x) (((x) & 0xf) << 12)
  125 +#define FTGMAC100_DBLAC_TXDES_SIZE(x) (((x) & 0xf) << 16)
  126 +#define FTGMAC100_DBLAC_IFG_CNT(x) (((x) & 0x7) << 20)
  127 +#define FTGMAC100_DBLAC_IFG_INC (1 << 23)
  128 +
  129 +/*
  130 + * DMA FIFO status register
  131 + */
  132 +#define FTGMAC100_DMAFIFOS_RXDMA1_SM(dmafifos) ((dmafifos) & 0xf)
  133 +#define FTGMAC100_DMAFIFOS_RXDMA2_SM(dmafifos) (((dmafifos) >> 4) & 0xf)
  134 +#define FTGMAC100_DMAFIFOS_RXDMA3_SM(dmafifos) (((dmafifos) >> 8) & 0x7)
  135 +#define FTGMAC100_DMAFIFOS_TXDMA1_SM(dmafifos) (((dmafifos) >> 12) & 0xf)
  136 +#define FTGMAC100_DMAFIFOS_TXDMA2_SM(dmafifos) (((dmafifos) >> 16) & 0x3)
  137 +#define FTGMAC100_DMAFIFOS_TXDMA3_SM(dmafifos) (((dmafifos) >> 18) & 0xf)
  138 +#define FTGMAC100_DMAFIFOS_RXFIFO_EMPTY (1 << 26)
  139 +#define FTGMAC100_DMAFIFOS_TXFIFO_EMPTY (1 << 27)
  140 +#define FTGMAC100_DMAFIFOS_RXDMA_GRANT (1 << 28)
  141 +#define FTGMAC100_DMAFIFOS_TXDMA_GRANT (1 << 29)
  142 +#define FTGMAC100_DMAFIFOS_RXDMA_REQ (1 << 30)
  143 +#define FTGMAC100_DMAFIFOS_TXDMA_REQ (1 << 31)
  144 +
  145 +/*
  146 + * Receive buffer size register
  147 + */
  148 +#define FTGMAC100_RBSR_SIZE(x) ((x) & 0x3fff)
  149 +
  150 +/*
  151 + * MAC control register
  152 + */
  153 +#define FTGMAC100_MACCR_TXDMA_EN (1 << 0)
  154 +#define FTGMAC100_MACCR_RXDMA_EN (1 << 1)
  155 +#define FTGMAC100_MACCR_TXMAC_EN (1 << 2)
  156 +#define FTGMAC100_MACCR_RXMAC_EN (1 << 3)
  157 +#define FTGMAC100_MACCR_RM_VLAN (1 << 4)
  158 +#define FTGMAC100_MACCR_HPTXR_EN (1 << 5)
  159 +#define FTGMAC100_MACCR_LOOP_EN (1 << 6)
  160 +#define FTGMAC100_MACCR_ENRX_IN_HALFTX (1 << 7)
  161 +#define FTGMAC100_MACCR_FULLDUP (1 << 8)
  162 +#define FTGMAC100_MACCR_GIGA_MODE (1 << 9)
  163 +#define FTGMAC100_MACCR_CRC_APD (1 << 10)
  164 +#define FTGMAC100_MACCR_RX_RUNT (1 << 12)
  165 +#define FTGMAC100_MACCR_JUMBO_LF (1 << 13)
  166 +#define FTGMAC100_MACCR_RX_ALL (1 << 14)
  167 +#define FTGMAC100_MACCR_HT_MULTI_EN (1 << 15)
  168 +#define FTGMAC100_MACCR_RX_MULTIPKT (1 << 16)
  169 +#define FTGMAC100_MACCR_RX_BROADPKT (1 << 17)
  170 +#define FTGMAC100_MACCR_DISCARD_CRCERR (1 << 18)
  171 +#define FTGMAC100_MACCR_FAST_MODE (1 << 19)
  172 +#define FTGMAC100_MACCR_SW_RST (1 << 31)
  173 +
  174 +/*
  175 + * PHY control register
  176 + */
  177 +#define FTGMAC100_PHYCR_MDC_CYCTHR_MASK 0x3f
  178 +#define FTGMAC100_PHYCR_MDC_CYCTHR(x) ((x) & 0x3f)
  179 +#define FTGMAC100_PHYCR_PHYAD(x) (((x) & 0x1f) << 16)
  180 +#define FTGMAC100_PHYCR_REGAD(x) (((x) & 0x1f) << 21)
  181 +#define FTGMAC100_PHYCR_MIIRD (1 << 26)
  182 +#define FTGMAC100_PHYCR_MIIWR (1 << 27)
  183 +
  184 +/*
  185 + * PHY data register
  186 + */
  187 +#define FTGMAC100_PHYDATA_MIIWDATA(x) ((x) & 0xffff)
  188 +#define FTGMAC100_PHYDATA_MIIRDATA(phydata) (((phydata) >> 16) & 0xffff)
  189 +
  190 +/*
  191 + * Transmit descriptor, aligned to 16 bytes
  192 + */
  193 +struct ftgmac100_txdes {
  194 + unsigned int txdes0;
  195 + unsigned int txdes1;
  196 + unsigned int txdes2; /* not used by HW */
  197 + unsigned int txdes3; /* TXBUF_BADR */
  198 +} __attribute__ ((aligned(16)));
  199 +
  200 +#define FTGMAC100_TXDES0_TXBUF_SIZE(x) ((x) & 0x3fff)
  201 +#define FTGMAC100_TXDES0_EDOTR (1 << 15)
  202 +#define FTGMAC100_TXDES0_CRC_ERR (1 << 19)
  203 +#define FTGMAC100_TXDES0_LTS (1 << 28)
  204 +#define FTGMAC100_TXDES0_FTS (1 << 29)
  205 +#define FTGMAC100_TXDES0_TXDMA_OWN (1 << 31)
  206 +
  207 +#define FTGMAC100_TXDES1_VLANTAG_CI(x) ((x) & 0xffff)
  208 +#define FTGMAC100_TXDES1_INS_VLANTAG (1 << 16)
  209 +#define FTGMAC100_TXDES1_TCP_CHKSUM (1 << 17)
  210 +#define FTGMAC100_TXDES1_UDP_CHKSUM (1 << 18)
  211 +#define FTGMAC100_TXDES1_IP_CHKSUM (1 << 19)
  212 +#define FTGMAC100_TXDES1_LLC (1 << 22)
  213 +#define FTGMAC100_TXDES1_TX2FIC (1 << 30)
  214 +#define FTGMAC100_TXDES1_TXIC (1 << 31)
  215 +
  216 +/*
  217 + * Receive descriptor, aligned to 16 bytes
  218 + */
  219 +struct ftgmac100_rxdes {
  220 + unsigned int rxdes0;
  221 + unsigned int rxdes1;
  222 + unsigned int rxdes2; /* not used by HW */
  223 + unsigned int rxdes3; /* RXBUF_BADR */
  224 +} __attribute__ ((aligned(16)));
  225 +
  226 +#define FTGMAC100_RXDES0_VDBC(x) ((x) & 0x3fff)
  227 +#define FTGMAC100_RXDES0_EDORR (1 << 15)
  228 +#define FTGMAC100_RXDES0_MULTICAST (1 << 16)
  229 +#define FTGMAC100_RXDES0_BROADCAST (1 << 17)
  230 +#define FTGMAC100_RXDES0_RX_ERR (1 << 18)
  231 +#define FTGMAC100_RXDES0_CRC_ERR (1 << 19)
  232 +#define FTGMAC100_RXDES0_FTL (1 << 20)
  233 +#define FTGMAC100_RXDES0_RUNT (1 << 21)
  234 +#define FTGMAC100_RXDES0_RX_ODD_NB (1 << 22)
  235 +#define FTGMAC100_RXDES0_FIFO_FULL (1 << 23)
  236 +#define FTGMAC100_RXDES0_PAUSE_OPCODE (1 << 24)
  237 +#define FTGMAC100_RXDES0_PAUSE_FRAME (1 << 25)
  238 +#define FTGMAC100_RXDES0_LRS (1 << 28)
  239 +#define FTGMAC100_RXDES0_FRS (1 << 29)
  240 +#define FTGMAC100_RXDES0_RXPKT_RDY (1 << 31)
  241 +
  242 +#define FTGMAC100_RXDES1_VLANTAG_CI 0xffff
  243 +#define FTGMAC100_RXDES1_PROT_MASK (0x3 << 20)
  244 +#define FTGMAC100_RXDES1_PROT_NONIP (0x0 << 20)
  245 +#define FTGMAC100_RXDES1_PROT_IP (0x1 << 20)
  246 +#define FTGMAC100_RXDES1_PROT_TCPIP (0x2 << 20)
  247 +#define FTGMAC100_RXDES1_PROT_UDPIP (0x3 << 20)
  248 +#define FTGMAC100_RXDES1_LLC (1 << 22)
  249 +#define FTGMAC100_RXDES1_DF (1 << 23)
  250 +#define FTGMAC100_RXDES1_VLANTAG_AVAIL (1 << 24)
  251 +#define FTGMAC100_RXDES1_TCP_CHKSUM_ERR (1 << 25)
  252 +#define FTGMAC100_RXDES1_UDP_CHKSUM_ERR (1 << 26)
  253 +#define FTGMAC100_RXDES1_IP_CHKSUM_ERR (1 << 27)
  254 +
  255 +#endif /* __FTGMAC100_H */
... ... @@ -61,6 +61,7 @@
61 61 int eth_3com_initialize (bd_t * bis);
62 62 int fec_initialize (bd_t *bis);
63 63 int fecmxc_initialize (bd_t *bis);
  64 +int ftgmac100_initialize(bd_t *bits);
64 65 int ftmac100_initialize(bd_t *bits);
65 66 int greth_initialize(bd_t *bis);
66 67 void gt6426x_eth_initialize(bd_t *bis);