From patchwork Thu Apr 18 09:25:30 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuo-Jung Su X-Patchwork-Id: 237573 X-Patchwork-Delegate: albert.aribaud@free.fr Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 646D52C01D9 for ; Thu, 18 Apr 2013 19:26:07 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 223584A326; Thu, 18 Apr 2013 11:25:49 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id T4tBli5R3-e0; Thu, 18 Apr 2013 11:25:48 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 485264A332; Thu, 18 Apr 2013 11:25:30 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id CC48A4A31C for ; Thu, 18 Apr 2013 11:25:19 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8KSG+zAULTQ8 for ; Thu, 18 Apr 2013 11:25:17 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-pd0-f170.google.com (mail-pd0-f170.google.com [209.85.192.170]) by theia.denx.de (Postfix) with ESMTPS id 5449B4A31E for ; Thu, 18 Apr 2013 11:25:14 +0200 (CEST) Received: by mail-pd0-f170.google.com with SMTP id 10so1417526pdi.29 for ; Thu, 18 Apr 2013 02:25:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:in-reply-to:references; bh=3viaLnEvj3D1iYJ+5sZF17QD0bFn/jTknQZ4jU5GKe0=; b=QAr8zJUdbuynfvDBgwFCRDDWiBm7rtrwYBaN824NyGE0BROiNvDiJlASoH3FbhKJK8 UcKWgkqCmuTjHLNa+wd3DSDiZ7pTePzggXZNa5qVJmO1PB9GDrrb9Icl2VMhOFHNCszi YNGgJUV/FTt8J/f5cCHT5p8paFsbM7gNDJQHV6orrIyNbfCCdDVqkfLNkVzijtajwG/T WCOaWpl51CI31cupBTojwKbTz19sFZcHJ75cjKZdOEtyyPJ6gAXj+kC63PjdJCSqp+sk ww2Ccu2HDqgoaRvTzXr2zeqYDR8LbpkERTd8EA6YOd3IevqVhng8OLA6kvsP8k79qb40 9LYw== X-Received: by 10.69.0.200 with SMTP id ba8mr13282566pbd.4.1366277111180; Thu, 18 Apr 2013 02:25:11 -0700 (PDT) Received: from localhost.localdomain ([220.132.37.35]) by mx.google.com with ESMTPS id xl10sm10280496pac.15.2013.04.18.02.25.09 (version=TLSv1 cipher=DES-CBC3-SHA bits=168/168); Thu, 18 Apr 2013 02:25:10 -0700 (PDT) From: Kuo-Jung Su To: u-boot@lists.denx.de Date: Thu, 18 Apr 2013 17:25:30 +0800 Message-Id: <1366277139-29728-4-git-send-email-dantesu@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1366277139-29728-1-git-send-email-dantesu@gmail.com> References: <1366277139-29728-1-git-send-email-dantesu@gmail.com> In-Reply-To: <1364540788-13943-2-git-send-email-dantesu@gmail.com> References: <1364540788-13943-2-git-send-email-dantesu@gmail.com> Cc: Kuo-Jung Su Subject: [U-Boot] [PATCH v2 03/12] net: add Faraday FTMAC110 10/100Mbps ethernet support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de From: Kuo-Jung Su Faraday FTMAC110 10/100Mbps supports half-word data transfer for Linux. However it has a weird DMA alignment issue: (1) Tx DMA Buffer Address: 1 bytes aligned: Invalid 2 bytes aligned: O.K 4 bytes aligned: O.K (2) Rx DMA Buffer Address: 1 bytes aligned: Invalid 2 bytes aligned: O.K 4 bytes aligned: Invalid!!! Signed-off-by: Kuo-Jung Su CC: Joe Hershberger --- drivers/net/Makefile | 1 + drivers/net/ftmac110.c | 452 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/ftmac110.h | 159 +++++++++++++++++ include/netdev.h | 1 + 4 files changed, 613 insertions(+) create mode 100644 drivers/net/ftmac110.c create mode 100644 drivers/net/ftmac110.h -- 1.7.9.5 diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 786a656..0e23817 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -46,6 +46,7 @@ COBJS-$(CONFIG_ETHOC) += ethoc.o COBJS-$(CONFIG_FEC_MXC) += fec_mxc.o COBJS-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o COBJS-$(CONFIG_FTGMAC100) += ftgmac100.o +COBJS-$(CONFIG_FTMAC110) += ftmac110.o COBJS-$(CONFIG_FTMAC100) += ftmac100.o COBJS-$(CONFIG_GRETH) += greth.o COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o diff --git a/drivers/net/ftmac110.c b/drivers/net/ftmac110.c new file mode 100644 index 0000000..f7b5385 --- /dev/null +++ b/drivers/net/ftmac110.c @@ -0,0 +1,452 @@ +/* + * Faraday 10/100Mbps Ethernet Controller + * + * (C) Copyright 2010 Faraday Technology + * Dante Su + * + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + */ + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) +#include +#endif + +#include "ftmac110.h" + +#define CFG_RXDES_NUM 8 +#define CFG_TXDES_NUM 2 +#define CFG_XBUF_SIZE 1536 + +/*******************************************************************/ +/* FTMAC110 DMA design issue */ +/* Dante Su 2010.02.03 */ +/* */ +/* The DMA engine has a weird restriction that its Rx DMA engine */ +/* accepts only 16-bits aligned address, 32-bits aligned is not */ +/* acceptable. However this restriction does not apply to Tx DMA. */ +/* Conclusion: */ +/* (1) Tx DMA Buffer Address: */ +/* 1 bytes aligned: Invalid */ +/* 2 bytes aligned: O.K */ +/* 4 bytes aligned: O.K (-> u-boot ZeroCopy is possible) */ +/* (2) Rx DMA Buffer Address: */ +/* 1 bytes aligned: Invalid */ +/* 2 bytes aligned: O.K */ +/* 4 bytes aligned: Invalid */ +/*******************************************************************/ + +struct ftmac110_chip { + void *regs; + uint32_t imr; + uint32_t maccr; + uint32_t lnkup; + uint32_t phy_addr; + + struct ftmac110_rxd *rxd; + ulong rxd_dma; + uint32_t rxd_idx; + + struct ftmac110_txd *txd; + ulong txd_dma; + uint32_t txd_idx; +}; + +/* Register access macros */ +#define MAC_READ(r) le32_to_cpu(readl(r)) +#define MAC_WRITE(v, r) writel(cpu_to_le32(v), r) + +static char ftmac110_mac_addr[] = { 0x00, 0x41, 0x71, 0x00, 0x00, 0x52 }; + +static int ftmac110_reset(struct eth_device *dev); + +static uint16_t mdio_read(struct eth_device *dev, + uint8_t phyaddr, uint8_t phyreg) +{ + struct ftmac110_chip *chip = dev->priv; + struct ftmac110_regs *regs = chip->regs; + uint32_t tmp; + + tmp = PHYCR_READ + | (phyaddr << PHYCR_ADDR_SHIFT) + | (phyreg << PHYCR_REG_SHIFT) + | 0x30000000; + + MAC_WRITE(tmp, ®s->phycr); + + do { + tmp = MAC_READ(®s->phycr); + } while (tmp & PHYCR_READ); + + return (uint16_t)(tmp & 0xFFFF); +} + +static void mdio_write(struct eth_device *dev, + uint8_t phyaddr, uint8_t phyreg, uint16_t phydata) +{ + struct ftmac110_chip *chip = dev->priv; + struct ftmac110_regs *regs = chip->regs; + unsigned int tmp; + + tmp = PHYCR_WRITE + | (phyaddr << PHYCR_ADDR_SHIFT) + | (phyreg << PHYCR_REG_SHIFT) + | 0x30000000; + + MAC_WRITE(phydata, ®s->phydr); + MAC_WRITE(tmp, ®s->phycr); + + do { + tmp = MAC_READ(®s->phycr); + } while (tmp & PHYCR_WRITE); +} + +static uint32_t ftmac110_phyqry(struct eth_device *dev) +{ + ulong ts; + uint32_t maccr; + uint16_t pa, tmp; + struct ftmac110_chip *chip = dev->priv; + + maccr = MACCR_100M | MACCR_FD; + + /* 0. find the phy device */ + for (pa = 0; pa < 32; ++pa) { + tmp = mdio_read(dev, pa, MII_PHYSID1); + if (tmp == 0xFFFF || tmp == 0x0000) + continue; + break; + } + if (pa >= 32) { + puts("ftmac110: phy device not found!\n"); + return maccr; + } else { + chip->phy_addr = pa; + } + + /* 1. check link status */ + chip->lnkup = 0; + for (ts = get_timer(0); get_timer(ts) < 1000; ) { + if (mdio_read(dev, chip->phy_addr, MII_BMSR) + & BMSR_LSTATUS) { + chip->lnkup = 1; + break; + } + } + if (!chip->lnkup) { + puts("ftmac110: link down\n"); + goto exit; + } + + /* 2. check A/N status */ + for (ts = get_timer(0); get_timer(ts) < 1000; ) { + if (mdio_read(dev, chip->phy_addr, MII_BMSR) + & BMSR_ANEGCOMPLETE) + break; + } + if (get_timer(ts) >= 1000) { + puts("ftmac110: A/N failed\n"); + goto exit; + } + + /* 3. build MACCR with the PHY status */ + tmp = mdio_read(dev, chip->phy_addr, MII_ADVERTISE); + tmp &= mdio_read(dev, chip->phy_addr, MII_LPA); + + /* 3-1. 10/100Mbps Detection */ + if (tmp & LPA_100FULL) /* 100Mbps full-duplex */ + maccr = MACCR_100M | MACCR_FD; + else if (tmp & LPA_100HALF) /* 100Mbps half-duplex */ + maccr = MACCR_100M; + else if (tmp & LPA_10FULL) /* 10Mbps full-duplex */ + maccr = MACCR_FD; + else if (tmp & LPA_10HALF) /* 10Mbps half-duplex */ + maccr = 0; + else + maccr = MACCR_100M | MACCR_FD; + + printf("ftmac110: %d Mbps, %s\n", + (maccr & MACCR_100M) ? 100 : 10, + (maccr & MACCR_FD) ? "Full" : "half"); + +exit: + return maccr; +} + +static int ftmac110_reset(struct eth_device *dev) +{ + uint8_t *a; + uint32_t i, maccr; + struct ftmac110_chip *chip = dev->priv; + struct ftmac110_regs *regs = chip->regs; + + /* 1. MAC reset */ + MAC_WRITE(MACCR_RESET, ®s->maccr); + while (MAC_READ(®s->maccr) & MACCR_RESET) + ; + + /* 1-1. Init tx ring */ + for (i = 0; i < CFG_TXDES_NUM; ++i) + chip->txd[i].owner = 0; /* owned by SW */ + chip->txd_idx = 0; + + /* 1-2. Init rx ring */ + for (i = 0; i < CFG_RXDES_NUM; ++i) { + chip->rxd[i].owner = 1; /* owned by HW */ + chip->rxd[i].bufsz = cpu_to_le16(CFG_XBUF_SIZE); + } + chip->rxd_idx = 0; + + /* 2. PHY status query */ + maccr = ftmac110_phyqry(dev); + + /* 3. Fix up the MACCR value */ + chip->maccr = maccr | MACCR_CRCAPD | MACCR_RXALL | MACCR_RXRUNT + | MACCR_RXEN | MACCR_TXEN | MACCR_RXDMAEN | MACCR_TXDMAEN; + chip->imr = 0; + + /* 4. MAC address setup */ + a = dev->enetaddr; + MAC_WRITE(a[1] | (a[0] << 8), ®s->mac[0]); + MAC_WRITE(a[5] | (a[4] << 8) | (a[3] << 16) + | (a[2] << 24), ®s->mac[1]); + + /* 5. MAC registers setup */ + MAC_WRITE(chip->rxd_dma, ®s->rxbar); + MAC_WRITE(chip->txd_dma, ®s->txbar); + MAC_WRITE(0x00001010, ®s->itc); + MAC_WRITE(0x00000001, ®s->aptc); + MAC_WRITE(0x00000390, ®s->dblac); + MAC_WRITE(0x000003FF, ®s->isr); + MAC_WRITE(chip->imr, ®s->imr); + MAC_WRITE(chip->maccr, ®s->maccr); + + return 0; +} + +static int ftmac110_probe(struct eth_device *dev, bd_t *bis) +{ + debug("ftmac110: probe\n"); + + if (ftmac110_reset(dev)) + return -1; + + return 0; +} + +static void ftmac110_halt(struct eth_device *dev) +{ + struct ftmac110_chip *chip = dev->priv; + struct ftmac110_regs *regs = chip->regs; + + MAC_WRITE(0, ®s->imr); + MAC_WRITE(0, ®s->maccr); + + debug("ftmac110: halt\n"); +} + +static int ftmac110_send(struct eth_device *dev, void *packet, int length) +{ + struct ftmac110_chip *chip = dev->priv; + struct ftmac110_regs *regs = chip->regs; + struct ftmac110_txd *cur_desc; + + if (!chip->lnkup) + return 0; + + if (length <= 0 || length > CFG_XBUF_SIZE) { + printf("ftmac110: bad tx packet length(%d)\n", length); + return 0; + } + + if (length < 60) + length = 60; + + cur_desc = &chip->txd[chip->txd_idx]; + if (cur_desc->owner) { + /* kick-off Tx DMA */ + MAC_WRITE(0xffffffff, ®s->txpd); + printf("ftmac110: out of txd\n"); + return 0; + } + + memcpy(cur_desc->vbuf, (void *)packet, length); + dma_map_single(cur_desc->vbuf, length, DMA_TO_DEVICE); + + cur_desc->len = cpu_to_le16(length); + cur_desc->lts = 1; + cur_desc->fts = 1; + cur_desc->owner = 1; + + /* kick-off Tx DMA */ + MAC_WRITE(0xffffffff, ®s->txpd); + + chip->txd_idx = (chip->txd_idx + 1) % CFG_TXDES_NUM; + + return length; +} + +static int ftmac110_recv(struct eth_device *dev) +{ + struct ftmac110_chip *chip = dev->priv; + struct ftmac110_rxd *cur_desc; + uint32_t rlen = 0; + uint8_t *buf; + uint16_t len; + + if (!chip->lnkup) + return 0; + + do { + cur_desc = &chip->rxd[chip->rxd_idx]; + if (cur_desc->owner == 1) + break; + + len = le16_to_cpu(cur_desc->len); + buf = cur_desc->vbuf; + + if (cur_desc->error) { + printf("ftmac110: rx error\n"); + } else { + dma_map_single(buf, len, DMA_FROM_DEVICE); + NetReceive(buf, len); + rlen += len; + } + + cur_desc->len = 0; + cur_desc->owner = 1; /* owned by hardware */ + + chip->rxd_idx = (chip->rxd_idx + 1) % CFG_RXDES_NUM; + } while (0); + + return rlen; +} + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) + +static int ftmac110_mdio_read( + const char *devname, uint8_t addr, uint8_t reg, uint16_t *value) +{ + int ret = 0; + struct eth_device *dev; + + dev = eth_get_dev_by_name(devname); + if (dev == NULL) { + printf("%s: no such device\n", devname); + ret = -1; + } else { + *value = mdio_read(dev, addr, reg); + } + + return ret; +} + +static int ftmac110_mdio_write( + const char *devname, uint8_t addr, uint8_t reg, uint16_t value) +{ + int ret = 0; + struct eth_device *dev; + + dev = eth_get_dev_by_name(devname); + if (dev == NULL) { + printf("%s: no such device\n", devname); + ret = -1; + } else { + mdio_write(dev, addr, reg, value); + } + + return ret; +} + +#endif /* #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) */ + +int ftmac110_initialize(bd_t *bis) +{ + int i, card_number = 0; + char enetvar[32]; + struct eth_device *dev; + struct ftmac110_chip *chip; + + dev = malloc(sizeof(*dev) + sizeof(*chip)); + if (dev == NULL) { + panic("ftmac110: out of memory 1\n"); + return -1; + } + chip = (struct ftmac110_chip *)(dev + 1); + memset(dev, 0, sizeof(*dev) + sizeof(*chip)); + + sprintf(dev->name, "FTMAC110#%d", card_number); + + dev->iobase = CONFIG_FTMAC110_BASE; + chip->regs = (void *)dev->iobase; + dev->priv = chip; + dev->init = ftmac110_probe; + dev->halt = ftmac110_halt; + dev->send = ftmac110_send; + dev->recv = ftmac110_recv; + + sprintf(enetvar, card_number ? "eth%daddr" : "ethaddr", card_number); + + if (!eth_getenv_enetaddr(enetvar, dev->enetaddr)) + memcpy(dev->enetaddr, ftmac110_mac_addr, 6); + + /* allocate tx descriptors (it must be 16 bytes aligned) */ + chip->txd = dma_alloc_coherent( + sizeof(struct ftmac110_txd) * CFG_TXDES_NUM, &chip->txd_dma); + if (chip->txd == NULL) + panic("ftmac110: out of memory 3\n"); + memset((void *)chip->txd, 0, + sizeof(struct ftmac110_txd) * CFG_TXDES_NUM); + for (i = 0; i < CFG_TXDES_NUM; ++i) { + void *va = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE); + if (!va) + panic("ftmac110: out of memory 4\n"); + chip->txd[i].vbuf = va; + chip->txd[i].buf = cpu_to_le32(virt_to_phys(va)); + chip->txd[i].len = 0; + chip->txd[i].end = 0; + chip->txd[i].owner = 0; /* owned by SW */ + } + chip->txd[CFG_TXDES_NUM - 1].end = 1; + chip->txd_idx = 0; + + /* allocate rx descriptors (it must be 16 bytes aligned) */ + chip->rxd = dma_alloc_coherent( + sizeof(struct ftmac110_rxd) * CFG_RXDES_NUM, &chip->rxd_dma); + if (!chip->rxd) + panic("ftmac110: out of memory 4\n"); + memset((void *)chip->rxd, 0, + sizeof(struct ftmac110_rxd) * CFG_RXDES_NUM); + for (i = 0; i < CFG_RXDES_NUM; ++i) { + void *va = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE + 2); + if (!va) + panic("ftmac110: out of memory 5\n"); + /* it needs to be exactly 2 bytes aligned */ + va = ((uint8_t *)va + 2); + chip->rxd[i].vbuf = va; + chip->rxd[i].buf = cpu_to_le32(virt_to_phys(va)); + chip->rxd[i].len = 0; + chip->rxd[i].bufsz = cpu_to_le16(CFG_XBUF_SIZE); + chip->rxd[i].end = 0; + chip->rxd[i].owner = 1; /* owned by HW */ + } + chip->rxd[CFG_RXDES_NUM - 1].end = 1; + chip->rxd_idx = 0; + + eth_register(dev); + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) + miiphy_register(dev->name, ftmac110_mdio_read, ftmac110_mdio_write); +#endif + + card_number++; + + return card_number; +} diff --git a/drivers/net/ftmac110.h b/drivers/net/ftmac110.h new file mode 100644 index 0000000..2cf435b --- /dev/null +++ b/drivers/net/ftmac110.h @@ -0,0 +1,159 @@ +/* + * Faraday 10/100Mbps Ethernet Controller + * + * (C) Copyright 2010 Faraday Technology + * Dante Su + * + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + */ + +#ifndef _FTMAC110_H +#define _FTMAC110_H + +struct ftmac110_regs { + uint32_t isr; /* 0x00: Interrups Status Register */ + uint32_t imr; /* 0x04: Interrupt Mask Register */ + uint32_t mac[2]; /* 0x08: MAC Address */ + uint32_t mht[2]; /* 0x10: Multicast Hash Table 0 Register */ + uint32_t txpd; /* 0x18: Transmit Poll Demand Register */ + uint32_t rxpd; /* 0x1c: Receive Poll Demand register */ + uint32_t txbar; /* 0x20: Tx Ring Base Address Register */ + uint32_t rxbar; /* 0x24: Rx Ring Base Address Register */ + uint32_t itc; /* 0x28: Interrupt Timer Control Register */ + uint32_t aptc; /* 0x2C: Automatic Polling Timer Control Register */ + uint32_t dblac; /* 0x30: DMA Burst Length&Arbitration Control */ + uint32_t revr; /* 0x34: Revision Register */ + uint32_t fear; /* 0x38: Feature Register */ + uint32_t rsvd[19]; + uint32_t maccr; /* 0x88: MAC Control Register */ + uint32_t macsr; /* 0x8C: MAC Status Register */ + uint32_t phycr; /* 0x90: PHY Control Register */ + uint32_t phydr; /* 0x94: PHY Data Register */ + uint32_t fcr; /* 0x98: Flow Control Register */ + uint32_t bpr; /* 0x9C: Back Pressure Register */ +}; + +/* Interrupt status/mask register(ISR/IMR) bits */ +#define ISR_PHYSTCHG (1 << 9) /* phy status change */ +#define ISR_AHBERR (1 << 8) /* bus error */ +#define ISR_RXLOST (1 << 7) /* rx lost due to fifo overflow */ +#define ISR_RXFIFO (1 << 6) /* rx to fifo */ +#define ISR_TXLOST (1 << 5) /* tx lost due to collision */ +#define ISR_TXOK (1 << 4) /* tx to ethernet */ +#define ISR_NOTXBUF (1 << 3) /* out of tx buffer */ +#define ISR_TXFIFO (1 << 2) /* packets transmitted to fifo */ +#define ISR_NORXBUF (1 << 1) /* out of rx buffer */ +#define ISR_RXOK (1 << 0) /* packets received to buffer (ram) */ + +/* MACC control bits */ +#define MACCR_100M (1 << 18) /* 100Mbps mode */ +#define MACCR_RXBCST (1 << 17) /* receive all broadcast packet */ +#define MACCR_RXMCST (1 << 16) /* receive all multicast packet */ +#define MACCR_FD (1 << 15) /* full duplex */ +#define MACCR_CRCAPD (1 << 14) /* append crc to transmit packet */ +#define MACCR_RXALL (1 << 12) /* ignore dst address */ +#define MACCR_RXFTL (1 << 11) /* rx packet even it's > 1518 byte */ +#define MACCR_RXRUNT (1 << 10) /* rx packet even it's < 64 byte */ +#define MACCR_RXMCSTHT (1 << 9) /* rx multicast per hash table */ +#define MACCR_RXEN (1 << 8) /* rx enable */ +#define MACCR_RXINHDTX (1 << 6) /* rx in half duplex tx */ +#define MACCR_TXEN (1 << 5) /* tx enable */ +#define MACCR_CRCDIS (1 << 4) /* rx packet even it's crc error */ +#define MACCR_LOOPBACK (1 << 3) /* Internal loop-back */ +#define MACCR_RESET (1 << 2) /* reset */ +#define MACCR_RXDMAEN (1 << 1) /* enable rx dma */ +#define MACCR_TXDMAEN (1 << 0) /* enable tx dma */ + +/* MDIO PHY bits */ +#define PHYCR_READ (1 << 26) +#define PHYCR_WRITE (1 << 27) +#define PHYCR_REG_SHIFT 21 +#define PHYCR_ADDR_SHIFT 16 + +/* + * descriptor structure + */ +struct ftmac110_rxd { + /* RXDES0 */ +#ifdef __ARMEB__ + uint32_t owner:1; /* BIT: 31 - 1:Hardware, 0: Software */ + uint32_t rsvd3:1; + uint32_t frs:1; + uint32_t lrs:1; + uint32_t rsvd2:5; + uint32_t error:5; + uint32_t bcast:1; + uint32_t mcast:1; + uint32_t rsvd1:5; + uint32_t len:11; +#else + uint32_t len:11; + uint32_t rsvd1:5; + uint32_t mcast:1; + uint32_t bcast:1; + uint32_t error:5; + uint32_t rsvd2:5; + uint32_t lrs:1; + uint32_t frs:1; + uint32_t rsvd3:1; + uint32_t owner:1; /* BIT: 31 - 1:Hardware, 0: Software */ +#endif + + /* RXDES1 */ +#ifdef __ARMEB__ + uint32_t end:1; + uint32_t rsvd4:20; + uint32_t bufsz:11; +#else + uint32_t bufsz:11; + uint32_t rsvd4:20; + uint32_t end:1; +#endif + + /* RXDES2 */ + uint32_t buf; + + /* RXDES3 */ + void *vbuf; /* It's not used in HW */ +}; + +struct ftmac110_txd { + /* TXDES0 */ +#ifdef __ARMEB__ + uint32_t owner:1; /* BIT: 31 - 1:Hardware, 0: Software */ + uint32_t rsvd1:29; + uint32_t collision:2; +#else + uint32_t collision:2; + uint32_t rsvd1:29; + uint32_t owner:1; /* BIT: 31 - 1:Hardware, 0: Software */ +#endif + + /* TXDES1 */ +#ifdef __ARMEB__ + uint32_t end:1; + uint32_t txic:1; + uint32_t tx2fic:1; + uint32_t fts:1; + uint32_t lts:1; + uint32_t rsvd2:16; + uint32_t len:11; +#else + uint32_t len:11; + uint32_t rsvd2:16; + uint32_t lts:1; + uint32_t fts:1; + uint32_t tx2fic:1; + uint32_t txic:1; + uint32_t end:1; +#endif + + /* TXDES2 */ + uint32_t buf; + + /* TXDES3 */ + void *vbuf; /* It's not used in HW */ +}; + +#endif /* FTMAC110_H */ diff --git a/include/netdev.h b/include/netdev.h index fd3e243..48c2fe5 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -67,6 +67,7 @@ int fecmxc_initialize(bd_t *bis); int fecmxc_initialize_multi(bd_t *bis, int dev_id, int phy_id, uint32_t addr); int ftgmac100_initialize(bd_t *bits); int ftmac100_initialize(bd_t *bits); +int ftmac110_initialize(bd_t *bits); int greth_initialize(bd_t *bis); void gt6426x_eth_initialize(bd_t *bis); int inca_switch_initialize(bd_t *bis);