Merge branch 'master' of git://git.denx.de/u-boot-net

This commit is contained in:
Wolfgang Denk 2010-02-03 20:10:20 +01:00
commit 05c2f4fe29
45 changed files with 2608 additions and 770 deletions

10
README
View File

@ -822,6 +822,16 @@ The following options need to be configured:
- NETWORK Support (other):
CONFIG_DRIVER_AT91EMAC
Support for AT91RM9200 EMAC.
CONFIG_RMII
Define this to use reduced MII inteface
CONFIG_DRIVER_AT91EMAC_QUIET
If this defined, the driver is quiet.
The driver doen't show link status messages.
CONFIG_DRIVER_LAN91C96
Support for SMSC's LAN91C96 chips.

View File

@ -23,9 +23,15 @@
*/
#include <common.h>
#include <exports.h>
#include <netdev.h>
#include <asm/arch/AT91RM9200.h>
#include <asm/io.h>
#if defined(CONFIG_DRIVER_ETHER)
#include <at91rm9200_net.h>
#include <dm9161.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
@ -95,6 +101,15 @@ void at91rm9200_GetPhyInterface(AT91PS_PhyOps p_phyops)
#endif
#endif /* CONFIG_DRIVER_ETHER */
#ifdef CONFIG_DRIVER_AT91EMAC
int board_eth_init(bd_t *bis)
{
int rc = 0;
rc = at91emac_register(bis, 0);
return rc;
}
#endif
/*
* Disk On Chip (NAND) Millenium initialization.
* The NAND lives in the CS2* space

View File

@ -23,9 +23,14 @@
*/
#include <common.h>
#include <exports.h>
#include <netdev.h>
#include <asm/arch/AT91RM9200.h>
#include <asm/io.h>
#if defined(CONFIG_DRIVER_ETHER)
#include <at91rm9200_net.h>
#include <dm9161.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
@ -84,3 +89,12 @@ void at91rm9200_GetPhyInterface(AT91PS_PhyOps p_phyops)
p_phyops->AutoNegotiate = dm9161_AutoNegotiate;
}
#endif
#ifdef CONFIG_DRIVER_AT91EMAC
int board_eth_init(bd_t *bis)
{
int rc = 0;
rc = at91emac_register(bis, 0);
return rc;
}
#endif

View File

@ -30,8 +30,12 @@
#include <common.h>
#include <asm/mach-types.h>
#include <asm/arch/AT91RM9200.h>
#include <asm/io.h>
#include <netdev.h>
#if defined(CONFIG_DRIVER_ETHER)
#include <at91rm9200_net.h>
#include <dm9161.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
@ -177,3 +181,12 @@ void at91rm9200_GetPhyInterface(AT91PS_PhyOps p_phyops)
#endif
#endif /* CONFIG_DRIVER_ETHER */
#ifdef CONFIG_DRIVER_AT91EMAC
int board_eth_init(bd_t *bis)
{
int rc = 0;
rc = at91emac_register(bis, 0);
return rc;
}
#endif

View File

@ -23,8 +23,12 @@
#include <common.h>
#include <asm/arch/AT91RM9200.h>
#include <netdev.h>
#include <asm/io.h>
#if defined(CONFIG_DRIVER_ETHER)
#include <at91rm9200_net.h>
#include <bcm5221.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
@ -79,3 +83,12 @@ void at91rm9200_GetPhyInterface(AT91PS_PhyOps p_phyops)
#endif
#endif /* CONFIG_DRIVER_ETHER */
#ifdef CONFIG_DRIVER_AT91EMAC
int board_eth_init(bd_t *bis)
{
int rc = 0;
rc = at91emac_register(bis, 0);
return rc;
}
#endif

View File

@ -26,9 +26,14 @@
*/
#include <common.h>
#include <netdev.h>
#include <asm/arch/AT91RM9200.h>
#include <asm/io.h>
#if defined(CONFIG_DRIVER_ETHER)
#include <at91rm9200_net.h>
#include <ks8721.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
@ -79,3 +84,12 @@ void at91rm9200_GetPhyInterface(AT91PS_PhyOps p_phyops)
#endif /* CONFIG_CMD_NET */
#endif /* CONFIG_DRIVER_ETHER */
#ifdef CONFIG_DRIVER_AT91EMAC
int board_eth_init(bd_t *bis)
{
int rc = 0;
rc = at91emac_register(bis, 0);
return rc;
}
#endif

View File

@ -159,7 +159,8 @@ int board_eth_init(bd_t *bd)
int i;
for (i = 0; i < ARRAY_SIZE(uec_info); i++)
uec_info[i].enet_interface = ENET_1000_RGMII_RXID;
uec_info[i].enet_interface_type = RGMII_RXID;
uec_info[i].speed = 1000;
}
return uec_eth_init(bd, uec_info, ARRAY_SIZE(uec_info));
}

View File

@ -28,8 +28,12 @@
#include <common.h>
#include <asm/arch/AT91RM9200.h>
#include <asm/io.h>
#include <netdev.h>
#if defined(CONFIG_DRIVER_ETHER)
#include <at91rm9200_net.h>
#include <lxt971a.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
@ -92,3 +96,12 @@ void at91rm9200_GetPhyInterface(AT91PS_PhyOps p_phyops)
#endif
#endif /* CONFIG_DRIVER_ETHER */
#ifdef CONFIG_DRIVER_AT91EMAC
int board_eth_init(bd_t *bis)
{
int rc = 0;
rc = at91emac_register(bis, 0);
return rc;
}
#endif

View File

@ -24,8 +24,13 @@
*/
#include <common.h>
#include <asm/io.h>
#include <netdev.h>
#if defined(CONFIG_DRIVER_ETHER)
#include <at91rm9200_net.h>
#include <dm9161.h>
#endif
#include "m501sk.h"
#include "net.h"
@ -186,4 +191,13 @@ void at91rm9200_GetPhyInterface(AT91PS_PhyOps p_phyops)
}
#endif /* CONFIG_CMD_NET */
#endif /* CONFIG_DRIVER_ETHER */
#ifdef CONFIG_DRIVER_AT91EMAC
int board_eth_init(bd_t *bis)
{
int rc = 0;
rc = at91emac_register(bis, 0);
return rc;
}
#endif
#endif /* CONFIG_M501SK */

View File

@ -27,8 +27,12 @@
#include <common.h>
#include <asm/arch/AT91RM9200.h>
#include <netdev.h>
#include <asm/io.h>
#if defined(CONFIG_DRIVER_ETHER)
#include <at91rm9200_net.h>
#include <dm9161.h>
#endif
#include <asm/mach-types.h>
DECLARE_GLOBAL_DATA_PTR;
@ -83,3 +87,12 @@ void at91rm9200_GetPhyInterface(AT91PS_PhyOps p_phyops)
#endif
#endif /* CONFIG_DRIVER_ETHER */
#ifdef CONFIG_DRIVER_AT91EMAC
int board_eth_init(bd_t *bis)
{
int rc = 0;
rc = at91emac_register(bis, 0);
return rc;
}
#endif

View File

