All of lore.kernel.org
 help / color / mirror / Atom feed
From: TsiChung Liew <Tsi-Chung.Liew@freescale.com>
To: u-boot@lists.denx.de
Subject: [U-Boot-Users] Patch: MPC8220 FEC and DMA update - part 1
Date: Mon, 14 May 2007 18:23:29 -0500	[thread overview]
Message-ID: <1179185010.19082.6.camel@Goku> (raw)

- Better handling in ethernet MII, applied new DMA functions
 
Regards,
TsiChung Liew
 
Signed-off by: TsiChung Liew Tsi-Chung.Liew at freescale.com

diff -rupN u-boot-all.git/cpu/mpc8220/cpu_init.c u-boot-all-8220-
fec/cpu/mpc8220/cpu_init.c
--- u-boot-all.git/cpu/mpc8220/cpu_init.c 2007-04-03 19:18:56.000000000
-0500
+++ u-boot-all-8220-fec/cpu/mpc8220/cpu_init.c 2007-05-10
16:51:31.000000000 -0500
@@ -23,6 +23,7 @@

#include <common.h>
#include <mpc8220.h>
+#include "MCD_dma.h"

DECLARE_GLOBAL_DATA_PTR;

@@ -129,8 +130,8 @@ int cpu_init_r (void)
*(vu_long *) 0xf0000710 |= 0x00000001;

#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_MPC8220_FEC)
- /* load FEC microcode */
- loadtask (0, 2);
+ MCD_initDma((dmaRegs *) (MMAP_DMA), (void *)(MMAP_SRAM + 512),
+     MCD_RELOC_TASKS);
#endif
return (0);
}
diff -rupN u-boot-all.git/cpu/mpc8220/dma.h u-boot-all-8220-
fec/cpu/mpc8220/dma.h
--- u-boot-all.git/cpu/mpc8220/dma.h 2007-04-03 19:18:56.000000000 -0500
+++ u-boot-all-8220-fec/cpu/mpc8220/dma.h 2007-05-10 16:51:42.000000000
-0500
@@ -23,21 +23,8 @@
  *---------------------------------------------------------------------
  */

-/* Layout of Ethernet controller Parameter SRAM area:
- * ----------------------------------------------------------------
- * 0x00: TBD_BASE, base address of TX BD ring
- * 0x04: TBD_NEXT, address of next TX BD to be processed
- * 0x08: RBD_BASE, base address of RX BD ring
- * 0x0C: RBD_NEXT, address of next RX BD to be processed
- * ---------------------------------------------------------------
- * ALL PARAMETERS ARE ALL LONGWORDS (FOUR BYTES EACH).
- */
-
-/* base address of SRAM area to store parameters used by Ethernet tasks
*/
-#define FEC_PARAM_BASE  (MMAP_SRAM + 0x5b00)
-
/* base address of SRAM area for buffer descriptors */
-#define FEC_BD_BASE     (MMAP_SRAM + 0x5b20)
+#define FEC1_BD_BASE     (MMAP_SRAM + 0x2200)

/*---------------------------------------------------------------------
  * common shortcuts  used  by driver C code
diff -rupN u-boot-all.git/cpu/mpc8220/fec.c u-boot-all-8220-
fec/cpu/mpc8220/fec.c
--- u-boot-all.git/cpu/mpc8220/fec.c 2007-04-03 19:18:56.000000000 -0500
+++ u-boot-all-8220-fec/cpu/mpc8220/fec.c 2007-05-10 16:52:47.000000000
-0500
@@ -12,41 +12,173 @@
#include <net.h>
#include <miiphy.h>
#include "dma.h"
+#include "MCD_dma.h"
#include "fec.h"

-#undef  DEBUG
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
     defined(CONFIG_MPC8220_FEC)

+DECLARE_GLOBAL_DATA_PTR;
+
#if !(defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII))
#error "CONFIG_MII has to be defined!"
#endif

-#ifdef DEBUG
-static void tfifo_print (char *devname, mpc8220_fec_priv * fec);
-static void rfifo_print (char *devname, mpc8220_fec_priv * fec);
-#endif /* DEBUG */
-
-#ifdef DEBUG
-static u32 local_crc32 (char *string, unsigned int crc_value, int len);
+/* dma related defines */
+#define FEC1_RX_TASK        0
+#define FEC1_TX_TASK        1
+#define FEC1_RX_PRIORITY    6
+#define FEC1_TX_PRIORITY    7
+#define FEC1_RX_INIT        16
+#define FEC1_TX_INIT        17
+
+#define FEC2_RX_TASK        2
+#define FEC2_TX_TASK        3
+#define FEC2_RX_PRIORITY    6
+#define FEC2_TX_PRIORITY    7
+#define FEC2_RX_INIT        30
+#define FEC2_TX_INIT        31
+
+#define FEC1_TBD_BASE FEC1_BD_BASE
+#define FEC1_RBD_BASE FEC1_BD_BASE + (FEC_TBD_NUM * sizeof(FEC_BD))
+#define FEC2_TBD_BASE FEC1_RBD_BASE + (FEC_RBD_NUM * sizeof(FEC_BD))
+#define FEC2_RBD_BASE FEC2_TBD_BASE + (FEC_TBD_NUM * sizeof(FEC_BD))
+
+#define PKT_MAXBUF_SIZE 1518
+#define TOUT_LOOP 8000
+#define FIFO_ERRSTAT (FIFO_STAT_RXW | FIFO_STAT_UF | FIFO_STAT_OF)
+
+#undef ET_DEBUG
+
+mpc8220_fec_priv fec_info[] = {
+ {
+ MMAP_FEC1, /* io base */
+ 0, /* num */
+ FEC1_RX_TASK, /* rxTask */
+ FEC1_TX_TASK, /* txTask */
+ FEC1_RX_PRIORITY, /* rxPri */
+ FEC1_TX_PRIORITY, /* txPri */
+ FEC1_RX_INIT, /* rxInit */
+ FEC1_TX_INIT, /* txInit */
+ MII10, /* xcv_type */
+#ifdef CFG_DISCOVER_PHY
+ -1, /* phy_addr */
+#else
+ CONFIG_PHY_ADDR,
#endif
-
-typedef struct {
- u8 data[1500]; /* actual data */
- int length; /* actual length */
- int used; /* buffer in use or not */
- u8 head[16]; /* MAC header(6 + 6 + 2) + 2(aligned) */
-} NBUF;
+ 0, /* phy_dupspd */
+ 0, /* phy_name */
+ 0, /* phyname init */
+ (FEC_BD *) FEC1_RBD_BASE, /* rbdBase */
+ (FEC_BD *) FEC1_TBD_BASE, /* tbdBase */
+ 0, /* rbdIndex */
+ 0, /* tbdIndex */
+ 0, /* usedTbdIndex */
+ 0, /* cleanTbdNum */
+ }
+ ,
+#ifdef CONFIG_HAS_ETH1
+ {
+ MMAP_FEC2, /* io base */
+ 1, /* num */
+ FEC2_RX_TASK, /* rxTask */
+ FEC2_TX_TASK, /* txTask */
+ FEC2_RX_PRIORITY, /* rxPri */
+ FEC2_TX_PRIORITY, /* txPri */
+ FEC2_RX_INIT, /* rxInit */
+ FEC2_TX_INIT, /* txInit */
+ MII10, /* xcv_type */
+#ifdef CFG_DISCOVER_PHY
+ -1, /* phy_addr */
+#else
+ CONFIG_PHY1_ADDR,
+#endif
+ 0, /* phy_dupspd */
+ 0, /* phy_name */
+ 0, /* phyname init */
+ (FEC_BD *) FEC2_RBD_BASE, /* rbdBase */
+ (FEC_BD *) FEC2_TBD_BASE, /* tbdBase */
+ 0, /* rbdIndex */
+ 0, /* tbdIndex */
+ 0, /* usedTbdIndex */
+ 0, /* cleanTbdNum */
+ }
+#endif
+};
+
+int mpc8220_fec_rbd_init(mpc8220_fec_priv * fec);
+void mpc8220_fec_tbd_init(mpc8220_fec_priv * fec);
+void mpc8220_fec_rbd_clean(mpc8220_fec_priv * fec, FEC_BD * pRbd);
+void mpc8220_fec_rbd_clean(mpc8220_fec_priv * fec, FEC_BD * pRbd);
+void mpc8220_fec_tbd_scrub(mpc8220_fec_priv * fec);
+void mpc8220_fec_set_hwaddr(mpc8220_fec_priv * fec, char *mac);
+void mpc8220_fec_set_hwaddr(mpc8220_fec_priv * fec, char *mac);
+void mpc8220_fec_halt(struct eth_device *dev);
+int mpc8220_fec_init(struct eth_device *dev, bd_t * bis);
+int mpc8220_fec_send(struct eth_device *dev, volatile void *eth_data,
+      int data_length);
+int mpc8220_fec_recv(struct eth_device *dev);
+int mpc8220_fec_initialize(bd_t * bis);
+void setFecDuplexSpeed(mpc8220_fec_priv * fec);
+void mii_discover_phy(struct eth_device *dev);
+int check_connection(struct eth_device *dev);

