aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/fec.c55
1 files changed, 25 insertions, 30 deletions
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index b4afd7a6ee29..937f1b4a3483 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -187,6 +187,7 @@ struct fec_enet_private {
187 int index; 187 int index;
188 int link; 188 int link;
189 int full_duplex; 189 int full_duplex;
190 struct completion mdio_done;
190}; 191};
191 192
192static irqreturn_t fec_enet_interrupt(int irq, void * dev_id); 193static irqreturn_t fec_enet_interrupt(int irq, void * dev_id);
@@ -205,7 +206,7 @@ static void fec_stop(struct net_device *dev);
205#define FEC_MMFR_TA (2 << 16) 206#define FEC_MMFR_TA (2 << 16)
206#define FEC_MMFR_DATA(v) (v & 0xffff) 207#define FEC_MMFR_DATA(v) (v & 0xffff)
207 208
208#define FEC_MII_TIMEOUT 10000 209#define FEC_MII_TIMEOUT 1000 /* us */
209 210
210/* Transmitter timeout */ 211/* Transmitter timeout */
211#define TX_TIMEOUT (2 * HZ) 212#define TX_TIMEOUT (2 * HZ)
@@ -334,6 +335,11 @@ fec_enet_interrupt(int irq, void * dev_id)
334 ret = IRQ_HANDLED; 335 ret = IRQ_HANDLED;
335 fec_enet_tx(dev); 336 fec_enet_tx(dev);
336 } 337 }
338
339 if (int_events & FEC_ENET_MII) {
340 ret = IRQ_HANDLED;
341 complete(&fep->mdio_done);
342 }
337 } while (int_events); 343 } while (int_events);
338 344
339 return ret; 345 return ret;
@@ -608,18 +614,13 @@ spin_unlock:
608 phy_print_status(phy_dev); 614 phy_print_status(phy_dev);
609} 615}
610 616
611/*
612 * NOTE: a MII transaction is during around 25 us, so polling it...
613 */
614static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) 617static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
615{ 618{
616 struct fec_enet_private *fep = bus->priv; 619 struct fec_enet_private *fep = bus->priv;
617 int timeout = FEC_MII_TIMEOUT; 620 unsigned long time_left;
618 621
619 fep->mii_timeout = 0; 622 fep->mii_timeout = 0;
620 623 init_completion(&fep->mdio_done);
621 /* clear MII end of transfer bit*/
622 writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
623 624
624 /* start a read op */ 625 /* start a read op */
625 writel(FEC_MMFR_ST | FEC_MMFR_OP_READ | 626 writel(FEC_MMFR_ST | FEC_MMFR_OP_READ |
@@ -627,13 +628,12 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
627 FEC_MMFR_TA, fep->hwp + FEC_MII_DATA); 628 FEC_MMFR_TA, fep->hwp + FEC_MII_DATA);
628 629
629 /* wait for end of transfer */ 630 /* wait for end of transfer */
630 while (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_MII)) { 631 time_left = wait_for_completion_timeout(&fep->mdio_done,
631 cpu_relax(); 632 usecs_to_jiffies(FEC_MII_TIMEOUT));
632 if (timeout-- < 0) { 633 if (time_left == 0) {
633 fep->mii_timeout = 1; 634 fep->mii_timeout = 1;
634 printk(KERN_ERR "FEC: MDIO read timeout\n"); 635 printk(KERN_ERR "FEC: MDIO read timeout\n");
635 return -ETIMEDOUT; 636 return -ETIMEDOUT;
636 }
637 } 637 }
638 638
639 /* return value */ 639 /* return value */
@@ -644,12 +644,10 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
644 u16 value) 644 u16 value)
645{ 645{
646 struct fec_enet_private *fep = bus->priv; 646 struct fec_enet_private *fep = bus->priv;
647 int timeout = FEC_MII_TIMEOUT; 647 unsigned long time_left;
648 648
649 fep->mii_timeout = 0; 649 fep->mii_timeout = 0;
650 650 init_completion(&fep->mdio_done);
651 /* clear MII end of transfer bit*/
652 writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
653 651
654 /* start a read op */ 652 /* start a read op */
655 writel(FEC_MMFR_ST | FEC_MMFR_OP_READ | 653 writel(FEC_MMFR_ST | FEC_MMFR_OP_READ |
@@ -658,13 +656,12 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
658 fep->hwp + FEC_MII_DATA); 656 fep->hwp + FEC_MII_DATA);
659 657
660 /* wait for end of transfer */ 658 /* wait for end of transfer */
661 while (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_MII)) { 659 time_left = wait_for_completion_timeout(&fep->mdio_done,
662 cpu_relax(); 660 usecs_to_jiffies(FEC_MII_TIMEOUT));
663 if (timeout-- < 0) { 661 if (time_left == 0) {
664 fep->mii_timeout = 1; 662 fep->mii_timeout = 1;
665 printk(KERN_ERR "FEC: MDIO write timeout\n"); 663 printk(KERN_ERR "FEC: MDIO write timeout\n");
666 return -ETIMEDOUT; 664 return -ETIMEDOUT;
667 }
668 } 665 }
669 666
670 return 0; 667 return 0;
@@ -1216,7 +1213,8 @@ fec_restart(struct net_device *dev, int duplex)
1216 writel(0, fep->hwp + FEC_R_DES_ACTIVE); 1213 writel(0, fep->hwp + FEC_R_DES_ACTIVE);
1217 1214
1218 /* Enable interrupts we wish to service */ 1215 /* Enable interrupts we wish to service */
1219 writel(FEC_ENET_TXF | FEC_ENET_RXF, fep->hwp + FEC_IMASK); 1216 writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII,
1217 fep->hwp + FEC_IMASK);
1220} 1218}
1221 1219
1222static void 1220static void
@@ -1236,9 +1234,6 @@ fec_stop(struct net_device *dev)
1236 writel(1, fep->hwp + FEC_ECNTRL); 1234 writel(1, fep->hwp + FEC_ECNTRL);
1237 udelay(10); 1235 udelay(10);
1238 1236
1239 /* Clear outstanding MII command interrupts. */
1240 writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
1241
1242 writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); 1237 writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
1243} 1238}
1244 1239