Merge branch 'master' of git://git.denx.de/u-boot-net
This commit is contained in:
commit
05c2f4fe29
10
README
10
README
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
/*
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
498
drivers/net/at91_emac.c
Normal 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;
|
||||
}
|
@ -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));
|
||||
|
@ -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
653
drivers/net/ep93xx_eth.c
Normal 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
144
drivers/net/ep93xx_eth.h
Normal 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
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
122
drivers/qe/uec.c
122
drivers/qe/uec.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
145
include/asm-arm/arch-at91/at91_emac.h
Normal file
145
include/asm-arm/arch-at91/at91_emac.h
Normal 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
|
@ -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;
|
||||
|
@ -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__); \
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user