int fec8220_miiphy_read (char *devname, u8 phyAddr, u8 regAddr, u16 *
retVal);
int fec8220_miiphy_write (char *devname, u8 phyAddr, u8 regAddr, u16
data);

/********************************************************************/
-#ifdef DEBUG
-static void mpc8220_fec_phydump (char *devname)
+#ifdef ET_DEBUG
+static void tfifo_print(char *devname, mpc8220_fec_priv * fec)
+{
+ volatile ethernet_regs *eth = (volatile ethernet_regs *)fec->iobase;
+ u16 phyStatus;
+
+ if ((eth->tfifo_lrf_ptr != eth->tfifo_lwf_ptr)
+     || (eth->tfifo_rdptr != eth->tfifo_wrptr)) {
+
+ miiphy_read(devname, fec->phy_addr, PHY_BMSR, &phyStatus);
+ printf("\nphyStatus: 0x%04x\n", phyStatus);
+ printf("ecntrl:   0x%08x\n", eth->ecntrl);
+ printf("ievent:   0x%08x\n", eth->ievent);
+ printf("x_status: 0x%08x\n", eth->x_status);
+ printf("tfifo: status 0x%08x\n", eth->tfifo_status);
+
+ printf(" control 0x%08x\n", eth->tfifo_cntrl);
+ printf(" lrfp 0x%08x\n", eth->tfifo_lrf_ptr);
+ printf(" lwfp 0x%08x\n", eth->tfifo_lwf_ptr);
+ printf(" alarm 0x%08x\n", eth->tfifo_alarm);
+ printf(" readptr 0x%08x\n", eth->tfifo_rdptr);
+ printf(" writptr 0x%08x\n", eth->tfifo_wrptr);
+ }
+}
+
+static void rfifo_print(char *devname, mpc8220_fec_priv * fec)
+{
+ volatile ethernet_regs *eth = (volatile ethernet_regs *)fec->iobase;
+ u16 phyStatus;
+
+ if ((eth->rfifo_lrf_ptr != eth->rfifo_lwf_ptr)
+     || (eth->rfifo_rdptr != eth->rfifo_wrptr)) {
+
+ miiphy_read(devname, fec->phy_addr, PHY_BMSR, &phyStatus);
+ printf("\nphyStatus: 0x%04x\n", phyStatus);
+ printf("ecntrl:   0x%08x\n", eth->ecntrl);
+ printf("ievent:   0x%08x\n", eth->ievent);
+ printf("x_status: 0x%08x\n", eth->x_status);
+ printf("rfifo: status 0x%08x\n", eth->rfifo_status);
+
+ printf(" control 0x%08x\n", eth->rfifo_cntrl);
+ printf(" lrfp 0x%08x\n", eth->rfifo_lrf_ptr);
+ printf(" lwfp 0x%08x\n", eth->rfifo_lwf_ptr);
+ printf(" alarm 0x%08x\n", eth->rfifo_alarm);
+ printf(" readptr 0x%08x\n", eth->rfifo_rdptr);
+ printf(" writptr 0x%08x\n", eth->rfifo_wrptr);
+ }
+}
+
+static void mpc8220_fec_phydump(char *devname, mpc8220_fec_priv * fec)
{
u16 phyStatus, i;
- u8 phyAddr = CONFIG_PHY_ADDR;
u8 reg_mask[] = {
#if CONFIG_PHY_TYPE == 0x79c874 /* AMD Am79C874 */
/* regs to print: 0...7, 16...19, 21, 23, 24 */
@@ -61,7 +193,7 @@ static void mpc8220_fec_phydump (char *d

for (i = 0; i < 32; i++) {
if (reg_mask[i]) {
- miiphy_read (devname, phyAddr, i, &phyStatus);
+ miiphy_read(devname, fec->phy_addr, i, &phyStatus);
printf ("Mii reg %d: 0x%04x\n", i, phyStatus);
}
}
@@ -69,7 +201,7 @@ static void mpc8220_fec_phydump (char *d
#endif

/********************************************************************/
-static int mpc8220_fec_rbd_init (mpc8220_fec_priv * fec)
+int mpc8220_fec_rbd_init(mpc8220_fec_priv * fec)
{
int ix;
char *data;
@@ -85,7 +217,7 @@ static int mpc8220_fec_rbd_init (mpc8220
fec->rbdBase[ix].dataPointer = (u32) data;
}
fec->rbdBase[ix].status = FEC_RBD_EMPTY;
- fec->rbdBase[ix].dataLength = 0;
+ fec->rbdBase[ix].dataLength = FEC_MAX_PKT_SIZE;
}
once++;

@@ -99,7 +231,7 @@ static int mpc8220_fec_rbd_init (mpc8220
}

/********************************************************************/
-static void mpc8220_fec_tbd_init (mpc8220_fec_priv * fec)
+void mpc8220_fec_tbd_init(mpc8220_fec_priv * fec)
{
int ix;

@@ -121,7 +253,7 @@ static void mpc8220_fec_tbd_init (mpc822
}

/********************************************************************/
-static void mpc8220_fec_rbd_clean (mpc8220_fec_priv * fec, FEC_RBD *
pRbd)
+void mpc8220_fec_rbd_clean(mpc8220_fec_priv * fec, FEC_BD * pRbd)
{
/*
* Reset buffer descriptor as empty
@@ -131,12 +263,12 @@ static void mpc8220_fec_rbd_clean (mpc82
else
pRbd->status = FEC_RBD_EMPTY;

- pRbd->dataLength = 0;
+ pRbd->dataLength = FEC_MAX_PKT_SIZE;

/*
- * Now, we have an empty RxBD, restart the SmartDMA receive task
+ * Now, we have an empty RxBD, restart the DMA receive task
*/
- DMA_TASK_ENABLE (FEC_RECV_TASK_NO);
+ MCD_continDma(fec->rxTask);

/*
* Increment BD count
@@ -145,11 +277,11 @@ static void mpc8220_fec_rbd_clean (mpc82
}

/********************************************************************/
-static void mpc8220_fec_tbd_scrub (mpc8220_fec_priv * fec)
+void mpc8220_fec_tbd_scrub(mpc8220_fec_priv * fec)
{
- FEC_TBD *pUsedTbd;
+ FEC_BD *pUsedTbd;

-#ifdef DEBUG
+#ifdef ET_DEBUG
printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n",
fec->cleanTbdNum, fec->usedTbdIndex);
#endif
@@ -160,7 +292,7 @@ static void mpc8220_fec_tbd_scrub (mpc82
while (fec->cleanTbdNum < FEC_TBD_NUM) {
pUsedTbd = &fec->tbdBase[fec->usedTbdIndex];
if (pUsedTbd->status & FEC_TBD_READY) {
-#ifdef DEBUG
+#ifdef ET_DEBUG
printf ("Cannot clean TBD %d, in use\n",
fec->cleanTbdNum);
#endif
@@ -184,13 +316,13 @@ static void mpc8220_fec_tbd_scrub (mpc82
}

/********************************************************************/
-static void mpc8220_fec_set_hwaddr (mpc8220_fec_priv * fec, char *mac)
+void mpc8220_fec_set_hwaddr(mpc8220_fec_priv * fec, char *mac)
{
+ volatile ethernet_regs *eth = (volatile ethernet_regs *)fec->iobase;
u8 currByte; /* byte for which to compute the CRC */
int byte; /* loop - counter */
int bit; /* loop - counter */
u32 crc = 0xffffffff; /* initial value */
-
/*
* The algorithm used is the following:
* we loop on each of the six bytes of the provided address,
@@ -225,32 +357,32 @@ static void mpc8220_fec_set_hwaddr (mpc8
* Set individual hash table register
*/
if (crc >= 32) {
- fec->eth->iaddr1 = (1 << (crc - 32));
- fec->eth->iaddr2 = 0;
+ eth->iaddr1 = (1 << (crc - 32));
+ eth->iaddr2 = 0;
} else {
- fec->eth->iaddr1 = 0;
- fec->eth->iaddr2 = (1 << crc);
+ eth->iaddr1 = 0;
+ eth->iaddr2 = (1 << crc);
}

/*
* Set physical address
*/
- fec->eth->paddr1 =
- (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3];
- fec->eth->paddr2 = (mac[4] << 24) + (mac[5] << 16) + 0x8808;
+ eth->paddr1 = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac
[3];
+ eth->paddr2 = (mac[4] << 24) + (mac[5] << 16) + 0x8808;
}

/********************************************************************/
-static int mpc8220_fec_init (struct eth_device *dev, bd_t * bis)
+int mpc8220_fec_init(struct eth_device *dev, bd_t * bis)
{
mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv;
- struct mpc8220_dma *dma = (struct mpc8220_dma *) MMAP_DMA;
- const u8 phyAddr = CONFIG_PHY_ADDR; /* Only one PHY */
+ volatile ethernet_regs *eth = (volatile ethernet_regs *)fec->iobase;

-#ifdef DEBUG
+#ifdef ET_DEBUG
printf ("mpc8220_fec_init... Begin\n");
#endif

+ mpc8220_fec_halt(dev);
+
/*
* Initialize RxBD/TxBD rings
*/
@@ -258,59 +390,88 @@ static int mpc8220_fec_init (struct eth_
mpc8220_fec_tbd_init (fec);

/*
- * Set up Pin Muxing for FEC 1
+ * Set up Pin Muxing for FEC
*/
+ if (fec->num == 0) {
+ /* pin mux for fec 1 */
*(vu_long *) MMAP_PCFG = 0;
- *(vu_long *) (MMAP_PCFG + 4) = 0;
+ *(vu_long *) (MMAP_PCFG + 4) &= 0x7fffffff;
+ } else if (fec->num == 1) {
+ /* pin mux for fec 2 */
+ *(vu_long *) (MMAP_PCFG + 8) &= 0x00000013;
+ *(vu_long *) (MMAP_PCFG + 0xc) &= 0xffffffdf;
+ }
+
/*
* Clear FEC-Lite interrupt event register(IEVENT)
*/
- fec->eth->ievent = 0xffffffff;
+ eth->ievent = FEC_EIR_CLEAR_ALL;

/*
* Set interrupt mask register
*/
- fec->eth->imask = 0x00000000;
+ eth->imask = 0;

/*
- * Set FEC-Lite receive control register(R_CNTRL):
+ * Set individual address filter for unicast address
+ * and set physical address registers.
*/
- if (fec->xcv_type == SEVENWIRE) {
- /*
- * Frame length=1518; 7-wire mode
- */
- fec->eth->r_cntrl = 0x05ee0020; /*0x05ee0000;FIXME */
- } else {
+ mpc8220_fec_set_hwaddr(fec, (char *)(dev->enetaddr));
+
/*
- * Frame length=1518; MII mode;
+ * Set multicast address filter
*/
- fec->eth->r_cntrl = 0x05ee0024; /*0x05ee0004;FIXME */
- }
+ eth->gaddr1 = 0;
+ eth->gaddr2 = 0;

- fec->eth->x_cntrl = 0x00000000; /* half-duplex, heartbeat disabled */
if (fec->xcv_type != SEVENWIRE) {
/*
* Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
* and do not drop the Preamble.
*/
- /* tbd - rtm */
- /*fec->eth->mii_speed = (((gd->ipb_clk >> 20) / 5) << 1); */
/* No MII for 7-wire mode */
- fec->eth->mii_speed = 0x00000030;
+ eth->mii_speed =
+     FEC_MSCR_MII_SPEED((gd->bus_clk / 1000000) / 5);
+ }
+
+ if (fec->xcv_type != SEVENWIRE) {
+#ifdef CFG_DISCOVER_PHY
+ mii_discover_phy(dev);
+#endif
+ if (check_connection(dev) == 0) {
+ printf("check cable connection!\n");
+ return -1;
+ }
+
+ /* adapt to the half/full speed settings */
+ fec->phy_dupspd = miiphy_duplex(dev->name, fec->phy_addr) << 16;
+ fec->phy_dupspd |= miiphy_speed(dev->name, fec->phy_addr);
+
+ switch (fec->phy_dupspd & 0xffff) {
+ case 10:
+ fec->xcv_type = MII10;
+ break;
+ case 100:
+ fec->xcv_type = MII100;
+ break;
+ }
}

+ setFecDuplexSpeed(fec);
+
/*
* Set Opcode/Pause Duration Register
*/
- fec->eth->op_pause = 0x00010020; /*FIXME0xffff0020; */
+ eth->op_pause = 0x00010020; /*FIXME0xffff0020; */

/*
* Set Rx FIFO alarm and granularity value
*/
- fec->eth->rfifo_cntrl = 0x0c000000;
- fec->eth->rfifo_alarm = 0x0000030c;
-#ifdef DEBUG
- if (fec->eth->rfifo_status & 0x00700000) {
+ eth->rfifo_cntrl = 0x0c000000;
+ eth->rfifo_alarm = 0x0000030c;
+
+#ifdef ET_DEBUG
+ if (eth->rfifo_status & FIFO_ERRSTAT) {
printf ("mpc8220_fec_init() RFIFO error\n");
}
#endif
@@ -318,197 +479,63 @@ static int mpc8220_fec_init (struct eth_
/*
* Set Tx FIFO granularity value
*/
- /*fec->eth->tfifo_cntrl = 0x0c000000; */ /*tbd - rtm */
- fec->eth->tfifo_cntrl = 0x0e000000;
-#ifdef DEBUG
- printf ("tfifo_status: 0x%08x\n", fec->eth->tfifo_status);
- printf ("tfifo_alarm: 0x%08x\n", fec->eth->tfifo_alarm);
+ eth->tfifo_cntrl = FIFO_CTRL_FRAME | FIFO_CTRL_GR(6) | 0x00040000;
+
+#ifdef ET_DEBUG
+ printf("tfifo_status: 0x%08x\n", eth->tfifo_status);
+ printf("tfifo_alarm: 0x%08x\n", eth->tfifo_alarm);
#endif

/*
* Set transmit fifo watermark register(X_WMRK), default = 64
*/
- fec->eth->tfifo_alarm = 0x00000080;
- fec->eth->x_wmrk = 0x2;
-
- /*
- * Set individual address filter for unicast address
- * and set physical address registers.
- */
- mpc8220_fec_set_hwaddr (fec, (char *)(dev->enetaddr));
-
- /*
- * Set multicast address filter
- */
- fec->eth->gaddr1 = 0x00000000;
- fec->eth->gaddr2 = 0x00000000;
+ eth->tfifo_alarm = 0x00000080;
+ eth->x_wmrk = 0x2;

/*
* Turn ON cheater FSM: ????
*/
- fec->eth->xmit_fsm = 0x03000000;
-
-#if 1
-/*#if defined(CONFIG_MPC5200)*/
- /*
- * Turn off COMM bus prefetch in the MGT5200 BestComm. It doesn't
- * work w/ the current receive task.
- */
- dma->PtdCntrl |= 0x00000001;
-#endif
+ eth->xmit_fsm = 0x03000000;

- /*
- * Set priority of different initiators
- */
- dma->IPR0 = 7; /* always */
- dma->IPR3 = 6; /* Eth RX */
- dma->IPR4 = 5; /* Eth Tx */
-
- /*
- * Clear SmartDMA task interrupt pending bits
- */
- DMA_CLEAR_IEVENT (FEC_RECV_TASK_NO);
-
- /*
- * Initialize SmartDMA parameters stored in SRAM
- */
- *(int *) FEC_TBD_BASE = (int) fec->tbdBase;
- *(int *) FEC_RBD_BASE = (int) fec->rbdBase;
- *(int *) FEC_TBD_NEXT = (int) fec->tbdBase;
- *(int *) FEC_RBD_NEXT = (int) fec->rbdBase;
-
- if (fec->xcv_type != SEVENWIRE) {
- /*
- * Initialize PHY(LXT971A):
- *
- *   Generally, on power up, the LXT971A reads its configuration
- *   pins to check for forced operation, If not cofigured for
- *   forced operation, it uses auto-negotiation/parallel detection
- *   to automatically determine line operating conditions.
- *   If the PHY device on the other side of the link supports
- *   auto-negotiation, the LXT971A auto-negotiates with it
- *   using Fast Link Pulse(FLP) Bursts. If the PHY partner does not
- *   support auto-negotiation, the LXT971A automatically detects
- *   the presence of either link pulses(10Mbps PHY) or Idle
- *   symbols(100Mbps) and sets its operating conditions accordingly.
- *
- *   When auto-negotiation is controlled by software, the following
- *   steps are recommended.
- *
- * Note:
- *   The physical address is dependent on hardware configuration.
- *
- */
- int timeout = 1;
- u16 phyStatus;
-
- /*
- * Reset PHY, then delay 300ns
- */
- miiphy_write (dev->name, phyAddr, 0x0, 0x8000);
- udelay (1000);
-
- if (fec->xcv_type == MII10) {
- /*
- * Force 10Base-T, FDX operation
- */
-#ifdef DEBUG
- printf ("Forcing 10 Mbps ethernet link... ");
-#endif
- miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
- /*
-    miiphy_write(fec, phyAddr, 0x0, 0x0100);
- */
- miiphy_write (dev->name, phyAddr, 0x0, 0x0180);
-
- timeout = 20;
- do { /* wait for link status to go down */
- udelay (10000);
- if ((timeout--) == 0) {
-#ifdef DEBUG
- printf ("hmmm, should not have waited...");
-#endif
- break;
- }
- miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
-#ifdef DEBUG
- printf ("=");
-#endif
- } while ((phyStatus & 0x0004)); /* !link up */
-
- timeout = 1000;
- do { /* wait for link status to come back up */
- udelay (10000);
- if ((timeout--) == 0) {
- printf ("failed. Link is down.\n");
- break;
- }
- miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
-#ifdef DEBUG
- printf ("+");
-#endif
- } while (!(phyStatus & 0x0004)); /* !link up */
-
-#ifdef DEBUG
- printf ("done.\n");
-#endif
- } else { /* MII100 */
- /*
- * Set the auto-negotiation advertisement register bits
- */
- miiphy_write (dev->name, phyAddr, 0x4, 0x01e1);
-
- /*
- * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
- */
- miiphy_write (dev->name, phyAddr, 0x0, 0x1200);
-
- /*
- * Wait for AN completion
- */
- timeout = 5000;
- do {
- udelay (1000);
-
- if ((timeout--) == 0) {
-#ifdef DEBUG
- printf ("PHY auto neg 0 failed...\n");
-#endif
- return -1;
- }
-
- if (miiphy_read (dev->name, phyAddr, 0x1, &phyStatus) !=
-     0) {
-#ifdef DEBUG
- printf ("PHY auto neg 1 failed 0x%04x...\n", phyStatus);
+#ifdef ET_DEBUG
+ if (fec->xcv_type != SEVENWIRE)
+ mpc8220_fec_phydump(dev->name, fec);
#endif
- return -1;
- }
- } while (!(phyStatus & 0x0004));

-#ifdef DEBUG
- printf ("PHY auto neg complete! \n");
-#endif
- }
-
- }
+ /* Enable DMA receive task */
+ MCD_startDma(fec->rxTask, /* Dma channel */
+      (u8 *) fec->rbdBase, /*Source Address */
+      0, /* Source increment */
+      (u8 *) (&eth->rfifo_data), /* dest */
+      4, /* dest increment */
+      0, /* DMA size */
+      4, /* xfer size */
+      fec->rxInit, /* initiator */
+      fec->rxPri, /* priority */
+      (MCD_FECRX_DMA | MCD_TT_FLAGS_DEF), /* Flags */
+      (MCD_NO_CSUM | MCD_NO_BYTE_SWAP) /* Function description */
+     );
+
+ /* Enable DMA tx task with no ready buffer descriptors */
+ MCD_startDma(fec->txTask, /* Dma channel */
+      (u8 *) fec->tbdBase, /*Source Address */
+      0, /* Source increment */
+      (u8 *) (&eth->tfifo_data), /* dest */
+      4, /* dest incr */
+      0, /* DMA size */
+      4, /* xfer size */
+      fec->txInit, /* initiator */
+      fec->txPri, /* priority */
+      (MCD_FECTX_DMA | MCD_TT_FLAGS_DEF), /* Flags */
+      (MCD_NO_CSUM | MCD_NO_BYTE_SWAP) /* Function description */
+     );

/*
* Enable FEC-Lite controller
*/
- fec->eth->ecntrl |= 0x00000006;
-
-#ifdef DEBUG
- if (fec->xcv_type != SEVENWIRE)
- mpc8220_fec_phydump (dev->name);
-#endif
-
- /*
- * Enable SmartDMA receive task
- */
- DMA_TASK_ENABLE (FEC_RECV_TASK_NO);
+ eth->ecntrl |= FEC_ECR_ETHER_EN;

-#ifdef DEBUG
+#ifdef ET_DEBUG
printf ("mpc8220_fec_init... Done \n");
#endif

@@ -516,120 +543,71 @@ static int mpc8220_fec_init (struct eth_
}

/********************************************************************/
-static void mpc8220_fec_halt (struct eth_device *dev)
+void mpc8220_fec_halt(struct eth_device *dev)
{
mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv;
+ volatile ethernet_regs *eth = (volatile ethernet_regs *)fec->iobase;
int counter = 0xffff;

-#ifdef DEBUG
+#ifdef ET_DEBUG
+ printf("mpc8220_fec_halt...\n");
+
if (fec->xcv_type != SEVENWIRE)
- mpc8220_fec_phydump (dev->name);
+ mpc8220_fec_phydump(dev->name, fec);
#endif

/*
- * mask FEC chip interrupts
- */
- fec->eth->imask = 0;
-
- /*
* issue graceful stop command to the FEC transmitter if necessary
*/
- fec->eth->x_cntrl |= 0x00000001;
+ eth->x_cntrl |= FEC_TCR_GTS;

/*
* wait for graceful stop to register
*/
- while ((counter--) && (!(fec->eth->ievent & 0x10000000)));
+ while ((counter--) && (!(eth->ievent & FEC_EIR_GRA))) ;

/*
- * Disable SmartDMA tasks
+ * Disable DMA tasks
*/
- DMA_TASK_DISABLE (FEC_XMIT_TASK_NO);
- DMA_TASK_DISABLE (FEC_RECV_TASK_NO);
+ MCD_killDma(fec->txTask);
+ MCD_killDma(fec->rxTask);;

/*
* Disable the Ethernet Controller
*/
- fec->eth->ecntrl &= 0xfffffffd;
+ eth->ecntrl &= ~FEC_ECR_ETHER_EN;

/*
* Clear FIFO status registers
*/
- fec->eth->rfifo_status &= 0x00700000;
- fec->eth->tfifo_status &= 0x00700000;
+ eth->rfifo_status &= FIFO_ERRSTAT;
+ eth->tfifo_status &= FIFO_ERRSTAT;

- fec->eth->reset_cntrl = 0x01000000;
+ eth->reset_cntrl = 0x01000000;
+
+ /* reset phy */
+ if (fec->xcv_type != SEVENWIRE) {
+ miiphy_read(dev->name, fec->phy_addr, PHY_BMCR, PHY_BMCR_RESET);
+ udelay(10000);
+ }

/*
* Issue a reset command to the FEC chip
*/
- fec->eth->ecntrl |= 0x1;
+ eth->ecntrl |= FEC_ECR_RESET;

/*
- * wait at least 16 clock cycles
+ * wait at least 20 clock cycles
*/
- udelay (10);
+ udelay(20);

-#ifdef DEBUG
+#ifdef ET_DEBUG
printf ("Ethernet task stopped\n");
#endif
}

-#ifdef DEBUG
/********************************************************************/
-
-static void tfifo_print (char *devname, mpc8220_fec_priv * fec)
-{
- u16 phyAddr = CONFIG_PHY_ADDR;
- u16 phyStatus;
-
- if ((fec->eth->tfifo_lrf_ptr != fec->eth->tfifo_lwf_ptr)
-     || (fec->eth->tfifo_rdptr != fec->eth->tfifo_wrptr)) {
-
- miiphy_read (devname, phyAddr, 0x1, &phyStatus);
- printf ("\nphyStatus: 0x%04x\n", phyStatus);
- printf ("ecntrl:   0x%08x\n", fec->eth->ecntrl);
- printf ("ievent:   0x%08x\n", fec->eth->ievent);
- printf ("x_status: 0x%08x\n", fec->eth->x_status);
- printf ("tfifo: status 0x%08x\n", fec->eth->tfifo_status);
-
- printf (" control 0x%08x\n", fec->eth->tfifo_cntrl);
- printf (" lrfp 0x%08x\n", fec->eth->tfifo_lrf_ptr);
- printf (" lwfp 0x%08x\n", fec->eth->tfifo_lwf_ptr);
- printf (" alarm 0x%08x\n", fec->eth->tfifo_alarm);
- printf (" readptr 0x%08x\n", fec->eth->tfifo_rdptr);
- printf (" writptr 0x%08x\n", fec->eth->tfifo_wrptr);
- }
-}
-
-static void rfifo_print (char *devname, mpc8220_fec_priv * fec)
-{
- u16 phyAddr = CONFIG_PHY_ADDR;
- u16 phyStatus;
-
- if ((fec->eth->rfifo_lrf_ptr != fec->eth->rfifo_lwf_ptr)
-     || (fec->eth->rfifo_rdptr != fec->eth->rfifo_wrptr)) {
-
- miiphy_read (devname, phyAddr, 0x1, &phyStatus);
- printf ("\nphyStatus: 0x%04x\n", phyStatus);
- printf ("ecntrl:   0x%08x\n", fec->eth->ecntrl);
- printf ("ievent:   0x%08x\n", fec->eth->ievent);
- printf ("x_status: 0x%08x\n", fec->eth->x_status);
- printf ("rfifo: status 0x%08x\n", fec->eth->rfifo_status);
-
- printf (" control 0x%08x\n", fec->eth->rfifo_cntrl);
- printf (" lrfp 0x%08x\n", fec->eth->rfifo_lrf_ptr);
- printf (" lwfp 0x%08x\n", fec->eth->rfifo_lwf_ptr);
- printf (" alarm 0x%08x\n", fec->eth->rfifo_alarm);
- printf (" readptr 0x%08x\n", fec->eth->rfifo_rdptr);
- printf (" writptr 0x%08x\n", fec->eth->rfifo_wrptr);
- }
-}
-#endif /* DEBUG */
-
-/********************************************************************/
-
-static int mpc8220_fec_send (struct eth_device *dev, volatile void
*eth_data,
+int mpc8220_fec_send(struct eth_device *dev, volatile void *eth_data,
     int data_length)
{
/*
@@ -637,13 +615,20 @@ static int mpc8220_fec_send (struct eth_
* 6-byte Ethernet addresses.
*/
mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv;
- FEC_TBD *pTbd;
+ FEC_BD *pTbd;

-#ifdef DEBUG
+#ifdef ET_DEBUG
printf ("tbd status: 0x%04x\n", fec->tbdBase[0].status);
tfifo_print (dev->name, fec);
#endif

+ if (fec->xcv_type != SEVENWIRE) {
+ if (check_connection(dev) == 0) {
+ printf("check cable connection!\n");
+ return -1;
+ }
+ }
+
/*
* Clear Tx BD ring at first
*/
@@ -660,7 +645,7 @@ static int mpc8220_fec_send (struct eth_
* Check the number of vacant TxBDs.
*/
if (fec->cleanTbdNum < 1) {
-#ifdef DEBUG
+#ifdef ET_DEBUG
printf ("No available TxBDs ...\n");
#endif
return -1;
@@ -675,48 +660,35 @@ static int mpc8220_fec_send (struct eth_
pTbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM;

-#ifdef DEBUG
+#ifdef ET_DEBUG
printf ("DMA_TASK_ENABLE, fec->tbdIndex = %d \n", fec->tbdIndex);
#endif

/*
- * Kick the MII i/f
+ * Enable DMA transmit task
*/
- if (fec->xcv_type != SEVENWIRE) {
- u16 phyStatus;
-
- miiphy_read (dev->name, 0, 0x1, &phyStatus);
- }
-
- /*
- * Enable SmartDMA transmit task
- */
-
-#ifdef DEBUG
+#ifdef ET_DEBUG
tfifo_print (dev->name, fec);
#endif

- DMA_TASK_ENABLE (FEC_XMIT_TASK_NO);
+ MCD_continDma(fec->txTask);

-#ifdef DEBUG
+#ifdef ET_DEBUG
tfifo_print (dev->name, fec);
-#endif
-
-#ifdef DEBUG
printf ("+");
#endif

fec->cleanTbdNum -= 1;

-#ifdef DEBUG
- printf ("smartDMA ethernet Tx task enabled\n");
+#ifdef ET_DEBUG
+ printf("DMA ethernet Tx task enabled\n");
#endif
/*
* wait until frame is sent .
*/
while (pTbd->status & FEC_TBD_READY) {
udelay (10);
-#ifdef DEBUG
+#ifdef ET_DEBUG
printf ("TDB status = %04x\n", pTbd->status);
#endif
}
@@ -724,47 +696,56 @@ static int mpc8220_fec_send (struct eth_
return 0;
}

-
/********************************************************************/
-static int mpc8220_fec_recv (struct eth_device *dev)
+int mpc8220_fec_recv(struct eth_device *dev)
{
/*
* This command pulls one frame from the card
*/
mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv;
- FEC_RBD *pRbd = &fec->rbdBase[fec->rbdIndex];
+ volatile ethernet_regs *eth = (volatile ethernet_regs *)fec->iobase;
+ FEC_BD *pRbd = &fec->rbdBase[fec->rbdIndex];
unsigned long ievent;
int frame_length, len = 0;
- NBUF *frame;

-#ifdef DEBUG
+#ifdef ET_DEBUG
printf ("mpc8220_fec_recv %d Start...\n", fec->rbdIndex);
printf ("-");
#endif

+ if (fec->xcv_type != SEVENWIRE) {
+ if (check_connection(dev) == 0) {
+ printf("check cable connection!\n");
+ return -1;
+ }
+ }
+
/*
* Check if any critical events have happened
*/
- ievent = fec->eth->ievent;
- fec->eth->ievent = ievent;
- if (ievent & 0x20060000) {
+ ievent = eth->ievent;
+ if (ievent != 0) {
+ eth->ievent = ievent;
+
+ if (ievent & (FEC_EIR_BABT | FEC_EIR_TXERR | FEC_EIR_RXERR)) {
/* BABT, Rx/Tx FIFO errors */
mpc8220_fec_halt (dev);
mpc8220_fec_init (dev, NULL);
return 0;
}
- if (ievent & 0x80000000) {
+ if (ievent & FEC_EIR_HBERR) {
/* Heartbeat error */
- fec->eth->x_cntrl |= 0x00000001;
+ eth->x_cntrl |= FEC_TCR_GTS;
}
- if (ievent & 0x10000000) {
+ if (ievent & FEC_EIR_GRA) {
/* Graceful stop complete */
- if (fec->eth->x_cntrl & 0x00000001) {
+ if (eth->x_cntrl & FEC_TCR_GTS) {
mpc8220_fec_halt (dev);
- fec->eth->x_cntrl &= ~0x00000001;
+ eth->x_cntrl &= ~FEC_TCR_GTS;
mpc8220_fec_init (dev, NULL);
}
}
+ }

if (!(pRbd->status & FEC_RBD_EMPTY)) {
if ((pRbd->status & FEC_RBD_LAST)
@@ -774,24 +755,11 @@ static int mpc8220_fec_recv (struct eth_
/*
* Get buffer address and size
*/
- frame = (NBUF *) pRbd->dataPointer;
frame_length = pRbd->dataLength - 4;

-#if (0)
- {
- int i;
-
- printf ("recv data hdr:");
- for (i = 0; i < 14; i++)
- printf ("%x ", *(frame->head + i));
- printf ("\n");
- }
-#endif
/*
*  Fill the buffer and pass it to upper layers
*/
-/* memcpy(buff, frame->head, 14);
- memcpy(buff + 14, frame->data, frame_length);*/
NetReceive ((volatile uchar *) pRbd->dataPointer,
    frame_length);
len = frame_length;
@@ -801,55 +769,41 @@ static int mpc8220_fec_recv (struct eth_
*/
mpc8220_fec_rbd_clean (fec, pRbd);
}
- DMA_CLEAR_IEVENT (FEC_RECV_TASK_NO);
+
return len;
}

-
/********************************************************************/
int mpc8220_fec_initialize (bd_t * bis)
{
- mpc8220_fec_priv *fec;
-
-#ifdef CONFIG_HAS_ETH1
- mpc8220_fec_priv *fec2;
-#endif
- struct eth_device *dev;
- char *tmp, *end;
+ char *tmp, *end, ethaddr[16];
char env_enetaddr[6];
-
-#ifdef CONFIG_HAS_ETH1
- char env_enet1addr[6];
-#endif
+ struct eth_device *dev;
int i;

- fec = (mpc8220_fec_priv *) malloc (sizeof (*fec));
+ for (i = 0; i < sizeof(fec_info) / sizeof(fec_info[0]); i++) {
+
+ fec_info[i].phy_name = (char *)malloc(32);
+
dev = (struct eth_device *) malloc (sizeof (*dev));
- memset (dev, 0, sizeof *dev);
+ if (dev == NULL)
+ return 0;

- fec->eth = (ethernet_regs *) MMAP_FEC1;
-#ifdef CONFIG_HAS_ETH1
- fec2 = (mpc8220_fec_priv *) malloc (sizeof (*fec));
- fec2->eth = (ethernet_regs *) MMAP_FEC2;
-#endif
- fec->tbdBase = (FEC_TBD *) FEC_BD_BASE;
- fec->rbdBase =
- (FEC_RBD *) (FEC_BD_BASE + FEC_TBD_NUM * sizeof (FEC_TBD));
- fec->xcv_type = MII100;
+ memset (dev, 0, sizeof *dev);

- dev->priv = (void *) fec;
- dev->iobase = MMAP_FEC1;
+ sprintf(dev->name, "FEC%d", fec_info[i].num);
+ dev->priv = &fec_info[i];
+ dev->iobase = fec_info[i].iobase;
dev->init = mpc8220_fec_init;
dev->halt = mpc8220_fec_halt;
dev->send = mpc8220_fec_send;
dev->recv = mpc8220_fec_recv;

- sprintf (dev->name, "FEC ETHERNET");
eth_register (dev);

#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
- miiphy_register (dev->name,
- fec8220_miiphy_read, fec8220_miiphy_write);
+ miiphy_register(dev->name, fec8220_miiphy_read,
+ fec8220_miiphy_write);
#endif

/*
@@ -857,7 +811,11 @@ int mpc8220_fec_initialize (bd_t * bis)
* a garbage after reset. When not using fec for booting
* the Linux fec driver will try to work with this garbage.
*/
- tmp = getenv ("ethaddr");
+ if (i > 0)
+ sprintf(ethaddr, "ethaddr");
+ else
+ sprintf(ethaddr, "eth%daddr", i);
+ tmp = getenv(ethaddr);
if (tmp) {
for (i = 0; i < 6; i++) {
env_enetaddr[i] =
@@ -865,33 +823,165 @@ int mpc8220_fec_initialize (bd_t * bis)
if (tmp)
tmp = (*end) ? end + 1 : end;
}
- mpc8220_fec_set_hwaddr (fec, env_enetaddr);
+ mpc8220_fec_set_hwaddr(&fec_info[i], env_enetaddr);
+ }
}
-#ifdef CONFIG_HAS_ETH1
- tmp = getenv ("eth1addr");
- if (tmp) {
- for (i = 0; i < 6; i++) {
- env_enet1addr[i] =
- tmp ? simple_strtoul (tmp, &end, 16) : 0;
- if (tmp)
- tmp = (*end) ? end + 1 : end;
+
+ return 1;
+}
+
+void setFecDuplexSpeed(mpc8220_fec_priv * fec)
+{
+ volatile ethernet_regs *eth = (volatile ethernet_regs *)fec->iobase;
+
+ eth->r_cntrl = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | FEC_RCR_FCE;
+ if (fec->xcv_type != SEVENWIRE)
+ eth->r_cntrl |= FEC_RCR_MII_MODE;
+
+ if ((fec->phy_dupspd >> 16) == FULL) {
+ /* Set maximum frame length */
+ eth->r_cntrl |= FEC_RCR_DRT;
+ eth->x_cntrl = FEC_TCR_FDEN;
+ eth->x_cntrl &= ~FEC_TCR_FDEN;
+ } else {
+ /* Half duplex mode */
+ eth->r_cntrl |= FEC_RCR_DRT;
+ eth->x_cntrl &= ~FEC_TCR_FDEN;
+ }
+
+ if ((fec->phy_dupspd & 0xFFFF) == _100BASET) {
+#ifdef ET_DEBUG
+ printf("100Mbps\n");
+#endif
+ printf("100Mbps\n");
+ } else {
+#ifdef ET_DEBUG
+ printf("10Mbps\n");
+#endif
+ printf("10Mbps\n");
+ }
+}
+
+/* PHY identification */
+#define PHY_ID_LXT970 0x78100000 /* LXT970 */
+#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */
+#define PHY_ID_82555 0x02a80150 /* Intel 82555 */
+#define PHY_ID_QS6612 0x01814400 /* QS6612 */
+#define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */
+#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */
+#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */
+#define PHY_ID_DP83848VV 0x20005C90 /* National 83848 */
+#define PHY_ID_DP83849 0x20005CA2 /* National 82849 */
+
+#define STR_ID_LXT970 "LXT970"
+#define STR_ID_LXT971 "LXT971"
+#define STR_ID_82555 "Intel82555"
+#define STR_ID_QS6612 "QS6612"
+#define STR_ID_AMD79C784 "AMD79C784"
+#define STR_ID_LSI80225 "LSI80225"
+#define STR_ID_LSI80225B "LSI80225/B"
+#define STR_ID_DP83848VV "N83848"
+#define STR_ID_DP83849 "N83849"
+
+void mii_discover_phy(struct eth_device *dev)
+{
+#define MAX_PHY_PASSES 11
+ mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv;
+ int pass, phyno;
+ u16 phytype;
+ u32 phyreg;
+
+ if (fec->phyname_init)
+ return;
+
+ for (pass = 1; pass <= MAX_PHY_PASSES && fec->phy_addr < 0; ++pass) {
+ if (pass > 1) {
+ /* PHY may need more time to recover from reset.
+ * The LXT970 needs 50ms typical, no maximum is
+ * specified, so wait 10ms before try again.
+ * With 11 passes this gives it 100ms to wake up.
+ */
+ udelay(10000); /* wait 10ms */
}
- mpc8220_fec_set_hwaddr (fec2, env_enet1addr);
+
+ for (phyno = 0; phyno < 32 && fec->phy_addr < 0; ++phyno) {
+
+ miiphy_read(dev->name, phyno, PHY_PHYIDR1, &phytype);
+
+#ifdef ET_DEBUG
+ printf("PHY type 0x%x pass %d type\n", phytype, pass);
+#endif
+
+ if (phytype != 0xffff) {
+ fec->phy_addr = phyno;
+ phyreg = phytype << 16;
+ miiphy_read(dev->name, phyno, PHY_PHYIDR2,
+     &phytype);
+ phyreg |= phytype;
+
+ switch (phytype & 0xfffffff0) {
+ case PHY_ID_LXT971:
+ strcpy(fec->phy_name, STR_ID_LXT971);
+ printf(STR_ID_LXT971);
+ fec->phyname_init = 1;
+ break;
+ default:
+ strcpy(fec->phy_name, "unknown");
+ fec->phyname_init = 1;
+ break;
+ }
+ }
+ }
+ }
+ if (fec->phy_addr < 0)
+ printf("No PHY device found.\n");
}
+
+int check_connection(struct eth_device *dev)
+{
+ mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv;
+ u16 autoneg = 0;
+ int i = 0;
+
+#define AUTONEGLINK (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS)
+ while (i < TOUT_LOOP) {
+ autoneg = 0;
+ miiphy_read(dev->name, fec->phy_addr, PHY_BMSR, &autoneg);
+ i++;
+
+ if ((autoneg & AUTONEGLINK) == AUTONEGLINK) {
+#ifdef ET_DEBUG
+ printf("autoneg mode %x\n", autoneg);
#endif
+ break;
+ }

- return 1;
+ udelay(500);
+ }
+ if (i >= TOUT_LOOP) {
+#ifdef ET_DEBUG
+ printf("Auto Negotiation not complete\n");
+#endif
+ return (0);
+ }
+ return (1);
}

/* MII-interface related functions */
/********************************************************************/
int fec8220_miiphy_read (char *devname, u8 phyAddr, u8 regAddr, u16 *
retVal)
{
- ethernet_regs *eth = (ethernet_regs *) MMAP_FEC1;
+ struct eth_device *dev;
+ volatile ethernet_regs *eth;
u32 reg; /* convenient holder for the PHY register */
u32 phy; /* convenient holder for the PHY */
int timeout = 0xffff;

+ dev = eth_get_dev_by_name(devname);
+ eth =
+     (volatile ethernet_regs *)(((mpc8220_fec_priv *) dev->priv)->
+        iobase);
+
/*
* reading from any PHY's register is done by properly
* programming the FEC's MII data register.
@@ -906,10 +996,10 @@ int fec8220_miiphy_read (char *devname, 
/*
* wait for the related interrupt
*/
- while ((timeout--) && (!(eth->ievent & 0x00800000)));
+ while ((timeout--) && (!(eth->ievent & FEC_EIR_MII))) ;

if (timeout == 0) {
-#ifdef DEBUG
+#ifdef ET_DEBUG
printf ("Read MDIO failed...\n");
#endif
return -1;
@@ -918,7 +1008,7 @@ int fec8220_miiphy_read (char *devname, 
/*
* clear mii interrupt bit
*/
- eth->ievent = 0x00800000;
+ eth->ievent = FEC_EIR_MII;

/*
* it's now safe to read the PHY's register
@@ -931,11 +1021,17 @@ int fec8220_miiphy_read (char *devname, 
/********************************************************************/
int fec8220_miiphy_write (char *devname, u8 phyAddr, u8 regAddr, u16
data)
{
- ethernet_regs *eth = (ethernet_regs *) MMAP_FEC1;
+ struct eth_device *dev;
+ volatile ethernet_regs *eth;
u32 reg; /* convenient holder for the PHY register */
u32 phy; /* convenient holder for the PHY */
int timeout = 0xffff;

+ dev = eth_get_dev_by_name(devname);
+ eth =
+     (volatile ethernet_regs *)(((mpc8220_fec_priv *) dev->priv)->
+        iobase);
+
reg = regAddr << FEC_MII_DATA_RA_SHIFT;
phy = phyAddr << FEC_MII_DATA_PA_SHIFT;

@@ -945,10 +1041,10 @@ int fec8220_miiphy_write (char *devname,
/*
* wait for the MII interrupt
*/
- while ((timeout--) && (!(eth->ievent & 0x00800000)));
+ while ((timeout--) && (!(eth->ievent & FEC_EIR_MII))) ;

if (timeout == 0) {
-#ifdef DEBUG
+#ifdef ET_DEBUG
printf ("Write MDIO failed...\n");
#endif
return -1;
@@ -957,44 +1053,9 @@ int fec8220_miiphy_write (char *devname,
/*
* clear MII interrupt bit
*/
- eth->ievent = 0x00800000;
+ eth->ievent = FEC_EIR_MII;

return 0;
}

-#ifdef DEBUG
-static u32 local_crc32 (char *string, unsigned int crc_value, int len)
-{
- int i;
- char c;
- unsigned int crc, count;
-
- /*
- * crc32 algorithm
- */
- /*
- * crc = 0xffffffff; * The initialized value should be 0xffffffff
- */
- crc = crc_value;
-
- for (i = len; --i >= 0;) {
- c = *string++;
- for (count = 0; count < 8; count++) {
- if ((c & 0x01) ^ (crc & 0x01)) {
- crc >>= 1;
- crc = crc ^ 0xedb88320;
- } else {
- crc >>= 1;
- }
- c >>= 1;
- }
- }
-
- /*
- * In big endian system, do byte swaping for crc value
- */
- return crc;
-}
-#endif /* DEBUG */
-
#endif /* CONFIG_MPC8220_FEC */
diff -rupN u-boot-all.git/cpu/mpc8220/fec_dma_tasks.S u-boot-all-8220-
fec/cpu/mpc8220/fec_dma_tasks.S
--- u-boot-all.git/cpu/mpc8220/fec_dma_tasks.S 2007-04-03
19:18:56.000000000 -0500
+++ u-boot-all-8220-fec/cpu/mpc8220/fec_dma_tasks.S 1969-12-31
18:00:00.000000000 -0600
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2004, Freescale Semiconductor, Inc.
- *
- * This file contains microcode for the FEC controller of the MPC8220.
- */
-
-#include <config.h>
-
-#if defined(CONFIG_MPC8220)
-
-/* sas/sccg, gas target */
-.section        smartdmaInitData,"aw", at progbits /* Initialized data for
task variables */
-.section        smartdmaTaskTable,"aw", at progbits /* Task tables */
-.align  9
-.globl taskTable
-taskTable:
-.globl scEthernetRecv_Entry
-scEthernetRecv_Entry: /* Task 0 */
-.long   scEthernetRecv_TDT - taskTable /* Task 0 Descriptor Table */
-.long   scEthernetRecv_TDT - taskTable + 0x00000094
-.long   scEthernetRecv_VarTab - taskTable /* Task 0 Variable Table */
-.long   scEthernetRecv_FDT - taskTable + 0x03 /* Task 0 Function
Descriptor Table & Flags */
-.long   0x00000000
-.long   0x00000000
-.long   scEthernetRecv_CSave - taskTable /* Task 0 context save space
*/
-.long   0xf0000000
-.globl scEthernetXmit_Entry
-scEthernetXmit_Entry: /* Task 1 */
-.long   scEthernetXmit_TDT - taskTable /* Task 1 Descriptor Table */
-.long   scEthernetXmit_TDT - taskTable + 0x000000e0
-.long   scEthernetXmit_VarTab - taskTable /* Task 1 Variable Table */
-.long   scEthernetXmit_FDT - taskTable + 0x03 /* Task 1 Function
Descriptor Table & Flags */
-.long   0x00000000
-.long   0x00000000
-.long   scEthernetXmit_CSave - taskTable /* Task 1 context save space
*/
-.long   0xf0000000
-
-

                 reply	other threads:[~2007-05-14 23:23 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1179185010.19082.6.camel@Goku \
    --to=tsi-chung.liew@freescale.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.