aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndrew Victor <andrew@sanpeople.com>2006-06-20 05:50:23 -0400
committerJeff Garzik <jeff@garzik.org>2006-06-22 22:56:21 -0400
commit775637df0caccc204628ebacca2b07f35c88b96b (patch)
tree837b379c417d2bd39f92ede7036642c12f47b014 /drivers
parentd955d90b90db4b3ac2a3e56d271f372c41fb00d6 (diff)
[PATCH] AT91RM9200 Ethernet #1: Link poll
For Ethernet PHYs that don't have an IRQ pin or boards that don't connect the IRQ pin to the processor, we enable a timer to poll the PHY's link state. Patch originally supplied by Eric Benard and Roman Kolesnikov. Signed-off-by: Andrew Victor <andrew@sanpeople.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/arm/at91_ether.c61
1 files changed, 43 insertions, 18 deletions
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
index 5503dc8a66e4..5b5095629a93 100644
--- a/drivers/net/arm/at91_ether.c
+++ b/drivers/net/arm/at91_ether.c
@@ -45,6 +45,9 @@
45static struct net_device *at91_dev; 45static struct net_device *at91_dev;
46static struct clk *ether_clk; 46static struct clk *ether_clk;
47 47
48static struct timer_list check_timer;
49#define LINK_POLL_INTERVAL (HZ)
50
48/* ..................................................................... */ 51/* ..................................................................... */
49 52
50/* 53/*
@@ -143,7 +146,7 @@ static void read_phy(unsigned char phy_addr, unsigned char address, unsigned int
143 * MAC accordingly. 146 * MAC accordingly.
144 * If no link or auto-negotiation is busy, then no changes are made. 147 * If no link or auto-negotiation is busy, then no changes are made.
145 */ 148 */
146static void update_linkspeed(struct net_device *dev) 149static void update_linkspeed(struct net_device *dev, int silent)
147{ 150{
148 struct at91_private *lp = (struct at91_private *) dev->priv; 151 struct at91_private *lp = (struct at91_private *) dev->priv;
149 unsigned int bmsr, bmcr, lpa, mac_cfg; 152 unsigned int bmsr, bmcr, lpa, mac_cfg;
@@ -151,7 +154,8 @@ static void update_linkspeed(struct net_device *dev)
151 154
152 if (!mii_link_ok(&lp->mii)) { /* no link */ 155 if (!mii_link_ok(&lp->mii)) { /* no link */
153 netif_carrier_off(dev); 156 netif_carrier_off(dev);
154 printk(KERN_INFO "%s: Link down.\n", dev->name); 157 if (!silent)
158 printk(KERN_INFO "%s: Link down.\n", dev->name);
155 return; 159 return;
156 } 160 }
157 161
@@ -186,7 +190,8 @@ static void update_linkspeed(struct net_device *dev)
186 } 190 }
187 at91_emac_write(AT91_EMAC_CFG, mac_cfg); 191 at91_emac_write(AT91_EMAC_CFG, mac_cfg);
188 192
189 printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex"); 193 if (!silent)
194 printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex");
190 netif_carrier_on(dev); 195 netif_carrier_on(dev);
191} 196}
192 197
@@ -226,7 +231,7 @@ static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id, struct pt_regs
226 goto done; 231 goto done;
227 } 232 }
228 233
229 update_linkspeed(dev); 234 update_linkspeed(dev, 0);
230 235
231done: 236done:
232 disable_mdi(); 237 disable_mdi();
@@ -243,14 +248,17 @@ static void enable_phyirq(struct net_device *dev)
243 unsigned int dsintr, irq_number; 248 unsigned int dsintr, irq_number;
244 int status; 249 int status;
245 250
246 if (lp->phy_type == MII_RTL8201_ID) /* RTL8201 does not have an interrupt */ 251 irq_number = lp->board_data.phy_irq_pin;
247 return; 252 if (!irq_number) {
248 if (lp->phy_type == MII_DP83847_ID) /* DP83847 does not have an interrupt */ 253 /*
249 return; 254 * PHY doesn't have an IRQ pin (RTL8201, DP83847, AC101L),
250 if (lp->phy_type == MII_AC101L_ID) /* AC101L interrupt not supported yet */ 255 * or board does not have it connected.
256 */
257 check_timer.expires = jiffies + LINK_POLL_INTERVAL;
258 add_timer(&check_timer);
251 return; 259 return;
260 }
252 261
253 irq_number = lp->board_data.phy_irq_pin;
254 status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev); 262 status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev);
255 if (status) { 263 if (status) {
256 printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status); 264 printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status);
@@ -292,12 +300,11 @@ static void disable_phyirq(struct net_device *dev)
292 unsigned int dsintr; 300 unsigned int dsintr;
293 unsigned int irq_number; 301 unsigned int irq_number;
294 302
295 if (lp->phy_type == MII_RTL8201_ID) /* RTL8201 does not have an interrupt */ 303 irq_number = lp->board_data.phy_irq_pin;
296 return; 304 if (!irq_number) {
297 if (lp->phy_type == MII_DP83847_ID) /* DP83847 does not have an interrupt */ 305 del_timer_sync(&check_timer);
298 return;
299 if (lp->phy_type == MII_AC101L_ID) /* AC101L interrupt not supported yet */
300 return; 306 return;
307 }
301 308
302 spin_lock_irq(&lp->lock); 309 spin_lock_irq(&lp->lock);
303 enable_mdi(); 310 enable_mdi();
@@ -326,7 +333,6 @@ static void disable_phyirq(struct net_device *dev)
326 disable_mdi(); 333 disable_mdi();
327 spin_unlock_irq(&lp->lock); 334 spin_unlock_irq(&lp->lock);
328 335
329 irq_number = lp->board_data.phy_irq_pin;
330 free_irq(irq_number, dev); /* Free interrupt handler */ 336 free_irq(irq_number, dev); /* Free interrupt handler */
331} 337}
332 338
@@ -355,6 +361,18 @@ static void reset_phy(struct net_device *dev)
355} 361}
356#endif 362#endif
357 363
364static void at91ether_check_link(unsigned long dev_id)
365{
366 struct net_device *dev = (struct net_device *) dev_id;
367
368 enable_mdi();
369 update_linkspeed(dev, 1);
370 disable_mdi();
371
372 check_timer.expires = jiffies + LINK_POLL_INTERVAL;
373 add_timer(&check_timer);
374}
375
358/* ......................... ADDRESS MANAGEMENT ........................ */ 376/* ......................... ADDRESS MANAGEMENT ........................ */
359 377
360/* 378/*
@@ -708,7 +726,7 @@ static int at91ether_open(struct net_device *dev)
708 /* Determine current link speed */ 726 /* Determine current link speed */
709 spin_lock_irq(&lp->lock); 727 spin_lock_irq(&lp->lock);
710 enable_mdi(); 728 enable_mdi();
711 update_linkspeed(dev); 729 update_linkspeed(dev, 0);
712 disable_mdi(); 730 disable_mdi();
713 spin_unlock_irq(&lp->lock); 731 spin_unlock_irq(&lp->lock);
714 732
@@ -992,11 +1010,18 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
992 /* Determine current link speed */ 1010 /* Determine current link speed */
993 spin_lock_irq(&lp->lock); 1011 spin_lock_irq(&lp->lock);
994 enable_mdi(); 1012 enable_mdi();
995 update_linkspeed(dev); 1013 update_linkspeed(dev, 0);
996 disable_mdi(); 1014 disable_mdi();
997 spin_unlock_irq(&lp->lock); 1015 spin_unlock_irq(&lp->lock);
998 netif_carrier_off(dev); /* will be enabled in open() */ 1016 netif_carrier_off(dev); /* will be enabled in open() */
999 1017
1018 /* If board has no PHY IRQ, use a timer to poll the PHY */
1019 if (!lp->board_data.phy_irq_pin) {
1020 init_timer(&check_timer);
1021 check_timer.data = (unsigned long)dev;
1022 check_timer.function = at91ether_check_link;
1023 }
1024
1000 /* Display ethernet banner */ 1025 /* Display ethernet banner */
1001 printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%02x:%02x:%02x:%02x:%02x:%02x)\n", 1026 printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%02x:%02x:%02x:%02x:%02x:%02x)\n",
1002 dev->name, (uint) dev->base_addr, dev->irq, 1027 dev->name, (uint) dev->base_addr, dev->irq,