X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=cpu%2Fmpc5xxx%2Ffec.c;h=21632722d3f4cbbb958effb5d6d36df874af0f91;hb=151ab83a936e66cf56971a0e0340609528474734;hp=16ca0a9d20d8cd29db4bdb82f4cd881ba31a0d0f;hpb=7784674852c66b0924bdc79062bd208aa51fd0a9;p=u-boot diff --git a/cpu/mpc5xxx/fec.c b/cpu/mpc5xxx/fec.c index 16ca0a9d20..21632722d3 100644 --- a/cpu/mpc5xxx/fec.c +++ b/cpu/mpc5xxx/fec.c @@ -17,7 +17,7 @@ /* #define DEBUG 0x28 */ #if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \ - defined(CONFIG_MPC5XXX_FEC) + defined(CONFIG_MPC5xxx_FEC) #if (DEBUG & 0x60) static void tfifo_print(mpc5xxx_fec_priv *fec); @@ -35,6 +35,33 @@ typedef struct { uint8 head[16]; /* MAC header(6 + 6 + 2) + 2(aligned) */ } NBUF; +/********************************************************************/ +#if (DEBUG & 0x2) +static void mpc5xxx_fec_phydump (void) +{ + uint16 phyStatus, i; + uint8 phyAddr = CONFIG_PHY_ADDR; + uint8 reg_mask[] = { +#if CONFIG_PHY_TYPE == 0x79c874 /* AMD Am79C874 */ + /* regs to print: 0...7, 16...19, 21, 23, 24 */ + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, +#else + /* regs to print: 0...8, 16...20 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +#endif + }; + + for (i = 0; i < 32; i++) { + if (reg_mask[i]) { + miiphy_read(phyAddr, i, &phyStatus); + printf("Mii reg %d: 0x%04x\n", i, phyStatus); + } + } +} +#endif + /********************************************************************/ static int mpc5xxx_fec_rbd_init(mpc5xxx_fec_priv *fec) { @@ -88,7 +115,7 @@ static void mpc5xxx_fec_tbd_init(mpc5xxx_fec_priv *fec) } /********************************************************************/ -static void mpc5xxx_fec_rbd_clean(mpc5xxx_fec_priv *fec, FEC_RBD * pRbd) +static void mpc5xxx_fec_rbd_clean(mpc5xxx_fec_priv *fec, volatile FEC_RBD * pRbd) { /* * Reset buffer descriptor as empty @@ -114,7 +141,7 @@ static void mpc5xxx_fec_rbd_clean(mpc5xxx_fec_priv *fec, FEC_RBD * pRbd) /********************************************************************/ static void mpc5xxx_fec_tbd_scrub(mpc5xxx_fec_priv *fec) { - FEC_TBD *pUsedTbd; + volatile FEC_TBD *pUsedTbd; #if (DEBUG & 0x1) printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n", @@ -208,9 +235,9 @@ static void mpc5xxx_fec_set_hwaddr(mpc5xxx_fec_priv *fec, char *mac) /********************************************************************/ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis) { + DECLARE_GLOBAL_DATA_PTR; mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv; struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA; - const uint8 phyAddr = 0; /* Only one PHY */ #if (DEBUG & 0x1) printf ("mpc5xxx_fec_init... Begin\n"); @@ -222,17 +249,6 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis) mpc5xxx_fec_rbd_init(fec); mpc5xxx_fec_tbd_init(fec); - /* - * Initialize GPIO pins - */ - if (fec->xcv_type == SEVENWIRE) { - /* 10MBit with 7-wire operation */ - *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00020000; - } else { - /* 100MBit with MD operation */ - *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00050000; - } - /* * Clear FEC-Lite interrupt event register(IEVENT) */ @@ -258,21 +274,13 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis) fec->eth->r_cntrl = 0x05ee0024; /*0x05ee0004;FIXME */ } - if (fec->xcv_type == SEVENWIRE) { - /* - * Set FEC-Lite transmit control register(X_CNTRL): - */ - /*fec->eth->x_cntrl = 0x00000002; */ /* half-duplex, heartbeat */ - fec->eth->x_cntrl = 0x00000000; /* half-duplex, heartbeat disabled */ - } else { - /*fec->eth->x_cntrl = 0x00000006; */ /* full-duplex, heartbeat */ - fec->eth->x_cntrl = 0x00000004; /* full-duplex, heartbeat disabled */ - + fec->eth->x_cntrl = 0x00000000; /* half-duplex, heartbeat disabled */ + if (fec->xcv_type != SEVENWIRE) { /* - * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock(25Mhz) + * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock * and do not drop the Preamble. */ - fec->eth->mii_speed = (0x5 << 1); /* No MII for 7-wire mode */ + fec->eth->mii_speed = (((gd->ipb_clk >> 20) / 5) << 1); /* No MII for 7-wire mode */ } /* @@ -346,10 +354,78 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis) /* * 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; + *(volatile int *)FEC_TBD_BASE = (int)fec->tbdBase; + *(volatile int *)FEC_RBD_BASE = (int)fec->rbdBase; + *(volatile int *)FEC_TBD_NEXT = (int)fec->tbdBase; + *(volatile int *)FEC_RBD_NEXT = (int)fec->rbdBase; + + /* + * Enable FEC-Lite controller + */ + fec->eth->ecntrl |= 0x00000006; + +#if (DEBUG & 0x2) + if (fec->xcv_type != SEVENWIRE) + mpc5xxx_fec_phydump (); +#endif + + /* + * Enable SmartDMA receive task + */ + SDMA_TASK_ENABLE(FEC_RECV_TASK_NO); + +#if (DEBUG & 0x1) + printf("mpc5xxx_fec_init... Done \n"); +#endif + + return 1; +} + +/********************************************************************/ +static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis) +{ + DECLARE_GLOBAL_DATA_PTR; + mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv; + const uint8 phyAddr = CONFIG_PHY_ADDR; /* Only one PHY */ + +#if (DEBUG & 0x1) + printf ("mpc5xxx_fec_init_phy... Begin\n"); +#endif + + /* + * Initialize GPIO pins + */ + if (fec->xcv_type == SEVENWIRE) { + /* 10MBit with 7-wire operation */ +#if defined(CONFIG_TOTAL5200) + /* 7-wire and USB2 on Ethernet */ + *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00030000; +#else /* !CONFIG_TOTAL5200 */ + /* 7-wire only */ + *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00020000; +#endif /* CONFIG_TOTAL5200 */ + } else { + /* 100MBit with MD operation */ + *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00050000; + } + + /* + * Clear FEC-Lite interrupt event register(IEVENT) + */ + fec->eth->ievent = 0xffffffff; + + /* + * Set interrupt mask register + */ + fec->eth->imask = 0x00000000; + + if (fec->xcv_type != SEVENWIRE) { + /* + * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock + * and do not drop the Preamble. + */ + fec->eth->mii_speed = (((gd->ipb_clk >> 20) / 5) << 1); /* No MII for 7-wire mode */ + } if (fec->xcv_type != SEVENWIRE) { /* @@ -386,7 +462,9 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis) /* * Force 10Base-T, FDX operation */ +#if (DEBUG & 0x2) printf("Forcing 10 Mbps ethernet link... "); +#endif miiphy_read(phyAddr, 0x1, &phyStatus); /* miiphy_write(fec, phyAddr, 0x0, 0x0100); @@ -421,7 +499,9 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis) #endif } while (!(phyStatus & 0x0004)); /* !link up */ +#if (DEBUG & 0x2) printf ("done.\n"); +#endif } else { /* MII100 */ /* * Set the auto-negotiation advertisement register bits @@ -453,7 +533,7 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis) #endif return -1; } - } while ((phyStatus & 0x0020) != 0x0020); + } while (!(phyStatus & 0x0004)); #if (DEBUG & 0x2) printf("PHY auto neg complete! \n"); @@ -462,36 +542,17 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis) } - /* - * Enable FEC-Lite controller - */ - fec->eth->ecntrl |= 0x00000006; - - if (fec->xcv_type != SEVENWIRE) { #if (DEBUG & 0x2) - uint16 phyStatus, i; - uint8 phyAddr = 0; - - for (i = 0; i < 9; i++) { - miiphy_read(phyAddr, i, &phyStatus); - printf("Mii reg %d: 0x%04x\n", i, phyStatus); - } - for (i = 16; i < 21; i++) { - miiphy_read(phyAddr, i, &phyStatus); - printf("Mii reg %d: 0x%04x\n", i, phyStatus); - } + if (fec->xcv_type != SEVENWIRE) + mpc5xxx_fec_phydump (); #endif - } - /* - * Enable SmartDMA receive task - */ - SDMA_TASK_ENABLE(FEC_RECV_TASK_NO); + #if (DEBUG & 0x1) - printf("mpc5xxx_fec_init... Done \n"); + printf("mpc5xxx_fec_init_phy... Done \n"); #endif - return 0; + return 1; } /********************************************************************/ @@ -504,22 +565,10 @@ static void mpc5xxx_fec_halt(struct eth_device *dev) int counter = 0xffff; #if (DEBUG & 0x2) - if (fec->xcv_type != SEVENWIRE) { - uint16 phyStatus, i; - uint8 phyAddr = 0; - - for (i = 0; i < 9; i++) { - miiphy_read(phyAddr, i, &phyStatus); - printf("Mii reg %d: 0x%04x\n", i, phyStatus); - } - for (i = 16; i < 21; i++) { - miiphy_read(phyAddr, i, &phyStatus); - printf ("Mii reg %d: 0x%04x\n", i, phyStatus); - } - } + if (fec->xcv_type != SEVENWIRE) + mpc5xxx_fec_phydump (); #endif - /* * mask FEC chip interrupts */ @@ -582,7 +631,7 @@ static void mpc5xxx_fec_halt(struct eth_device *dev) static void tfifo_print(mpc5xxx_fec_priv *fec) { - uint16 phyAddr = 0; + uint16 phyAddr = CONFIG_PHY_ADDR; uint16 phyStatus; if ((fec->eth->tfifo_lrf_ptr != fec->eth->tfifo_lwf_ptr) @@ -606,7 +655,7 @@ static void tfifo_print(mpc5xxx_fec_priv *fec) static void rfifo_print(mpc5xxx_fec_priv *fec) { - uint16 phyAddr = 0; + uint16 phyAddr = CONFIG_PHY_ADDR; uint16 phyStatus; if ((fec->eth->rfifo_lrf_ptr != fec->eth->rfifo_lwf_ptr) @@ -639,7 +688,7 @@ static int mpc5xxx_fec_send(struct eth_device *dev, volatile void *eth_data, * 6-byte Ethernet addresses. */ mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv; - FEC_TBD *pTbd; + volatile FEC_TBD *pTbd; #if (DEBUG & 0x20) printf("tbd status: 0x%04x\n", fec->tbdBase[0].status); @@ -730,7 +779,7 @@ static int mpc5xxx_fec_recv(struct eth_device *dev) * This command pulls one frame from the card */ mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv; - FEC_RBD *pRbd = &fec->rbdBase[fec->rbdIndex]; + volatile FEC_RBD *pRbd = &fec->rbdBase[fec->rbdIndex]; unsigned long ievent; int frame_length, len = 0; NBUF *frame; @@ -809,15 +858,29 @@ int mpc5xxx_fec_initialize(bd_t * bis) { mpc5xxx_fec_priv *fec; struct eth_device *dev; + char *tmp, *end; + char env_enetaddr[6]; + int i; fec = (mpc5xxx_fec_priv *)malloc(sizeof(*fec)); dev = (struct eth_device *)malloc(sizeof(*dev)); + memset(dev, 0, sizeof *dev); fec->eth = (ethernet_regs *)MPC5XXX_FEC; fec->tbdBase = (FEC_TBD *)FEC_BD_BASE; fec->rbdBase = (FEC_RBD *)(FEC_BD_BASE + FEC_TBD_NUM * sizeof(FEC_TBD)); -#ifdef CONFIG_ICECUBE +#if defined(CONFIG_ICECUBE) || defined(CONFIG_PM520) || \ + defined(CONFIG_TOP5200) || defined(CONFIG_TQM5200) || \ + defined(CONFIG_INKA4X0) +# ifndef CONFIG_FEC_10MBIT fec->xcv_type = MII100; +# else + fec->xcv_type = MII10; +# endif +#elif defined(CONFIG_TOTAL5200) + fec->xcv_type = SEVENWIRE; +#else +#error fec->xcv_type not initialized. #endif dev->priv = (void *)fec; @@ -830,6 +893,22 @@ int mpc5xxx_fec_initialize(bd_t * bis) sprintf(dev->name, "FEC ETHERNET"); eth_register(dev); + /* + * Try to set the mac address now. The fec mac address is + * 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 (tmp) { + for (i=0; i<6; i++) { + env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0; + if (tmp) + tmp = (*end) ? end+1 : end; + } + mpc5xxx_fec_set_hwaddr(fec, env_enetaddr); + } + + mpc5xxx_fec_init_phy(dev, bis); return 1; } @@ -945,4 +1024,4 @@ static uint32 local_crc32(char *string, unsigned int crc_value, int len) } #endif /* DEBUG */ -#endif /* CONFIG_MPC5XXX_FEC */ +#endif /* CONFIG_MPC5xxx_FEC */