@ -28,10 +28,10 @@
#include <at91rm9200_net.h>
#include <net.h>
#include <bcm5221.h>
#ifdef CONFIG_DRIVER_ETHER
#include <bcm5221.h>
#if defined(CONFIG_CMD_NET)
/*

View File

@ -23,9 +23,8 @@
#include <at91rm9200_net.h>
#include <net.h>
#include <dm9161.h>
#ifdef CONFIG_DRIVER_ETHER
#include <dm9161.h>
#if defined(CONFIG_CMD_NET)

View File

@ -27,6 +27,7 @@ LIB := $(obj)libnet.a
COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o
COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o
COBJS-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o
COBJS-$(CONFIG_BCM570x) += bcm570x.o bcm570x_autoneg.o 5701rls.o
COBJS-$(CONFIG_BFIN_MAC) += bfin_mac.o
@ -37,6 +38,7 @@ COBJS-$(CONFIG_DNET) += dnet.o
COBJS-$(CONFIG_E1000) += e1000.o
COBJS-$(CONFIG_EEPRO100) += eepro100.o
COBJS-$(CONFIG_ENC28J60) += enc28j60.o
COBJS-$(CONFIG_EP93XX) += ep93xx_eth.o
COBJS-$(CONFIG_FEC_MXC) += fec_mxc.o
COBJS-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o
COBJS-$(CONFIG_FTMAC100) += ftmac100.o

498
drivers/net/at91_emac.c Normal file
View File

@ -0,0 +1,498 @@
/*
* Copyright (C) 2009 BuS Elektronik GmbH & Co. KG
* Jens Scharsig (esw@bus-elektronik.de)
*
* (C) Copyright 2003
* Author : Hamid Ikdoumi (Atmel)
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/io.h>
#ifndef CONFIG_AT91_LEGACY
#include <asm/arch/hardware.h>
#include <asm/arch/at91_emac.h>
#include <asm/arch/at91_pmc.h>
#include <asm/arch/at91_pio.h>
#else
/* remove next 5 lines, if all RM9200 boards convert to at91 arch */
#include <asm/arch-at91/at91rm9200.h>
#include <asm/arch-at91/hardware.h>
#include <asm/arch-at91/at91_emac.h>
#include <asm/arch-at91/at91_pmc.h>
#include <asm/arch-at91/at91_pio.h>
#endif
#include <net.h>
#include <netdev.h>
#include <malloc.h>
#include <miiphy.h>
#include <linux/mii.h>
#undef MII_DEBUG
#undef ET_DEBUG
#if (CONFIG_SYS_RX_ETH_BUFFER > 1024)
#error AT91 EMAC supports max 1024 RX buffers. \
Please decrease the CONFIG_SYS_RX_ETH_BUFFER value
#endif
/* MDIO clock must not exceed 2.5 MHz, so enable MCK divider */
#if (AT91C_MASTER_CLOCK > 80000000)
#define HCLK_DIV AT91_EMAC_CFG_MCLK_64
#elif (AT91C_MASTER_CLOCK > 40000000)
#define HCLK_DIV AT91_EMAC_CFG_MCLK_32
#elif (AT91C_MASTER_CLOCK > 20000000)
#define HCLK_DIV AT91_EMAC_CFG_MCLK_16
#else
#define HCLK_DIV AT91_EMAC_CFG_MCLK_8
#endif
#ifdef ET_DEBUG
#define DEBUG_AT91EMAC(...) printf(__VA_ARGS__);
#else
#define DEBUG_AT91EMAC(...)
#endif
#ifdef MII_DEBUG
#define DEBUG_AT91PHY(...) printf(__VA_ARGS__);
#else
#define DEBUG_AT91PHY(...)
#endif
#ifndef CONFIG_DRIVER_AT91EMAC_QUIET
#define VERBOSEP(...) printf(__VA_ARGS__);
#else
#define VERBOSEP(...)
#endif
#define RBF_ADDR 0xfffffffc
#define RBF_OWNER (1<<0)
#define RBF_WRAP (1<<1)
#define RBF_BROADCAST (1<<31)
#define RBF_MULTICAST (1<<30)
#define RBF_UNICAST (1<<29)
#define RBF_EXTERNAL (1<<28)
#define RBF_UNKOWN (1<<27)
#define RBF_SIZE 0x07ff
#define RBF_LOCAL4 (1<<26)
#define RBF_LOCAL3 (1<<25)
#define RBF_LOCAL2 (1<<24)
#define RBF_LOCAL1 (1<<23)
#define RBF_FRAMEMAX CONFIG_SYS_RX_ETH_BUFFER
#define RBF_FRAMELEN 0x600
typedef struct {
unsigned long addr, size;
} rbf_t;
typedef struct {
rbf_t rbfdt[RBF_FRAMEMAX];
unsigned long rbindex;
} emac_device;
void at91emac_EnableMDIO(at91_emac_t *at91mac)
{
/* Mac CTRL reg set for MDIO enable */
writel(readl(&at91mac->ctl) | AT91_EMAC_CTL_MPE, &at91mac->ctl);
}
void at91emac_DisableMDIO(at91_emac_t *at91mac)
{
/* Mac CTRL reg set for MDIO disable */
writel(readl(&at91mac->ctl) & ~AT91_EMAC_CTL_MPE, &at91mac->ctl);
}
int at91emac_read(at91_emac_t *at91mac, unsigned char addr,
unsigned char reg, unsigned short *value)
{
at91emac_EnableMDIO(at91mac);
writel(AT91_EMAC_MAN_HIGH | AT91_EMAC_MAN_RW_R |
AT91_EMAC_MAN_REGA(reg) | AT91_EMAC_MAN_CODE_802_3 |
AT91_EMAC_MAN_PHYA(addr),
&at91mac->man);
udelay(10000);
*value = readl(&at91mac->man) & AT91_EMAC_MAN_DATA_MASK;
at91emac_DisableMDIO(at91mac);
DEBUG_AT91PHY("AT91PHY read %x REG(%d)=%x\n", at91mac, reg, *value)
return 0;
}
int at91emac_write(at91_emac_t *at91mac, unsigned char addr,
unsigned char reg, unsigned short value)
{
DEBUG_AT91PHY("AT91PHY write %x REG(%d)=%x\n", at91mac, reg, &value)
at91emac_EnableMDIO(at91mac);
writel(AT91_EMAC_MAN_HIGH | AT91_EMAC_MAN_RW_W |
AT91_EMAC_MAN_REGA(reg) | AT91_EMAC_MAN_CODE_802_3 |
AT91_EMAC_MAN_PHYA(addr) | (value & AT91_EMAC_MAN_DATA_MASK),
&at91mac->man);
udelay(10000);
at91emac_DisableMDIO(at91mac);
return 0;
}
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
at91_emac_t *get_emacbase_by_name(char *devname)
{
struct eth_device *netdev;
netdev = eth_get_dev_by_name(devname);
return (at91_emac_t *) netdev->iobase;
}
int at91emac_mii_read(char *devname, unsigned char addr,
unsigned char reg, unsigned short *value)
{
at91_emac_t *emac;
emac = get_emacbase_by_name(devname);
at91emac_read(emac , addr, reg, value);
return 0;
}
int at91emac_mii_write(char *devname, unsigned char addr,
unsigned char reg, unsigned short value)
{
at91_emac_t *emac;
emac = get_emacbase_by_name(devname);
at91emac_write(emac, addr, reg, value);
return 0;
}
#endif
static int at91emac_phy_reset(struct eth_device *netdev)
{
int i;
u16 status, adv;
at91_emac_t *emac;
emac = (at91_emac_t *) netdev->iobase;
adv = ADVERTISE_CSMA | ADVERTISE_ALL;
at91emac_write(emac, 0, MII_ADVERTISE, adv);
VERBOSEP("%s: Starting autonegotiation...\n", netdev->name);
at91emac_write(emac, 0, MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART));
for (i = 0; i < 100000 / 100; i++) {
at91emac_read(emac, 0, MII_BMSR, &status);
if (status & BMSR_ANEGCOMPLETE)
break;
udelay(100);
}
if (status & BMSR_ANEGCOMPLETE) {
VERBOSEP("%s: Autonegotiation complete\n", netdev->name);
} else {
printf("%s: Autonegotiation timed out (status=0x%04x)\n",
netdev->name, status);
return 1;
}
return 0;
}
static int at91emac_phy_init(struct eth_device *netdev)
{
u16 phy_id, status, adv, lpa;
int media, speed, duplex;
int i;
at91_emac_t *emac;
emac = (at91_emac_t *) netdev->iobase;
/* Check if the PHY is up to snuff... */
at91emac_read(emac, 0, MII_PHYSID1, &phy_id);
if (phy_id == 0xffff) {
printf("%s: No PHY present\n", netdev->name);
return 1;
}
at91emac_read(emac, 0, MII_BMSR, &status);
if (!(status & BMSR_LSTATUS)) {
/* Try to re-negotiate if we don't have link already. */
if (at91emac_phy_reset(netdev))
return 2;
for (i = 0; i < 100000 / 100; i++) {
at91emac_read(emac, 0, MII_BMSR, &status);
if (status & BMSR_LSTATUS)
break;
udelay(100);
}
}
if (!(status & BMSR_LSTATUS)) {
VERBOSEP("%s: link down\n", netdev->name);
return 3;
} else {
at91emac_read(emac, 0, MII_ADVERTISE, &adv);
at91emac_read(emac, 0, MII_LPA, &lpa);
media = mii_nway_result(lpa & adv);
speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
? 1 : 0);
duplex = (media & ADVERTISE_FULL) ? 1 : 0;
VERBOSEP("%s: link up, %sMbps %s-duplex\n",
netdev->name,
speed ? "100" : "10",
duplex ? "full" : "half");
}
return 0;
}
int at91emac_UpdateLinkSpeed(at91_emac_t *emac)
{
unsigned short stat1;
at91emac_read(emac, 0, MII_BMSR, &stat1);
if (!(stat1 & BMSR_LSTATUS)) /* link status up? */
return 1;
if (stat1 & BMSR_100FULL) {
/*set Emac for 100BaseTX and Full Duplex */
writel(readl(&emac->cfg) |
AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD,
&emac->cfg);
return 0;
}
if (stat1 & BMSR_10FULL) {
/*set MII for 10BaseT and Full Duplex */
writel((readl(&emac->cfg) &
~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD)
) | AT91_EMAC_CFG_FD,
&emac->cfg);
return 0;
}
if (stat1 & BMSR_100HALF) {
/*set MII for 100BaseTX and Half Duplex */
writel((readl(&emac->cfg) &
~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD)
) | AT91_EMAC_CFG_SPD,
&emac->cfg);
return 0;
}
if (stat1 & BMSR_10HALF) {
/*set MII for 10BaseT and Half Duplex */
writel((readl(&emac->cfg) &
~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD)),
&emac->cfg);
return 0;
}
return 1;
}
static int at91emac_init(struct eth_device *netdev, bd_t *bd)
{
int i;
u32 value;
emac_device *dev;
at91_emac_t *emac;
at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE;
at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
emac = (at91_emac_t *) netdev->iobase;
dev = (emac_device *) netdev->priv;
/* PIO Disable Register */
value = AT91_PMX_AA_EMDIO | AT91_PMX_AA_EMDC |
AT91_PMX_AA_ERXER | AT91_PMX_AA_ERX1 |
AT91_PMX_AA_ERX0 | AT91_PMX_AA_ECRS |
AT91_PMX_AA_ETX1 | AT91_PMX_AA_ETX0 |
AT91_PMX_AA_ETXEN | AT91_PMX_AA_EREFCK;
writel(value, &pio->pioa.pdr);
writel(value, &pio->pioa.asr);
#ifdef CONFIG_RMII
value = AT91_PMX_BA_ERXCK;
#else
value = AT91_PMX_BA_ERXCK | AT91_PMX_BA_ECOL |
AT91_PMX_BA_ERXDV | AT91_PMX_BA_ERX3 |
AT91_PMX_BA_ERX2 | AT91_PMX_BA_ETXER |
AT91_PMX_BA_ETX3 | AT91_PMX_BA_ETX2;
#endif
writel(value, &pio->piob.pdr);
writel(value, &pio->piob.bsr);
writel(1 << AT91_ID_EMAC, &pmc->pcer);
writel(readl(&emac->ctl) | AT91_EMAC_CTL_CSR, &emac->ctl);
DEBUG_AT91EMAC("init MAC-ADDR %x%x \n",
cpu_to_le16(*((u16 *)(netdev->enetaddr + 4))),
cpu_to_le32(*((u32 *)netdev->enetaddr)));
writel(cpu_to_le32(*((u32 *)netdev->enetaddr)), &emac->sa2l);
writel(cpu_to_le16(*((u16 *)(netdev->enetaddr + 4))), &emac->sa2h);
DEBUG_AT91EMAC("init MAC-ADDR %x%x \n",
readl(&emac->sa2h), readl(&emac->sa2l));
/* Init Ethernet buffers */
for (i = 0; i < RBF_FRAMEMAX; i++) {
dev->rbfdt[i].addr = (unsigned long) NetRxPackets[i];
dev->rbfdt[i].size = 0;
}
dev->rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP;
dev->rbindex = 0;
writel((u32) &(dev->rbfdt[0]), &emac->rbqp);
writel(readl(&emac->rsr) &
~(AT91_EMAC_RSR_OVR | AT91_EMAC_RSR_REC | AT91_EMAC_RSR_BNA),
&emac->rsr);
value = AT91_EMAC_CFG_CAF | AT91_EMAC_CFG_NBC |
HCLK_DIV;
#ifdef CONFIG_RMII
value |= AT91C_EMAC_RMII;
#endif
writel(value, &emac->cfg);
writel(readl(&emac->ctl) | AT91_EMAC_CTL_TE | AT91_EMAC_CTL_RE,
&emac->ctl);
if (!at91emac_phy_init(netdev)) {
at91emac_UpdateLinkSpeed(emac);
return 0;
}
return 1;
}
static void at91emac_halt(struct eth_device *netdev)
{
at91_emac_t *emac;
emac = (at91_emac_t *) netdev->iobase;
writel(readl(&emac->ctl) & ~(AT91_EMAC_CTL_TE | AT91_EMAC_CTL_RE),
&emac->ctl);
DEBUG_AT91EMAC("halt MAC\n");
}
static int at91emac_send(struct eth_device *netdev, volatile void *packet,
int length)
{
at91_emac_t *emac;
emac = (at91_emac_t *) netdev->iobase;
while (!(readl(&emac->tsr) & AT91_EMAC_TSR_BNQ))
;
writel((u32) packet, &emac->tar);
writel(AT91_EMAC_TCR_LEN(length), &emac->tcr);
while (AT91_EMAC_TCR_LEN(readl(&emac->tcr)))
;
DEBUG_AT91EMAC("Send %d \n", length);
writel(readl(&emac->tsr) | AT91_EMAC_TSR_COMP, &emac->tsr);
return 0;
}
static int at91emac_recv(struct eth_device *netdev)
{
emac_device *dev;
at91_emac_t *emac;
rbf_t *rbfp;
int size;
emac = (at91_emac_t *) netdev->iobase;
dev = (emac_device *) netdev->priv;
rbfp = &dev->rbfdt[dev->rbindex];
while (rbfp->addr & RBF_OWNER) {
size = rbfp->size & RBF_SIZE;
NetReceive(NetRxPackets[dev->rbindex], size);
DEBUG_AT91EMAC("Recv[%d]: %d bytes @ %x \n",
dev->rbindex, size, rbfp->addr);
rbfp->addr &= ~RBF_OWNER;
rbfp->size = 0;
if (dev->rbindex < (RBF_FRAMEMAX-1))
dev->rbindex++;
else
dev->rbindex = 0;
rbfp = &(dev->rbfdt[dev->rbindex]);
if (!(rbfp->addr & RBF_OWNER))
writel(readl(&emac->rsr) | AT91_EMAC_RSR_REC,
&emac->rsr);
}
if (readl(&emac->isr) & AT91_EMAC_IxR_RBNA) {
/* EMAC silicon bug 41.3.1 workaround 1 */
writel(readl(&emac->ctl) & ~AT91_EMAC_CTL_RE, &emac->ctl);
writel(readl(&emac->ctl) | AT91_EMAC_CTL_RE, &emac->ctl);
dev->rbindex = 0;
printf("%s: reset receiver (EMAC dead lock bug)\n",
netdev->name);
}
return 0;
}
int at91emac_register(bd_t *bis, unsigned long iobase)
{
emac_device *emac;
emac_device *emacfix;
struct eth_device *dev;
if (iobase == 0)
iobase = AT91_EMAC_BASE;
emac = malloc(sizeof(*emac)+512);
if (emac == NULL)
return 1;
dev = malloc(sizeof(*dev));
if (dev == NULL) {
free(emac);
return 1;
}
/* alignment as per Errata (64 bytes) is insufficient! */
emacfix = (emac_device *) (((unsigned long) emac + 0x1ff) & 0xFFFFFE00);
memset(emacfix, 0, sizeof(emac_device));
memset(dev, 0, sizeof(*dev));
#ifndef CONFIG_RMII
sprintf(dev->name, "AT91 EMAC");
#else
sprintf(dev->name, "AT91 EMAC RMII");
#endif
dev->iobase = iobase;
dev->priv = emacfix;
dev->init = at91emac_init;
dev->halt = at91emac_halt;
dev->send = at91emac_send;
dev->recv = at91emac_recv;
eth_register(dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, at91emac_mii_read, at91emac_mii_write);
#endif
return 1;
}

View File

@ -308,14 +308,13 @@ int cs8900_initialize(u8 dev_num, int base_addr)
dev = malloc(sizeof(*dev));
if (!dev) {
free(dev);
return 0;
}
memset(dev, 0, sizeof(*dev));
priv = malloc(sizeof(*priv));
if (!priv) {
free(priv);
free(dev);
return 0;
}
memset(priv, 0, sizeof(*priv));

View File

