From e66b19ce6dbe6f91b18ba47273cbe89eb5a80e78 Mon Sep 17 00:00:00 2001 From: Siddarth Gore Date: Tue, 19 Jan 2010 11:09:07 +0530 Subject: NET: kirkwood-egiga smi access fix Although the datasheet mentions seperate smi registers for each port, using Port 1 smi register to access ethernet phys does not work. Hence only Port 0 smi register should be used to access all devices connected to the smi bus. This behavior is consistant with the mv643xx driver in the linux kernel. Signed-off-by: Siddarth Gore Acked-by: Prafulla Wadaskar Signed-off-by: Ben Warren diff --git a/drivers/net/kirkwood_egiga.c b/drivers/net/kirkwood_egiga.c index 07a86cd..2ad7fea 100644 --- a/drivers/net/kirkwood_egiga.c +++ b/drivers/net/kirkwood_egiga.c @@ -39,6 +39,7 @@ #include "kirkwood_egiga.h" #define KIRKWOOD_PHY_ADR_REQUEST 0xee +#define KWGBE_SMI_REG (((struct kwgbe_registers *)KW_EGIGA0_BASE)->smi) /* * smi_reg_read - miiphy_read callback function. @@ -76,7 +77,7 @@ static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data) /* wait till the SMI is not busy */ do { /* read smi register */ - smi_reg = KWGBEREG_RD(regs->smi); + smi_reg = KWGBEREG_RD(KWGBE_SMI_REG); if (timeout-- == 0) { printf("Err..(%s) SMI busy timeout\n", __FUNCTION__); return -EFAULT; @@ -89,14 +90,14 @@ static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data) | KWGBE_PHY_SMI_OPCODE_READ; /* write the smi register */ - KWGBEREG_WR(regs->smi, smi_reg); + KWGBEREG_WR(KWGBE_SMI_REG, smi_reg); /*wait till read value is ready */ timeout = KWGBE_PHY_SMI_TIMEOUT; do { /* read smi register */ - smi_reg = KWGBEREG_RD(regs->smi); + smi_reg = KWGBEREG_RD(KWGBE_SMI_REG); if (timeout-- == 0) { printf("Err..(%s) SMI read ready timeout\n", __FUNCTION__); @@ -107,7 +108,7 @@ static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data) /* Wait for the data to update in the SMI register */ for (timeout = 0; timeout < KWGBE_PHY_SMI_TIMEOUT; timeout++) ; - *data = (u16) (KWGBEREG_RD(regs->smi) & KWGBE_PHY_SMI_DATA_MASK); + *data = (u16) (KWGBEREG_RD(KWGBE_SMI_REG) & KWGBE_PHY_SMI_DATA_MASK); debug("%s:(adr %d, off %d) value= %04x\n", __FUNCTION__, phy_adr, reg_ofs, *data); @@ -150,7 +151,7 @@ static int smi_reg_write(char *devname, u8 phy_adr, u8 reg_ofs, u16 data) timeout = KWGBE_PHY_SMI_TIMEOUT; do { /* read smi register */ - smi_reg = KWGBEREG_RD(regs->smi); + smi_reg = KWGBEREG_RD(KWGBE_SMI_REG); if (timeout-- == 0) { printf("Err..(%s) SMI busy timeout\n", __FUNCTION__); return -ETIME; @@ -164,7 +165,7 @@ static int smi_reg_write(char *devname, u8 phy_adr, u8 reg_ofs, u16 data) smi_reg &= ~KWGBE_PHY_SMI_OPCODE_READ; /* write the smi register */ - KWGBEREG_WR(regs->smi, smi_reg); + KWGBEREG_WR(KWGBE_SMI_REG, smi_reg); return 0; } -- cgit v0.10.2 From 4294b2485bf0e8d68c893190a96bb0e7856b12c4 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Mon, 1 Feb 2010 14:51:30 +0100 Subject: fec_mxc: add support for MX51 processor The patch add support for the Freescale mx51 processor to the FEC ethernet driver. Signed-off-by: Stefano Babic Signed-off-by: Ben Warren diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 19116f2..446076f 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -108,6 +108,17 @@ static int fec_miiphy_read(char *dev, uint8_t phyAddr, uint8_t regAddr, return 0; } +static void fec_mii_setspeed(struct fec_priv *fec) +{ + /* + * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock + * and do not drop the Preamble. + */ + writel((((imx_get_fecclk() / 1000000) + 2) / 5) << 1, + &fec->eth->mii_speed); + debug("fec_init: mii_speed %#lx\n", + fec->eth->mii_speed); +} static int fec_miiphy_write(char *dev, uint8_t phyAddr, uint8_t regAddr, uint16_t data) { @@ -236,7 +247,7 @@ static int fec_rbd_init(struct fec_priv *fec, int count, int size) fec->rdb_ptr = malloc(size * count + DB_DATA_ALIGNMENT); p = (uint32_t)fec->rdb_ptr; if (!p) { - puts("fec_imx27: not enough malloc memory!\n"); + puts("fec_mxc: not enough malloc memory\n"); return -ENOMEM; } memset((void *)p, 0, size * count + DB_DATA_ALIGNMENT); @@ -299,6 +310,13 @@ static void fec_rbd_clean(int last, struct fec_bd *pRbd) 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 + */ +#ifdef CONFIG_MX51 + return -1; +#else struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE; int i; @@ -306,10 +324,12 @@ static int fec_get_hwaddr(struct eth_device *dev, unsigned char *mac) mac[6-1-i] = readl(&iim->iim_bank_area0[IIM0_MAC + i]); return is_valid_ether_addr(mac); +#endif } -static int fec_set_hwaddr(struct eth_device *dev, unsigned char *mac) +static int fec_set_hwaddr(struct eth_device *dev) { + uchar *mac = dev->enetaddr; struct fec_priv *fec = (struct fec_priv *)dev->priv; writel(0, &fec->eth->iaddr1); @@ -373,7 +393,7 @@ static int fec_init(struct eth_device *dev, bd_t* bd) sizeof(struct fec_bd) + DB_ALIGNMENT); base = (uint32_t)fec->base_ptr; if (!base) { - puts("fec_imx27: not enough malloc memory!\n"); + puts("fec_mxc: not enough malloc memory\n"); return -ENOMEM; } memset((void *)base, 0, (2 + FEC_RBD_NUM) * @@ -411,14 +431,8 @@ static int fec_init(struct eth_device *dev, bd_t* bd) * Frame length=1518; MII mode; */ writel(0x05ee0024, &fec->eth->r_cntrl); /* FIXME 0x05ee0004 */ - /* - * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock - * and do not drop the Preamble. - */ - writel((((imx_get_ahbclk() / 1000000) + 2) / 5) << 1, - &fec->eth->mii_speed); - debug("fec_init: mii_speed %#lx\n", - (((imx_get_ahbclk() / 1000000) + 2) / 5) << 1); + + fec_mii_setspeed(fec); } /* * Set Opcode/Pause Duration Register @@ -460,6 +474,7 @@ static int fec_init(struct eth_device *dev, bd_t* bd) miiphy_restart_aneg(dev); fec_open(dev); + fec_set_hwaddr(dev); return 0; } @@ -522,7 +537,7 @@ static int fec_send(struct eth_device *dev, volatile void* packet, int length) * Check for valid length of data. */ if ((length > 1500) || (length <= 0)) { - printf("Payload (%d) to large!\n", length); + printf("Payload (%d) too large\n", length); return -1; } @@ -651,22 +666,14 @@ static int fec_recv(struct eth_device *dev) static int fec_probe(bd_t *bd) { - struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; struct eth_device *edev; struct fec_priv *fec = &gfec; - unsigned char ethaddr_str[20]; unsigned char ethaddr[6]; - char *tmp = getenv("ethaddr"); - char *end; - - /* enable FEC clock */ - writel(readl(&pll->pccr1) | PCCR1_HCLK_FEC, &pll->pccr1); - writel(readl(&pll->pccr0) | PCCR0_FEC_EN, &pll->pccr0); /* create and fill edev struct */ edev = (struct eth_device *)malloc(sizeof(struct eth_device)); if (!edev) { - puts("fec_imx27: not enough malloc memory!\n"); + puts("fec_mxc: not enough malloc memory\n"); return -ENOMEM; } edev->priv = fec; @@ -702,14 +709,7 @@ static int fec_probe(bd_t *bd) * Frame length=1518; MII mode; */ writel(0x05ee0024, &fec->eth->r_cntrl); /* FIXME 0x05ee0004 */ - /* - * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock - * and do not drop the Preamble. - */ - writel((((imx_get_ahbclk() / 1000000) + 2) / 5) << 1, - &fec->eth->mii_speed); - debug("fec_init: mii_speed %#lx\n", - (((imx_get_ahbclk() / 1000000) + 2) / 5) << 1); + fec_mii_setspeed(fec); sprintf(edev->name, "FEC_MXC"); @@ -717,20 +717,11 @@ static int fec_probe(bd_t *bd) eth_register(edev); - if ((NULL != tmp) && (12 <= strlen(tmp))) { - int i; - /* convert MAC from string to int */ - for (i = 0; i < 6; i++) { - ethaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0; - if (tmp) - tmp = (*end) ? end + 1 : end; - } - } else if (fec_get_hwaddr(edev, ethaddr) == 0) { + if (fec_get_hwaddr(edev, ethaddr) == 0) { printf("got MAC address from EEPROM: %pM\n", ethaddr); - setenv("ethaddr", (char *)ethaddr_str); + memcpy(edev->enetaddr, ethaddr, 6); + fec_set_hwaddr(edev); } - memcpy(edev->enetaddr, ethaddr, 6); - fec_set_hwaddr(edev, ethaddr); return 0; } -- cgit v0.10.2 From ab5a0dcb9c8f19e351fc33c5db91469bfb1d9438 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 2 Feb 2010 13:43:48 +0100 Subject: net: Use 0.5 sec timeout in miiphy_reset() instead of counting loop This patch fixes a problem I've notived on a buggy PPC4xx system. This system has problems with the PHY MDIO communication and seemed to be stuck/crashed in miiphy_reset(). But degugging revealed, that the CPU didn't crash, but "only" hung in this counting loop for about 2 minutes. This patch now uses a real timeout of 0.5 seconds (as mentioned in the comment in miiphy_reset). Signed-off-by: Stefan Roese Signed-off-by: Ben Warren diff --git a/common/miiphyutil.c b/common/miiphyutil.c index 196ef4a..856fbc7 100644 --- a/common/miiphyutil.c +++ b/common/miiphyutil.c @@ -293,7 +293,7 @@ int miiphy_info (char *devname, unsigned char addr, unsigned int *oui, int miiphy_reset (char *devname, unsigned char addr) { unsigned short reg; - int loop_cnt; + int timeout = 500; if (miiphy_read (devname, addr, PHY_BMCR, ®) != 0) { debug ("PHY status read failed\n"); @@ -311,13 +311,13 @@ int miiphy_reset (char *devname, unsigned char addr) * auto-clearing). This should happen within 0.5 seconds per the * IEEE spec. */ - loop_cnt = 0; reg = 0x8000; - while (((reg & 0x8000) != 0) && (loop_cnt++ < 1000000)) { - if (miiphy_read (devname, addr, PHY_BMCR, ®) != 0) { - debug ("PHY status read failed\n"); - return (-1); + while (((reg & 0x8000) != 0) && timeout--) { + if (miiphy_read(devname, addr, PHY_BMCR, ®) != 0) { + debug("PHY status read failed\n"); + return -1; } + udelay(1000); } if ((reg & 0x8000) == 0) { return (0); -- cgit v0.10.2