summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ftgmac100.c488
-rw-r--r--drivers/net/ftgmac100.h63
2 files changed, 422 insertions, 129 deletions
diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c
index 5ccc4beda8..9d5ba98243 100644
--- a/drivers/net/ftgmac100.c
+++ b/drivers/net/ftgmac100.c
@@ -15,13 +15,21 @@
#include <malloc.h>
#include <net.h>
#include <asm/io.h>
-#include <asm/dma-mapping.h>
#include <linux/mii.h>
+#include <i2c.h>
+
+#include <asm/arch/ast_scu.h>
+#include <asm/arch/aspeed.h>
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+#include <miiphy.h>
+#endif
+
+
#include "ftgmac100.h"
#define ETH_ZLEN 60
-#define CFG_XBUF_SIZE 1536
/* RBSR - hw default init value is also 0x640 */
#define RBSR_DEFAULT_VALUE 0x640
@@ -30,10 +38,8 @@
#define PKTBUFSTX 4 /* must be power of 2 */
struct ftgmac100_data {
- ulong txdes_dma;
- struct ftgmac100_txdes *txdes;
- ulong rxdes_dma;
- struct ftgmac100_rxdes *rxdes;
+ struct ftgmac100_txdes txdes[PKTBUFSTX];
+ struct ftgmac100_rxdes rxdes[PKTBUFSRX];
int tx_index;
int rx_index;
int phy_addr;
@@ -46,73 +52,171 @@ static int ftgmac100_mdiobus_read(struct eth_device *dev, int phy_addr,
int regnum)
{
struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+ int fear0;
int phycr;
int i;
- phycr = readl(&ftgmac100->phycr);
+#ifdef AST_MAC_OWN
+ if (__raw_readl(&ftgmac100->physts) & FTGMAC100_PHY_STS_UNVALID) {
+ printf("owner \n");
+ } else {
+ printf("not owner \n");
+ __raw_writel(__raw_readl(&ftgmac100->physts) | FTGMAC100_PHY_REQ_EN, &ftgmac100->physts);
+ while(!(__raw_readl(&ftgmac100->isr) & FTGMAC100_INT_FLAG_ACK)) {
+ mdelay(10);
+ i++;
+ if(i > 1000) {
+ printf("time out \n");
+ break;
+ }
+ }
+ __raw_writel(__raw_readl(&ftgmac100->physts) | FTGMAC100_PHY_POLL, &ftgmac100->physts);
+ __raw_writel(__raw_readl(&ftgmac100->physts) & ~FTGMAC100_PHY_REQ_EN, &ftgmac100->physts);
+ __raw_writel(FTGMAC100_INT_FLAG_ACK, &ftgmac100->isr);
- /* preserve MDC cycle threshold */
- phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK;
+ }
+#endif
- phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr)
- | FTGMAC100_PHYCR_REGAD(regnum)
- | FTGMAC100_PHYCR_MIIRD;
+ fear0 = __raw_readl(&ftgmac100->fear0);
+ if(fear0 & (1 << 31)) { //New MDC/MDIO
+ phycr = FTGMAC100_PHYCR_NEW_FIRE | FTGMAC100_PHYCR_ST_22 | FTGMAC100_PHYCR_NEW_READ |
+ FTGMAC100_PHYCR_NEW_PHYAD(phy_addr) | // 20141114
+ FTGMAC100_PHYCR_NEW_REGAD(regnum); // 20141114
- writel(phycr, &ftgmac100->phycr);
+ __raw_writel(phycr, &ftgmac100->phycr);
- for (i = 0; i < 10; i++) {
- phycr = readl(&ftgmac100->phycr);
+ for (i = 0; i < 10; i++) {
+ phycr = __raw_readl(&ftgmac100->phycr);
- if ((phycr & FTGMAC100_PHYCR_MIIRD) == 0) {
- int data;
+ if ((phycr & FTGMAC100_PHYCR_NEW_FIRE) == 0) {
+ int data;
- data = readl(&ftgmac100->phydata);
- return FTGMAC100_PHYDATA_MIIRDATA(data);
+ data = __raw_readl(&ftgmac100->phydata);
+ return FTGMAC100_PHYDATA_NEW_MIIWDATA(data);
+ }
+
+ mdelay(10);
}
- mdelay(10);
- }
+ debug("mdio read timed out\n");
+ return -1;
+
+ } else {
+ phycr = __raw_readl(&ftgmac100->phycr);
- debug("mdio read timed out\n");
- return -1;
+ /* preserve MDC cycle threshold */
+ // phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK;
+
+ phycr = FTGMAC100_PHYCR_PHYAD(phy_addr)
+ | FTGMAC100_PHYCR_REGAD(regnum)
+ | FTGMAC100_PHYCR_MIIRD | 0x34;
+
+ __raw_writel(phycr, &ftgmac100->phycr);
+
+ for (i = 0; i < 10; i++) {
+ phycr = __raw_readl(&ftgmac100->phycr);
+
+ if ((phycr & FTGMAC100_PHYCR_MIIRD) == 0) {
+ int data;
+
+ data = __raw_readl(&ftgmac100->phydata);
+ return FTGMAC100_PHYDATA_MIIRDATA(data);
+ }
+
+ mdelay(10);
+ }
+
+ debug("mdio read timed out\n");
+ return -1;
+ }
}
static int ftgmac100_mdiobus_write(struct eth_device *dev, int phy_addr,
int regnum, u16 value)
{
struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+ int fear0;
int phycr;
int data;
int i;
- phycr = readl(&ftgmac100->phycr);
+#ifdef AST_MAC_OWN
+ if (__raw_readl(&ftgmac100->physts) & FTGMAC100_PHY_STS_UNVALID) {
+ printf("owner \n");
+ } else {
+ printf("not owner \n");
+ __raw_writel(__raw_readl(&ftgmac100->physts) | FTGMAC100_PHY_REQ_EN, &ftgmac100->physts);
+ while(!(__raw_readl(&ftgmac100->isr) & FTGMAC100_INT_FLAG_ACK)) {
+ mdelay(10);
+ i++;
+ if(i > 1000) {
+ printf("time out \n");
+ break;
+ }
+ }
+ __raw_writel(__raw_readl(&ftgmac100->physts) | FTGMAC100_PHY_POLL, &ftgmac100->physts);
+ __raw_writel(__raw_readl(&ftgmac100->physts) & ~FTGMAC100_PHY_REQ_EN, &ftgmac100->physts);
+ __raw_writel(FTGMAC100_INT_FLAG_ACK, &ftgmac100->isr);
+
+ }
+#endif
+
+ fear0 = __raw_readl(&ftgmac100->fear0);
+ if(fear0 & (1 << 31)) { //New MDC/MDIO
+ phycr = (value << 16) |
+ FTGMAC100_PHYCR_NEW_FIRE | FTGMAC100_PHYCR_ST_22 |
+ FTGMAC100_PHYCR_NEW_WRITE |
+ FTGMAC100_PHYCR_NEW_PHYAD(phy_addr) | // 20141114
+ FTGMAC100_PHYCR_NEW_REGAD(regnum); // 20141114
+
+ __raw_writel(phycr, &ftgmac100->phycr);
+
+ for (i = 0; i < 10; i++) {
+ phycr = __raw_readl(&ftgmac100->phycr);
- /* preserve MDC cycle threshold */
- phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK;
+ if ((phycr & FTGMAC100_PHYCR_NEW_FIRE) == 0) {
+ debug("(phycr & FTGMAC100_PHYCR_MIIWR) == 0: " \
+ "phy_addr: %x\n", phy_addr);
+ return 0;
+ }
- phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr)
- | FTGMAC100_PHYCR_REGAD(regnum)
- | FTGMAC100_PHYCR_MIIWR;
+ mdelay(10);
+ }
+
+ debug("mdio write timed out\n");
+ return -1;
- data = FTGMAC100_PHYDATA_MIIWDATA(value);
+ } else {
- writel(data, &ftgmac100->phydata);
- writel(phycr, &ftgmac100->phycr);
+ phycr = __raw_readl(&ftgmac100->phycr);
- for (i = 0; i < 10; i++) {
- phycr = readl(&ftgmac100->phycr);
+ /* preserve MDC cycle threshold */
+ // phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK;
- if ((phycr & FTGMAC100_PHYCR_MIIWR) == 0) {
- debug("(phycr & FTGMAC100_PHYCR_MIIWR) == 0: " \
- "phy_addr: %x\n", phy_addr);
- return 0;
+ phycr = FTGMAC100_PHYCR_PHYAD(phy_addr)
+ | FTGMAC100_PHYCR_REGAD(regnum)
+ | FTGMAC100_PHYCR_MIIWR | 0x34;
+
+ data = FTGMAC100_PHYDATA_MIIWDATA(value);
+
+ __raw_writel(data, &ftgmac100->phydata);
+ __raw_writel(phycr, &ftgmac100->phycr);
+
+ for (i = 0; i < 10; i++) {
+ phycr = __raw_readl(&ftgmac100->phycr);
+
+ if ((phycr & FTGMAC100_PHYCR_MIIWR) == 0) {
+ debug("(phycr & FTGMAC100_PHYCR_MIIWR) == 0: " \
+ "phy_addr: %x\n", phy_addr);
+ return 0;
+ }
+
+ mdelay(1);
}
- mdelay(1);
+ debug("mdio write timed out\n");
+ return -1;
}
-
- debug("mdio write timed out\n");
- return -1;
}
int ftgmac100_phy_read(struct eth_device *dev, int addr, int reg, u16 *value)
@@ -133,6 +237,30 @@ int ftgmac100_phy_write(struct eth_device *dev, int addr, int reg, u16 value)
return 0;
}
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+static int ftgmac100_reg_read(const char *devname, u8 phy_addr, u8 phy_reg,
+ u16 *value)
+{
+ struct eth_device *dev = eth_get_dev_by_name(devname);
+ *value = ftgmac100_mdiobus_read(dev , phy_addr, phy_reg);
+
+ if (*value == -1)
+ return -1;
+
+ return 0;
+
+}
+
+static int ftgmac100_reg_write(const char *devname, u8 phy_addr, u8 phy_reg, u16 value)
+{
+ struct eth_device *dev = eth_get_dev_by_name(devname);
+ if (ftgmac100_mdiobus_write(dev, phy_addr, phy_reg, value) == -1)
+ return -1;
+
+ return 0;
+}
+#endif
+
static int ftgmac100_phy_reset(struct eth_device *dev)
{
struct ftgmac100_data *priv = dev->priv;
@@ -172,35 +300,41 @@ static int ftgmac100_phy_init(struct eth_device *dev)
struct ftgmac100_data *priv = dev->priv;
int phy_addr;
- u16 phy_id, status, adv, lpa, stat_ge;
+// u32 phy_id;
+ u16 phy_id1, status, adv, lpa, stat_ge;
+ u16 phy_id2;
int media, speed, duplex;
int i;
/* Check if the PHY is up to snuff... */
for (phy_addr = 0; phy_addr < CONFIG_PHY_MAX_ADDR; phy_addr++) {
- ftgmac100_phy_read(dev, phy_addr, MII_PHYSID1, &phy_id);
+ ftgmac100_phy_read(dev, phy_addr, MII_PHYSID1, &phy_id1);
+ ftgmac100_phy_read(dev, phy_addr, MII_PHYSID2, &phy_id2);
/*
* When it is unable to found PHY,
* the interface usually return 0xffff or 0x0000
*/
- if (phy_id != 0xffff && phy_id != 0x0) {
- printf("%s: found PHY at 0x%02x\n",
- dev->name, phy_addr);
+ if (phy_id1 != 0xffff && phy_id1 != 0x0) {
+// printf("%s: found PHY at 0x%02x\n",
+// dev->name, phy_addr);
priv->phy_addr = phy_addr;
break;
}
}
- if (phy_id == 0xffff || phy_id == 0x0) {
+ if (phy_id1 == 0xffff || phy_id1 == 0x0) {
printf("%s: no PHY present\n", dev->name);
return 0;
}
ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &status);
+// printf("phy_id : %x , status %x \n",((phy_id1 << 16) | phy_id2), status );
+
if (!(status & BMSR_LSTATUS)) {
+// printf("! status \n");
/* Try to re-negotiate if we don't have link already. */
ftgmac100_phy_reset(dev);
@@ -269,7 +403,7 @@ static int ftgmac100_update_link_speed(struct eth_device *dev)
return 0;
/* read MAC control register and clear related bits */
- maccr = readl(&ftgmac100->maccr) &
+ maccr = __raw_readl(&ftgmac100->maccr) &
~(FTGMAC100_MACCR_GIGA_MODE |
FTGMAC100_MACCR_FAST_MODE |
FTGMAC100_MACCR_FULLDUP);
@@ -308,7 +442,7 @@ static int ftgmac100_update_link_speed(struct eth_device *dev)
}
/* update MII config into maccr */
- writel(maccr, &ftgmac100->maccr);
+ __raw_writel(maccr, &ftgmac100->maccr);
return 1;
}
@@ -322,10 +456,13 @@ static void ftgmac100_reset(struct eth_device *dev)
debug("%s()\n", __func__);
- writel(FTGMAC100_MACCR_SW_RST, &ftgmac100->maccr);
+ //Ryan modify
+ __raw_writel(__raw_readl(&ftgmac100->maccr) | FTGMAC100_MACCR_SW_RST, &ftgmac100->maccr);
- while (readl(&ftgmac100->maccr) & FTGMAC100_MACCR_SW_RST)
- ;
+ while (__raw_readl(&ftgmac100->maccr) & FTGMAC100_MACCR_SW_RST);
+
+ //Use New MDC and MDIO interface
+ __raw_writel(__raw_readl(&ftgmac100->fear0) | 0x80000000, &ftgmac100->fear0);
}
/*
@@ -340,15 +477,47 @@ static void ftgmac100_set_mac(struct eth_device *dev,
debug("%s(%x %x)\n", __func__, maddr, laddr);
- writel(maddr, &ftgmac100->mac_madr);
- writel(laddr, &ftgmac100->mac_ladr);
+ __raw_writel(maddr, &ftgmac100->mac_madr);
+ __raw_writel(laddr, &ftgmac100->mac_ladr);
}
static void ftgmac100_set_mac_from_env(struct eth_device *dev)
{
- eth_getenv_enetaddr("ethaddr", dev->enetaddr);
+#ifdef CONFIG_SYS_I2C_MAC_OFFSET
+
+ char *s;
+ int i, env; // env variable 0: eeprom, 1: environment parameters
+
+ s = getenv ("eeprom");
+ env = (s && (*s == 'y')) ? 1 : 0;
+
+ if (env) {
+ printf("TODO ... eerprom --> \n");
+ eeprom_init();
+ i2c_set_bus_num(3);
+ eeprom_read(CONFIG_SYS_I2C_EEPROM_ADDR, CONFIG_SYS_I2C_MAC_OFFSET, dev->enetaddr, 6);
+
+ for (i = 0; i < 6; i++) {
+ if (dev->enetaddr[i] != 0xFF) {
+ env = 0; //Suppose not all 0xFF is valid
+ }
+ }
+ }
+
+ if(env)
+ eth_getenv_enetaddr_by_index("eth", dev->index, dev->enetaddr);
+// eth_setenv_enetaddr("ethaddr", dev->enetaddr);
+ else
+ eth_getenv_enetaddr_by_index("eth", dev->index, dev->enetaddr);
+// eth_getenv_enetaddr("ethaddr", dev->enetaddr);
ftgmac100_set_mac(dev, dev->enetaddr);
+#else
+ eth_getenv_enetaddr_by_index("eth", dev->index, dev->enetaddr);
+// eth_getenv_enetaddr("ethaddr", dev->enetaddr);
+ ftgmac100_set_mac(dev, dev->enetaddr);
+#endif
+
}
/*
@@ -360,87 +529,64 @@ static void ftgmac100_halt(struct eth_device *dev)
debug("%s()\n", __func__);
- writel(0, &ftgmac100->maccr);
+// __raw_writel(0, &ftgmac100->maccr);
+ //ryan modify
+ __raw_writel(__raw_readl(&ftgmac100->maccr) & ~(FTGMAC100_MACCR_TXDMA_EN | FTGMAC100_MACCR_RXDMA_EN | FTGMAC100_MACCR_TXMAC_EN | FTGMAC100_MACCR_RXMAC_EN), &ftgmac100->maccr);
+
}
static int ftgmac100_init(struct eth_device *dev, bd_t *bd)
{
struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
struct ftgmac100_data *priv = dev->priv;
- struct ftgmac100_txdes *txdes;
- struct ftgmac100_rxdes *rxdes;
+ struct ftgmac100_txdes *txdes = priv->txdes;
+ struct ftgmac100_rxdes *rxdes = priv->rxdes;
unsigned int maccr;
- void *buf;
int i;
debug("%s()\n", __func__);
- if (!priv->txdes) {
- txdes = dma_alloc_coherent(
- sizeof(*txdes) * PKTBUFSTX, &priv->txdes_dma);
- if (!txdes)
- panic("ftgmac100: out of memory\n");
- memset(txdes, 0, sizeof(*txdes) * PKTBUFSTX);
- priv->txdes = txdes;
- }
- txdes = priv->txdes;
-
- if (!priv->rxdes) {
- rxdes = dma_alloc_coherent(
- sizeof(*rxdes) * PKTBUFSRX, &priv->rxdes_dma);
- if (!rxdes)
- panic("ftgmac100: out of memory\n");
- memset(rxdes, 0, sizeof(*rxdes) * PKTBUFSRX);
- priv->rxdes = rxdes;
- }
- rxdes = priv->rxdes;
+ //Ryan Add
+ ftgmac100_reset(dev);
/* set the ethernet address */
ftgmac100_set_mac_from_env(dev);
/* disable all interrupts */
- writel(0, &ftgmac100->ier);
+ __raw_writel(0, &ftgmac100->ier);
/* initialize descriptors */
priv->tx_index = 0;
priv->rx_index = 0;
- txdes[PKTBUFSTX - 1].txdes0 = FTGMAC100_TXDES0_EDOTR;
- rxdes[PKTBUFSRX - 1].rxdes0 = FTGMAC100_RXDES0_EDORR;
+ txdes[PKTBUFSTX - 1].txdes0 = cpu_to_le32(FTGMAC100_TXDES0_EDOTR);
+ rxdes[PKTBUFSRX - 1].rxdes0 = cpu_to_le32(FTGMAC100_RXDES0_EDORR);
for (i = 0; i < PKTBUFSTX; i++) {
/* TXBUF_BADR */
- if (!txdes[i].txdes2) {
- buf = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE);
- if (!buf)
- panic("ftgmac100: out of memory\n");
- txdes[i].txdes3 = virt_to_phys(buf);
- txdes[i].txdes2 = (uint)buf;
- }
+ txdes[i].txdes3 = 0;
txdes[i].txdes1 = 0;
}
for (i = 0; i < PKTBUFSRX; i++) {
/* RXBUF_BADR */
- if (!rxdes[i].rxdes2) {
- buf = net_rx_packets[i];
- rxdes[i].rxdes3 = virt_to_phys(buf);
- rxdes[i].rxdes2 = (uint)buf;
- }
- rxdes[i].rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
+ rxdes[i].rxdes3 = cpu_to_le32((unsigned int)net_rx_packets[i]);
+
+// rxdes[i].rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
+ rxdes[i].rxdes0 = cpu_to_le32(le32_to_cpu(rxdes[i].rxdes0) & ~FTGMAC100_RXDES0_RXPKT_RDY);
}
/* transmit ring */
- writel(priv->txdes_dma, &ftgmac100->txr_badr);
+ __raw_writel((unsigned int)txdes, &ftgmac100->txr_badr);
/* receive ring */
- writel(priv->rxdes_dma, &ftgmac100->rxr_badr);
+ __raw_writel((unsigned int)rxdes, &ftgmac100->rxr_badr);
/* poll receive descriptor automatically */
- writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc);
+ __raw_writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc);
/* config receive buffer size register */
- writel(FTGMAC100_RBSR_SIZE(RBSR_DEFAULT_VALUE), &ftgmac100->rbsr);
+ __raw_writel(FTGMAC100_RBSR_SIZE(RBSR_DEFAULT_VALUE), &ftgmac100->rbsr);
/* enable transmitter, receiver */
maccr = FTGMAC100_MACCR_TXMAC_EN |
@@ -452,13 +598,34 @@ static int ftgmac100_init(struct eth_device *dev, bd_t *bd)
FTGMAC100_MACCR_RX_RUNT |
FTGMAC100_MACCR_RX_BROADPKT;
- writel(maccr, &ftgmac100->maccr);
+ __raw_writel(maccr, &ftgmac100->maccr);
+//Ryan modify
+#if 1
+ ftgmac100_phy_init(dev);
+ if (!ftgmac100_update_link_speed(dev))
+ return -1;
+#else
if (!ftgmac100_phy_init(dev)) {
if (!ftgmac100_update_link_speed(dev))
return -1;
}
+#endif
+/////////////////
+#if 0 //(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
+ /* Search phy address from range 0-31 */
+ phy_adr = ethernet_phy_detect(dev);
+ if (phy_adr < 0) {
+ printf("FTGMAC100 : PHY not detected at address range 0-31\n");
+ return -1;
+ } else {
+ debug("FTGMAC100 : PHY detected at addr %d\n", phy_adr);
+ miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ, phy_adr);
+ }
+#endif
+
+//////////////////
return 0;
}
@@ -473,10 +640,12 @@ static int ftgmac100_recv(struct eth_device *dev)
curr_des = &priv->rxdes[priv->rx_index];
- if (!(curr_des->rxdes0 & FTGMAC100_RXDES0_RXPKT_RDY))
+ invalidate_dcache_range((u32) curr_des, (u32) curr_des + sizeof(struct ftgmac100_rxdes));
+
+ if (!(le32_to_cpu(curr_des->rxdes0) & FTGMAC100_RXDES0_RXPKT_RDY))
return -1;
- if (curr_des->rxdes0 & (FTGMAC100_RXDES0_RX_ERR |
+ if (le32_to_cpu(curr_des->rxdes0) & (FTGMAC100_RXDES0_RX_ERR |
FTGMAC100_RXDES0_CRC_ERR |
FTGMAC100_RXDES0_FTL |
FTGMAC100_RXDES0_RUNT |
@@ -484,19 +653,20 @@ static int ftgmac100_recv(struct eth_device *dev)
return -1;
}
- rxlen = FTGMAC100_RXDES0_VDBC(curr_des->rxdes0);
+ rxlen = FTGMAC100_RXDES0_VDBC(le32_to_cpu(curr_des->rxdes0));
debug("%s(): RX buffer %d, %x received\n",
__func__, priv->rx_index, rxlen);
- /* invalidate d-cache */
- dma_map_single((void *)curr_des->rxdes2, rxlen, DMA_FROM_DEVICE);
+ invalidate_dcache_range((u32) (le32_to_cpu(curr_des->rxdes3)), (u32) (le32_to_cpu(curr_des->rxdes3)) + rxlen);
/* pass the packet up to the protocol layers. */
- net_process_received_packet((void *)curr_des->rxdes2, rxlen);
+ net_process_received_packet((void *)le32_to_cpu(curr_des->rxdes3), rxlen);
/* release buffer to DMA */
- curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
+ //curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
+
+ curr_des->rxdes0 = cpu_to_le32(le32_to_cpu(curr_des->rxdes0) & ~FTGMAC100_RXDES0_RXPKT_RDY);
priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX;
@@ -511,6 +681,9 @@ static int ftgmac100_send(struct eth_device *dev, void *packet, int length)
struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
struct ftgmac100_data *priv = dev->priv;
struct ftgmac100_txdes *curr_des = &priv->txdes[priv->tx_index];
+ unsigned long start;
+ unsigned long now;
+ unsigned long diff_time;
if (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) {
debug("%s(): no TX descriptor available\n", __func__);
@@ -521,18 +694,45 @@ static int ftgmac100_send(struct eth_device *dev, void *packet, int length)
length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
- memcpy((void *)curr_des->txdes2, (void *)packet, length);
- dma_map_single((void *)curr_des->txdes2, length, DMA_TO_DEVICE);
+ /* initiate a transmit sequence */
+ curr_des->txdes3 = cpu_to_le32((unsigned int)packet); /* TXBUF_BADR */
/* only one descriptor on TXBUF */
+ /*
curr_des->txdes0 &= FTGMAC100_TXDES0_EDOTR;
+
curr_des->txdes0 |= FTGMAC100_TXDES0_FTS |
FTGMAC100_TXDES0_LTS |
FTGMAC100_TXDES0_TXBUF_SIZE(length) |
FTGMAC100_TXDES0_TXDMA_OWN ;
+ */
+ curr_des->txdes0 = cpu_to_le32(le32_to_cpu(curr_des->txdes0) & FTGMAC100_TXDES0_EDOTR);
+
+ curr_des->txdes0 = cpu_to_le32(le32_to_cpu(curr_des->txdes0) | (FTGMAC100_TXDES0_FTS |
+ FTGMAC100_TXDES0_LTS |
+ FTGMAC100_TXDES0_TXBUF_SIZE(length) |
+ FTGMAC100_TXDES0_TXDMA_OWN));
/* start transmit */
- writel(1, &ftgmac100->txpd);
+ __raw_writel(1, &ftgmac100->txpd);
+ invalidate_dcache_range((u32) curr_des, (u32) curr_des + sizeof(struct ftgmac100_rxdes));
+
+ /* wait for transfer to succeed */
+ start = get_timer(0);
+
+ while (le32_to_cpu(curr_des->txdes0) & FTGMAC100_TXDES0_TXDMA_OWN) {
+// invalidate_dcache_range((u32) curr_des, (u32) curr_des + sizeof(struct ftgmac100_rxdes));
+ now = get_timer(0);
+ if ( now >= start )
+ diff_time = now - start;
+ else
+ diff_time = now + 0xFFFFFFFF - start;
+ if (diff_time >= 5000) /* 5ms */
+ {
+ debug("%s(): timed out\n", __func__);
+ return -1;
+ }
+ }
debug("%s(): packet sent\n", __func__);
@@ -546,6 +746,61 @@ int ftgmac100_initialize(bd_t *bd)
struct eth_device *dev;
struct ftgmac100_data *priv;
+#if 1 //Ryan Chen for more mac use
+ int i, card_number = 0, mac_no;
+ unsigned int iobase[CONFIG_MAC_NUM];
+
+ mac_no = CONFIG_MAC_NUM;
+ iobase[0] = AST_MAC0_BASE;
+
+#ifdef AST_MAC1_BASE
+ iobase[1] = AST_MAC1_BASE;
+#endif
+ for (i = 0; i < mac_no; i++)
+ {
+ ast_scu_multi_func_eth(i);
+ ast_scu_init_eth(i);
+
+ debug ("FTGMAC100: Device @0x%x\n", iobase[i]);
+
+ dev = malloc(sizeof *dev);
+
+ /* Transmit and receive descriptors should align to 16 bytes */
+ priv = memalign(16, sizeof(struct ftgmac100_data));
+ if (!priv) {
+ printf("%s(): failed to allocate priv\n", __func__);
+ goto free_dev;
+ }
+
+ memset(dev, 0, sizeof(*dev));
+ memset(priv, 0, sizeof(*priv));
+
+ sprintf(dev->name, "FTGMAC100#%d", card_number);
+
+ dev->iobase = iobase[i];
+ dev->init = ftgmac100_init;
+ dev->halt = ftgmac100_halt;
+ dev->send = ftgmac100_send;
+ dev->recv = ftgmac100_recv;
+ dev->priv = priv;
+ dev->write_hwaddr = NULL; //20130209, ryan chen add
+
+ eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+ miiphy_register(dev->name, ftgmac100_reg_read, ftgmac100_reg_write);
+#endif
+
+ /* set the ethernet address */
+ ftgmac100_set_mac_from_env(dev);
+
+ ftgmac100_reset(dev);
+
+ card_number++;
+ }
+ return card_number;
+
+#else
dev = malloc(sizeof *dev);
if (!dev) {
printf("%s(): failed to allocate dev\n", __func__);
@@ -562,8 +817,8 @@ int ftgmac100_initialize(bd_t *bd)
memset(dev, 0, sizeof(*dev));
memset(priv, 0, sizeof(*priv));
- strcpy(dev->name, "FTGMAC100");
- dev->iobase = CONFIG_FTGMAC100_BASE;
+ sprintf(dev->name, "FTGMAC100#0");
+ dev->iobase = AST_MAC0_BASE;
dev->init = ftgmac100_init;
dev->halt = ftgmac100_halt;
dev->send = ftgmac100_send;
@@ -571,13 +826,18 @@ int ftgmac100_initialize(bd_t *bd)
dev->priv = priv;
eth_register(dev);
-
+//////
+ ast_scu_multi_func_eth(0);
+ ast_scu_init_eth(0);
+/////
ftgmac100_reset(dev);
return 1;
+#endif
free_dev:
free(dev);
-out:
+//out:
return 0;
+
}
diff --git a/drivers/net/ftgmac100.h b/drivers/net/ftgmac100.h
index 71121ba9d4..96de3492d6 100644
--- a/drivers/net/ftgmac100.h
+++ b/drivers/net/ftgmac100.h
@@ -31,26 +31,28 @@ struct ftgmac100 {
unsigned int aptc; /* 0x34 */
unsigned int dblac; /* 0x38 */
unsigned int dmafifos; /* 0x3c */
- unsigned int revr; /* 0x40 */
- unsigned int fear; /* 0x44 */
+ unsigned int fear0; /* 0x40 */
+ unsigned int fear1; /* 0x44 */
unsigned int tpafcr; /* 0x48 */
unsigned int rbsr; /* 0x4c */
unsigned int maccr; /* 0x50 */
unsigned int macsr; /* 0x54 */
unsigned int tm; /* 0x58 */
- unsigned int resv1; /* 0x5c */ /* not defined in spec */
+ unsigned int physts; /* 0x5c */ /* not defined in spec */
unsigned int phycr; /* 0x60 */
unsigned int phydata; /* 0x64 */
unsigned int fcr; /* 0x68 */
unsigned int bpr; /* 0x6c */
unsigned int wolcr; /* 0x70 */
unsigned int wolsr; /* 0x74 */
- unsigned int wfcrc; /* 0x78 */
- unsigned int resv2; /* 0x7c */ /* not defined in spec */
- unsigned int wfbm1; /* 0x80 */
- unsigned int wfbm2; /* 0x84 */
- unsigned int wfbm3; /* 0x88 */
- unsigned int wfbm4; /* 0x8c */
+// unsigned int wfcrc; /* 0x78 */
+// unsigned int resv2; /* 0x7c */ /* not defined in spec */
+ unsigned int wfbm1m; /* 0x78 */
+ unsigned int wfbm1l; /* 0x7c */
+ unsigned int wfbm2m; /* 0x80 */
+ unsigned int wfbm2l; /* 0x84 */
+ unsigned int wfbm3m; /* 0x88 */
+ unsigned int wfbm3l; /* 0x8c */
unsigned int nptxr_ptr; /* 0x90 */
unsigned int hptxr_ptr; /* 0x94 */
unsigned int rxr_ptr; /* 0x98 */
@@ -82,6 +84,11 @@ struct ftgmac100 {
#define FTGMAC100_INT_AHB_ERR (1 << 8)
#define FTGMAC100_INT_PHYSTS_CHG (1 << 9)
#define FTGMAC100_INT_NO_HPTXBUF (1 << 10)
+////
+#define FTGMAC100_INT_PHY_CHG (1 << 28)
+#define FTGMAC100_INT_PHY_TIMEOUT (1 << 29)
+#define FTGMAC100_INT_FLAG_ACK (1 << 30)
+#define FTGMAC100_INT_FLAG_REQ (1 << 31)
/*
* Interrupt timer control register
@@ -144,11 +151,12 @@ struct ftgmac100 {
#define FTGMAC100_MACCR_RXMAC_EN (1 << 3)
#define FTGMAC100_MACCR_RM_VLAN (1 << 4)
#define FTGMAC100_MACCR_HPTXR_EN (1 << 5)
-#define FTGMAC100_MACCR_LOOP_EN (1 << 6)
+//#define FTGMAC100_MACCR_LOOP_EN (1 << 6)
#define FTGMAC100_MACCR_ENRX_IN_HALFTX (1 << 7)
#define FTGMAC100_MACCR_FULLDUP (1 << 8)
#define FTGMAC100_MACCR_GIGA_MODE (1 << 9)
#define FTGMAC100_MACCR_CRC_APD (1 << 10)
+#define FTGMAC100_MACCR_LOW_SEN (1 << 11) //new
#define FTGMAC100_MACCR_RX_RUNT (1 << 12)
#define FTGMAC100_MACCR_JUMBO_LF (1 << 13)
#define FTGMAC100_MACCR_RX_ALL (1 << 14)
@@ -159,6 +167,19 @@ struct ftgmac100 {
#define FTGMAC100_MACCR_FAST_MODE (1 << 19)
#define FTGMAC100_MACCR_SW_RST (1 << 31)
+/* */
+#define FTGMAC100_PHY_LINK_UP (1 << 0)
+#define FTGMAC100_PHY_100M_MODE (1 << 2)
+#define FTGMAC100_PHY_FULL_DUPLEX (1 << 1)
+#define FTGMAC100_PHY_1G_MODE (1 << 3)
+
+#define FTGMAC100_PHY_STS_UNVALID (1 << 16)
+
+#define FTGMAC100_PHY_POLL (1 << 28)
+#define FTGMAC100_PHY_LINK (1 << 29)
+#define FTGMAC100_PHY_ACK_EN (1 << 30)
+#define FTGMAC100_PHY_REQ_EN (1 << 31)
+
/*
* PHY control register
*/
@@ -169,12 +190,22 @@ struct ftgmac100 {
#define FTGMAC100_PHYCR_MIIRD (1 << 26)
#define FTGMAC100_PHYCR_MIIWR (1 << 27)
+//New MDC/MDIO
+#define FTGMAC100_PHYCR_NEW_FIRE (1 << 15)
+#define FTGMAC100_PHYCR_ST_22 (1 << 12)
+#define FTGMAC100_PHYCR_NEW_WRITE (1 << 10)
+#define FTGMAC100_PHYCR_NEW_READ (2 << 10)
+#define FTGMAC100_PHYCR_NEW_PHYAD(x) (((x) & 0x1f) << 5)
+#define FTGMAC100_PHYCR_NEW_REGAD(x) ((x) & 0x1f)
+
/*
* PHY data register
*/
#define FTGMAC100_PHYDATA_MIIWDATA(x) ((x) & 0xffff)
#define FTGMAC100_PHYDATA_MIIRDATA(phydata) (((phydata) >> 16) & 0xffff)
+#define FTGMAC100_PHYDATA_NEW_MIIWDATA(x) ((x) & 0xffff)
+
/*
* Transmit descriptor, aligned to 16 bytes
*/
@@ -186,17 +217,18 @@ struct ftgmac100_txdes {
} __attribute__ ((aligned(16)));
#define FTGMAC100_TXDES0_TXBUF_SIZE(x) ((x) & 0x3fff)
-#define FTGMAC100_TXDES0_EDOTR (1 << 15)
+//#define FTGMAC100_TXDES0_EDOTR (1 << 15)
#define FTGMAC100_TXDES0_CRC_ERR (1 << 19)
#define FTGMAC100_TXDES0_LTS (1 << 28)
#define FTGMAC100_TXDES0_FTS (1 << 29)
+#define FTGMAC100_TXDES0_EDOTR (1 << 30) //org is 15 ->30
#define FTGMAC100_TXDES0_TXDMA_OWN (1 << 31)
#define FTGMAC100_TXDES1_VLANTAG_CI(x) ((x) & 0xffff)
#define FTGMAC100_TXDES1_INS_VLANTAG (1 << 16)
-#define FTGMAC100_TXDES1_TCP_CHKSUM (1 << 17)
-#define FTGMAC100_TXDES1_UDP_CHKSUM (1 << 18)
-#define FTGMAC100_TXDES1_IP_CHKSUM (1 << 19)
+//#define FTGMAC100_TXDES1_TCP_CHKSUM (1 << 17)
+//#define FTGMAC100_TXDES1_UDP_CHKSUM (1 << 18)
+//#define FTGMAC100_TXDES1_IP_CHKSUM (1 << 19)
#define FTGMAC100_TXDES1_LLC (1 << 22)
#define FTGMAC100_TXDES1_TX2FIC (1 << 30)
#define FTGMAC100_TXDES1_TXIC (1 << 31)
@@ -212,7 +244,7 @@ struct ftgmac100_rxdes {
} __attribute__ ((aligned(16)));
#define FTGMAC100_RXDES0_VDBC(x) ((x) & 0x3fff)
-#define FTGMAC100_RXDES0_EDORR (1 << 15)
+//#define FTGMAC100_RXDES0_EDORR (1 << 15)
#define FTGMAC100_RXDES0_MULTICAST (1 << 16)
#define FTGMAC100_RXDES0_BROADCAST (1 << 17)
#define FTGMAC100_RXDES0_RX_ERR (1 << 18)
@@ -225,6 +257,7 @@ struct ftgmac100_rxdes {
#define FTGMAC100_RXDES0_PAUSE_FRAME (1 << 25)
#define FTGMAC100_RXDES0_LRS (1 << 28)
#define FTGMAC100_RXDES0_FRS (1 << 29)
+#define FTGMAC100_RXDES0_EDORR (1 << 30) //org 15->30
#define FTGMAC100_RXDES0_RXPKT_RDY (1 << 31)
#define FTGMAC100_RXDES1_VLANTAG_CI 0xffff
OpenPOWER on IntegriCloud