@ -42,10 +42,17 @@
#include <miiphy.h>
#include <malloc.h>
#include <asm/arch/emac_defs.h>
#include <asm/io.h>
unsigned int emac_dbg = 0;
#define debug_emac(fmt,args...) if (emac_dbg) printf(fmt,##args)
#ifdef DAVINCI_EMAC_GIG_ENABLE
#define emac_gigabit_enable() davinci_eth_gigabit_enable()
#else
#define emac_gigabit_enable() /* no gigabit to enable */
#endif
static void davinci_eth_mdio_enable(void);
static int gen_init_phy(int phy_addr);
@ -99,12 +106,14 @@ static void davinci_eth_mdio_enable(void)
clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
adap_mdio->CONTROL = (clkdiv & 0xff) |
MDIO_CONTROL_ENABLE |
MDIO_CONTROL_FAULT |
MDIO_CONTROL_FAULT_ENABLE;
writel((clkdiv & 0xff) |
MDIO_CONTROL_ENABLE |
MDIO_CONTROL_FAULT |
MDIO_CONTROL_FAULT_ENABLE,
&adap_mdio->CONTROL);
while (adap_mdio->CONTROL & MDIO_CONTROL_IDLE) {;}
while (readl(&adap_mdio->CONTROL) & MDIO_CONTROL_IDLE)
;
}
/*
@ -119,7 +128,8 @@ static int davinci_eth_phy_detect(void)
active_phy_addr = 0xff;
if ((phy_act_state = adap_mdio->ALIVE) == 0)
phy_act_state = readl(&adap_mdio->ALIVE) & EMAC_MDIO_PHY_MASK;
if (phy_act_state == 0)
return(0); /* No active PHYs */
debug_emac("davinci_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state);
@ -144,15 +154,18 @@ int davinci_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
{
int tmp;
while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
;
adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
MDIO_USERACCESS0_WRITE_READ |
((reg_num & 0x1f) << 21) |
((phy_addr & 0x1f) << 16);
writel(MDIO_USERACCESS0_GO |
MDIO_USERACCESS0_WRITE_READ |
((reg_num & 0x1f) << 21) |
((phy_addr & 0x1f) << 16),
&adap_mdio->USERACCESS0);
/* Wait for command to complete */
while ((tmp = adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) {;}
while ((tmp = readl(&adap_mdio->USERACCESS0)) & MDIO_USERACCESS0_GO)
;
if (tmp & MDIO_USERACCESS0_ACK) {
*data = tmp & 0xffff;
@ -167,16 +180,19 @@ int davinci_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
int davinci_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
{
while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
;
adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO |
MDIO_USERACCESS0_WRITE_WRITE |
((reg_num & 0x1f) << 21) |
((phy_addr & 0x1f) << 16) |
(data & 0xffff);
writel(MDIO_USERACCESS0_GO |
MDIO_USERACCESS0_WRITE_WRITE |
((reg_num & 0x1f) << 21) |
((phy_addr & 0x1f) << 16) |
(data & 0xffff),
&adap_mdio->USERACCESS0);
/* Wait for command to complete */
while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;}
while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
;
return(1);
}
@ -245,9 +261,24 @@ static int davinci_mii_phy_write(char *devname, unsigned char addr, unsigned cha
{
return(davinci_eth_phy_write(addr, reg, value) ? 0 : 1);
}
#endif
static void __attribute__((unused)) davinci_eth_gigabit_enable(void)
{
u_int16_t data;
if (davinci_eth_phy_read(EMAC_MDIO_PHY_NUM, 0, &data)) {
if (data & (1 << 6)) { /* speed selection MSB */
/*
* Check if link detected is giga-bit
* If Gigabit mode detected, enable gigbit in MAC
*/
writel(EMAC_MACCONTROL_GIGFORCE |
EMAC_MACCONTROL_GIGABIT_ENABLE,
&adap_emac->MACCONTROL);
}
}
}
/* Eth device open */
static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
@ -255,64 +286,73 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
dv_reg_p addr;
u_int32_t clkdiv, cnt;
volatile emac_desc *rx_desc;
unsigned long mac_hi;
unsigned long mac_lo;
debug_emac("+ emac_open\n");
/* Reset EMAC module and disable interrupts in wrapper */
adap_emac->SOFTRESET = 1;
while (adap_emac->SOFTRESET != 0) {;}
adap_ewrap->EWCTL = 0;
writel(1, &adap_emac->SOFTRESET);
while (readl(&adap_emac->SOFTRESET) != 0)
;
#if defined(DAVINCI_EMAC_VERSION2)
writel(1, &adap_ewrap->softrst);
while (readl(&adap_ewrap->softrst) != 0)
;
#else
writel(0, &adap_ewrap->EWCTL);
for (cnt = 0; cnt < 5; cnt++) {
clkdiv = adap_ewrap->EWCTL;
clkdiv = readl(&adap_ewrap->EWCTL);
}
#endif
rx_desc = emac_rx_desc;
adap_emac->TXCONTROL = 0x01;
adap_emac->RXCONTROL = 0x01;
writel(1, &adap_emac->TXCONTROL);
writel(1, &adap_emac->RXCONTROL);
/* Set MAC Addresses & Init multicast Hash to 0 (disable any multicast receive) */
/* Using channel 0 only - other channels are disabled */
adap_emac->MACINDEX = 0;
adap_emac->MACADDRHI =
(davinci_eth_mac_addr[3] << 24) |
(davinci_eth_mac_addr[2] << 16) |
(davinci_eth_mac_addr[1] << 8) |
(davinci_eth_mac_addr[0]);
adap_emac->MACADDRLO =
(davinci_eth_mac_addr[5] << 8) |
(davinci_eth_mac_addr[4]);
writel(0, &adap_emac->MACINDEX);
mac_hi = (davinci_eth_mac_addr[3] << 24) |
(davinci_eth_mac_addr[2] << 16) |
(davinci_eth_mac_addr[1] << 8) |
(davinci_eth_mac_addr[0]);
mac_lo = (davinci_eth_mac_addr[5] << 8) |
(davinci_eth_mac_addr[4]);
adap_emac->MACHASH1 = 0;
adap_emac->MACHASH2 = 0;
writel(mac_hi, &adap_emac->MACADDRHI);
#if defined(DAVINCI_EMAC_VERSION2)
writel(mac_lo | EMAC_MAC_ADDR_IS_VALID | EMAC_MAC_ADDR_MATCH,
&adap_emac->MACADDRLO);
#else
writel(mac_lo, &adap_emac->MACADDRLO);
#endif
writel(0, &adap_emac->MACHASH1);
writel(0, &adap_emac->MACHASH2);
/* Set source MAC address - REQUIRED */
adap_emac->MACSRCADDRHI =
(davinci_eth_mac_addr[3] << 24) |
(davinci_eth_mac_addr[2] << 16) |
(davinci_eth_mac_addr[1] << 8) |
(davinci_eth_mac_addr[0]);
adap_emac->MACSRCADDRLO =
(davinci_eth_mac_addr[4] << 8) |
(davinci_eth_mac_addr[5]);
writel(mac_hi, &adap_emac->MACSRCADDRHI);
writel(mac_lo, &adap_emac->MACSRCADDRLO);
/* Set DMA 8 TX / 8 RX Head pointers to 0 */
addr = &adap_emac->TX0HDP;
for(cnt = 0; cnt < 16; cnt++)
*addr++ = 0;
writel(0, addr++);
addr = &adap_emac->RX0HDP;
for(cnt = 0; cnt < 16; cnt++)
*addr++ = 0;
writel(0, addr++);
/* Clear Statistics (do this before setting MacControl register) */
addr = &adap_emac->RXGOODFRAMES;
for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
*addr++ = 0;
writel(0, addr++);
/* No multicast addressing */
adap_emac->MACHASH1 = 0;
adap_emac->MACHASH2 = 0;
writel(0, &adap_emac->MACHASH1);
writel(0, &adap_emac->MACHASH2);
/* Create RX queue and set receive process in place */
emac_rx_active_head = emac_rx_desc;
@ -324,34 +364,52 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
rx_desc++;
}
/* Set the last descriptor's "next" parameter to 0 to end the RX desc list */
/* Finalize the rx desc list */
rx_desc--;
rx_desc->next = 0;
emac_rx_active_tail = rx_desc;
emac_rx_queue_active = 1;
/* Enable TX/RX */
adap_emac->RXMAXLEN = EMAC_MAX_ETHERNET_PKT_SIZE;
adap_emac->RXBUFFEROFFSET = 0;
writel(EMAC_MAX_ETHERNET_PKT_SIZE, &adap_emac->RXMAXLEN);
writel(0, &adap_emac->RXBUFFEROFFSET);
/* No fancy configs - Use this for promiscous for debug - EMAC_RXMBPENABLE_RXCAFEN_ENABLE */
adap_emac->RXMBPENABLE = EMAC_RXMBPENABLE_RXBROADEN;
/*
* No fancy configs - Use this for promiscous debug
* - EMAC_RXMBPENABLE_RXCAFEN_ENABLE
*/
writel(EMAC_RXMBPENABLE_RXBROADEN, &adap_emac->RXMBPENABLE);
/* Enable ch 0 only */
adap_emac->RXUNICASTSET = 0x01;
writel(1, &adap_emac->RXUNICASTSET);
/* Enable MII interface and Full duplex mode */
adap_emac->MACCONTROL = (EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE);
#ifdef CONFIG_SOC_DA8XX
writel((EMAC_MACCONTROL_MIIEN_ENABLE |
EMAC_MACCONTROL_FULLDUPLEX_ENABLE |
EMAC_MACCONTROL_RMIISPEED_100),
&adap_emac->MACCONTROL);
#else
writel((EMAC_MACCONTROL_MIIEN_ENABLE |
EMAC_MACCONTROL_FULLDUPLEX_ENABLE),
&adap_emac->MACCONTROL);
#endif
/* Init MDIO & get link state */
clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT);
writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT,
&adap_mdio->CONTROL);
/* We need to wait for MDIO to start */
udelay(1000);
if (!phy.get_link_speed(active_phy_addr))
return(0);
emac_gigabit_enable();
/* Start receive process */
adap_emac->RX0HDP = (u_int32_t)emac_rx_desc;
writel((u_int32_t)emac_rx_desc, &adap_emac->RX0HDP);
debug_emac("- emac_open\n");
@ -368,34 +426,42 @@ static void davinci_eth_ch_teardown(int ch)
if (ch == EMAC_CH_TX) {
/* Init TX channel teardown */
adap_emac->TXTEARDOWN = 1;
for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->TX0CP) {
/* Wait here for Tx teardown completion interrupt to occur
* Note: A task delay can be called here to pend rather than
* occupying CPU cycles - anyway it has been found that teardown
* takes very few cpu cycles and does not affect functionality */
dly--;
udelay(1);
if (dly == 0)
writel(1, &adap_emac->TXTEARDOWN);
do {
/*
* Wait here for Tx teardown completion interrupt to
* occur. Note: A task delay can be called here to pend
* rather than occupying CPU cycles - anyway it has
* been found that teardown takes very few cpu cycles
* and does not affect functionality
*/
dly--;
udelay(1);
if (dly == 0)
break;
}
adap_emac->TX0CP = cnt;
adap_emac->TX0HDP = 0;
cnt = readl(&adap_emac->TX0CP);
} while (cnt != 0xfffffffc);
writel(cnt, &adap_emac->TX0CP);
writel(0, &adap_emac->TX0HDP);
} else {
/* Init RX channel teardown */
adap_emac->RXTEARDOWN = 1;
for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->RX0CP) {
/* Wait here for Rx teardown completion interrupt to occur
* Note: A task delay can be called here to pend rather than
* occupying CPU cycles - anyway it has been found that teardown
* takes very few cpu cycles and does not affect functionality */
dly--;
udelay(1);
if (dly == 0)
writel(1, &adap_emac->RXTEARDOWN);
do {
/*
* Wait here for Rx teardown completion interrupt to
* occur. Note: A task delay can be called here to pend
* rather than occupying CPU cycles - anyway it has
* been found that teardown takes very few cpu cycles
* and does not affect functionality
*/
dly--;
udelay(1);
if (dly == 0)
break;
}
adap_emac->RX0CP = cnt;
adap_emac->RX0HDP = 0;
cnt = readl(&adap_emac->RX0CP);
} while (cnt != 0xfffffffc);
writel(cnt, &adap_emac->RX0CP);
writel(0, &adap_emac->RX0HDP);
}
debug_emac("- emac_ch_teardown\n");
@ -410,8 +476,12 @@ static void davinci_eth_close(struct eth_device *dev)
davinci_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */
/* Reset EMAC module and disable interrupts in wrapper */
adap_emac->SOFTRESET = 1;
adap_ewrap->EWCTL = 0;
writel(1, &adap_emac->SOFTRESET);
#if defined(DAVINCI_EMAC_VERSION2)
writel(1, &adap_ewrap->softrst);
#else
writel(0, &adap_ewrap->EWCTL);
#endif
debug_emac("- emac_close\n");
}
@ -435,6 +505,8 @@ static int davinci_eth_send_packet (struct eth_device *dev,
return (ret_status);
}
emac_gigabit_enable();
/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
if (length < EMAC_MIN_ETHERNET_PKT_SIZE) {
length = EMAC_MIN_ETHERNET_PKT_SIZE;
@ -449,7 +521,7 @@ static int davinci_eth_send_packet (struct eth_device *dev,
EMAC_CPPI_OWNERSHIP_BIT |
EMAC_CPPI_EOP_BIT);
/* Send the packet */
adap_emac->TX0HDP = (unsigned int) emac_tx_desc;
writel((unsigned long)emac_tx_desc, &adap_emac->TX0HDP);
/* Wait for packet to complete or link down */
while (1) {
@ -457,7 +529,10 @@ static int davinci_eth_send_packet (struct eth_device *dev,
davinci_eth_ch_teardown (EMAC_CH_TX);
return (ret_status);
}
if (adap_emac->TXINTSTATRAW & 0x01) {
emac_gigabit_enable();
if (readl(&adap_emac->TXINTSTATRAW) & 0x01) {
ret_status = length;
break;
}
@ -490,15 +565,15 @@ static int davinci_eth_rcv_packet (struct eth_device *dev)
}
/* Ack received packet descriptor */
adap_emac->RX0CP = (unsigned int) rx_curr_desc;
writel((unsigned long)rx_curr_desc, &adap_emac->RX0CP);
curr_desc = rx_curr_desc;
emac_rx_active_head =
(volatile emac_desc *) rx_curr_desc->next;
if (status & EMAC_CPPI_EOQ_BIT) {
if (emac_rx_active_head) {
adap_emac->RX0HDP =
(unsigned int) emac_rx_active_head;
writel((unsigned long)emac_rx_active_head,
&adap_emac->RX0HDP);
} else {
emac_rx_queue_active = 0;
printf ("INFO:emac_rcv_packet: RX Queue not active\n");
@ -515,8 +590,8 @@ static int davinci_eth_rcv_packet (struct eth_device *dev)
emac_rx_active_head = curr_desc;
emac_rx_active_tail = curr_desc;
if (emac_rx_queue_active != 0) {
adap_emac->RX0HDP =
(unsigned int) emac_rx_active_head;
writel((unsigned long)emac_rx_active_head,
&adap_emac->RX0HDP);
printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
emac_rx_queue_active = 1;
}
@ -526,7 +601,8 @@ static int davinci_eth_rcv_packet (struct eth_device *dev)
tail_desc->next = (unsigned int) curr_desc;
status = tail_desc->pkt_flag_len;
if (status & EMAC_CPPI_EOQ_BIT) {
adap_emac->RX0HDP = (unsigned int) curr_desc;
writel((unsigned long)curr_desc,
&adap_emac->RX0HDP);
status &= ~EMAC_CPPI_EOQ_BIT;
tail_desc->pkt_flag_len = status;
}
@ -566,7 +642,7 @@ int davinci_emac_initialize(void)
davinci_eth_mdio_enable();
for (i = 0; i < 256; i++) {
if (adap_mdio->ALIVE)
if (readl(&adap_mdio->ALIVE))
break;
udelay(10);
}

653
drivers/net/ep93xx_eth.c Normal file
View File

@ -0,0 +1,653 @@
/*
* Cirrus Logic EP93xx ethernet MAC / MII driver.
*
* Copyright (C) 2010, 2009
* Matthias Kaehlcke <matthias@kaehlcke.net>
*
* Copyright (C) 2004, 2005
* Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com>
*
* Based on the original eth.[ch] Cirrus Logic EP93xx Rev D. Ethernet Driver,
* which is
*
* (C) Copyright 2002 2003
* Adam Bezanson, Network Audio Technologies, Inc.
* <bezanson@netaudiotech.com>
*
* See file CREDITS for list of people who contributed to this project.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <command.h>
#include <common.h>
#include <asm/arch/ep93xx.h>
#include <asm/io.h>
#include <malloc.h>
#include <miiphy.h>
#include <linux/types.h>
#include "ep93xx_eth.h"
#define GET_PRIV(eth_dev) ((struct ep93xx_priv *)(eth_dev)->priv)
#define GET_REGS(eth_dev) (GET_PRIV(eth_dev)->regs)
/* ep93xx_miiphy ops forward declarations */
static int ep93xx_miiphy_read(char * const dev, unsigned char const addr,
unsigned char const reg, unsigned short * const value);
static int ep93xx_miiphy_write(char * const dev, unsigned char const addr,
unsigned char const reg, unsigned short const value);
#if defined(EP93XX_MAC_DEBUG)
/**
* Dump ep93xx_mac values to the terminal.
*/
static void dump_dev(struct eth_device *dev)
{
struct ep93xx_priv *priv = GET_PRIV(dev);
int i;
printf("\ndump_dev()\n");
printf(" rx_dq.base %p\n", priv->rx_dq.base);
printf(" rx_dq.current %p\n", priv->rx_dq.current);
printf(" rx_dq.end %p\n", priv->rx_dq.end);
printf(" rx_sq.base %p\n", priv->rx_sq.base);
printf(" rx_sq.current %p\n", priv->rx_sq.current);
printf(" rx_sq.end %p\n", priv->rx_sq.end);
for (i = 0; i < NUMRXDESC; i++)
printf(" rx_buffer[%2.d] %p\n", i, NetRxPackets[i]);
printf(" tx_dq.base %p\n", priv->tx_dq.base);
printf(" tx_dq.current %p\n", priv->tx_dq.current);
printf(" tx_dq.end %p\n", priv->tx_dq.end);
printf(" tx_sq.base %p\n", priv->tx_sq.base);
printf(" tx_sq.current %p\n", priv->tx_sq.current);
printf(" tx_sq.end %p\n", priv->tx_sq.end);
}
/**
* Dump all RX status queue entries to the terminal.
*/
static void dump_rx_status_queue(struct eth_device *dev)
{
struct ep93xx_priv *priv = GET_PRIV(dev);
int i;
printf("\ndump_rx_status_queue()\n");
printf(" descriptor address word1 word2\n");
for (i = 0; i < NUMRXDESC; i++) {
printf(" [ %p ] %08X %08X\n",
priv->rx_sq.base + i,
(priv->rx_sq.base + i)->word1,
(priv->rx_sq.base + i)->word2);
}
}
/**
* Dump all RX descriptor queue entries to the terminal.
*/
static void dump_rx_descriptor_queue(struct eth_device *dev)
{
struct ep93xx_priv *priv = GET_PRIV(dev);
int i;
printf("\ndump_rx_descriptor_queue()\n");
printf(" descriptor address word1 word2\n");
for (i = 0; i < NUMRXDESC; i++) {
printf(" [ %p ] %08X %08X\n",
priv->rx_dq.base + i,
(priv->rx_dq.base + i)->word1,
(priv->rx_dq.base + i)->word2);
}
}
/**
* Dump all TX descriptor queue entries to the terminal.
*/
static void dump_tx_descriptor_queue(struct eth_device *dev)
{
struct ep93xx_priv *priv = GET_PRIV(dev);
int i;
printf("\ndump_tx_descriptor_queue()\n");
printf(" descriptor address word1 word2\n");
for (i = 0; i < NUMTXDESC; i++) {
printf(" [ %p ] %08X %08X\n",
priv->tx_dq.base + i,
(priv->tx_dq.base + i)->word1,
(priv->tx_dq.base + i)->word2);
}
}
/**
* Dump all TX status queue entries to the terminal.
*/
static void dump_tx_status_queue(struct eth_device *dev)
{
struct ep93xx_priv *priv = GET_PRIV(dev);
int i;
printf("\ndump_tx_status_queue()\n");
printf(" descriptor address word1\n");
for (i = 0; i < NUMTXDESC; i++) {
printf(" [ %p ] %08X\n",
priv->rx_sq.base + i,
(priv->rx_sq.base + i)->word1);
}
}
#else
#define dump_dev(x)
#define dump_rx_descriptor_queue(x)
#define dump_rx_status_queue(x)
#define dump_tx_descriptor_queue(x)
#define dump_tx_status_queue(x)
#endif /* defined(EP93XX_MAC_DEBUG) */
/**
* Reset the EP93xx MAC by twiddling the soft reset bit and spinning until
* it's cleared.
*/
static void ep93xx_mac_reset(struct eth_device *dev)
{
struct mac_regs *mac = GET_REGS(dev);
uint32_t value;
debug("+ep93xx_mac_reset");
value = readl(&mac->selfctl);
value |= SELFCTL_RESET;
writel(value, &mac->selfctl);
while (readl(&mac->selfctl) & SELFCTL_RESET)
; /* noop */
debug("-ep93xx_mac_reset");
}
/* Eth device open */
static int ep93xx_eth_open(struct eth_device *dev, bd_t *bd)
{
struct ep93xx_priv *priv = GET_PRIV(dev);
struct mac_regs *mac = GET_REGS(dev);
uchar *mac_addr = dev->enetaddr;
int i;
debug("+ep93xx_eth_open");
/* Reset the MAC */
ep93xx_mac_reset(dev);
/* Reset the descriptor queues' current and end address values */
priv->tx_dq.current = priv->tx_dq.base;
priv->tx_dq.end = (priv->tx_dq.base + NUMTXDESC);
priv->tx_sq.current = priv->tx_sq.base;
priv->tx_sq.end = (priv->tx_sq.base + NUMTXDESC);
priv->rx_dq.current = priv->rx_dq.base;
priv->rx_dq.end = (priv->rx_dq.base + NUMRXDESC);
priv->rx_sq.current = priv->rx_sq.base;
priv->rx_sq.end = (priv->rx_sq.base + NUMRXDESC);
/*
* Set the transmit descriptor and status queues' base address,
* current address, and length registers. Set the maximum frame
* length and threshold. Enable the transmit descriptor processor.
*/
writel((uint32_t)priv->tx_dq.base, &mac->txdq.badd);
writel((uint32_t)priv->tx_dq.base, &mac->txdq.curadd);
writel(sizeof(struct tx_descriptor) * NUMTXDESC, &mac->txdq.blen);
writel((uint32_t)priv->tx_sq.base, &mac->txstsq.badd);
writel((uint32_t)priv->tx_sq.base, &mac->txstsq.curadd);
writel(sizeof(struct tx_status) * NUMTXDESC, &mac->txstsq.blen);
writel(0x00040000, &mac->txdthrshld);
writel(0x00040000, &mac->txststhrshld);
writel((TXSTARTMAX << 0) | (PKTSIZE_ALIGN << 16), &mac->maxfrmlen);
writel(BMCTL_TXEN, &mac->bmctl);
/*
* Set the receive descriptor and status queues' base address,
* current address, and length registers. Enable the receive
* descriptor processor.
*/
writel((uint32_t)priv->rx_dq.base, &mac->rxdq.badd);
writel((uint32_t)priv->rx_dq.base, &mac->rxdq.curadd);
writel(sizeof(struct rx_descriptor) * NUMRXDESC, &mac->rxdq.blen);
writel((uint32_t)priv->rx_sq.base, &mac->rxstsq.badd);
writel((uint32_t)priv->rx_sq.base, &mac->rxstsq.curadd);
writel(sizeof(struct rx_status) * NUMRXDESC, &mac->rxstsq.blen);
writel(0x00040000, &mac->rxdthrshld);
writel(BMCTL_RXEN, &mac->bmctl);
writel(0x00040000, &mac->rxststhrshld);
/* Wait until the receive descriptor processor is active */
while (!(readl(&mac->bmsts) & BMSTS_RXACT))
; /* noop */
/*
* Initialize the RX descriptor queue. Clear the TX descriptor queue.
* Clear the RX and TX status queues. Enqueue the RX descriptor and
* status entries to the MAC.
*/
for (i = 0; i < NUMRXDESC; i++) {
/* set buffer address */
(priv->rx_dq.base + i)->word1 = (uint32_t)NetRxPackets[i];
/* set buffer length, clear buffer index and NSOF */
(priv->rx_dq.base + i)->word2 = PKTSIZE_ALIGN;
}
memset(priv->tx_dq.base, 0,
(sizeof(struct tx_descriptor) * NUMTXDESC));
memset(priv->rx_sq.base, 0,
(sizeof(struct rx_status) * NUMRXDESC));
memset(priv->tx_sq.base, 0,
(sizeof(struct tx_status) * NUMTXDESC));
writel(NUMRXDESC, &mac->rxdqenq);
writel(NUMRXDESC, &mac->rxstsqenq);
/* Set the primary MAC address */
writel(AFP_IAPRIMARY, &mac->afp);
writel(mac_addr[0] | (mac_addr[1] << 8) |
(mac_addr[2] << 16) | (mac_addr[3] << 24),
&mac->indad);
writel(mac_addr[4] | (mac_addr[5] << 8), &mac->indad_upper);
/* Turn on RX and TX */
writel(RXCTL_IA0 | RXCTL_BA | RXCTL_SRXON |
RXCTL_RCRCA | RXCTL_MA, &mac->rxctl);
writel(TXCTL_STXON, &mac->txctl);
/* Dump data structures if we're debugging */
dump_dev(dev);
dump_rx_descriptor_queue(dev);
dump_rx_status_queue(dev);
dump_tx_descriptor_queue(dev);
dump_tx_status_queue(dev);
debug("-ep93xx_eth_open");
return 1;
}
/**
* Halt EP93xx MAC transmit and receive by clearing the TxCTL and RxCTL
* registers.
*/
static void ep93xx_eth_close(struct eth_device *dev)
{
struct mac_regs *mac = GET_REGS(dev);
debug("+ep93xx_eth_close");
writel(0x00000000, &mac->rxctl);
writel(0x00000000, &mac->txctl);
debug("-ep93xx_eth_close");
}
/**
* Copy a frame of data from the MAC into the protocol layer for further
* processing.
*/
static int ep93xx_eth_rcv_packet(struct eth_device *dev)
{
struct mac_regs *mac = GET_REGS(dev);
struct ep93xx_priv *priv = GET_PRIV(dev);
int len = -1;
debug("+ep93xx_eth_rcv_packet");
if (RX_STATUS_RFP(priv->rx_sq.current)) {
if (RX_STATUS_RWE(priv->rx_sq.current)) {
/*
* We have a good frame. Extract the frame's length
* from the current rx_status_queue entry, and copy
* the frame's data into NetRxPackets[] of the
* protocol stack. We track the total number of
* bytes in the frame (nbytes_frame) which will be
* used when we pass the data off to the protocol
* layer via NetReceive().
*/
len = RX_STATUS_FRAME_LEN(priv->rx_sq.current);
NetReceive((uchar *)priv->rx_dq.current->word1, len);
debug("reporting %d bytes...\n", len);
} else {
/* Do we have an erroneous packet? */
error("packet rx error, status %08X %08X",
priv->rx_sq.current->word1,
priv->rx_sq.current->word2);
dump_rx_descriptor_queue(dev);
dump_rx_status_queue(dev);
}
/*
* Clear the associated status queue entry, and
* increment our current pointers to the next RX
* descriptor and status queue entries (making sure
* we wrap properly).
*/
memset((void *)priv->rx_sq.current, 0,
sizeof(struct rx_status));
priv->rx_sq.current++;
if (priv->rx_sq.current >= priv->rx_sq.end)
priv->rx_sq.current = priv->rx_sq.base;
priv->rx_dq.current++;
if (priv->rx_dq.current >= priv->rx_dq.end)
priv->rx_dq.current = priv->rx_dq.base;
/*
* Finally, return the RX descriptor and status entries
* back to the MAC engine, and loop again, checking for
* more descriptors to process.
*/
writel(1, &mac->rxdqenq);
writel(1, &mac->rxstsqenq);
} else {
len = 0;
}
debug("-ep93xx_eth_rcv_packet %d", len);
return len;
}
/**
* Send a block of data via ethernet.
*/
static int ep93xx_eth_send_packet(struct eth_device *dev,
volatile void * const packet, int const length)
{
struct mac_regs *mac = GET_REGS(dev);
struct ep93xx_priv *priv = GET_PRIV(dev);
int ret = -1;
debug("+ep93xx_eth_send_packet");
/* Parameter check */
BUG_ON(packet == NULL);
/*
* Initialize the TX descriptor queue with the new packet's info.
* Clear the associated status queue entry. Enqueue the packet
* to the MAC for transmission.
*/
/* set buffer address */
priv->tx_dq.current->word1 = (uint32_t)packet;
/* set buffer length and EOF bit */
priv->tx_dq.current->word2 = length | TX_DESC_EOF;
/* clear tx status */
priv->tx_sq.current->word1 = 0;
/* enqueue the TX descriptor */
writel(1, &mac->txdqenq);
/* wait for the frame to become processed */
while (!TX_STATUS_TXFP(priv->tx_sq.current))
; /* noop */
if (!TX_STATUS_TXWE(priv->tx_sq.current)) {
error("packet tx error, status %08X",
priv->tx_sq.current->word1);
dump_tx_descriptor_queue(dev);
dump_tx_status_queue(dev);
/* TODO: Add better error handling? */
goto eth_send_out;
}
ret = 0;
/* Fall through */
eth_send_out:
debug("-ep93xx_eth_send_packet %d", ret);
return ret;
}
#if defined(CONFIG_MII)
int ep93xx_miiphy_initialize(bd_t * const bd)
{
miiphy_register("ep93xx_eth0", ep93xx_miiphy_read, ep93xx_miiphy_write);
return 0;
}
#endif
/**
* Initialize the EP93xx MAC. The MAC hardware is reset. Buffers are
* allocated, if necessary, for the TX and RX descriptor and status queues,
* as well as for received packets. The EP93XX MAC hardware is initialized.
* Transmit and receive operations are enabled.
*/
int ep93xx_eth_initialize(u8 dev_num, int base_addr)
{
int ret = -1;
struct eth_device *dev;
struct ep93xx_priv *priv;
debug("+ep93xx_eth_initialize");
priv = malloc(sizeof(*priv));
if (!priv) {
error("malloc() failed");
goto eth_init_failed_0;
}
memset(priv, 0, sizeof(*priv));
priv->regs = (struct mac_regs *)base_addr;
priv->tx_dq.base = calloc(NUMTXDESC,
sizeof(struct tx_descriptor));
if (priv->tx_dq.base == NULL) {
error("calloc() failed");
goto eth_init_failed_1;
}
priv->tx_sq.base = calloc(NUMTXDESC,
sizeof(struct tx_status));
if (priv->tx_sq.base == NULL) {
error("calloc() failed");
goto eth_init_failed_2;
}
priv->rx_dq.base = calloc(NUMRXDESC,
sizeof(struct rx_descriptor));
if (priv->rx_dq.base == NULL) {
error("calloc() failed");
goto eth_init_failed_3;
}
priv->rx_sq.base = calloc(NUMRXDESC,
sizeof(struct rx_status));
if (priv->rx_sq.base == NULL) {
error("calloc() failed");
goto eth_init_failed_4;
}
dev = malloc(sizeof *dev);
if (dev == NULL) {
error("malloc() failed");
goto eth_init_failed_5;
}
memset(dev, 0, sizeof *dev);
dev->iobase = base_addr;
dev->priv = priv;
dev->init = ep93xx_eth_open;
dev->halt = ep93xx_eth_close;
dev->send = ep93xx_eth_send_packet;
dev->recv = ep93xx_eth_rcv_packet;
sprintf(dev->name, "ep93xx_eth-%hu", dev_num);
eth_register(dev);
/* Done! */
ret = 1;
goto eth_init_done;
eth_init_failed_5:
free(priv->rx_sq.base);
/* Fall through */
eth_init_failed_4:
free(priv->rx_dq.base);
/* Fall through */
eth_init_failed_3:
free(priv->tx_sq.base);
/* Fall through */
eth_init_failed_2:
free(priv->tx_dq.base);
/* Fall through */
eth_init_failed_1:
free(priv);
/* Fall through */
eth_init_failed_0:
/* Fall through */
eth_init_done:
debug("-ep93xx_eth_initialize %d", ret);
return ret;
}
#if defined(CONFIG_MII)
/**
* Maximum MII address we support
*/
#define MII_ADDRESS_MAX 31
/**
* Maximum MII register address we support
*/
#define MII_REGISTER_MAX 31
/**
* Read a 16-bit value from an MII register.
*/
static int ep93xx_miiphy_read(char * const dev, unsigned char const addr,
unsigned char const reg, unsigned short * const value)
{
struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
int ret = -1;
uint32_t self_ctl;
debug("+ep93xx_miiphy_read");
/* Parameter checks */
BUG_ON(dev == NULL);
BUG_ON(addr > MII_ADDRESS_MAX);
BUG_ON(reg > MII_REGISTER_MAX);
BUG_ON(value == NULL);
/*
* Save the current SelfCTL register value. Set MAC to suppress
* preamble bits. Wait for any previous MII command to complete
* before issuing the new command.
*/
self_ctl = readl(&mac->selfctl);
#if defined(CONFIG_MII_SUPPRESS_PREAMBLE)
writel(self_ctl & ~(1 << 8), &mac->selfctl);
#endif /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */
while (readl(&mac->miists) & MIISTS_BUSY)
; /* noop */
/*
* Issue the MII 'read' command. Wait for the command to complete.
* Read the MII data value.
*/
writel(MIICMD_OPCODE_READ | ((uint32_t)addr << 5) | (uint32_t)reg,
&mac->miicmd);
while (readl(&mac->miists) & MIISTS_BUSY)
; /* noop */
*value = (unsigned short)readl(&mac->miidata);
/* Restore the saved SelfCTL value and return. */
writel(self_ctl, &mac->selfctl);
ret = 0;
/* Fall through */
debug("-ep93xx_miiphy_read");
return ret;
}
/**
* Write a 16-bit value to an MII register.
*/
static int ep93xx_miiphy_write(char * const dev, unsigned char const addr,
unsigned char const reg, unsigned short const value)
{
struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
int ret = -1;
uint32_t self_ctl;
debug("+ep93xx_miiphy_write");
/* Parameter checks */
BUG_ON(dev == NULL);
BUG_ON(addr > MII_ADDRESS_MAX);
BUG_ON(reg > MII_REGISTER_MAX);
/*
* Save the current SelfCTL register value. Set MAC to suppress
* preamble bits. Wait for any previous MII command to complete
* before issuing the new command.
*/
self_ctl = readl(&mac->selfctl);
#if defined(CONFIG_MII_SUPPRESS_PREAMBLE)
writel(self_ctl & ~(1 << 8), &mac->selfctl);
#endif /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */
while (readl(&mac->miists) & MIISTS_BUSY)
; /* noop */
/* Issue the MII 'write' command. Wait for the command to complete. */
writel((uint32_t)value, &mac->miidata);
writel(MIICMD_OPCODE_WRITE | ((uint32_t)addr << 5) | (uint32_t)reg,
&mac->miicmd);
while (readl(&mac->miists) & MIISTS_BUSY)
; /* noop */
/* Restore the saved SelfCTL value and return. */
writel(self_ctl, &mac->selfctl);
ret = 0;
/* Fall through */
debug("-ep93xx_miiphy_write");
return ret;
}
#endif /* defined(CONFIG_MII) */

144
drivers/net/ep93xx_eth.h Normal file
View File

@ -0,0 +1,144 @@
/*
* Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
*
* Copyright (C) 2004, 2005
* Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#ifndef _EP93XX_ETH_H
#define _EP93XX_ETH_H
#include <net.h>
/**
* #define this to dump device status and queue info during initialization and
* following errors.
*/
#undef EP93XX_MAC_DEBUG
/**
* Number of descriptor and status entries in our RX queues.
* It must be power of 2 !
*/
#define NUMRXDESC PKTBUFSRX
/**
* Number of descriptor and status entries in our TX queues.
*/
#define NUMTXDESC 1
/**
* 944 = (1024 - 64) - 16, Fifo size - Minframesize - 16 (Chip FACT)
*/
#define TXSTARTMAX 944
/**
* Receive descriptor queue entry
*/
struct rx_descriptor {
uint32_t word1;
uint32_t word2;
};
/**
* Receive status queue entry
*/
struct rx_status {
uint32_t word1;
uint32_t word2;
};
#define RX_STATUS_RWE(rx_status) ((rx_status->word1 >> 30) & 0x01)
#define RX_STATUS_RFP(rx_status) ((rx_status->word1 >> 31) & 0x01)
#define RX_STATUS_FRAME_LEN(rx_status) (rx_status->word2 & 0xFFFF)
/**
* Transmit descriptor queue entry
*/
struct tx_descriptor {
uint32_t word1;
uint32_t word2;
};
#define TX_DESC_EOF (1 << 31)
/**
* Transmit status queue entry
*/
struct tx_status {
uint32_t word1;
};
#define TX_STATUS_TXWE(tx_status) (((tx_status)->word1 >> 30) & 0x01)
#define TX_STATUS_TXFP(tx_status) (((tx_status)->word1 >> 31) & 0x01)
/**
* Transmit descriptor queue
*/
struct tx_descriptor_queue {
struct tx_descriptor *base;
struct tx_descriptor *current;
struct tx_descriptor *end;
};
/**
* Transmit status queue
*/
struct tx_status_queue {
struct tx_status *base;
volatile struct tx_status *current;
struct tx_status *end;
};
/**
* Receive descriptor queue
*/
struct rx_descriptor_queue {
struct rx_descriptor *base;
struct rx_descriptor *current;
struct rx_descriptor *end;
};
/**
* Receive status queue
*/
struct rx_status_queue {
struct rx_status *base;
volatile struct rx_status *current;
struct rx_status *end;
};
/**
* EP93xx MAC private data structure
*/
struct ep93xx_priv {
struct rx_descriptor_queue rx_dq;
struct rx_status_queue rx_sq;
void *rx_buffer[NUMRXDESC];
struct tx_descriptor_queue tx_dq;
struct tx_status_queue tx_sq;
struct mac_regs *regs;
};
#endif

View File

@ -42,6 +42,7 @@
#include <net.h>
#include <netdev.h>
#include <malloc.h>
#include <miiphy.h>
#include <linux/mii.h>
#include <asm/io.h>
@ -164,6 +165,36 @@ static u16 macb_mdio_read(struct macb_device *macb, u8 reg)
return MACB_BFEXT(DATA, frame);
}
#if defined(CONFIG_CMD_MII)
int macb_miiphy_read(char *devname, u8 phy_adr, u8 reg, u16 *value)
{
struct eth_device *dev = eth_get_dev_by_name(devname);
struct macb_device *macb = to_macb(dev);
if ( macb->phy_addr != phy_adr )
return -1;
*value = macb_mdio_read(macb, reg);
return 0;
}
int macb_miiphy_write(char *devname, u8 phy_adr, u8 reg, u16 value)
{
struct eth_device *dev = eth_get_dev_by_name(devname);
struct macb_device *macb = to_macb(dev);
if ( macb->phy_addr != phy_adr )
return -1;
macb_mdio_write(macb, reg, value);
return 0;
}
#endif
#if defined(CONFIG_CMD_NET)
static int macb_send(struct eth_device *netdev, volatile void *packet,
@ -542,84 +573,9 @@ int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
eth_register(netdev);
return 0;
}
#endif
#if defined(CONFIG_CMD_MII)
int miiphy_read(unsigned char addr, unsigned char reg, unsigned short *value)
{
unsigned long netctl;
unsigned long netstat;
unsigned long frame;
int iflag;
iflag = disable_interrupts();
netctl = macb_readl(&macb, EMACB_NCR);
netctl |= MACB_BIT(MPE);
macb_writel(&macb, EMACB_NCR, netctl);
if (iflag)
enable_interrupts();
frame = (MACB_BF(SOF, 1)
| MACB_BF(RW, 2)
| MACB_BF(PHYA, addr)
| MACB_BF(REGA, reg)
| MACB_BF(CODE, 2));
macb_writel(&macb, EMACB_MAN, frame);
do {
netstat = macb_readl(&macb, EMACB_NSR);
} while (!(netstat & MACB_BIT(IDLE)));
frame = macb_readl(&macb, EMACB_MAN);
*value = MACB_BFEXT(DATA, frame);
iflag = disable_interrupts();
netctl = macb_readl(&macb, EMACB_NCR);
netctl &= ~MACB_BIT(MPE);
macb_writel(&macb, EMACB_NCR, netctl);
if (iflag)
enable_interrupts();
return 0;
}
int miiphy_write(unsigned char addr, unsigned char reg, unsigned short value)
{
unsigned long netctl;
unsigned long netstat;
unsigned long frame;
int iflag;
iflag = disable_interrupts();
netctl = macb_readl(&macb, EMACB_NCR);
netctl |= MACB_BIT(MPE);
macb_writel(&macb, EMACB_NCR, netctl);
if (iflag)
enable_interrupts();
frame = (MACB_BF(SOF, 1)
| MACB_BF(RW, 1)
| MACB_BF(PHYA, addr)
| MACB_BF(REGA, reg)
| MACB_BF(CODE, 2)
| MACB_BF(DATA, value));
macb_writel(&macb, EMACB_MAN, frame);
do {
netstat = macb_readl(&macb, EMACB_NSR);
} while (!(netstat & MACB_BIT(IDLE)));
iflag = disable_interrupts();
netctl = macb_readl(&macb, EMACB_NCR);
netctl &= ~MACB_BIT(MPE);
macb_writel(&macb, EMACB_NCR, netctl);
if (iflag)
enable_interrupts();
miiphy_register(netdev->name, macb_miiphy_read, macb_miiphy_write);
#endif
return 0;
}

View File

@ -257,12 +257,15 @@ int smc911x_initialize(u8 dev_num, int base_addr)
addrh = smc911x_get_mac_csr(dev, ADDRH);
addrl = smc911x_get_mac_csr(dev, ADDRL);
dev->enetaddr[0] = addrl;
dev->enetaddr[1] = addrl >> 8;
dev->enetaddr[2] = addrl >> 16;
dev->enetaddr[3] = addrl >> 24;
dev->enetaddr[4] = addrh;
dev->enetaddr[5] = addrh >> 8;
if (!(addrl == 0xffffffff && addrh == 0x0000ffff)) {
/* address is obtained from optional eeprom */
dev->enetaddr[0] = addrl;
dev->enetaddr[1] = addrl >> 8;
dev->enetaddr[2] = addrl >> 16;
dev->enetaddr[3] = addrl >> 24;
dev->enetaddr[4] = addrh;
dev->enetaddr[5] = addrh >> 8;
}
dev->init = smc911x_init;
dev->halt = smc911x_halt;

File diff suppressed because it is too large Load Diff

View File

@ -323,9 +323,10 @@ static int uec_set_mac_duplex(uec_private_t *uec, int duplex)
return 0;
}
static int uec_set_mac_if_mode(uec_private_t *uec, enet_interface_e if_mode)
static int uec_set_mac_if_mode(uec_private_t *uec,
enet_interface_type_e if_mode, int speed)
{
enet_interface_e enet_if_mode;
enet_interface_type_e enet_if_mode;
uec_info_t *uec_info;
uec_t *uec_regs;
u32 upsmr;
@ -346,52 +347,68 @@ static int uec_set_mac_if_mode(uec_private_t *uec, enet_interface_e if_mode)
upsmr = in_be32(&uec->uccf->uf_regs->upsmr);
upsmr &= ~(UPSMR_RPM | UPSMR_TBIM | UPSMR_R10M | UPSMR_RMM);
switch (enet_if_mode) {
case ENET_100_MII:
case ENET_10_MII:
switch (speed) {
case 10:
maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
switch (enet_if_mode) {
case MII:
break;
case RGMII:
upsmr |= (UPSMR_RPM | UPSMR_R10M);
break;
case RMII:
upsmr |= (UPSMR_R10M | UPSMR_RMM);
break;
default:
return -EINVAL;
break;
}
break;
case ENET_1000_GMII:
maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
break;
case ENET_1000_TBI:
maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
upsmr |= UPSMR_TBIM;
break;
case ENET_1000_RTBI:
maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
upsmr |= (UPSMR_RPM | UPSMR_TBIM);
break;
case ENET_1000_RGMII_RXID:
case ENET_1000_RGMII_ID:
case ENET_1000_RGMII:
maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
upsmr |= UPSMR_RPM;
break;
case ENET_100_RGMII:
case 100:
maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
upsmr |= UPSMR_RPM;
switch (enet_if_mode) {
case MII:
break;
case RGMII:
upsmr |= UPSMR_RPM;
break;
case RMII:
upsmr |= UPSMR_RMM;
break;
default:
return -EINVAL;
break;
}
break;
case ENET_10_RGMII:
maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
upsmr |= (UPSMR_RPM | UPSMR_R10M);
break;
case ENET_100_RMII:
maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
upsmr |= UPSMR_RMM;
break;
case ENET_10_RMII:
maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
upsmr |= (UPSMR_R10M | UPSMR_RMM);
break;
case ENET_1000_SGMII:
case 1000:
maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
upsmr |= UPSMR_SGMM;
switch (enet_if_mode) {
case GMII:
break;
case TBI:
upsmr |= UPSMR_TBIM;
break;
case RTBI:
upsmr |= (UPSMR_RPM | UPSMR_TBIM);
break;
case RGMII_RXID:
case RGMII_ID:
case RGMII:
upsmr |= UPSMR_RPM;
break;
case SGMII:
upsmr |= UPSMR_SGMM;
break;
default:
return -EINVAL;
break;
}
break;
default:
return -EINVAL;
break;
}
out_be32(&uec_regs->maccfg2, maccfg2);
out_be32(&uec->uccf->uf_regs->upsmr, upsmr);
@ -504,7 +521,7 @@ static void adjust_link(struct eth_device *dev)
struct uec_mii_info *mii_info = uec->mii_info;
extern void change_phy_interface_mode(struct eth_device *dev,
enet_interface_e mode);
enet_interface_type_e mode, int speed);
uec_regs = uec->uec_regs;
if (mii_info->link) {
@ -522,25 +539,19 @@ static void adjust_link(struct eth_device *dev)
}
if (mii_info->speed != uec->oldspeed) {
enet_interface_type_e mode = \
uec->uec_info->enet_interface_type;
if (uec->uec_info->uf_info.eth_type == GIGA_ETH) {
switch (mii_info->speed) {
case 1000:
break;
case 100:
printf ("switching to rgmii 100\n");
/* change phy to rgmii 100 */
change_phy_interface_mode(dev,
ENET_100_RGMII);
/* change the MAC interface mode */
uec_set_mac_if_mode(uec,ENET_100_RGMII);
mode = RGMII;
break;
case 10:
printf ("switching to rgmii 10\n");
/* change phy to rgmii 10 */
change_phy_interface_mode(dev,
ENET_10_RGMII);
/* change the MAC interface mode */
uec_set_mac_if_mode(uec,ENET_10_RGMII);
mode = RGMII;
break;
default:
printf("%s: Ack,Speed(%d)is illegal\n",
@ -549,6 +560,11 @@ static void adjust_link(struct eth_device *dev)
}
}
/* change phy */
change_phy_interface_mode(dev, mode, mii_info->speed);
/* change the MAC interface mode */
uec_set_mac_if_mode(uec, mode, mii_info->speed);
printf("%s: Speed %dBT\n", dev->name, mii_info->speed);
uec->oldspeed = mii_info->speed;
}
@ -980,7 +996,6 @@ static int uec_startup(uec_private_t *uec)
int num_threads_tx;
int num_threads_rx;
u32 utbipar;
enet_interface_e enet_interface;
u32 length;
u32 align;
qe_bd_t *bd;
@ -1060,7 +1075,7 @@ static int uec_startup(uec_private_t *uec)
out_be32(&uec_regs->maccfg2, MACCFG2_INIT_VALUE);
/* Setup MAC interface mode */
uec_set_mac_if_mode(uec, uec_info->enet_interface);
uec_set_mac_if_mode(uec, uec_info->enet_interface_type, uec_info->speed);
/* Setup MII management base */
#ifndef CONFIG_eTSEC_MDIO_BUS
@ -1075,7 +1090,6 @@ static int uec_startup(uec_private_t *uec)
/* Setup UTBIPAR */
utbipar = in_be32(&uec_regs->utbipar);
utbipar &= ~UTBIPAR_PHY_ADDRESS_MASK;
enet_interface = uec->uec_info->enet_interface;
/* Initialize UTBIPAR address to CONFIG_UTBIPAR_INIT_TBIPA for ALL UEC.
* This frees up the remaining SMI addresses for use.
@ -1084,7 +1098,8 @@ static int uec_startup(uec_private_t *uec)
out_be32(&uec_regs->utbipar, utbipar);
/* Configure the TBI for SGMII operation */
if (uec->uec_info->enet_interface == ENET_1000_SGMII) {
if ((uec->uec_info->enet_interface_type == SGMII) &&
(uec->uec_info->speed == 1000)) {
uec_write_phy_reg(uec->dev, uec_regs->utbipar,
ENET_TBI_MII_ANA, TBIANA_SETTINGS);
@ -1215,6 +1230,7 @@ static int uec_init(struct eth_device* dev, bd_t *bd)
if (err || i <= 0)
printf("warning: %s: timeout on PHY link\n", dev->name);
adjust_link(dev);
uec->the_first_run = 1;
}

View File

@ -662,22 +662,18 @@ typedef enum uec_num_of_threads {
/* UEC ethernet interface type
*/
typedef enum enet_interface {
ENET_10_MII,
ENET_10_RMII,
ENET_10_RGMII,
ENET_100_MII,
ENET_100_RMII,
ENET_100_RGMII,
ENET_1000_GMII,
ENET_1000_RGMII,
ENET_1000_RGMII_ID,
ENET_1000_RGMII_RXID,
ENET_1000_RGMII_TXID,
ENET_1000_TBI,
ENET_1000_RTBI,
ENET_1000_SGMII
} enet_interface_e;
typedef enum enet_interface_type {
MII,
RMII,
RGMII,
GMII,
RGMII_ID,
RGMII_RXID,
RGMII_TXID,
TBI,
RTBI,
SGMII
} enet_interface_type_e;
/* UEC initialization info struct
*/
@ -696,7 +692,8 @@ typedef enum enet_interface {
.tx_bd_ring_len = 16, \
.rx_bd_ring_len = 16, \
.phy_address = CONFIG_SYS_UEC##num##_PHY_ADDR, \
.enet_interface = CONFIG_SYS_UEC##num##_INTERFACE_MODE, \
.enet_interface_type = CONFIG_SYS_UEC##num##_INTERFACE_TYPE, \
.speed = CONFIG_SYS_UEC##num##_INTERFACE_SPEED, \
}
typedef struct uec_info {
@ -708,7 +705,8 @@ typedef struct uec_info {
u16 rx_bd_ring_len;
u16 tx_bd_ring_len;
u8 phy_address;
enet_interface_e enet_interface;
enet_interface_type_e enet_interface_type;
int speed;
} uec_info_t;
/* UEC driver initialized info

View File

@ -401,7 +401,8 @@ static int bcm_init(struct uec_mii_info *mii_info)
gbit_config_aneg(mii_info);
if (uec->uec_info->enet_interface == ENET_1000_RGMII_RXID) {
if ((uec->uec_info->enet_interface_type == RGMII_RXID) &&
(uec->uec_info->speed == 1000)) {
u16 val;
int cnt = 50;
@ -429,20 +430,22 @@ static int marvell_init(struct uec_mii_info *mii_info)
{
struct eth_device *edev = mii_info->dev;
uec_private_t *uec = edev->priv;
enum enet_interface iface = uec->uec_info->enet_interface;
enum enet_interface_type iface = uec->uec_info->enet_interface_type;
int speed = uec->uec_info->speed;
if (iface == ENET_1000_RGMII_ID ||
iface == ENET_1000_RGMII_RXID ||
iface == ENET_1000_RGMII_TXID) {
if ((speed == 1000) &&
(iface == RGMII_ID ||
iface == RGMII_RXID ||
iface == RGMII_TXID)) {
int temp;
temp = phy_read(mii_info, MII_M1111_PHY_EXT_CR);
if (iface == ENET_1000_RGMII_ID) {
if (iface == RGMII_ID) {
temp |= MII_M1111_RX_DELAY | MII_M1111_TX_DELAY;
} else if (iface == ENET_1000_RGMII_RXID) {
} else if (iface == RGMII_RXID) {
temp &= ~MII_M1111_TX_DELAY;
temp |= MII_M1111_RX_DELAY;
} else if (iface == ENET_1000_RGMII_TXID) {
} else if (iface == RGMII_TXID) {
temp &= ~MII_M1111_RX_DELAY;
temp |= MII_M1111_TX_DELAY;
}
@ -795,7 +798,9 @@ struct phy_info *uec_get_phy_info (struct uec_mii_info *mii_info)
}
void marvell_phy_interface_mode (struct eth_device *dev,
enet_interface_e mode)
enet_interface_type_e type,
int speed
)
{
uec_private_t *uec = (uec_private_t *) dev->priv;
struct uec_mii_info *mii_info;
@ -807,33 +812,35 @@ void marvell_phy_interface_mode (struct eth_device *dev,
}
mii_info = uec->mii_info;
if (mode == ENET_100_RGMII) {
phy_write (mii_info, 0x00, 0x9140);
phy_write (mii_info, 0x1d, 0x001f);
phy_write (mii_info, 0x1e, 0x200c);
phy_write (mii_info, 0x1d, 0x0005);
phy_write (mii_info, 0x1e, 0x0000);
phy_write (mii_info, 0x1e, 0x0100);
phy_write (mii_info, 0x09, 0x0e00);
phy_write (mii_info, 0x04, 0x01e1);
phy_write (mii_info, 0x00, 0x9140);
phy_write (mii_info, 0x00, 0x1000);
udelay (100000);
phy_write (mii_info, 0x00, 0x2900);
phy_write (mii_info, 0x14, 0x0cd2);
phy_write (mii_info, 0x00, 0xa100);
phy_write (mii_info, 0x09, 0x0000);
phy_write (mii_info, 0x1b, 0x800b);
phy_write (mii_info, 0x04, 0x05e1);
phy_write (mii_info, 0x00, 0xa100);
phy_write (mii_info, 0x00, 0x2100);
udelay (1000000);
} else if (mode == ENET_10_RGMII) {
phy_write (mii_info, 0x14, 0x8e40);
phy_write (mii_info, 0x1b, 0x800b);
phy_write (mii_info, 0x14, 0x0c82);
phy_write (mii_info, 0x00, 0x8100);
udelay (1000000);
if (type == RGMII) {
if (speed == 100) {
phy_write (mii_info, 0x00, 0x9140);
phy_write (mii_info, 0x1d, 0x001f);
phy_write (mii_info, 0x1e, 0x200c);
phy_write (mii_info, 0x1d, 0x0005);
phy_write (mii_info, 0x1e, 0x0000);
phy_write (mii_info, 0x1e, 0x0100);
phy_write (mii_info, 0x09, 0x0e00);
phy_write (mii_info, 0x04, 0x01e1);
phy_write (mii_info, 0x00, 0x9140);
phy_write (mii_info, 0x00, 0x1000);
udelay (100000);
phy_write (mii_info, 0x00, 0x2900);
phy_write (mii_info, 0x14, 0x0cd2);
phy_write (mii_info, 0x00, 0xa100);
phy_write (mii_info, 0x09, 0x0000);
phy_write (mii_info, 0x1b, 0x800b);
phy_write (mii_info, 0x04, 0x05e1);
phy_write (mii_info, 0x00, 0xa100);
phy_write (mii_info, 0x00, 0x2100);
udelay (1000000);
} else if (speed == 10) {
phy_write (mii_info, 0x14, 0x8e40);
phy_write (mii_info, 0x1b, 0x800b);
phy_write (mii_info, 0x14, 0x0c82);
phy_write (mii_info, 0x00, 0x8100);
udelay (1000000);
}
}
/* handle 88e1111 rev.B2 erratum 5.6 */
@ -844,9 +851,10 @@ void marvell_phy_interface_mode (struct eth_device *dev,
/* now the B2 will correctly report autoneg completion status */
}
void change_phy_interface_mode (struct eth_device *dev, enet_interface_e mode)
void change_phy_interface_mode (struct eth_device *dev,
enet_interface_type_e type, int speed)
{
#ifdef CONFIG_PHY_MODE_NEED_CHANGE
marvell_phy_interface_mode (dev, mode);
marvell_phy_interface_mode (dev, type, speed);
#endif
}

View File

@ -53,9 +53,8 @@ int smc91111_eeprom (int argc, char *argv[])
int c, i, j, done, line, reg, value, start, what;
char input[50];
struct eth_device dev = {
.iobase = CONFIG_SMC91111_BASE
};
struct eth_device dev;
dev.iobase = CONFIG_SMC91111_BASE;
/* Print the ABI version */
app_startup (argv);

View File

@ -0,0 +1,145 @@
/*
* Memory Setup stuff - taken from blob memsetup.S
*
* Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de)
*
* based on AT91RM9200 datasheet revision I (36. Ethernet MAC (EMAC))
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef AT91_H
#define AT91_H
typedef struct at91_emac {
u32 ctl;
u32 cfg;
u32 sr;
u32 tar;
u32 tcr;
u32 tsr;
u32 rbqp;
u32 reserved0;
u32 rsr;
u32 isr;
u32 ier;
u32 idr;
u32 imr;
u32 man;
u32 reserved1[2];
u32 fra;
u32 scol;
u32 mocl;
u32 ok;
u32 seqe;
u32 ale;
u32 dte;
u32 lcol;
u32 ecol;
u32 cse;
u32 tue;
u32 cde;
u32 elr;
u32 rjb;
u32 usf;
u32 sqee;
u32 drfc;
u32 reserved2[3];
u32 hsh;
u32 hsl;
u32 sh1l;
u32 sa1h;
u32 sa2l;
u32 sa2h;
u32 sa3l;
u32 sa3h;
u32 sa4l;
u32 sa4h;
} at91_emac_t;
#define AT91_EMAC_CTL_LB 0x0001
#define AT91_EMAC_CTL_LBL 0x0002
#define AT91_EMAC_CTL_RE 0x0004
#define AT91_EMAC_CTL_TE 0x0008
#define AT91_EMAC_CTL_MPE 0x0010
#define AT91_EMAC_CTL_CSR 0x0020
#define AT91_EMAC_CTL_ISR 0x0040
#define AT91_EMAC_CTL_WES 0x0080
#define AT91_EMAC_CTL_BP 0x1000
#define AT91_EMAC_CFG_SPD 0x0001
#define AT91_EMAC_CFG_FD 0x0002
#define AT91_EMAC_CFG_BR 0x0004
#define AT91_EMAC_CFG_CAF 0x0010
#define AT91_EMAC_CFG_NBC 0x0020
#define AT91_EMAC_CFG_MTI 0x0040
#define AT91_EMAC_CFG_UNI 0x0080
#define AT91_EMAC_CFG_BIG 0x0100
#define AT91_EMAC_CFG_EAE 0x0200
#define AT91_EMAC_CFG_CLK_MASK 0xFFFFF3FF
#define AT91_EMAC_CFG_MCLK_8 0x0000
#define AT91_EMAC_CFG_MCLK_16 0x0400
#define AT91_EMAC_CFG_MCLK_32 0x0800
#define AT91_EMAC_CFG_MCLK_64 0x0C00
#define AT91_EMAC_CFG_RTY 0x1000
#define AT91_EMAC_CFG_RMII 0x2000
#define AT91_EMAC_SR_LINK 0x0001
#define AT91_EMAC_SR_MDIO 0x0002
#define AT91_EMAC_SR_IDLE 0x0004
#define AT91_EMAC_TCR_LEN(x) (x & 0x7FF)
#define AT91_EMAC_TCR_NCRC 0x8000
#define AT91_EMAC_TSR_OVR 0x0001
#define AT91_EMAC_TSR_COL 0x0002
#define AT91_EMAC_TSR_RLE 0x0004
#define AT91_EMAC_TSR_TXIDLE 0x0008
#define AT91_EMAC_TSR_BNQ 0x0010
#define AT91_EMAC_TSR_COMP 0x0020
#define AT91_EMAC_TSR_UND 0x0040
#define AT91_EMAC_RSR_BNA 0x0001
#define AT91_EMAC_RSR_REC 0x0002
#define AT91_EMAC_RSR_OVR 0x0004
/* ISR, IER, IDR, IMR use the same bits */
#define AT91_EMAC_IxR_DONE 0x0001
#define AT91_EMAC_IxR_RCOM 0x0002
#define AT91_EMAC_IxR_RBNA 0x0004
#define AT91_EMAC_IxR_TOVR 0x0008
#define AT91_EMAC_IxR_TUND 0x0010
#define AT91_EMAC_IxR_RTRY 0x0020
#define AT91_EMAC_IxR_TBRE 0x0040
#define AT91_EMAC_IxR_TCOM 0x0080
#define AT91_EMAC_IxR_TIDLE 0x0100
#define AT91_EMAC_IxR_LINK 0x0200
#define AT91_EMAC_IxR_ROVR 0x0400
#define AT91_EMAC_IxR_HRESP 0x0800
#define AT91_EMAC_MAN_DATA_MASK 0xFFFF
#define AT91_EMAC_MAN_CODE_802_3 0x00020000
#define AT91_EMAC_MAN_REGA(reg) ((reg & 0x1F) << 18)
#define AT91_EMAC_MAN_PHYA(phy) ((phy & 0x1F) << 23)
#define AT91_EMAC_MAN_RW_R 0x20000000
#define AT91_EMAC_MAN_RW_W 0x10000000
#define AT91_EMAC_MAN_HIGH 0x40000000
#define AT91_EMAC_MAN_LOW 0x80000000
#endif

View File

@ -43,6 +43,13 @@
#define EMAC_WRAPPER_BASE_ADDR (0x01d0a000)
#define EMAC_WRAPPER_RAM_ADDR (0x01d08000)
#define EMAC_MDIO_BASE_ADDR (0x01d0b000)
#define DAVINCI_EMAC_VERSION2
#elif defined(CONFIG_SOC_DA8XX)
#define EMAC_BASE_ADDR DAVINCI_EMAC_CNTRL_REGS_BASE
#define EMAC_WRAPPER_BASE_ADDR DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE
#define EMAC_WRAPPER_RAM_ADDR DAVINCI_EMAC_WRAPPER_RAM_BASE
#define EMAC_MDIO_BASE_ADDR DAVINCI_MDIO_CNTRL_REGS_BASE
#define DAVINCI_EMAC_VERSION2
#else
#define EMAC_BASE_ADDR (0x01c80000)
#define EMAC_WRAPPER_BASE_ADDR (0x01c81000)
@ -50,6 +57,11 @@
#define EMAC_MDIO_BASE_ADDR (0x01c84000)
#endif
#ifdef CONFIG_SOC_DM646X
#define DAVINCI_EMAC_VERSION2
#define DAVINCI_EMAC_GIG_ENABLE
#endif
#ifdef CONFIG_SOC_DM646X
/* MDIO module input frequency */
#define EMAC_MDIO_BUS_FREQ 76500000
@ -60,6 +72,11 @@
#define EMAC_MDIO_BUS_FREQ 121500000
/* MDIO clock output frequency */
#define EMAC_MDIO_CLOCK_FREQ 2200000 /* 2.2 MHz */
#elif defined(CONFIG_SOC_DA8XX)
/* MDIO module input frequency */
#define EMAC_MDIO_BUS_FREQ clk_get(DAVINCI_MDIO_CLKID)
/* MDIO clock output frequency */
#define EMAC_MDIO_CLOCK_FREQ 2000000 /* 2.0 MHz */
#else
/* MDIO module input frequency */
#define EMAC_MDIO_BUS_FREQ 99000000 /* PLL/6 - 99 MHz */
@ -128,6 +145,10 @@ typedef volatile struct _emac_desc
#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE (0x1)
#define EMAC_MACCONTROL_GIGABIT_ENABLE (1 << 7)
#define EMAC_MACCONTROL_GIGFORCE (1 << 17)
#define EMAC_MACCONTROL_RMIISPEED_100 (1 << 15)
#define EMAC_MAC_ADDR_MATCH (1 << 19)
#define EMAC_MAC_ADDR_IS_VALID (1 << 20)
#define EMAC_RXMBPENABLE_RXCAFEN_ENABLE (0x200000)
#define EMAC_RXMBPENABLE_RXBROADEN (0x2000)
@ -283,10 +304,40 @@ typedef struct {
/* EMAC Wrapper Registers Structure */
typedef struct {
#if defined(CONFIG_SOC_DM646X) || defined(CONFIG_SOC_DM365)
dv_reg IDVER;
dv_reg SOFTRST;
dv_reg EMCTRL;
#ifdef DAVINCI_EMAC_VERSION2
dv_reg idver;
dv_reg softrst;
dv_reg emctrl;
dv_reg c0rxthreshen;
dv_reg c0rxen;
dv_reg c0txen;
dv_reg c0miscen;
dv_reg c1rxthreshen;
dv_reg c1rxen;
dv_reg c1txen;
dv_reg c1miscen;
dv_reg c2rxthreshen;
dv_reg c2rxen;
dv_reg c2txen;
dv_reg c2miscen;
dv_reg c0rxthreshstat;
dv_reg c0rxstat;
dv_reg c0txstat;
dv_reg c0miscstat;
dv_reg c1rxthreshstat;
dv_reg c1rxstat;
dv_reg c1txstat;
dv_reg c1miscstat;
dv_reg c2rxthreshstat;
dv_reg c2rxstat;
dv_reg c2txstat;
dv_reg c2miscstat;
dv_reg c0rximax;
dv_reg c0tximax;
dv_reg c1rximax;
dv_reg c1tximax;
dv_reg c2rximax;
dv_reg c2tximax;
#else
u_int8_t RSVD0[4100];
dv_reg EWCTL;

View File

@ -123,6 +123,11 @@ typedef volatile unsigned char vu_char;
#define debugX(level,fmt,args...)
#endif /* DEBUG */
#define error(fmt, args...) do { \
printf("ERROR: " fmt "\nat %s:%d/%s()\n", \
##args, __FILE__, __LINE__, __func__); \
} while (0)
#ifndef BUG
#define BUG() do { \
printf("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \

View File

@ -347,7 +347,8 @@
#define CONFIG_SYS_UEC1_TX_CLK QE_CLK10
#define CONFIG_SYS_UEC1_ETH_TYPE FAST_ETH
#define CONFIG_SYS_UEC1_PHY_ADDR 4
#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_100_MII
#define CONFIG_SYS_UEC1_INTERFACE_TYPE MII
#define CONFIG_SYS_UEC1_INTERFACE_SPEED 100
#endif
#define CONFIG_UEC_ETH2 /* ETH4 */
@ -358,7 +359,8 @@
#define CONFIG_SYS_UEC2_TX_CLK QE_CLK3
#define CONFIG_SYS_UEC2_ETH_TYPE FAST_ETH
#define CONFIG_SYS_UEC2_PHY_ADDR 0
#define CONFIG_SYS_UEC2_INTERFACE_MODE ENET_100_MII
#define CONFIG_SYS_UEC2_INTERFACE_TYPE MII
#define CONFIG_SYS_UEC2_INTERFACE_SPEED 100
#endif
/*

View File

@ -362,7 +362,8 @@
#define CONFIG_SYS_UEC1_TX_CLK QE_CLK10
#define CONFIG_SYS_UEC1_ETH_TYPE FAST_ETH
#define CONFIG_SYS_UEC1_PHY_ADDR 3
#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_100_MII
#define CONFIG_SYS_UEC1_INTERFACE_TYPE MII
#define CONFIG_SYS_UEC1_INTERFACE_SPEED 100
#endif
#define CONFIG_UEC_ETH2 /* ETH4 */
@ -373,7 +374,8 @@
#define CONFIG_SYS_UEC2_TX_CLK QE_CLK8
#define CONFIG_SYS_UEC2_ETH_TYPE FAST_ETH
#define CONFIG_SYS_UEC2_PHY_ADDR 4
#define CONFIG_SYS_UEC2_INTERFACE_MODE ENET_100_MII
#define CONFIG_SYS_UEC2_INTERFACE_TYPE MII
#define CONFIG_SYS_UEC2_INTERFACE_SPEED 100
#endif
/*

View File

@ -400,7 +400,8 @@
#define CONFIG_SYS_UEC1_TX_CLK QE_CLK9
#define CONFIG_SYS_UEC1_ETH_TYPE GIGA_ETH
#define CONFIG_SYS_UEC1_PHY_ADDR 0
#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_1000_RGMII_ID
#define CONFIG_SYS_UEC1_INTERFACE_TYPE RGMII_ID
#define CONFIG_SYS_UEC1_INTERFACE_SPEED 1000
#endif
#define CONFIG_UEC_ETH2 /* GETH2 */
@ -411,7 +412,8 @@
#define CONFIG_SYS_UEC2_TX_CLK QE_CLK4
#define CONFIG_SYS_UEC2_ETH_TYPE GIGA_ETH
#define CONFIG_SYS_UEC2_PHY_ADDR 1
#define CONFIG_SYS_UEC2_INTERFACE_MODE ENET_1000_RGMII_ID
#define CONFIG_SYS_UEC2_INTERFACE_TYPE RGMII_ID
#define CONFIG_SYS_UEC2_INTERFACE_SPEED 1000
#endif
/*

View File

@ -318,7 +318,8 @@
#define CONFIG_SYS_UEC1_TX_CLK QE_CLK9
#define CONFIG_SYS_UEC1_ETH_TYPE GIGA_ETH
#define CONFIG_SYS_UEC1_PHY_ADDR 2
#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_1000_RGMII_RXID
#define CONFIG_SYS_UEC1_INTERFACE_TYPE RGMII_RXID
#define CONFIG_SYS_UEC1_INTERFACE_SPEED 1000
#endif
#define CONFIG_UEC_ETH2 /* GETH2 */
@ -329,7 +330,8 @@
#define CONFIG_SYS_UEC2_TX_CLK QE_CLK4
#define CONFIG_SYS_UEC2_ETH_TYPE GIGA_ETH
#define CONFIG_SYS_UEC2_PHY_ADDR 4
#define CONFIG_SYS_UEC2_INTERFACE_MODE ENET_1000_RGMII_RXID
#define CONFIG_SYS_UEC2_INTERFACE_TYPE RGMII_RXID
#define CONFIG_SYS_UEC2_INTERFACE_SPEED 1000
#endif
/*

View File

@ -333,7 +333,8 @@ extern unsigned long get_clock_freq(void);
#define CONFIG_SYS_UEC1_TX_CLK QE_CLK16
#define CONFIG_SYS_UEC1_ETH_TYPE GIGA_ETH
#define CONFIG_SYS_UEC1_PHY_ADDR 7
#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_1000_RGMII_ID
#define CONFIG_SYS_UEC1_INTERFACE_TYPE RGMII_ID
#define CONFIG_SYS_UEC1_INTERFACE_SPEED 1000
#endif
#define CONFIG_UEC_ETH2 /* GETH2 */
@ -344,7 +345,8 @@ extern unsigned long get_clock_freq(void);
#define CONFIG_SYS_UEC2_TX_CLK QE_CLK16
#define CONFIG_SYS_UEC2_ETH_TYPE GIGA_ETH
#define CONFIG_SYS_UEC2_PHY_ADDR 1
#define CONFIG_SYS_UEC2_INTERFACE_MODE ENET_1000_RGMII_ID
#define CONFIG_SYS_UEC2_INTERFACE_TYPE RGMII_ID
#define CONFIG_SYS_UEC2_INTERFACE_SPEED 1000
#endif
#endif /* CONFIG_QE */

View File

@ -376,12 +376,14 @@ extern unsigned long get_clock_freq(void);
#define CONFIG_SYS_UEC1_TX_CLK QE_CLK12
#define CONFIG_SYS_UEC1_ETH_TYPE GIGA_ETH
#define CONFIG_SYS_UEC1_PHY_ADDR 7
#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_1000_RGMII_ID
#define CONFIG_SYS_UEC1_INTERFACE_TYPE RGMII_ID
#define CONFIG_SYS_UEC1_INTERFACE_SPEED 1000
#elif defined(CONFIG_SYS_UCC_RMII_MODE)
#define CONFIG_SYS_UEC1_TX_CLK QE_CLK16 /* CLK16 for RMII */
#define CONFIG_SYS_UEC1_ETH_TYPE FAST_ETH
#define CONFIG_SYS_UEC1_PHY_ADDR 8 /* 0x8 for RMII */
#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_100_RMII
#define CONFIG_SYS_UEC1_INTERFACE_TYPE RMII
#define CONFIG_SYS_UEC1_INTERFACE_SPEED 100
#endif /* CONFIG_SYS_UCC_RGMII_MODE */
#endif /* CONFIG_UEC_ETH1 */
@ -395,12 +397,14 @@ extern unsigned long get_clock_freq(void);
#define CONFIG_SYS_UEC2_TX_CLK QE_CLK17
#define CONFIG_SYS_UEC2_ETH_TYPE GIGA_ETH
#define CONFIG_SYS_UEC2_PHY_ADDR 1
#define CONFIG_SYS_UEC2_INTERFACE_MODE ENET_1000_RGMII_ID
#define CONFIG_SYS_UEC2_INTERFACE_TYPE RGMII_ID
#define CONFIG_SYS_UEC2_INTERFACE_SPEED 1000
#elif defined(CONFIG_SYS_UCC_RMII_MODE)
#define CONFIG_SYS_UEC2_TX_CLK QE_CLK16 /* CLK 16 for RMII */
#define CONFIG_SYS_UEC2_ETH_TYPE FAST_ETH
#define CONFIG_SYS_UEC2_PHY_ADDR 0x9 /* 0x9 for RMII */
#define CONFIG_SYS_UEC2_INTERFACE_MODE ENET_100_RMII
#define CONFIG_SYS_UEC2_INTERFACE_TYPE RMII
#define CONFIG_SYS_UEC2_INTERFACE_SPEED 100
#endif /* CONFIG_SYS_UCC_RGMII_MODE */
#endif /* CONFIG_UEC_ETH2 */
@ -414,12 +418,14 @@ extern unsigned long get_clock_freq(void);
#define CONFIG_SYS_UEC3_TX_CLK QE_CLK12
#define CONFIG_SYS_UEC3_ETH_TYPE GIGA_ETH
#define CONFIG_SYS_UEC3_PHY_ADDR 2
#define CONFIG_SYS_UEC3_INTERFACE_MODE ENET_1000_RGMII_ID
#define CONFIG_SYS_UEC3_INTERFACE_TYPE RGMII_ID
#define CONFIG_SYS_UEC3_INTERFACE_SPEED 1000
#elif defined(CONFIG_SYS_UCC_RMII_MODE)
#define CONFIG_SYS_UEC3_TX_CLK QE_CLK16 /* CLK_16 for RMII */
#define CONFIG_SYS_UEC3_ETH_TYPE FAST_ETH
#define CONFIG_SYS_UEC3_PHY_ADDR 0xA /* 0xA for RMII */
#define CONFIG_SYS_UEC3_INTERFACE_MODE ENET_100_RMII
#define CONFIG_SYS_UEC3_INTERFACE_TYPE RMII
#define CONFIG_SYS_UEC3_INTERFACE_SPEED 100
#endif /* CONFIG_SYS_UCC_RGMII_MODE */
#endif /* CONFIG_UEC_ETH3 */
@ -433,12 +439,14 @@ extern unsigned long get_clock_freq(void);
#define CONFIG_SYS_UEC4_TX_CLK QE_CLK17
#define CONFIG_SYS_UEC4_ETH_TYPE GIGA_ETH
#define CONFIG_SYS_UEC4_PHY_ADDR 3
#define CONFIG_SYS_UEC4_INTERFACE_MODE ENET_1000_RGMII_ID
#define CONFIG_SYS_UEC4_INTERFACE_TYPE RGMII_ID
#define CONFIG_SYS_UEC4_INTERFACE_SPEED 1000
#elif defined(CONFIG_SYS_UCC_RMII_MODE)
#define CONFIG_SYS_UEC4_TX_CLK QE_CLK16 /* CLK16 for RMII */
#define CONFIG_SYS_UEC4_ETH_TYPE FAST_ETH
#define CONFIG_SYS_UEC4_PHY_ADDR 0xB /* 0xB for RMII */
#define CONFIG_SYS_UEC4_INTERFACE_MODE ENET_100_RMII
#define CONFIG_SYS_UEC4_INTERFACE_TYPE RMII
#define CONFIG_SYS_UEC4_INTERFACE_SPEED 100
#endif /* CONFIG_SYS_UCC_RGMII_MODE */
#endif /* CONFIG_UEC_ETH4 */
@ -451,7 +459,8 @@ extern unsigned long get_clock_freq(void);
#define CONFIG_SYS_UEC6_TX_CLK QE_CLK_NONE
#define CONFIG_SYS_UEC6_ETH_TYPE GIGA_ETH
#define CONFIG_SYS_UEC6_PHY_ADDR 4
#define CONFIG_SYS_UEC6_INTERFACE_MODE ENET_1000_SGMII
#define CONFIG_SYS_UEC6_INTERFACE_TYPE SGMII
#define CONFIG_SYS_UEC6_INTERFACE_SPEED 1000
#endif /* CONFIG_UEC_ETH6 */
#undef CONFIG_UEC_ETH8 /* GETH8 */
@ -463,7 +472,8 @@ extern unsigned long get_clock_freq(void);
#define CONFIG_SYS_UEC8_TX_CLK QE_CLK_NONE
#define CONFIG_SYS_UEC8_ETH_TYPE GIGA_ETH
#define CONFIG_SYS_UEC8_PHY_ADDR 6
#define CONFIG_SYS_UEC8_INTERFACE_MODE ENET_1000_SGMII
#define CONFIG_SYS_UEC8_INTERFACE_TYPE SGMII
#define CONFIG_SYS_UEC8_INTERFACE_SPEED 1000
#endif /* CONFIG_UEC_ETH8 */
#endif /* CONFIG_QE */

View File

@ -122,7 +122,14 @@
#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM
#define CONFIG_SYS_MEMTEST_END CONFIG_SYS_MEMTEST_START + PHYS_SDRAM_SIZE - 262144
#define CONFIG_DRIVER_ETHER
#define CONFIG_NET_MULTI 1
#ifdef CONFIG_NET_MULTI
#define CONFIG_DRIVER_AT91EMAC 1
#define CONFIG_SYS_RX_ETH_BUFFER 8
#else
#define CONFIG_DRIVER_ETHER 1
#endif
#define CONFIG_NET_RETRY_COUNT 20
#define CONFIG_AT91C_USE_RMII

View File

@ -145,7 +145,13 @@
/*
* Network Driver Setting
*/
#define CONFIG_DRIVER_ETHER
#define CONFIG_NET_MULTI 1
#ifdef CONFIG_NET_MULTI
#define CONFIG_DRIVER_AT91EMAC 1
#define CONFIG_SYS_RX_ETH_BUFFER 8
#else
#define CONFIG_DRIVER_ETHER 1
#endif
#define CONFIG_NET_RETRY_COUNT 20
#define CONFIG_AT91C_USE_RMII

View File

@ -152,7 +152,13 @@
#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM
#define CONFIG_SYS_MEMTEST_END CONFIG_SYS_MEMTEST_START + PHYS_SDRAM_SIZE - 262144
#define CONFIG_DRIVER_ETHER
#define CONFIG_NET_MULTI 1
#ifdef CONFIG_NET_MULTI
#define CONFIG_DRIVER_AT91EMAC 1
#define CONFIG_SYS_RX_ETH_BUFFER 8
#else
#define CONFIG_DRIVER_ETHER 1
#endif
#define CONFIG_NET_RETRY_COUNT 20
#define CONFIG_AT91C_USE_RMII

View File

@ -128,7 +128,13 @@
#define CONFIG_SYS_MEMTEST_END \
(CONFIG_SYS_MEMTEST_START + PHYS_SDRAM_SIZE - 512 * 1024)
#define CONFIG_DRIVER_ETHER 1
#define CONFIG_NET_MULTI 1
#ifdef CONFIG_NET_MULTI
#define CONFIG_DRIVER_AT91EMAC 1
#define CONFIG_SYS_RX_ETH_BUFFER 8
#else
#define CONFIG_DRIVER_ETHER 1
#endif
#define CONFIG_NET_RETRY_COUNT 20
#define CONFIG_AT91C_USE_RMII 1
#define CONFIG_PHY_ADDRESS (1 << 5)

View File

@ -126,7 +126,13 @@
#define CONFIG_SYS_ALT_MEMTEST 1
#define CONFIG_SYS_MEMTEST_SCRATCH CONFIG_SYS_MEMTEST_START + PHYS_SDRAM_SIZE - 4
#define CONFIG_DRIVER_ETHER
#define CONFIG_NET_MULTI 1
#ifdef CONFIG_NET_MULTI
#define CONFIG_DRIVER_AT91EMAC 1
#define CONFIG_SYS_RX_ETH_BUFFER 8
#else
#define CONFIG_DRIVER_ETHER 1
#endif
#define CONFIG_NET_RETRY_COUNT 20
#undef CONFIG_AT91C_USE_RMII

View File

@ -115,7 +115,13 @@
#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM
#define CONFIG_SYS_MEMTEST_END CONFIG_SYS_MEMTEST_START + PHYS_SDRAM_SIZE - (512*1024)
#define CONFIG_DRIVER_ETHER
#define CONFIG_NET_MULTI 1
#ifdef CONFIG_NET_MULTI
#define CONFIG_DRIVER_AT91EMAC 1
#define CONFIG_SYS_RX_ETH_BUFFER 8
#else
#define CONFIG_DRIVER_ETHER 1
#endif
#define CONFIG_NET_RETRY_COUNT 20
#define CONFIG_SYS_FLASH_BASE 0x10000000

View File

@ -295,7 +295,8 @@
#define CONFIG_SYS_UEC1_TX_CLK QE_CLK17
#define CONFIG_SYS_UEC1_ETH_TYPE FAST_ETH
#define CONFIG_SYS_UEC1_PHY_ADDR 0
#define CONFIG_SYS_UEC1_INTERFACE_MODE ENET_100_RMII
#define CONFIG_SYS_UEC1_INTERFACE_TYPE RMII
#define CONFIG_SYS_UEC1_INTERFACE_SPEED 100
#endif
/*

View File

@ -34,6 +34,7 @@
#define AT91C_MASTER_CLOCK 59904000
#define AT91_SLOW_CLOCK 32768 /* slow clock */
#define CONFIG_AT91RM9200 1 /* It's an Atmel AT91RM9200 SoC */
#define CONFIG_AT91RM9200DK 1 /* on an AT91RM9200DK Board */
#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
@ -166,7 +167,13 @@
/* CONFIG_SYS_MEMTEST_START + PHYS_SDRAM_SIZE - 262144 */
#define CONFIG_SYS_MEMTEST_END 0x00100000
#define CONFIG_DRIVER_ETHER
#define CONFIG_NET_MULTI 1
#ifdef CONFIG_NET_MULTI
#define CONFIG_DRIVER_AT91EMAC 1
#define CONFIG_SYS_RX_ETH_BUFFER 8
#else
#define CONFIG_DRIVER_ETHER 1
#endif
#define CONFIG_NET_RETRY_COUNT 20
#define CONFIG_AT91C_USE_RMII

View File

@ -181,7 +181,13 @@
#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM
#define CONFIG_SYS_MEMTEST_END CONFIG_SYS_MEMTEST_START + PHYS_SDRAM_SIZE - 262144
#define CONFIG_DRIVER_ETHER
#define CONFIG_NET_MULTI 1
#ifdef CONFIG_NET_MULTI
#define CONFIG_DRIVER_AT91EMAC 1
#define CONFIG_SYS_RX_ETH_BUFFER 8
#else
#define CONFIG_DRIVER_ETHER 1
#endif
#define CONFIG_NET_RETRY_COUNT 20
#undef CONFIG_AT91C_USE_RMII

View File

@ -42,6 +42,7 @@ int cpu_eth_init(bd_t *bis);
/* Driver initialization prototypes */
int au1x00_enet_initialize(bd_t*);
int at91emac_register(bd_t *bis, unsigned long iobase);
int bfin_EMAC_initialize(bd_t *bis);
int cs8900_initialize(u8 dev_num, int base_addr);
int dc21x4x_initialize(bd_t *bis);
@ -49,6 +50,7 @@ int davinci_emac_initialize(void);
int dnet_eth_initialize(int id, void *regs, unsigned int phy_addr);
int e1000_initialize(bd_t *bis);
int eepro100_initialize(bd_t *bis);
int ep93xx_eth_initialize(u8 dev_num, int base_addr);
int eth_3com_initialize (bd_t * bis);
int fec_initialize (bd_t *bis);
int fecmxc_initialize (bd_t *bis);

View File

@ -153,6 +153,19 @@
#define MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK 0x0700
#define MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT 8
#define MIIM_BCM54XX_SHD 0x1c /* 0x1c shadow registers */
#define MIIM_BCM54XX_SHD_WRITE 0x8000
#define MIIM_BCM54XX_SHD_VAL(x) ((x & 0x1f) << 10)
#define MIIM_BCM54XX_SHD_DATA(x) ((x & 0x3ff) << 0)
#define MIIM_BCM54XX_SHD_WR_ENCODE(val, data) \
(MIIM_BCM54XX_SHD_WRITE | MIIM_BCM54XX_SHD_VAL(val) | \
MIIM_BCM54XX_SHD_DATA(data))
#define MIIM_BCM54XX_EXP_DATA 0x15 /* Expansion register data */
#define MIIM_BCM54XX_EXP_SEL 0x17 /* Expansion register select */
#define MIIM_BCM54XX_EXP_SEL_SSD 0x0e00 /* Secondary SerDes select */
#define MIIM_BCM54XX_EXP_SEL_ER 0x0f00 /* Expansion register select */
/* Cicada Auxiliary Control/Status Register */
#define MIIM_CIS8201_AUX_CONSTAT 0x1c
#define MIIM_CIS8201_AUXCONSTAT_INIT 0x0004
@ -571,9 +584,9 @@ typedef struct tsec
/* This flag currently only has
* meaning if we're using the eTSEC */
#define TSEC_REDUCED (1 << 1)
#define TSEC_SGMII (1 << 2)
#define TSEC_REDUCED (1 << 1) /* MAC-PHY interface uses RGMII */
#define TSEC_SGMII (1 << 2) /* MAC-PHY interface uses SGMII */
#define TSEC_FIBER (1 << 3) /* PHY uses fiber, eg 1000 Base-X */
struct tsec_private {
volatile tsec_t *regs;
@ -644,7 +657,6 @@ struct tsec_info_struct {
u32 flags;
};
int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info);
int tsec_standard_init(bd_t *bis);
int tsec_eth_init(bd_t *bis, struct tsec_info_struct *tsec_info, int num);