[U-Boot-Users] Patch: MPC8220 FEC and DMA update - part 1

- Better handling in ethernet MII, applied new DMA functions
Regards, TsiChung Liew
Signed-off by: TsiChung Liew Tsi-Chung.Liew@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 *) (ð->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 *) (ð->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",@progbits /* Initialized data for task variables */ -.section smartdmaTaskTable,"aw",@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 - -
participants (1)
-
TsiChung Liew