X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Fnet%2Fethernet%2Ffreescale%2Ffec_main.c;h=2451ab1b5a83c46dc6c1bae24ad8bfee509f6eab;hb=6e0895c2ea326cc4bb11e8fa2f654628d5754c31;hp=2b78a1ebe9034afc7aabc03eef8ed20f60c30eda;hpb=96d2222bf1ee52b3c656a03c33dd0de6b25ca8df;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 2b78a1ebe903..2451ab1b5a83 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -52,11 +52,6 @@ #include -#ifndef CONFIG_ARM -#include -#include -#endif - #include "fec.h" #if defined(CONFIG_ARM) @@ -105,6 +100,9 @@ static struct platform_device_id fec_devtype[] = { .name = "imx6q-fec", .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | FEC_QUIRK_HAS_BUFDESC_EX, + }, { + .name = "mvf-fec", + .driver_data = FEC_QUIRK_ENET_MAC, }, { /* sentinel */ } @@ -116,6 +114,7 @@ enum imx_fec_type { IMX27_FEC, /* runs on i.mx27/35/51 */ IMX28_FEC, IMX6Q_FEC, + MVF_FEC, }; static const struct of_device_id fec_dt_ids[] = { @@ -123,6 +122,7 @@ static const struct of_device_id fec_dt_ids[] = { { .compatible = "fsl,imx27-fec", .data = &fec_devtype[IMX27_FEC], }, { .compatible = "fsl,imx28-fec", .data = &fec_devtype[IMX28_FEC], }, { .compatible = "fsl,imx6q-fec", .data = &fec_devtype[IMX6Q_FEC], }, + { .compatible = "fsl,mvf-fec", .data = &fec_devtype[MVF_FEC], }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, fec_dt_ids); @@ -261,7 +261,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) /* Ooops. All transmit buffers are full. Bail out. * This should not happen, since ndev->tbusy should be set. */ - printk("%s: tx queue full!.\n", ndev->name); + netdev_err(ndev, "tx queue full!\n"); return NETDEV_TX_BUSY; } @@ -344,6 +344,53 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) return NETDEV_TX_OK; } +/* Init RX & TX buffer descriptors + */ +static void fec_enet_bd_init(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + struct bufdesc *bdp; + unsigned int i; + + /* Initialize the receive buffer descriptors. */ + bdp = fep->rx_bd_base; + for (i = 0; i < RX_RING_SIZE; i++) { + + /* Initialize the BD for every fragment in the page. */ + if (bdp->cbd_bufaddr) + bdp->cbd_sc = BD_ENET_RX_EMPTY; + else + bdp->cbd_sc = 0; + bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); + } + + /* Set the last buffer to wrap */ + bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); + bdp->cbd_sc |= BD_SC_WRAP; + + fep->cur_rx = fep->rx_bd_base; + + /* ...and the same for transmit */ + bdp = fep->tx_bd_base; + fep->cur_tx = bdp; + for (i = 0; i < TX_RING_SIZE; i++) { + + /* Initialize the BD for every fragment in the page. */ + bdp->cbd_sc = 0; + if (bdp->cbd_bufaddr && fep->tx_skbuff[i]) { + dev_kfree_skb_any(fep->tx_skbuff[i]); + fep->tx_skbuff[i] = NULL; + } + bdp->cbd_bufaddr = 0; + bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); + } + + /* Set the last buffer to wrap */ + bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); + bdp->cbd_sc |= BD_SC_WRAP; + fep->dirty_tx = bdp; +} + /* This function is called to start or restart the FEC during a link * change. This only happens when switching between half and full * duplex. @@ -387,6 +434,8 @@ fec_restart(struct net_device *ndev, int duplex) /* Set maximum receive buffer size. */ writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); + fec_enet_bd_init(ndev); + /* Set receive and transmit descriptor base. */ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); if (fep->bufdesc_ex) @@ -396,7 +445,6 @@ fec_restart(struct net_device *ndev, int duplex) writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE, fep->hwp + FEC_X_DES_START); - fep->cur_rx = fep->rx_bd_base; for (i = 0; i <= TX_RING_MOD_MASK; i++) { if (fep->tx_skbuff[i]) { @@ -525,7 +573,7 @@ fec_stop(struct net_device *ndev) writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */ udelay(10); if (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_GRA)) - printk("fec_stop : Graceful transmit stop did not complete !\n"); + netdev_err(ndev, "Graceful transmit stop did not complete!\n"); } /* Whack a reset. We should wait for this. */ @@ -623,7 +671,7 @@ fec_enet_tx(struct net_device *ndev) } if (status & BD_ENET_TX_READY) - printk("HEY! Enet xmit interrupt and TX_READY.\n"); + netdev_err(ndev, "HEY! Enet xmit interrupt and TX_READY\n"); /* Deferred means some collisions occurred during transmit, * but we eventually sent the packet OK. @@ -691,7 +739,7 @@ fec_enet_rx(struct net_device *ndev, int budget) * the last indicator should be set. */ if ((status & BD_ENET_RX_LAST) == 0) - printk("FEC ENET: rcv is not +last\n"); + netdev_err(ndev, "rcv is not +last\n"); if (!fep->opened) goto rx_processing_done; @@ -865,7 +913,6 @@ static void fec_get_mac(struct net_device *ndev) */ iap = macaddr; -#ifdef CONFIG_OF /* * 2) from device tree data */ @@ -877,7 +924,6 @@ static void fec_get_mac(struct net_device *ndev) iap = (unsigned char *) mac; } } -#endif /* * 3) from flash or fuse (via platform data) @@ -951,6 +997,7 @@ static void fec_enet_adjust_link(struct net_device *ndev) } else { if (fep->link) { fec_stop(ndev); + fep->link = phy_dev->link; status_change = 1; } } @@ -980,7 +1027,7 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) usecs_to_jiffies(FEC_MII_TIMEOUT)); if (time_left == 0) { fep->mii_timeout = 1; - printk(KERN_ERR "FEC: MDIO read timeout\n"); + netdev_err(fep->netdev, "MDIO read timeout\n"); return -ETIMEDOUT; } @@ -1008,7 +1055,7 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, usecs_to_jiffies(FEC_MII_TIMEOUT)); if (time_left == 0) { fep->mii_timeout = 1; - printk(KERN_ERR "FEC: MDIO write timeout\n"); + netdev_err(fep->netdev, "MDIO write timeout\n"); return -ETIMEDOUT; } @@ -1048,9 +1095,7 @@ static int fec_enet_mii_probe(struct net_device *ndev) } if (phy_id >= PHY_MAX_ADDR) { - printk(KERN_INFO - "%s: no PHY, assuming direct connection to switch\n", - ndev->name); + netdev_info(ndev, "no PHY, assuming direct connection to switch\n"); strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); phy_id = 0; } @@ -1059,7 +1104,7 @@ static int fec_enet_mii_probe(struct net_device *ndev) phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link, fep->phy_interface); if (IS_ERR(phy_dev)) { - printk(KERN_ERR "%s: could not attach to PHY\n", ndev->name); + netdev_err(ndev, "could not attach to PHY\n"); return PTR_ERR(phy_dev); } @@ -1077,11 +1122,9 @@ static int fec_enet_mii_probe(struct net_device *ndev) fep->link = 0; fep->full_duplex = 0; - printk(KERN_INFO - "%s: Freescale FEC PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", - ndev->name, - fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev), - fep->phy_dev->irq); + netdev_info(ndev, "Freescale FEC PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", + fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev), + fep->phy_dev->irq); return 0; } @@ -1594,8 +1637,6 @@ static int fec_enet_init(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); struct bufdesc *cbd_base; - struct bufdesc *bdp; - unsigned int i; /* Allocate memory for buffer descriptors. */ cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma, @@ -1603,6 +1644,7 @@ static int fec_enet_init(struct net_device *ndev) if (!cbd_base) return -ENOMEM; + memset(cbd_base, 0, PAGE_SIZE); spin_lock_init(&fep->hw_lock); fep->netdev = ndev; @@ -1626,51 +1668,12 @@ static int fec_enet_init(struct net_device *ndev) writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK); netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, FEC_NAPI_WEIGHT); - /* Initialize the receive buffer descriptors. */ - bdp = fep->rx_bd_base; - for (i = 0; i < RX_RING_SIZE; i++) { - - /* Initialize the BD for every fragment in the page. */ - bdp->cbd_sc = 0; - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); - } - - /* Set the last buffer to wrap */ - bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); - bdp->cbd_sc |= BD_SC_WRAP; - - /* ...and the same for transmit */ - bdp = fep->tx_bd_base; - fep->cur_tx = bdp; - for (i = 0; i < TX_RING_SIZE; i++) { - - /* Initialize the BD for every fragment in the page. */ - bdp->cbd_sc = 0; - bdp->cbd_bufaddr = 0; - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); - } - - /* Set the last buffer to wrap */ - bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); - bdp->cbd_sc |= BD_SC_WRAP; - fep->dirty_tx = bdp; - fec_restart(ndev, 0); return 0; } #ifdef CONFIG_OF -static int fec_get_phy_mode_dt(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - - if (np) - return of_get_phy_mode(np); - - return -ENODEV; -} - static void fec_reset_phy(struct platform_device *pdev) { int err, phy_reset; @@ -1699,11 +1702,6 @@ static void fec_reset_phy(struct platform_device *pdev) gpio_set_value(phy_reset, 1); } #else /* CONFIG_OF */ -static int fec_get_phy_mode_dt(struct platform_device *pdev) -{ - return -ENODEV; -} - static void fec_reset_phy(struct platform_device *pdev) { /* @@ -1762,7 +1760,7 @@ fec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ndev); - ret = fec_get_phy_mode_dt(pdev); + ret = of_get_phy_mode(pdev->dev.of_node); if (ret < 0) { pdata = pdev->dev.platform_data; if (pdata) @@ -1852,6 +1850,9 @@ fec_probe(struct platform_device *pdev) if (ret) goto failed_register; + if (fep->bufdesc_ex && fep->ptp_clock) + netdev_info(ndev, "registered PHC device %d\n", fep->dev_id); + return 0; failed_register: @@ -1904,7 +1905,7 @@ fec_drv_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int fec_suspend(struct device *dev) { @@ -1936,24 +1937,15 @@ fec_resume(struct device *dev) return 0; } +#endif /* CONFIG_PM_SLEEP */ -static const struct dev_pm_ops fec_pm_ops = { - .suspend = fec_suspend, - .resume = fec_resume, - .freeze = fec_suspend, - .thaw = fec_resume, - .poweroff = fec_suspend, - .restore = fec_resume, -}; -#endif +static SIMPLE_DEV_PM_OPS(fec_pm_ops, fec_suspend, fec_resume); static struct platform_driver fec_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, -#ifdef CONFIG_PM .pm = &fec_pm_ops, -#endif .of_match_table = fec_dt_ids, }, .id_table = fec_devtype,