int     index;
        int     link;
        int     full_duplex;
+       struct  completion mdio_done;
 };
 
 static irqreturn_t fec_enet_interrupt(int irq, void * dev_id);
 #define FEC_MMFR_TA            (2 << 16)
 #define FEC_MMFR_DATA(v)       (v & 0xffff)
 
-#define FEC_MII_TIMEOUT                10000
+#define FEC_MII_TIMEOUT                1000 /* us */
 
 /* Transmitter timeout */
 #define TX_TIMEOUT (2 * HZ)
                        ret = IRQ_HANDLED;
                        fec_enet_tx(dev);
                }
+
+               if (int_events & FEC_ENET_MII) {
+                       ret = IRQ_HANDLED;
+                       complete(&fep->mdio_done);
+               }
        } while (int_events);
 
        return ret;
                phy_print_status(phy_dev);
 }
 
-/*
- * NOTE: a MII transaction is during around 25 us, so polling it...
- */
 static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
 {
        struct fec_enet_private *fep = bus->priv;
-       int timeout = FEC_MII_TIMEOUT;
+       unsigned long time_left;
 
        fep->mii_timeout = 0;
-
-       /* clear MII end of transfer bit*/
-       writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
+       init_completion(&fep->mdio_done);
 
        /* start a read op */
        writel(FEC_MMFR_ST | FEC_MMFR_OP_READ |
                FEC_MMFR_TA, fep->hwp + FEC_MII_DATA);
 
        /* wait for end of transfer */
-       while (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_MII)) {
-               cpu_relax();
-               if (timeout-- < 0) {
-                       fep->mii_timeout = 1;
-                       printk(KERN_ERR "FEC: MDIO read timeout\n");
-                       return -ETIMEDOUT;
-               }
+       time_left = wait_for_completion_timeout(&fep->mdio_done,
+                       usecs_to_jiffies(FEC_MII_TIMEOUT));
+       if (time_left == 0) {
+               fep->mii_timeout = 1;
+               printk(KERN_ERR "FEC: MDIO read timeout\n");
+               return -ETIMEDOUT;
        }
 
        /* return value */
                           u16 value)
 {
        struct fec_enet_private *fep = bus->priv;
-       int timeout = FEC_MII_TIMEOUT;
+       unsigned long time_left;
 
        fep->mii_timeout = 0;
-
-       /* clear MII end of transfer bit*/
-       writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
+       init_completion(&fep->mdio_done);
 
        /* start a read op */
        writel(FEC_MMFR_ST | FEC_MMFR_OP_READ |
                fep->hwp + FEC_MII_DATA);
 
        /* wait for end of transfer */
-       while (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_MII)) {
-               cpu_relax();
-               if (timeout-- < 0) {
-                       fep->mii_timeout = 1;
-                       printk(KERN_ERR "FEC: MDIO write timeout\n");
-                       return -ETIMEDOUT;
-               }
+       time_left = wait_for_completion_timeout(&fep->mdio_done,
+                       usecs_to_jiffies(FEC_MII_TIMEOUT));
+       if (time_left == 0) {
+               fep->mii_timeout = 1;
+               printk(KERN_ERR "FEC: MDIO write timeout\n");
+               return -ETIMEDOUT;
        }
 
        return 0;
        writel(0, fep->hwp + FEC_R_DES_ACTIVE);
 
        /* Enable interrupts we wish to service */
-       writel(FEC_ENET_TXF | FEC_ENET_RXF, fep->hwp + FEC_IMASK);
+       writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII,
+                       fep->hwp + FEC_IMASK);
 }
 
 static void
        writel(1, fep->hwp + FEC_ECNTRL);
        udelay(10);
 
-       /* Clear outstanding MII command interrupts. */
-       writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
-
        writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
 }