X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fnet%2Ffec_mxc.c;h=c17f9379bf93a3ff663395f0f3b56c8aa5fa60c9;hb=f7ac99fdd9eaf64df9731c2e8fdf97e9d3e2c82a;hp=446076fea117a39b71fa8ceded99e7f7dd441065;hpb=0b692dcb190655c7eb96b6b8003bee163e3b58dd;p=u-boot diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 446076fea1..c17f9379bf 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -62,7 +62,7 @@ struct fec_priv gfec = { /* * MII-interface related functions */ -static int fec_miiphy_read(char *dev, uint8_t phyAddr, uint8_t regAddr, +static int fec_miiphy_read(const char *dev, uint8_t phyAddr, uint8_t regAddr, uint16_t *retVal) { struct eth_device *edev = eth_get_dev_by_name(dev); @@ -119,7 +119,7 @@ static void fec_mii_setspeed(struct fec_priv *fec) debug("fec_init: mii_speed %#lx\n", fec->eth->mii_speed); } -static int fec_miiphy_write(char *dev, uint8_t phyAddr, uint8_t regAddr, +static int fec_miiphy_write(const char *dev, uint8_t phyAddr, uint8_t regAddr, uint16_t data) { struct eth_device *edev = eth_get_dev_by_name(dev); @@ -162,7 +162,9 @@ static int miiphy_restart_aneg(struct eth_device *dev) * Wake up from sleep if necessary * Reset PHY, then delay 300ns */ +#ifdef CONFIG_MX27 miiphy_write(dev->name, CONFIG_FEC_MXC_PHYADDR, PHY_MIPGSR, 0x00FF); +#endif miiphy_write(dev->name, CONFIG_FEC_MXC_PHYADDR, PHY_BMCR, PHY_BMCR_RESET); udelay(1000); @@ -312,9 +314,9 @@ static int fec_get_hwaddr(struct eth_device *dev, unsigned char *mac) { /* * The MX27 can store the mac address in internal eeprom - * This mechanism is not supported now by MX51 + * This mechanism is not supported now by MX51 or MX25 */ -#ifdef CONFIG_MX51 +#if defined(CONFIG_MX51) || defined(CONFIG_MX25) return -1; #else struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE; @@ -323,7 +325,7 @@ static int fec_get_hwaddr(struct eth_device *dev, unsigned char *mac) for (i = 0; i < 6; i++) mac[6-1-i] = readl(&iim->iim_bank_area0[IIM0_MAC + i]); - return is_valid_ether_addr(mac); + return !is_valid_ether_addr(mac); #endif } @@ -363,7 +365,36 @@ static int fec_open(struct eth_device *edev) /* * Enable FEC-Lite controller */ - writel(FEC_ECNTRL_ETHER_EN, &fec->eth->ecntrl); + writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_ETHER_EN, + &fec->eth->ecntrl); +#ifdef CONFIG_MX25 + udelay(100); + /* + * setup the MII gasket for RMII mode + */ + + /* disable the gasket */ + writew(0, &fec->eth->miigsk_enr); + + /* wait for the gasket to be disabled */ + while (readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) + udelay(2); + + /* configure gasket for RMII, 50 MHz, no loopback, and no echo */ + writew(MIIGSK_CFGR_IF_MODE_RMII, &fec->eth->miigsk_cfgr); + + /* re-enable the gasket */ + writew(MIIGSK_ENR_EN, &fec->eth->miigsk_enr); + + /* wait until MII gasket is ready */ + int max_loops = 10; + while ((readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) == 0) { + if (--max_loops <= 0) { + printf("WAIT for MII Gasket ready timed out\n"); + break; + } + } +#endif miiphy_wait_aneg(edev); miiphy_speed(edev->name, CONFIG_FEC_MXC_PHYADDR); @@ -383,6 +414,9 @@ static int fec_init(struct eth_device *dev, bd_t* bd) uint32_t base; struct fec_priv *fec = (struct fec_priv *)dev->priv; + /* Initialize MAC address */ + fec_set_hwaddr(dev); + /* * reserve memory for both buffer descriptor chains at once * Datasheet forces the startaddress of each chain is 16 byte @@ -474,7 +508,6 @@ static int fec_init(struct eth_device *dev, bd_t* bd) miiphy_restart_aneg(dev); fec_open(dev); - fec_set_hwaddr(dev); return 0; } @@ -490,7 +523,7 @@ static void fec_halt(struct eth_device *dev) /* * issue graceful stop command to the FEC transmitter if necessary */ - writel(FEC_ECNTRL_RESET | readl(&fec->eth->x_cntrl), + writel(FEC_TCNTRL_GTS | readl(&fec->eth->x_cntrl), &fec->eth->x_cntrl); debug("eth_halt: wait for stop regs\n"); @@ -498,7 +531,7 @@ static void fec_halt(struct eth_device *dev) * wait for graceful stop to register */ while ((counter--) && (!(readl(&fec->eth->ievent) & FEC_IEVENT_GRA))) - ; /* FIXME ensure time */ + udelay(1); /* * Disable SmartDMA tasks @@ -510,7 +543,8 @@ static void fec_halt(struct eth_device *dev) * Disable the Ethernet Controller * Note: this will also reset the BD index counter! */ - writel(0, &fec->eth->ecntrl); + writel(readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_ETHER_EN, + &fec->eth->ecntrl); fec->rbd_index = 0; fec->tbd_index = 0; debug("eth_halt: done\n"); @@ -569,7 +603,7 @@ static int fec_send(struct eth_device *dev, volatile void* packet, int length) * wait until frame is sent . */ while (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) { - /* FIXME: Timeout */ + udelay(1); } debug("fec_send: status 0x%x index %d\n", readw(&fec->tbd_base[fec->tbd_index].status), @@ -676,11 +710,13 @@ static int fec_probe(bd_t *bd) puts("fec_mxc: not enough malloc memory\n"); return -ENOMEM; } + memset(edev, 0, sizeof(*edev)); edev->priv = fec; edev->init = fec_init; edev->send = fec_send; edev->recv = fec_recv; edev->halt = fec_halt; + edev->write_hwaddr = fec_set_hwaddr; fec->eth = (struct ethernet_regs *)IMX_FEC_BASE; fec->bd = bd; @@ -688,7 +724,7 @@ static int fec_probe(bd_t *bd) fec->xcv_type = MII100; /* Reset chip. */ - writel(FEC_ECNTRL_RESET, &fec->eth->ecntrl); + writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_RESET, &fec->eth->ecntrl); while (readl(&fec->eth->ecntrl) & 1) udelay(10); @@ -711,7 +747,7 @@ static int fec_probe(bd_t *bd) writel(0x05ee0024, &fec->eth->r_cntrl); /* FIXME 0x05ee0004 */ fec_mii_setspeed(fec); - sprintf(edev->name, "FEC_MXC"); + sprintf(edev->name, "FEC"); miiphy_register(edev->name, fec_miiphy_read, fec_miiphy_write); @@ -720,7 +756,6 @@ static int fec_probe(bd_t *bd) if (fec_get_hwaddr(edev, ethaddr) == 0) { printf("got MAC address from EEPROM: %pM\n", ethaddr); memcpy(edev->enetaddr, ethaddr, 6); - fec_set_hwaddr(edev); } return 0;