|
@@ -130,7 +130,14 @@ int tulip_debug = TULIP_DEBUG;
|
|
|
int tulip_debug = 1;
|
|
|
#endif
|
|
|
|
|
|
+static void tulip_timer(unsigned long data)
|
|
|
+{
|
|
|
+ struct net_device *dev = (struct net_device *)data;
|
|
|
+ struct tulip_private *tp = netdev_priv(dev);
|
|
|
|
|
|
+ if (netif_running(dev))
|
|
|
+ schedule_work(&tp->media_work);
|
|
|
+}
|
|
|
|
|
|
/*
|
|
|
* This table use during operation for capabilities and media timer.
|
|
@@ -144,59 +151,60 @@ struct tulip_chip_table tulip_tbl[] = {
|
|
|
|
|
|
/* DC21140 */
|
|
|
{ "Digital DS21140 Tulip", 128, 0x0001ebef,
|
|
|
- HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer },
|
|
|
+ HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer,
|
|
|
+ tulip_media_task },
|
|
|
|
|
|
/* DC21142, DC21143 */
|
|
|
{ "Digital DS21142/43 Tulip", 128, 0x0801fbff,
|
|
|
HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY
|
|
|
- | HAS_INTR_MITIGATION | HAS_PCI_MWI, t21142_timer },
|
|
|
+ | HAS_INTR_MITIGATION | HAS_PCI_MWI, tulip_timer, t21142_media_task },
|
|
|
|
|
|
/* LC82C168 */
|
|
|
{ "Lite-On 82c168 PNIC", 256, 0x0001fbef,
|
|
|
- HAS_MII | HAS_PNICNWAY, pnic_timer },
|
|
|
+ HAS_MII | HAS_PNICNWAY, pnic_timer, },
|
|
|
|
|
|
/* MX98713 */
|
|
|
{ "Macronix 98713 PMAC", 128, 0x0001ebef,
|
|
|
- HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer },
|
|
|
+ HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer, },
|
|
|
|
|
|
/* MX98715 */
|
|
|
{ "Macronix 98715 PMAC", 256, 0x0001ebef,
|
|
|
- HAS_MEDIA_TABLE, mxic_timer },
|
|
|
+ HAS_MEDIA_TABLE, mxic_timer, },
|
|
|
|
|
|
/* MX98725 */
|
|
|
{ "Macronix 98725 PMAC", 256, 0x0001ebef,
|
|
|
- HAS_MEDIA_TABLE, mxic_timer },
|
|
|
+ HAS_MEDIA_TABLE, mxic_timer, },
|
|
|
|
|
|
/* AX88140 */
|
|
|
{ "ASIX AX88140", 128, 0x0001fbff,
|
|
|
HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY
|
|
|
- | IS_ASIX, tulip_timer },
|
|
|
+ | IS_ASIX, tulip_timer, tulip_media_task },
|
|
|
|
|
|
/* PNIC2 */
|
|
|
{ "Lite-On PNIC-II", 256, 0x0801fbff,
|
|
|
- HAS_MII | HAS_NWAY | HAS_8023X | HAS_PCI_MWI, pnic2_timer },
|
|
|
+ HAS_MII | HAS_NWAY | HAS_8023X | HAS_PCI_MWI, pnic2_timer, },
|
|
|
|
|
|
/* COMET */
|
|
|
{ "ADMtek Comet", 256, 0x0001abef,
|
|
|
- HAS_MII | MC_HASH_ONLY | COMET_MAC_ADDR, comet_timer },
|
|
|
+ HAS_MII | MC_HASH_ONLY | COMET_MAC_ADDR, comet_timer, },
|
|
|
|
|
|
/* COMPEX9881 */
|
|
|
{ "Compex 9881 PMAC", 128, 0x0001ebef,
|
|
|
- HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer },
|
|
|
+ HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer, },
|
|
|
|
|
|
/* I21145 */
|
|
|
{ "Intel DS21145 Tulip", 128, 0x0801fbff,
|
|
|
HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI
|
|
|
- | HAS_NWAY | HAS_PCI_MWI, t21142_timer },
|
|
|
+ | HAS_NWAY | HAS_PCI_MWI, tulip_timer, tulip_media_task },
|
|
|
|
|
|
/* DM910X */
|
|
|
{ "Davicom DM9102/DM9102A", 128, 0x0001ebef,
|
|
|
HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI,
|
|
|
- tulip_timer },
|
|
|
+ tulip_timer, tulip_media_task },
|
|
|
|
|
|
/* RS7112 */
|
|
|
{ "Conexant LANfinity", 256, 0x0001ebef,
|
|
|
- HAS_MII | HAS_ACPI, tulip_timer },
|
|
|
+ HAS_MII | HAS_ACPI, tulip_timer, tulip_media_task },
|
|
|
|
|
|
};
|
|
|
|
|
@@ -524,20 +532,9 @@ static void tulip_tx_timeout(struct net_device *dev)
|
|
|
"SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n",
|
|
|
dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12),
|
|
|
ioread32(ioaddr + CSR13), ioread32(ioaddr + CSR14), ioread32(ioaddr + CSR15));
|
|
|
- if ( ! tp->medialock && tp->mtable) {
|
|
|
- do
|
|
|
- --tp->cur_index;
|
|
|
- while (tp->cur_index >= 0
|
|
|
- && (tulip_media_cap[tp->mtable->mleaf[tp->cur_index].media]
|
|
|
- & MediaIsFD));
|
|
|
- if (--tp->cur_index < 0) {
|
|
|
- /* We start again, but should instead look for default. */
|
|
|
- tp->cur_index = tp->mtable->leafcount - 1;
|
|
|
- }
|
|
|
- tulip_select_media(dev, 0);
|
|
|
- printk(KERN_WARNING "%s: transmit timed out, switching to %s "
|
|
|
- "media.\n", dev->name, medianame[dev->if_port]);
|
|
|
- }
|
|
|
+ tp->timeout_recovery = 1;
|
|
|
+ schedule_work(&tp->media_work);
|
|
|
+ goto out_unlock;
|
|
|
} else if (tp->chip_id == PNIC2) {
|
|
|
printk(KERN_WARNING "%s: PNIC2 transmit timed out, status %8.8x, "
|
|
|
"CSR6/7 %8.8x / %8.8x CSR12 %8.8x, resetting...\n",
|
|
@@ -577,14 +574,9 @@ static void tulip_tx_timeout(struct net_device *dev)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
- /* Stop and restart the chip's Tx processes . */
|
|
|
-
|
|
|
- tulip_restart_rxtx(tp);
|
|
|
- /* Trigger an immediate transmit demand. */
|
|
|
- iowrite32(0, ioaddr + CSR1);
|
|
|
-
|
|
|
- tp->stats.tx_errors++;
|
|
|
+ tulip_tx_timeout_complete(tp, ioaddr);
|
|
|
|
|
|
+out_unlock:
|
|
|
spin_unlock_irqrestore (&tp->lock, flags);
|
|
|
dev->trans_start = jiffies;
|
|
|
netif_wake_queue (dev);
|
|
@@ -734,6 +726,8 @@ static void tulip_down (struct net_device *dev)
|
|
|
void __iomem *ioaddr = tp->base_addr;
|
|
|
unsigned long flags;
|
|
|
|
|
|
+ flush_scheduled_work();
|
|
|
+
|
|
|
del_timer_sync (&tp->timer);
|
|
|
#ifdef CONFIG_TULIP_NAPI
|
|
|
del_timer_sync (&tp->oom_timer);
|
|
@@ -1400,6 +1394,8 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
|
|
|
tp->timer.data = (unsigned long)dev;
|
|
|
tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
|
|
|
|
|
|
+ INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task, dev);
|
|
|
+
|
|
|
dev->base_addr = (unsigned long)ioaddr;
|
|
|
|
|
|
#ifdef CONFIG_TULIP_MWI
|