patch-2.4.9 linux/drivers/net/3c59x.c
Next file: linux/drivers/net/8139too.c
Previous file: linux/drivers/net/3c505.c
Back to the patch index
Back to the overall index
- Lines: 636
- Date:
Sun Aug 12 12:27:18 2001
- Orig file:
v2.4.8/linux/drivers/net/3c59x.c
- Orig date:
Tue Jul 3 17:08:20 2001
diff -u --recursive --new-file v2.4.8/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c
@@ -9,9 +9,13 @@
Members of the series include Fast EtherLink 3c590/3c592/3c595/3c597
and the EtherLink XL 3c900 and 3c905 cards.
+ Problem reports and questions should be directed to
+ vortex@scyld.com
+
The author may be reached as becker@scyld.com, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
+ Scyld Computing Corporation
+ 410 Severn Ave., Suite 210
+ Annapolis MD 21403
Linux Kernel Additions:
@@ -50,7 +54,7 @@
- Put vortex_info_tbl into __devinitdata
- In the vortex_error StatsFull HACK, disable stats in vp->intr_enable as well
as in the hardware.
- - Increased the loop counter in wait_for_completion from 2,000 to 4,000.
+ - Increased the loop counter in issue_and_wait from 2,000 to 4,000.
LK1.1.5 28 April 2000, andrewm
- Added powerpc defines (John Daniel <jdaniel@etresoft.com> said these work...)
@@ -92,7 +96,7 @@
- Ignore request_region() return value - already reserved if Cardbus.
- Merged some additional Cardbus flags from Don's 0.99Qk
- Some fixes for 3c556 (Fred Maciel)
- - Fix for EISA initialisation (Jan Rkorajski)
+ - Fix for EISA initialisation (Jan Rekorajski)
- Renamed MII_XCVR_PWR and EEPROM_230 to align with 3c575_cb and D. Becker's drivers
- Fixed MII_XCVR_PWR for 3CCFE575CT
- Added INVERT_LED_PWR, used it.
@@ -121,7 +125,7 @@
LK1.1.12 1 Jan 2001 andrewm (2.4.0-pre1)
- Call pci_enable_device before we request our IRQ (Tobias Ringstrom)
- Add 3c590 PCI latency timer hack to vortex_probe1 (from 0.99Ra)
- - Added extended wait_for_completion for the 3c905CX.
+ - Added extended issue_and_wait for the 3c905CX.
- Look for an MII on PHY index 24 first (3c905CX oddity).
- Add HAS_NWAY to 3cSOHO100-TX (Brett Frankenberger)
- Don't free skbs we don't own on oom path in vortex_open().
@@ -149,6 +153,19 @@
- Implemented alloc_etherdev() API
- Special-case the 'Tx error 82' message.
+ LK1.1.16 18 July 2001 akpm
+ - Make NETIF_F_SG dependent upon nr_free_highpages(), not on CONFIG_HIGHMEM
+ - Lessen verbosity of bootup messages
+ - Fix WOL - use new PM API functions.
+ - Use netif_running() instead of vp->open in suspend/resume.
+ - Don't reset the interface logic on open/close/rmmod. It upsets
+ autonegotiation, and hence DHCP (from 0.99T).
+ - Back out EEPROM_NORESET flag because of the above (we do it for all
+ NICs).
+ - Correct 3c982 identification string
+ - Rename wait_for_completion() to issue_and_wait() to avoid completion.h
+ clash.
+
- See http://www.uow.edu.au/~andrewm/linux/#3c59x-2.3 for more details.
- Also see Documentation/networking/vortex.txt
*/
@@ -164,8 +181,8 @@
#define DRV_NAME "3c59x"
-#define DRV_VERSION "LK1.1.15"
-#define DRV_RELDATE "6 June 2001"
+#define DRV_VERSION "LK1.1.16"
+#define DRV_RELDATE "19 July 2001"
@@ -230,6 +247,7 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
+#include <linux/highmem.h>
#include <asm/irq.h> /* For NR_IRQS only. */
#include <asm/bitops.h>
#include <asm/io.h>
@@ -244,10 +262,11 @@
static char version[] __devinitdata =
-DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " Donald Becker and others. http://www.scyld.com/network/vortex.html\n";
+DRV_NAME ": Donald Becker and others. www.scyld.com/network/vortex.html\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
-MODULE_DESCRIPTION("3Com 3c59x/3c90x/3c575 series Vortex/Boomerang/Cyclone driver");
+MODULE_DESCRIPTION("3Com 3c59x/3c9xx ethernet driver "
+ DRV_VERSION " " DRV_RELDATE);
MODULE_PARM(debug, "i");
MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
@@ -379,7 +398,7 @@
EEPROM_8BIT=0x10, /* AKPM: Uses 0x230 as the base bitmaps for EEPROM reads */
HAS_PWR_CTRL=0x20, HAS_MII=0x40, HAS_NWAY=0x80, HAS_CB_FNS=0x100,
INVERT_MII_PWR=0x200, INVERT_LED_PWR=0x400, MAX_COLLISION_RESET=0x800,
- EEPROM_OFFSET=0x1000, EEPROM_NORESET=0x2000, HAS_HWCKSM=0x4000 };
+ EEPROM_OFFSET=0x1000, HAS_HWCKSM=0x2000 };
enum vortex_chips {
CH_3C590 = 0,
@@ -436,7 +455,7 @@
#define EISA_TBL_OFFSET 0 /* Offset of this entry for vortex_eisa_init */
{"3c590 Vortex 10Mbps",
PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, },
- {"3c592 EISA 10mbps Demon/Vortex", /* AKPM: from Don's 3c59x_cb.c 0.49H */
+ {"3c592 EISA 10Mbps Demon/Vortex", /* AKPM: from Don's 3c59x_cb.c 0.49H */
PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, },
{"3c597 EISA Fast Demon/Vortex", /* AKPM: from Don's 3c59x_cb.c 0.49H */
PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, },
@@ -475,7 +494,7 @@
PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
{"3c980 Cyclone",
PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
- {"3c980 10/100 Base-TX NIC(Python-T)",
+ {"3c982 Dual Port Server Cyclone",
PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
{"3cSOHO100-TX Hurricane",
@@ -487,7 +506,7 @@
HAS_HWCKSM, 128, },
{"3c556B Laptop Hurricane",
PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR|
- EEPROM_NORESET|HAS_HWCKSM, 128, },
+ HAS_HWCKSM, 128, },
{"3c575 [Megahertz] 10/100 LAN CardBus",
PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
@@ -752,6 +771,7 @@
partner_flow_ctrl:1, /* Partner supports flow control */
has_nway:1,
enable_wol:1, /* Wake-on-LAN is enabled */
+ pm_state_valid:1, /* power_state[] has sane contents */
open:1,
medialock:1,
must_free_region:1; /* Flag: if zero, Cardbus owns the I/O region */
@@ -767,6 +787,7 @@
u16 io_size; /* Size of PCI region (for release_region) */
spinlock_t lock; /* Serialise access to device & its vortex_private */
spinlock_t mdio_lock; /* Serialise access to mdio hardware */
+ u32 power_state[16];
};
/* The action to take with a media selection timer tick.
@@ -847,11 +868,8 @@
{
struct net_device *dev = pdev->driver_data;
- printk(KERN_DEBUG "vortex_suspend(%s)\n", dev->name);
-
if (dev && dev->priv) {
- struct vortex_private *vp = (struct vortex_private *)dev->priv;
- if (vp->open) {
+ if (netif_running(dev)) {
netif_device_detach(dev);
vortex_down(dev);
}
@@ -863,11 +881,8 @@
{
struct net_device *dev = pdev->driver_data;
- printk(KERN_DEBUG "vortex_resume(%s)\n", dev->name);
-
if (dev && dev->priv) {
- struct vortex_private *vp = (struct vortex_private *)dev->priv;
- if (vp->open) {
+ if (netif_running(dev)) {
vortex_up(dev);
netif_device_attach(dev);
}
@@ -958,13 +973,12 @@
int i, step;
struct net_device *dev;
static int printed_version;
- int retval;
+ int retval, print_info;
struct vortex_chip_info * const vci = &vortex_info_tbl[chip_idx];
char *print_name;
if (!printed_version) {
- printk (KERN_INFO "%s", version);
- printk (KERN_INFO "See Documentation/networking/vortex.txt\n");
+ printk (version);
printed_version = 1;
}
@@ -977,14 +991,40 @@
goto out;
}
SET_MODULE_OWNER(dev);
+ vp = dev->priv;
+
+ /* The lower four bits are the media type. */
+ if (dev->mem_start) {
+ /*
+ * The 'options' param is passed in as the third arg to the
+ * LILO 'ether=' argument for non-modular use
+ */
+ option = dev->mem_start;
+ }
+ else if (card_idx < MAX_UNITS)
+ option = options[card_idx];
+ else
+ option = -1;
- printk(KERN_INFO "%s: 3Com %s %s at 0x%lx, ",
+ if (option > 0) {
+ if (option & 0x8000)
+ vortex_debug = 7;
+ if (option & 0x4000)
+ vortex_debug = 2;
+ if (option & 0x0400)
+ vp->enable_wol = 1;
+ }
+
+ print_info = (vortex_debug > 1);
+ if (print_info)
+ printk (KERN_INFO "See Documentation/networking/vortex.txt\n");
+
+ printk(KERN_INFO "%s: 3Com %s %s at 0x%lx. Vers " DRV_VERSION "\n",
print_name,
pdev ? "PCI" : "EISA",
vci->name,
ioaddr);
- vp = dev->priv;
dev->base_addr = ioaddr;
dev->irq = irq;
dev->mtu = mtu;
@@ -1048,19 +1088,6 @@
if (pdev)
pci_set_drvdata(pdev, dev);
- /* The lower four bits are the media type. */
- if (dev->mem_start) {
- /*
- * AKPM: ewww.. The 'options' param is passed in as the third arg to the
- * LILO 'ether=' argument for non-modular use
- */
- option = dev->mem_start;
- }
- else if (card_idx < MAX_UNITS)
- option = options[card_idx];
- else
- option = -1;
-
vp->media_override = 7;
if (option >= 0) {
vp->media_override = ((option & 7) == 2) ? 0 : option & 15;
@@ -1117,27 +1144,33 @@
printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
for (i = 0; i < 3; i++)
((u16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
- for (i = 0; i < 6; i++)
- printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
+ if (print_info) {
+ for (i = 0; i < 6; i++)
+ printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
+ }
EL3WINDOW(2);
for (i = 0; i < 6; i++)
outb(dev->dev_addr[i], ioaddr + i);
#ifdef __sparc__
- printk(", IRQ %s\n", __irq_itoa(dev->irq));
+ if (print_info)
+ printk(", IRQ %s\n", __irq_itoa(dev->irq));
#else
- printk(", IRQ %d\n", dev->irq);
+ if (print_info)
+ printk(", IRQ %d\n", dev->irq);
/* Tell them about an invalid IRQ. */
- if (vortex_debug && (dev->irq <= 0 || dev->irq >= NR_IRQS))
+ if (dev->irq <= 0 || dev->irq >= NR_IRQS)
printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n",
dev->irq);
#endif
EL3WINDOW(4);
step = (inb(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
- printk(KERN_INFO " product code %02x%02x rev %02x.%d date %02d-"
- "%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
- step, (eeprom[4]>>5) & 15, eeprom[4] & 31, eeprom[4]>>9);
+ if (print_info) {
+ printk(KERN_INFO " product code %02x%02x rev %02x.%d date %02d-"
+ "%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
+ step, (eeprom[4]>>5) & 15, eeprom[4] & 31, eeprom[4]>>9);
+ }
if (pdev && vci->drv_flags & HAS_CB_FNS) {
@@ -1151,8 +1184,10 @@
if (!vp->cb_fn_base)
goto free_ring;
}
- printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n",
- print_name, fn_st_addr, vp->cb_fn_base);
+ if (print_info) {
+ printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n",
+ print_name, fn_st_addr, vp->cb_fn_base);
+ }
EL3WINDOW(2);
n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010;
@@ -1170,7 +1205,8 @@
if (vp->info1 & 0x8000) {
vp->full_duplex = 1;
- printk(KERN_INFO "Full duplex capable\n");
+ if (print_info)
+ printk(KERN_INFO "Full duplex capable\n");
}
{
@@ -1181,16 +1217,17 @@
if ((vp->available_media & 0xff) == 0) /* Broken 3c916 */
vp->available_media = 0x40;
config = inl(ioaddr + Wn3_Config);
- if (vortex_debug > 1)
+ if (print_info) {
printk(KERN_DEBUG " Internal config register is %4.4x, "
"transceivers %#x.\n", config, inw(ioaddr + Wn3_Options));
- printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
- 8 << RAM_SIZE(config),
- RAM_WIDTH(config) ? "word" : "byte",
- ram_split[RAM_SPLIT(config)],
- AUTOSELECT(config) ? "autoselect/" : "",
- XCVR(config) > XCVR_ExtMII ? "<invalid transceiver>" :
- media_tbl[XCVR(config)].name);
+ printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
+ 8 << RAM_SIZE(config),
+ RAM_WIDTH(config) ? "word" : "byte",
+ ram_split[RAM_SPLIT(config)],
+ AUTOSELECT(config) ? "autoselect/" : "",
+ XCVR(config) > XCVR_ExtMII ? "<invalid transceiver>" :
+ media_tbl[XCVR(config)].name);
+ }
vp->default_media = XCVR(config);
if (vp->default_media == XCVR_NWAY)
vp->has_nway = 1;
@@ -1198,8 +1235,9 @@
}
if (vp->media_override != 7) {
- printk(KERN_INFO " Media override to transceiver type %d (%s).\n",
- vp->media_override, media_tbl[vp->media_override].name);
+ printk(KERN_INFO "%s: Media override to transceiver type %d (%s).\n",
+ print_name, vp->media_override,
+ media_tbl[vp->media_override].name);
dev->if_port = vp->media_override;
} else
dev->if_port = vp->default_media;
@@ -1226,8 +1264,10 @@
mii_status = mdio_read(dev, phyx, 1);
if (mii_status && mii_status != 0xffff) {
vp->phys[phy_idx++] = phyx;
- printk(KERN_INFO " MII transceiver found at address %d,"
- " status %4x.\n", phyx, mii_status);
+ if (print_info) {
+ printk(KERN_INFO " MII transceiver found at address %d,"
+ " status %4x.\n", phyx, mii_status);
+ }
if ((mii_status & 0x0040) == 0)
mii_preamble_required++;
}
@@ -1246,13 +1286,12 @@
}
}
- if (pdev && vp->enable_wol && (vp->capabilities & CapPwrMgmt))
- acpi_set_WOL(dev);
-
if (vp->capabilities & CapBusMaster) {
vp->full_bus_master_tx = 1;
- printk(KERN_INFO" Enabling bus-master transmits and %s receives.\n",
- (vp->info2 & 1) ? "early" : "whole-frame" );
+ if (print_info) {
+ printk(KERN_INFO " Enabling bus-master transmits and %s receives.\n",
+ (vp->info2 & 1) ? "early" : "whole-frame" );
+ }
vp->full_bus_master_rx = (vp->info2 & 1) ? 1 : 2;
vp->bus_master = 0; /* AKPM: vortex only */
}
@@ -1260,11 +1299,14 @@
/* The 3c59x-specific entries in the device structure. */
dev->open = vortex_open;
if (vp->full_bus_master_tx) {
+ struct sysinfo sysinfo;
+
dev->hard_start_xmit = boomerang_start_xmit;
-#ifndef CONFIG_HIGHMEM
- /* Actually, it still should work with iommu. */
- dev->features |= NETIF_F_SG;
-#endif
+ si_meminfo(&sysinfo);
+ if (sysinfo.totalhigh == 0) {
+ /* Actually, it still should work with iommu. */
+ dev->features |= NETIF_F_SG;
+ }
if (((hw_checksums[card_idx] == -1) && (vp->drv_flags & HAS_HWCKSM)) ||
(hw_checksums[card_idx] == 1)) {
dev->features |= NETIF_F_IP_CSUM;
@@ -1273,7 +1315,7 @@
dev->hard_start_xmit = vortex_start_xmit;
}
- if (vortex_debug > 0) {
+ if (print_info) {
printk(KERN_INFO "%s: scatter/gather %sabled. h/w checksums %sabled\n",
print_name,
(dev->features & NETIF_F_SG) ? "en":"dis",
@@ -1286,6 +1328,11 @@
dev->set_multicast_list = set_rx_mode;
dev->tx_timeout = vortex_tx_timeout;
dev->watchdog_timeo = (watchdog * HZ) / 1000;
+ if (pdev && vp->enable_wol) {
+ vp->pm_state_valid = 1;
+ pci_save_state(vp->pdev, vp->power_state);
+ acpi_set_WOL(dev);
+ }
retval = register_netdev(dev);
if (retval == 0)
return 0;
@@ -1306,7 +1353,7 @@
}
static void
-wait_for_completion(struct net_device *dev, int cmd)
+issue_and_wait(struct net_device *dev, int cmd)
{
int i;
@@ -1338,8 +1385,10 @@
unsigned int config;
int i;
- if (vp->pdev && vp->enable_wol) /* AKPM: test not needed? */
+ if (vp->pdev && vp->enable_wol) {
pci_set_power_state(vp->pdev, 0); /* Go active */
+ pci_restore_state(vp->pdev, vp->power_state);
+ }
/* Before initializing select the active media port. */
EL3WINDOW(3);
@@ -1352,19 +1401,23 @@
dev->if_port = vp->media_override;
} else if (vp->autoselect) {
if (vp->has_nway) {
- printk(KERN_INFO "%s: using NWAY device table, not %d\n", dev->name, dev->if_port);
+ if (vortex_debug > 1)
+ printk(KERN_INFO "%s: using NWAY device table, not %d\n",
+ dev->name, dev->if_port);
dev->if_port = XCVR_NWAY;
} else {
/* Find first available media type, starting with 100baseTx. */
dev->if_port = XCVR_100baseTx;
while (! (vp->available_media & media_tbl[dev->if_port].mask))
dev->if_port = media_tbl[dev->if_port].next;
- printk(KERN_INFO "%s: first available media type: %s\n",
+ if (vortex_debug > 1)
+ printk(KERN_INFO "%s: first available media type: %s\n",
dev->name, media_tbl[dev->if_port].name);
}
} else {
dev->if_port = vp->default_media;
- printk(KERN_INFO "%s: using default media %s\n",
+ if (vortex_debug > 1)
+ printk(KERN_INFO "%s: using default media %s\n",
dev->name, media_tbl[dev->if_port].name);
}
@@ -1420,8 +1473,11 @@
dev->name, config);
}
- wait_for_completion(dev, TxReset);
- wait_for_completion(dev, RxReset);
+ issue_and_wait(dev, TxReset);
+ /*
+ * Don't reset the PHY - that upsets autonegotiation during DHCP operations.
+ */
+ issue_and_wait(dev, RxReset|0x04);
outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
@@ -1494,7 +1550,7 @@
set_rx_mode(dev);
outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
-// wait_for_completion(dev, SetTxStart|0x07ff);
+// issue_and_wait(dev, SetTxStart|0x07ff);
outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
/* Allow status bits to be seen. */
@@ -1523,9 +1579,6 @@
int i;
int retval;
- if (vp->pdev && vp->enable_wol) /* AKPM: test not needed? */
- pci_set_power_state(vp->pdev, 0); /* Go active */
-
/* Use the now-standard shared IRQ implementation. */
if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ?
&boomerang_interrupt : &vortex_interrupt, SA_SHIRQ, dev->name, dev))) {
@@ -1566,7 +1619,6 @@
}
vortex_up(dev);
- vp->open = 1;
return 0;
out_free_irq:
@@ -1732,7 +1784,7 @@
if (vortex_debug > 0)
dump_tx_ring(dev);
- wait_for_completion(dev, TxReset);
+ issue_and_wait(dev, TxReset);
vp->stats.tx_errors++;
if (vp->full_bus_master_tx) {
@@ -1842,12 +1894,13 @@
/* In this case, blow the card away */
vortex_down(dev);
- wait_for_completion(dev, TotalReset | 0xff);
+ issue_and_wait(dev, TotalReset | 0xff);
vortex_up(dev); /* AKPM: bug. vortex_up() assumes that the rx ring is full. It may not be. */
} else if (fifo_diag & 0x0400)
do_tx_reset = 1;
if (fifo_diag & 0x3000) {
- wait_for_completion(dev, RxReset);
+ /* Reset Rx fifo and upload logic */
+ issue_and_wait(dev, RxReset|0x07);
/* Set the Rx filter to the current state. */
set_rx_mode(dev);
outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
@@ -1856,7 +1909,7 @@
}
if (do_tx_reset) {
- wait_for_completion(dev, TxReset|reset_mask);
+ issue_and_wait(dev, TxReset|reset_mask);
outw(TxEnable, ioaddr + EL3_CMD);
if (!vp->full_bus_master_tx)
netif_wake_queue(dev);
@@ -1908,7 +1961,7 @@
if (tx_status & 0x04) vp->stats.tx_fifo_errors++;
if (tx_status & 0x38) vp->stats.tx_aborted_errors++;
if (tx_status & 0x30) {
- wait_for_completion(dev, TxReset);
+ issue_and_wait(dev, TxReset);
}
outw(TxEnable, ioaddr + EL3_CMD);
}
@@ -1985,7 +2038,7 @@
spin_lock_irqsave(&vp->lock, flags);
/* Wait for the stall to complete. */
- wait_for_completion(dev, DownStall);
+ issue_and_wait(dev, DownStall);
prev_entry->next = cpu_to_le32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc));
if (inl(ioaddr + DownListPtr) == 0) {
outl(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr);
@@ -2306,7 +2359,7 @@
"size %d.\n", dev->name, pkt_len);
}
vp->stats.rx_dropped++;
- wait_for_completion(dev, RxDiscard);
+ issue_and_wait(dev, RxDiscard);
}
return 0;
@@ -2459,8 +2512,10 @@
if (vp->full_bus_master_tx)
outl(0, ioaddr + DownListPtr);
- if (vp->pdev && vp->enable_wol && (vp->capabilities & CapPwrMgmt))
+ if (vp->pdev && vp->enable_wol) {
+ pci_save_state(vp->pdev, vp->power_state);
acpi_set_WOL(dev);
+ }
}
static int
@@ -2522,7 +2577,6 @@
}
}
- vp->open = 0;
return 0;
}
@@ -2544,7 +2598,7 @@
printk(KERN_ERR " Transmit list %8.8x vs. %p.\n",
inl(ioaddr + DownListPtr),
&vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
- wait_for_completion(dev, DownStall);
+ issue_and_wait(dev, DownStall);
for (i = 0; i < TX_RING_SIZE; i++) {
printk(KERN_ERR " %d: @%p length %8.8x status %8.8x\n", i,
&vp->tx_ring[i],
@@ -2821,8 +2875,10 @@
/* The RxFilter must accept the WOL frames. */
outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
outw(RxEnable, ioaddr + EL3_CMD);
+
/* Change the power state to D3; RxEnable doesn't take effect. */
- pci_set_power_state(vp->pdev, 0x8103);
+ pci_enable_wake(vp->pdev, 0, 1);
+ pci_set_power_state(vp->pdev, 3);
}
@@ -2843,8 +2899,15 @@
* here
*/
unregister_netdev(dev);
- /* Should really use wait_for_completion() here */
- outw((vp->drv_flags & EEPROM_NORESET) ? (TotalReset|0x10) : TotalReset, dev->base_addr + EL3_CMD);
+ /* Should really use issue_and_wait() here */
+ outw(TotalReset|0x14, dev->base_addr + EL3_CMD);
+
+ if (vp->pdev && vp->enable_wol) {
+ pci_set_power_state(vp->pdev, 0); /* Go active */
+ if (vp->pm_state_valid)
+ pci_restore_state(vp->pdev, vp->power_state);
+ }
+
pci_free_consistent(pdev,
sizeof(struct boom_rx_desc) * RX_RING_SIZE
+ sizeof(struct boom_tx_desc) * TX_RING_SIZE,
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)