summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/freescale/fec_main.c
diff options
context:
space:
mode:
authorFugang Duan <fugang.duan@nxp.com>2020-04-27 22:08:04 +0800
committerDavid S. Miller <davem@davemloft.net>2020-04-30 20:31:04 -0700
commit0a699302be5986307b3dcf84ac7a0dd30f9e9305 (patch)
tree36e0c5adb486b30d308cbc1bff8bf50edafb335e /drivers/net/ethernet/freescale/fec_main.c
parent88ec7cb22ddde725ed4ce15991f0bd9dd817fd85 (diff)
net: ethernet: fec: Revert "net: ethernet: fec: Replace interrupt driven MDIO with polled IO"
This reverts commit 29ae6bd1b0d8a57d7c00ab12cbb949fc41986eef. The commit breaks ethernet function on i.MX6SX, i.MX7D, i.MX8MM, i.MX8MQ, and i.MX8QXP platforms. Boot yocto system by NFS mounting rootfs will be failed with the commit. Signed-off-by: Fugang Duan <fugang.duan@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/freescale/fec_main.c')
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c67
1 files changed, 33 insertions, 34 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 1ae075a246a3..c7b84bb22f75 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -976,8 +976,8 @@ fec_restart(struct net_device *ndev)
writel((__force u32)cpu_to_be32(temp_mac[1]),
fep->hwp + FEC_ADDR_HIGH);
- /* Clear any outstanding interrupt, except MDIO. */
- writel((0xffffffff & ~FEC_ENET_MII), fep->hwp + FEC_IEVENT);
+ /* Clear any outstanding interrupt. */
+ writel(0xffffffff, fep->hwp + FEC_IEVENT);
fec_enet_bd_init(ndev);
@@ -1123,7 +1123,7 @@ fec_restart(struct net_device *ndev)
if (fep->link)
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
else
- writel(0, fep->hwp + FEC_IMASK);
+ writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
/* Init the interrupt coalescing */
fec_enet_itr_coal_init(ndev);
@@ -1652,10 +1652,6 @@ fec_enet_interrupt(int irq, void *dev_id)
irqreturn_t ret = IRQ_NONE;
int_events = readl(fep->hwp + FEC_IEVENT);
-
- /* Don't clear MDIO events, we poll for those */
- int_events &= ~FEC_ENET_MII;
-
writel(int_events, fep->hwp + FEC_IEVENT);
fec_enet_collect_events(fep, int_events);
@@ -1663,12 +1659,16 @@ fec_enet_interrupt(int irq, void *dev_id)
ret = IRQ_HANDLED;
if (napi_schedule_prep(&fep->napi)) {
- /* Disable interrupts */
- writel(0, fep->hwp + FEC_IMASK);
+ /* Disable the NAPI interrupts */
+ writel(FEC_NAPI_IMASK, fep->hwp + FEC_IMASK);
__napi_schedule(&fep->napi);
}
}
+ if (int_events & FEC_ENET_MII) {
+ ret = IRQ_HANDLED;
+ complete(&fep->mdio_done);
+ }
return ret;
}
@@ -1818,24 +1818,11 @@ static void fec_enet_adjust_link(struct net_device *ndev)
phy_print_status(phy_dev);
}
-static int fec_enet_mdio_wait(struct fec_enet_private *fep)
-{
- uint ievent;
- int ret;
-
- ret = readl_poll_timeout_atomic(fep->hwp + FEC_IEVENT, ievent,
- ievent & FEC_ENET_MII, 2, 30000);
-
- if (!ret)
- writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
-
- return ret;
-}
-
static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
{
struct fec_enet_private *fep = bus->priv;
struct device *dev = &fep->pdev->dev;
+ unsigned long time_left;
int ret = 0, frame_start, frame_addr, frame_op;
bool is_c45 = !!(regnum & MII_ADDR_C45);
@@ -1843,6 +1830,8 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
if (ret < 0)
return ret;
+ reinit_completion(&fep->mdio_done);
+
if (is_c45) {
frame_start = FEC_MMFR_ST_C45;
@@ -1854,9 +1843,11 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
fep->hwp + FEC_MII_DATA);
/* wait for end of transfer */
- ret = fec_enet_mdio_wait(fep);
- if (ret) {
+ time_left = wait_for_completion_timeout(&fep->mdio_done,
+ usecs_to_jiffies(FEC_MII_TIMEOUT));
+ if (time_left == 0) {
netdev_err(fep->netdev, "MDIO address write timeout\n");
+ ret = -ETIMEDOUT;
goto out;
}
@@ -1875,9 +1866,11 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
FEC_MMFR_TA, fep->hwp + FEC_MII_DATA);
/* wait for end of transfer */
- ret = fec_enet_mdio_wait(fep);
- if (ret) {
+ time_left = wait_for_completion_timeout(&fep->mdio_done,
+ usecs_to_jiffies(FEC_MII_TIMEOUT));
+ if (time_left == 0) {
netdev_err(fep->netdev, "MDIO read timeout\n");
+ ret = -ETIMEDOUT;
goto out;
}
@@ -1895,6 +1888,7 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
{
struct fec_enet_private *fep = bus->priv;
struct device *dev = &fep->pdev->dev;
+ unsigned long time_left;
int ret, frame_start, frame_addr;
bool is_c45 = !!(regnum & MII_ADDR_C45);
@@ -1904,6 +1898,8 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
else
ret = 0;
+ reinit_completion(&fep->mdio_done);
+
if (is_c45) {
frame_start = FEC_MMFR_ST_C45;
@@ -1915,9 +1911,11 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
fep->hwp + FEC_MII_DATA);
/* wait for end of transfer */
- ret = fec_enet_mdio_wait(fep);
- if (ret) {
+ time_left = wait_for_completion_timeout(&fep->mdio_done,
+ usecs_to_jiffies(FEC_MII_TIMEOUT));
+ if (time_left == 0) {
netdev_err(fep->netdev, "MDIO address write timeout\n");
+ ret = -ETIMEDOUT;
goto out;
}
} else {
@@ -1933,9 +1931,12 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
fep->hwp + FEC_MII_DATA);
/* wait for end of transfer */
- ret = fec_enet_mdio_wait(fep);
- if (ret)
+ time_left = wait_for_completion_timeout(&fep->mdio_done,
+ usecs_to_jiffies(FEC_MII_TIMEOUT));
+ if (time_left == 0) {
netdev_err(fep->netdev, "MDIO write timeout\n");
+ ret = -ETIMEDOUT;
+ }
out:
pm_runtime_mark_last_busy(dev);
@@ -2144,9 +2145,6 @@ static int fec_enet_mii_init(struct platform_device *pdev)
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
- /* Clear any pending transaction complete indication */
- writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
-
fep->mii_bus = mdiobus_alloc();
if (fep->mii_bus == NULL) {
err = -ENOMEM;
@@ -3688,6 +3686,7 @@ fec_probe(struct platform_device *pdev)
fep->irq[i] = irq;
}
+ init_completion(&fep->mdio_done);
ret = fec_enet_mii_init(pdev);
if (ret)
goto failed_mii_init;