Commit 0a699302 authored by Fugang Duan's avatar Fugang Duan Committed by David S. Miller

net: ethernet: fec: Revert "net: ethernet: fec: Replace interrupt driven MDIO with polled IO"

This reverts commit 29ae6bd1.

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: default avatarFugang Duan <fugang.duan@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 88ec7cb2
...@@ -376,7 +376,8 @@ struct bufdesc_ex { ...@@ -376,7 +376,8 @@ struct bufdesc_ex {
#define FEC_ENET_TS_AVAIL ((uint)0x00010000) #define FEC_ENET_TS_AVAIL ((uint)0x00010000)
#define FEC_ENET_TS_TIMER ((uint)0x00008000) #define FEC_ENET_TS_TIMER ((uint)0x00008000)
#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF) #define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII)
#define FEC_NAPI_IMASK FEC_ENET_MII
#define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF)) #define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF))
/* ENET interrupt coalescing macro define */ /* ENET interrupt coalescing macro define */
...@@ -542,6 +543,7 @@ struct fec_enet_private { ...@@ -542,6 +543,7 @@ struct fec_enet_private {
int link; int link;
int full_duplex; int full_duplex;
int speed; int speed;
struct completion mdio_done;
int irq[FEC_IRQ_NUM]; int irq[FEC_IRQ_NUM];
bool bufdesc_ex; bool bufdesc_ex;
int pause_flag; int pause_flag;
......
...@@ -976,8 +976,8 @@ fec_restart(struct net_device *ndev) ...@@ -976,8 +976,8 @@ fec_restart(struct net_device *ndev)
writel((__force u32)cpu_to_be32(temp_mac[1]), writel((__force u32)cpu_to_be32(temp_mac[1]),
fep->hwp + FEC_ADDR_HIGH); fep->hwp + FEC_ADDR_HIGH);
/* Clear any outstanding interrupt, except MDIO. */ /* Clear any outstanding interrupt. */
writel((0xffffffff & ~FEC_ENET_MII), fep->hwp + FEC_IEVENT); writel(0xffffffff, fep->hwp + FEC_IEVENT);
fec_enet_bd_init(ndev); fec_enet_bd_init(ndev);
...@@ -1123,7 +1123,7 @@ fec_restart(struct net_device *ndev) ...@@ -1123,7 +1123,7 @@ fec_restart(struct net_device *ndev)
if (fep->link) if (fep->link)
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
else else
writel(0, fep->hwp + FEC_IMASK); writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
/* Init the interrupt coalescing */ /* Init the interrupt coalescing */
fec_enet_itr_coal_init(ndev); fec_enet_itr_coal_init(ndev);
...@@ -1652,10 +1652,6 @@ fec_enet_interrupt(int irq, void *dev_id) ...@@ -1652,10 +1652,6 @@ fec_enet_interrupt(int irq, void *dev_id)
irqreturn_t ret = IRQ_NONE; irqreturn_t ret = IRQ_NONE;
int_events = readl(fep->hwp + FEC_IEVENT); 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); writel(int_events, fep->hwp + FEC_IEVENT);
fec_enet_collect_events(fep, int_events); fec_enet_collect_events(fep, int_events);
...@@ -1663,12 +1659,16 @@ fec_enet_interrupt(int irq, void *dev_id) ...@@ -1663,12 +1659,16 @@ fec_enet_interrupt(int irq, void *dev_id)
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
if (napi_schedule_prep(&fep->napi)) { if (napi_schedule_prep(&fep->napi)) {
/* Disable interrupts */ /* Disable the NAPI interrupts */
writel(0, fep->hwp + FEC_IMASK); writel(FEC_NAPI_IMASK, fep->hwp + FEC_IMASK);
__napi_schedule(&fep->napi); __napi_schedule(&fep->napi);
} }
} }
if (int_events & FEC_ENET_MII) {
ret = IRQ_HANDLED;
complete(&fep->mdio_done);
}
return ret; return ret;
} }
...@@ -1818,24 +1818,11 @@ static void fec_enet_adjust_link(struct net_device *ndev) ...@@ -1818,24 +1818,11 @@ static void fec_enet_adjust_link(struct net_device *ndev)
phy_print_status(phy_dev); 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) static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
{ {
struct fec_enet_private *fep = bus->priv; struct fec_enet_private *fep = bus->priv;
struct device *dev = &fep->pdev->dev; struct device *dev = &fep->pdev->dev;
unsigned long time_left;
int ret = 0, frame_start, frame_addr, frame_op; int ret = 0, frame_start, frame_addr, frame_op;
bool is_c45 = !!(regnum & MII_ADDR_C45); 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) ...@@ -1843,6 +1830,8 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
if (ret < 0) if (ret < 0)
return ret; return ret;
reinit_completion(&fep->mdio_done);
if (is_c45) { if (is_c45) {
frame_start = FEC_MMFR_ST_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) ...@@ -1854,9 +1843,11 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
fep->hwp + FEC_MII_DATA); fep->hwp + FEC_MII_DATA);
/* wait for end of transfer */ /* wait for end of transfer */
ret = fec_enet_mdio_wait(fep); time_left = wait_for_completion_timeout(&fep->mdio_done,
if (ret) { usecs_to_jiffies(FEC_MII_TIMEOUT));
if (time_left == 0) {
netdev_err(fep->netdev, "MDIO address write timeout\n"); netdev_err(fep->netdev, "MDIO address write timeout\n");
ret = -ETIMEDOUT;
goto out; goto out;
} }
...@@ -1875,9 +1866,11 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) ...@@ -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); FEC_MMFR_TA, fep->hwp + FEC_MII_DATA);
/* wait for end of transfer */ /* wait for end of transfer */
ret = fec_enet_mdio_wait(fep); time_left = wait_for_completion_timeout(&fep->mdio_done,
if (ret) { usecs_to_jiffies(FEC_MII_TIMEOUT));
if (time_left == 0) {
netdev_err(fep->netdev, "MDIO read timeout\n"); netdev_err(fep->netdev, "MDIO read timeout\n");
ret = -ETIMEDOUT;
goto out; goto out;
} }
...@@ -1895,6 +1888,7 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, ...@@ -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 fec_enet_private *fep = bus->priv;
struct device *dev = &fep->pdev->dev; struct device *dev = &fep->pdev->dev;
unsigned long time_left;
int ret, frame_start, frame_addr; int ret, frame_start, frame_addr;
bool is_c45 = !!(regnum & MII_ADDR_C45); 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, ...@@ -1904,6 +1898,8 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
else else
ret = 0; ret = 0;
reinit_completion(&fep->mdio_done);
if (is_c45) { if (is_c45) {
frame_start = FEC_MMFR_ST_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, ...@@ -1915,9 +1911,11 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
fep->hwp + FEC_MII_DATA); fep->hwp + FEC_MII_DATA);
/* wait for end of transfer */ /* wait for end of transfer */
ret = fec_enet_mdio_wait(fep); time_left = wait_for_completion_timeout(&fep->mdio_done,
if (ret) { usecs_to_jiffies(FEC_MII_TIMEOUT));
if (time_left == 0) {
netdev_err(fep->netdev, "MDIO address write timeout\n"); netdev_err(fep->netdev, "MDIO address write timeout\n");
ret = -ETIMEDOUT;
goto out; goto out;
} }
} else { } else {
...@@ -1933,9 +1931,12 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, ...@@ -1933,9 +1931,12 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
fep->hwp + FEC_MII_DATA); fep->hwp + FEC_MII_DATA);
/* wait for end of transfer */ /* wait for end of transfer */
ret = fec_enet_mdio_wait(fep); time_left = wait_for_completion_timeout(&fep->mdio_done,
if (ret) usecs_to_jiffies(FEC_MII_TIMEOUT));
if (time_left == 0) {
netdev_err(fep->netdev, "MDIO write timeout\n"); netdev_err(fep->netdev, "MDIO write timeout\n");
ret = -ETIMEDOUT;
}
out: out:
pm_runtime_mark_last_busy(dev); pm_runtime_mark_last_busy(dev);
...@@ -2144,9 +2145,6 @@ static int fec_enet_mii_init(struct platform_device *pdev) ...@@ -2144,9 +2145,6 @@ static int fec_enet_mii_init(struct platform_device *pdev)
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); 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(); fep->mii_bus = mdiobus_alloc();
if (fep->mii_bus == NULL) { if (fep->mii_bus == NULL) {
err = -ENOMEM; err = -ENOMEM;
...@@ -3688,6 +3686,7 @@ fec_probe(struct platform_device *pdev) ...@@ -3688,6 +3686,7 @@ fec_probe(struct platform_device *pdev)
fep->irq[i] = irq; fep->irq[i] = irq;
} }
init_completion(&fep->mdio_done);
ret = fec_enet_mii_init(pdev); ret = fec_enet_mii_init(pdev);
if (ret) if (ret)
goto failed_mii_init; goto failed_mii_init;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment