aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tulip
diff options
context:
space:
mode:
authorFrancois Romieu <romieu@fr.zoreil.com>2006-09-08 14:15:38 -0400
committerJeff Garzik <jeff@garzik.org>2006-09-11 09:05:37 -0400
commit0bb3cf726b37c13abce9f9134a68b94aa10e8803 (patch)
tree52a1fe8fdd08bdc088c1fb95957ecf5e698b8def /drivers/net/tulip
parent40c0d87948ab635e814f45664259d4cc193651a1 (diff)
[PATCH] Defer tulip_select_media() to process context
Move tulip_select_media() processing to a workqueue, instead of delaying in interrupt context, edited by Kyle McMartin to use kevent thread, instead of creating its own workqueue. Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> Signed-off-by: Valerie Henson <val_henson@linux.intel.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/tulip')
-rw-r--r--drivers/net/tulip/21142.c4
-rw-r--r--drivers/net/tulip/timer.c14
-rw-r--r--drivers/net/tulip/tulip.h19
-rw-r--r--drivers/net/tulip/tulip_core.c64
4 files changed, 60 insertions, 41 deletions
diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c
index 937025f8b5a1..fa3a2bb105ad 100644
--- a/drivers/net/tulip/21142.c
+++ b/drivers/net/tulip/21142.c
@@ -26,9 +26,9 @@ static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
26 26
27/* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list 27/* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list
28 of available transceivers. */ 28 of available transceivers. */
29void t21142_timer(unsigned long data) 29void t21142_media_task(void *data)
30{ 30{
31 struct net_device *dev = (struct net_device *)data; 31 struct net_device *dev = data;
32 struct tulip_private *tp = netdev_priv(dev); 32 struct tulip_private *tp = netdev_priv(dev);
33 void __iomem *ioaddr = tp->base_addr; 33 void __iomem *ioaddr = tp->base_addr;
34 int csr12 = ioread32(ioaddr + CSR12); 34 int csr12 = ioread32(ioaddr + CSR12);
diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c
index f75bc5ecd73c..066e5d6bcbd8 100644
--- a/drivers/net/tulip/timer.c
+++ b/drivers/net/tulip/timer.c
@@ -18,13 +18,14 @@
18#include "tulip.h" 18#include "tulip.h"
19 19
20 20
21void tulip_timer(unsigned long data) 21void tulip_media_task(void *data)
22{ 22{
23 struct net_device *dev = (struct net_device *)data; 23 struct net_device *dev = data;
24 struct tulip_private *tp = netdev_priv(dev); 24 struct tulip_private *tp = netdev_priv(dev);
25 void __iomem *ioaddr = tp->base_addr; 25 void __iomem *ioaddr = tp->base_addr;
26 u32 csr12 = ioread32(ioaddr + CSR12); 26 u32 csr12 = ioread32(ioaddr + CSR12);
27 int next_tick = 2*HZ; 27 int next_tick = 2*HZ;
28 unsigned long flags;
28 29
29 if (tulip_debug > 2) { 30 if (tulip_debug > 2) {
30 printk(KERN_DEBUG "%s: Media selection tick, %s, status %8.8x mode" 31 printk(KERN_DEBUG "%s: Media selection tick, %s, status %8.8x mode"
@@ -126,6 +127,15 @@ void tulip_timer(unsigned long data)
126 } 127 }
127 break; 128 break;
128 } 129 }
130
131
132 spin_lock_irqsave(&tp->lock, flags);
133 if (tp->timeout_recovery) {
134 tulip_tx_timeout_complete(tp, ioaddr);
135 tp->timeout_recovery = 0;
136 }
137 spin_unlock_irqrestore(&tp->lock, flags);
138
129 /* mod_timer synchronizes us with potential add_timer calls 139 /* mod_timer synchronizes us with potential add_timer calls
130 * from interrupts. 140 * from interrupts.
131 */ 141 */
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
index 3bcfbf3d23ed..64d443a80d8c 100644
--- a/drivers/net/tulip/tulip.h
+++ b/drivers/net/tulip/tulip.h
@@ -44,7 +44,8 @@ struct tulip_chip_table {
44 int io_size; 44 int io_size;
45 int valid_intrs; /* CSR7 interrupt enable settings */ 45 int valid_intrs; /* CSR7 interrupt enable settings */
46 int flags; 46 int flags;
47 void (*media_timer) (unsigned long data); 47 void (*media_timer) (unsigned long);
48 void (*media_task) (void *);
48}; 49};
49 50
50 51
@@ -366,6 +367,7 @@ struct tulip_private {
366 unsigned int medialock:1; /* Don't sense media type. */ 367 unsigned int medialock:1; /* Don't sense media type. */
367 unsigned int mediasense:1; /* Media sensing in progress. */ 368 unsigned int mediasense:1; /* Media sensing in progress. */
368 unsigned int nway:1, nwayset:1; /* 21143 internal NWay. */ 369 unsigned int nway:1, nwayset:1; /* 21143 internal NWay. */
370 unsigned int timeout_recovery:1;
369 unsigned int csr0; /* CSR0 setting. */ 371 unsigned int csr0; /* CSR0 setting. */
370 unsigned int csr6; /* Current CSR6 control settings. */ 372 unsigned int csr6; /* Current CSR6 control settings. */
371 unsigned char eeprom[EEPROM_SIZE]; /* Serial EEPROM contents. */ 373 unsigned char eeprom[EEPROM_SIZE]; /* Serial EEPROM contents. */
@@ -384,6 +386,7 @@ struct tulip_private {
384 void __iomem *base_addr; 386 void __iomem *base_addr;
385 int csr12_shadow; 387 int csr12_shadow;
386 int pad0; /* Used for 8-byte alignment */ 388 int pad0; /* Used for 8-byte alignment */
389 struct work_struct media_work;
387}; 390};
388 391
389 392
@@ -398,7 +401,7 @@ struct eeprom_fixup {
398 401
399/* 21142.c */ 402/* 21142.c */
400extern u16 t21142_csr14[]; 403extern u16 t21142_csr14[];
401void t21142_timer(unsigned long data); 404void t21142_media_task(void *data);
402void t21142_start_nway(struct net_device *dev); 405void t21142_start_nway(struct net_device *dev);
403void t21142_lnk_change(struct net_device *dev, int csr5); 406void t21142_lnk_change(struct net_device *dev, int csr5);
404 407
@@ -436,7 +439,7 @@ void pnic_lnk_change(struct net_device *dev, int csr5);
436void pnic_timer(unsigned long data); 439void pnic_timer(unsigned long data);
437 440
438/* timer.c */ 441/* timer.c */
439void tulip_timer(unsigned long data); 442void tulip_media_task(void *data);
440void mxic_timer(unsigned long data); 443void mxic_timer(unsigned long data);
441void comet_timer(unsigned long data); 444void comet_timer(unsigned long data);
442 445
@@ -485,4 +488,14 @@ static inline void tulip_restart_rxtx(struct tulip_private *tp)
485 tulip_start_rxtx(tp); 488 tulip_start_rxtx(tp);
486} 489}
487 490
491static inline void tulip_tx_timeout_complete(struct tulip_private *tp, void __iomem *ioaddr)
492{
493 /* Stop and restart the chip's Tx processes. */
494 tulip_restart_rxtx(tp);
495 /* Trigger an immediate transmit demand. */
496 iowrite32(0, ioaddr + CSR1);
497
498 tp->stats.tx_errors++;
499}
500
488#endif /* __NET_TULIP_H__ */ 501#endif /* __NET_TULIP_H__ */
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 6a7ca8695ff2..7e1ca3cae1ee 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -130,7 +130,14 @@ int tulip_debug = TULIP_DEBUG;
130int tulip_debug = 1; 130int tulip_debug = 1;
131#endif 131#endif
132 132
133static void tulip_timer(unsigned long data)
134{
135 struct net_device *dev = (struct net_device *)data;
136 struct tulip_private *tp = netdev_priv(dev);
133 137
138 if (netif_running(dev))
139 schedule_work(&tp->media_work);
140}
134 141
135/* 142/*
136 * This table use during operation for capabilities and media timer. 143 * This table use during operation for capabilities and media timer.
@@ -144,59 +151,60 @@ struct tulip_chip_table tulip_tbl[] = {
144 151
145 /* DC21140 */ 152 /* DC21140 */
146 { "Digital DS21140 Tulip", 128, 0x0001ebef, 153 { "Digital DS21140 Tulip", 128, 0x0001ebef,
147 HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer }, 154 HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer,
155 tulip_media_task },
148 156
149 /* DC21142, DC21143 */ 157 /* DC21142, DC21143 */
150 { "Digital DS21142/43 Tulip", 128, 0x0801fbff, 158 { "Digital DS21142/43 Tulip", 128, 0x0801fbff,
151 HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY 159 HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY
152 | HAS_INTR_MITIGATION | HAS_PCI_MWI, t21142_timer }, 160 | HAS_INTR_MITIGATION | HAS_PCI_MWI, tulip_timer, t21142_media_task },
153 161
154 /* LC82C168 */ 162 /* LC82C168 */
155 { "Lite-On 82c168 PNIC", 256, 0x0001fbef, 163 { "Lite-On 82c168 PNIC", 256, 0x0001fbef,
156 HAS_MII | HAS_PNICNWAY, pnic_timer }, 164 HAS_MII | HAS_PNICNWAY, pnic_timer, },
157 165
158 /* MX98713 */ 166 /* MX98713 */
159 { "Macronix 98713 PMAC", 128, 0x0001ebef, 167 { "Macronix 98713 PMAC", 128, 0x0001ebef,
160 HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer }, 168 HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer, },
161 169
162 /* MX98715 */ 170 /* MX98715 */
163 { "Macronix 98715 PMAC", 256, 0x0001ebef, 171 { "Macronix 98715 PMAC", 256, 0x0001ebef,
164 HAS_MEDIA_TABLE, mxic_timer }, 172 HAS_MEDIA_TABLE, mxic_timer, },
165 173
166 /* MX98725 */ 174 /* MX98725 */
167 { "Macronix 98725 PMAC", 256, 0x0001ebef, 175 { "Macronix 98725 PMAC", 256, 0x0001ebef,
168 HAS_MEDIA_TABLE, mxic_timer }, 176 HAS_MEDIA_TABLE, mxic_timer, },
169 177
170 /* AX88140 */ 178 /* AX88140 */
171 { "ASIX AX88140", 128, 0x0001fbff, 179 { "ASIX AX88140", 128, 0x0001fbff,
172 HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY 180 HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY
173 | IS_ASIX, tulip_timer }, 181 | IS_ASIX, tulip_timer, tulip_media_task },
174 182
175 /* PNIC2 */ 183 /* PNIC2 */
176 { "Lite-On PNIC-II", 256, 0x0801fbff, 184 { "Lite-On PNIC-II", 256, 0x0801fbff,
177 HAS_MII | HAS_NWAY | HAS_8023X | HAS_PCI_MWI, pnic2_timer }, 185 HAS_MII | HAS_NWAY | HAS_8023X | HAS_PCI_MWI, pnic2_timer, },
178 186
179 /* COMET */ 187 /* COMET */
180 { "ADMtek Comet", 256, 0x0001abef, 188 { "ADMtek Comet", 256, 0x0001abef,
181 HAS_MII | MC_HASH_ONLY | COMET_MAC_ADDR, comet_timer }, 189 HAS_MII | MC_HASH_ONLY | COMET_MAC_ADDR, comet_timer, },
182 190
183 /* COMPEX9881 */ 191 /* COMPEX9881 */
184 { "Compex 9881 PMAC", 128, 0x0001ebef, 192 { "Compex 9881 PMAC", 128, 0x0001ebef,
185 HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer }, 193 HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer, },
186 194
187 /* I21145 */ 195 /* I21145 */
188 { "Intel DS21145 Tulip", 128, 0x0801fbff, 196 { "Intel DS21145 Tulip", 128, 0x0801fbff,
189 HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI 197 HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI
190 | HAS_NWAY | HAS_PCI_MWI, t21142_timer }, 198 | HAS_NWAY | HAS_PCI_MWI, tulip_timer, tulip_media_task },
191 199
192 /* DM910X */ 200 /* DM910X */
193 { "Davicom DM9102/DM9102A", 128, 0x0001ebef, 201 { "Davicom DM9102/DM9102A", 128, 0x0001ebef,
194 HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI, 202 HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI,
195 tulip_timer }, 203 tulip_timer, tulip_media_task },
196 204
197 /* RS7112 */ 205 /* RS7112 */
198 { "Conexant LANfinity", 256, 0x0001ebef, 206 { "Conexant LANfinity", 256, 0x0001ebef,
199 HAS_MII | HAS_ACPI, tulip_timer }, 207 HAS_MII | HAS_ACPI, tulip_timer, tulip_media_task },
200 208
201}; 209};
202 210
@@ -524,20 +532,9 @@ static void tulip_tx_timeout(struct net_device *dev)
524 "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n", 532 "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n",
525 dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12), 533 dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12),
526 ioread32(ioaddr + CSR13), ioread32(ioaddr + CSR14), ioread32(ioaddr + CSR15)); 534 ioread32(ioaddr + CSR13), ioread32(ioaddr + CSR14), ioread32(ioaddr + CSR15));
527 if ( ! tp->medialock && tp->mtable) { 535 tp->timeout_recovery = 1;
528 do 536 schedule_work(&tp->media_work);
529 --tp->cur_index; 537 goto out_unlock;
530 while (tp->cur_index >= 0
531 && (tulip_media_cap[tp->mtable->mleaf[tp->cur_index].media]
532 & MediaIsFD));
533 if (--tp->cur_index < 0) {
534 /* We start again, but should instead look for default. */
535 tp->cur_index = tp->mtable->leafcount - 1;
536 }
537 tulip_select_media(dev, 0);
538 printk(KERN_WARNING "%s: transmit timed out, switching to %s "
539 "media.\n", dev->name, medianame[dev->if_port]);
540 }
541 } else if (tp->chip_id == PNIC2) { 538 } else if (tp->chip_id == PNIC2) {
542 printk(KERN_WARNING "%s: PNIC2 transmit timed out, status %8.8x, " 539 printk(KERN_WARNING "%s: PNIC2 transmit timed out, status %8.8x, "
543 "CSR6/7 %8.8x / %8.8x CSR12 %8.8x, resetting...\n", 540 "CSR6/7 %8.8x / %8.8x CSR12 %8.8x, resetting...\n",
@@ -577,14 +574,9 @@ static void tulip_tx_timeout(struct net_device *dev)
577 } 574 }
578#endif 575#endif
579 576
580 /* Stop and restart the chip's Tx processes . */ 577 tulip_tx_timeout_complete(tp, ioaddr);
581
582 tulip_restart_rxtx(tp);
583 /* Trigger an immediate transmit demand. */
584 iowrite32(0, ioaddr + CSR1);
585
586 tp->stats.tx_errors++;
587 578
579out_unlock:
588 spin_unlock_irqrestore (&tp->lock, flags); 580 spin_unlock_irqrestore (&tp->lock, flags);
589 dev->trans_start = jiffies; 581 dev->trans_start = jiffies;
590 netif_wake_queue (dev); 582 netif_wake_queue (dev);
@@ -734,6 +726,8 @@ static void tulip_down (struct net_device *dev)
734 void __iomem *ioaddr = tp->base_addr; 726 void __iomem *ioaddr = tp->base_addr;
735 unsigned long flags; 727 unsigned long flags;
736 728
729 flush_scheduled_work();
730
737 del_timer_sync (&tp->timer); 731 del_timer_sync (&tp->timer);
738#ifdef CONFIG_TULIP_NAPI 732#ifdef CONFIG_TULIP_NAPI
739 del_timer_sync (&tp->oom_timer); 733 del_timer_sync (&tp->oom_timer);
@@ -1400,6 +1394,8 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
1400 tp->timer.data = (unsigned long)dev; 1394 tp->timer.data = (unsigned long)dev;
1401 tp->timer.function = tulip_tbl[tp->chip_id].media_timer; 1395 tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
1402 1396
1397 INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task, dev);
1398
1403 dev->base_addr = (unsigned long)ioaddr; 1399 dev->base_addr = (unsigned long)ioaddr;
1404 1400
1405#ifdef CONFIG_TULIP_MWI 1401#ifdef CONFIG_TULIP_MWI