- Additional ethtool features
v1.19a 28Oct2002 Davud Ruggiero <jdr@farfalle.com>
- Increase *read_eeprom udelay to workaround oops with 2 cards.
+ v1.19b 08Nov2002 Marc Zyngier <maz@wild-wind.fr.eu.org>
+ - Introduce driver model for EISA cards.
*/
#define DRV_NAME "3c509"
-#define DRV_VERSION "1.19a"
-#define DRV_RELDATE "28Oct2002"
+#define DRV_VERSION "1.19b"
+#define DRV_RELDATE "08Nov2002"
/* A few values that may be tweaked. */
#include <linux/delay.h> /* for udelay() */
#include <linux/spinlock.h>
#include <linux/ethtool.h>
+#include <linux/device.h>
+#include <linux/eisa.h>
#include <asm/uaccess.h>
#include <asm/bitops.h>
#ifdef __ISAPNP__
struct pnp_dev *pnpdev;
#endif
+#ifdef CONFIG_EISA
+ struct eisa_device *edev;
+#endif
};
static int id_port __initdata = 0x110; /* Start with 0x110 to avoid new sound cards.*/
static struct net_device *el3_root_dev;
static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data);
#endif
+#ifdef CONFIG_EISA
+struct eisa_device_id el3_eisa_ids[] = {
+ { "TCM5092" },
+ { "TCM5093" },
+ { "" }
+};
+
+static int el3_eisa_probe (struct device *device);
+static int el3_eisa_remove (struct device *device);
+
+struct eisa_driver el3_eisa_driver = {
+ .id_table = el3_eisa_ids,
+ .driver = {
+ .name = "3c509",
+ .probe = el3_eisa_probe,
+ .remove = __devexit_p (el3_eisa_remove)
+ }
+};
+#endif
+
#ifdef CONFIG_MCA
struct el3_mca_adapters_struct {
char* name;
#endif /* __ISAPNP__ */
static int nopnp;
-int __init el3_probe(struct net_device *dev, int card_idx)
+/* With the driver model introduction for EISA devices, both init
+ * and cleanup have been split :
+ * - EISA devices probe/remove starts in el3_eisa_probe/el3_eisa_remove
+ * - MCA/ISA still use el3_probe
+ *
+ * Both call el3_common_init/el3_common_remove. */
+
+static int __init el3_common_init (struct net_device *dev)
+{
+ struct el3_private *lp = dev->priv;
+ short i;
+
+#ifdef CONFIG_EISA
+ if (!lp->edev) /* EISA devices are not chained */
+#endif
+ {
+ lp->next_dev = el3_root_dev;
+ el3_root_dev = dev;
+ }
+ spin_lock_init(&lp->lock);
+
+ if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */
+ dev->if_port = (dev->mem_start & 0x0f);
+ } else { /* xcvr codes 0/8 */
+ /* use eeprom value, but save user's full-duplex selection */
+ dev->if_port |= (dev->mem_start & 0x08);
+ }
+
+ {
+ const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
+ printk("%s: 3c5x9 at %#3.3lx, %s port, address ",
+ dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)]);
+ }
+
+ /* Read in the station address. */
+ for (i = 0; i < 6; i++)
+ printk(" %2.2x", dev->dev_addr[i]);
+ printk(", IRQ %d.\n", dev->irq);
+
+ if (el3_debug > 0)
+ printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
+
+ /* The EL3-specific entries in the device structure. */
+ dev->open = &el3_open;
+ dev->hard_start_xmit = &el3_start_xmit;
+ dev->stop = &el3_close;
+ dev->get_stats = &el3_get_stats;
+ dev->set_multicast_list = &set_multicast_list;
+ dev->tx_timeout = el3_tx_timeout;
+ dev->watchdog_timeo = TX_TIMEOUT;
+ dev->do_ioctl = netdev_ioctl;
+
+#ifdef CONFIG_PM
+ /* register power management */
+ lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback);
+ if (lp->pmdev) {
+ struct pm_dev *p;
+ p = lp->pmdev;
+ p->data = (struct net_device *)dev;
+ }
+#endif
+
+ return 0;
+}
+
+static void el3_common_remove (struct net_device *dev)
+{
+ struct el3_private *lp = dev->priv;
+
+ (void) lp; /* Keep gcc quiet... */
+#ifdef CONFIG_MCA
+ if(lp->mca_slot!=-1)
+ mca_mark_as_unused(lp->mca_slot);
+#endif
+#ifdef CONFIG_PM
+ if (lp->pmdev)
+ pm_unregister(lp->pmdev);
+#endif
+#ifdef __ISAPNP__
+ if (lp->pnpdev)
+ pnp_device_detach(lp->pnpdev);
+#endif
+
+ unregister_netdev (dev);
+ release_region(dev->base_addr, EL3_IO_EXTENT);
+ kfree (dev);
+}
+
+static int __init el3_probe(int card_idx)
{
+ struct net_device *dev;
struct el3_private *lp;
short lrs_state = 0xff, i;
int ioaddr, irq, if_port;
struct pnp_dev *idev = NULL;
#endif /* __ISAPNP__ */
- if (dev) SET_MODULE_OWNER(dev);
-
- /* First check all slots of the EISA bus. The next slot address to
- probe is kept in 'eisa_addr' to support multiple probe() calls. */
- if (EISA_bus) {
- static int eisa_addr = 0x1000;
- while (eisa_addr < 0x9000) {
- int device_id;
-
- ioaddr = eisa_addr;
- eisa_addr += 0x1000;
-
- /* Check the standard EISA ID register for an encoded '3Com'. */
- if (inw(ioaddr + 0xC80) != 0x6d50)
- continue;
-
- /* Avoid conflict with 3c590, 3c592, 3c597, etc */
- device_id = (inb(ioaddr + 0xC82)<<8) + inb(ioaddr + 0xC83);
- if ((device_id & 0xFF00) == 0x5900) {
- continue;
- }
-
- /* Change the register set to the configuration window 0. */
- outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD);
-
- irq = inw(ioaddr + WN0_IRQ) >> 12;
- if_port = inw(ioaddr + 6)>>14;
- for (i = 0; i < 3; i++)
- phys_addr[i] = htons(read_eeprom(ioaddr, i));
-
- /* Restore the "Product ID" to the EEPROM read register. */
- read_eeprom(ioaddr, 3);
-
- /* Was the EISA code an add-on hack? Nahhhhh... */
- goto found;
- }
- }
-
#ifdef CONFIG_MCA
/* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, heavily
* modified by Chris Beauregard (cpbeaure@csclub.uwaterloo.ca)
}
irq = id_read_eeprom(9) >> 12;
+#if 0 /* Huh ?
+ Can someone explain what is this for ? */
if (dev) { /* Set passed-in IRQ or I/O Addr. */
if (dev->irq > 1 && dev->irq < 16)
irq = dev->irq;
return -ENODEV;
}
}
+#endif
if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509"))
return -EBUSY;
/* Free the interrupt so that some other card can use it. */
outw(0x0f00, ioaddr + WN0_IRQ);
found:
+ dev = init_etherdev(NULL, sizeof(struct el3_private));
if (dev == NULL) {
- dev = init_etherdev(dev, sizeof(struct el3_private));
- if (dev == NULL) {
- release_region(ioaddr, EL3_IO_EXTENT);
- return -ENOMEM;
- }
- SET_MODULE_OWNER(dev);
+ release_region(ioaddr, EL3_IO_EXTENT);
+ return -ENOMEM;
}
+ SET_MODULE_OWNER(dev);
+
memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
dev->base_addr = ioaddr;
dev->irq = irq;
-
- if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */
- dev->if_port = (dev->mem_start & 0x0f);
- } else { /* xcvr codes 0/8 */
- /* use eeprom value, but save user's full-duplex selection */
- dev->if_port = (if_port | (dev->mem_start & 0x08) );
- }
-
- {
- const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
- printk("%s: 3c5x9 at %#3.3lx, %s port, address ",
- dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)]);
- }
-
- /* Read in the station address. */
- for (i = 0; i < 6; i++)
- printk(" %2.2x", dev->dev_addr[i]);
- printk(", IRQ %d.\n", dev->irq);
-
- /* Make up a EL3-specific-data structure. */
- if (dev->priv == NULL)
- dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct el3_private));
-
+ dev->if_port = if_port;
lp = dev->priv;
#ifdef __ISAPNP__
lp->pnpdev = idev;
#endif
lp->mca_slot = mca_slot;
- lp->next_dev = el3_root_dev;
- spin_lock_init(&lp->lock);
- el3_root_dev = dev;
- if (el3_debug > 0)
- printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
+ return el3_common_init (dev);
+}
- /* The EL3-specific entries in the device structure. */
- dev->open = &el3_open;
- dev->hard_start_xmit = &el3_start_xmit;
- dev->stop = &el3_close;
- dev->get_stats = &el3_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->tx_timeout = el3_tx_timeout;
- dev->watchdog_timeo = TX_TIMEOUT;
- dev->do_ioctl = netdev_ioctl;
+#ifdef CONFIG_EISA
+static int __init el3_eisa_probe (struct device *device)
+{
+ struct el3_private *lp;
+ short i;
+ int ioaddr, irq, if_port;
+ u16 phys_addr[3];
+ struct net_device *dev = NULL;
+ struct eisa_device *edev;
-#ifdef CONFIG_PM
- /* register power management */
- lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback);
- if (lp->pmdev) {
- struct pm_dev *p;
- p = lp->pmdev;
- p->data = (struct net_device *)dev;
+ /* Yeepee, The driver framework is calling us ! */
+ edev = to_eisa_device (device);
+ ioaddr = edev->base_addr;
+
+ if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509"))
+ return -EBUSY;
+
+ /* Change the register set to the configuration window 0. */
+ outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD);
+
+ irq = inw(ioaddr + WN0_IRQ) >> 12;
+ if_port = inw(ioaddr + 6)>>14;
+ for (i = 0; i < 3; i++)
+ phys_addr[i] = htons(read_eeprom(ioaddr, i));
+
+ /* Restore the "Product ID" to the EEPROM read register. */
+ read_eeprom(ioaddr, 3);
+
+ dev = init_etherdev(NULL, sizeof(struct el3_private));
+ if (dev == NULL) {
+ release_region(ioaddr, EL3_IO_EXTENT);
+ return -ENOMEM;
}
-#endif
- /* Fill in the generic fields of the device structure. */
- ether_setup(dev);
- return 0;
+ SET_MODULE_OWNER(dev);
+
+ memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
+ dev->base_addr = ioaddr;
+ dev->irq = irq;
+ dev->if_port = if_port;
+ lp = dev->priv;
+ lp->mca_slot = -1;
+ lp->edev = edev;
+ eisa_set_drvdata (edev, dev);
+
+ return el3_common_init (dev);
+}
+
+static int __devexit el3_eisa_remove (struct device *device)
+{
+ struct eisa_device *edev;
+ struct net_device *dev;
+
+ edev = to_eisa_device (device);
+ dev = eisa_get_drvdata (edev);
+
+ el3_common_remove (dev);
+ return 0;
}
+#endif
/* Read a word from the EEPROM using the regular EEPROM access register.
Assume that we are in register window zero.
el3_close(struct net_device *dev)
{
int ioaddr = dev->base_addr;
-
+ struct el3_private *lp = (struct el3_private *)dev->priv;
+
if (el3_debug > 2)
printk("%s: Shutting down ethercard.\n", dev->name);
free_irq(dev->irq, dev);
/* Switching back to window 0 disables the IRQ. */
EL3WINDOW(0);
- /* But we explicitly zero the IRQ line select anyway. */
- outw(0x0f00, ioaddr + WN0_IRQ);
+ if (!lp->edev) {
+ /* But we explicitly zero the IRQ line select anyway. Don't do
+ * it on EISA cards, it prevents the module from getting an
+ * IRQ after unload+reload... */
+ outw(0x0f00, ioaddr + WN0_IRQ);
+ }
return 0;
}
#endif /* CONFIG_PM */
-#ifdef MODULE
/* Parameters that may be passed into the module. */
static int debug = -1;
static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
MODULE_DESCRIPTION("3Com Etherlink III (3c509, 3c509B) ISA/PnP ethernet driver");
MODULE_LICENSE("GPL");
-int
-init_module(void)
+static int __init el3_init_module(void)
{
int el3_cards = 0;
el3_debug = debug;
el3_root_dev = NULL;
- while (el3_probe(0, el3_cards) == 0) {
+ while (el3_probe(el3_cards) == 0) {
if (irq[el3_cards] > 1)
el3_root_dev->irq = irq[el3_cards];
if (xcvr[el3_cards] >= 0)
el3_cards++;
}
+#ifdef CONFIG_EISA
+ if (eisa_driver_register (&el3_eisa_driver) < 0) {
+ eisa_driver_unregister (&el3_eisa_driver);
+ }
+ else
+ el3_cards++; /* Found an eisa card */
+#endif
return el3_cards ? 0 : -ENODEV;
}
-void
-cleanup_module(void)
+static void __exit el3_cleanup_module(void)
{
struct net_device *next_dev;
/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
while (el3_root_dev) {
struct el3_private *lp = (struct el3_private *)el3_root_dev->priv;
-#ifdef CONFIG_MCA
- if(lp->mca_slot!=-1)
- mca_mark_as_unused(lp->mca_slot);
-#endif
-#ifdef CONFIG_PM
- if (lp->pmdev)
- pm_unregister(lp->pmdev);
-#endif
next_dev = lp->next_dev;
- unregister_netdev(el3_root_dev);
- release_region(el3_root_dev->base_addr, EL3_IO_EXTENT);
-#ifdef __ISAPNP__
- if (lp->pnpdev)
- pnp_device_detach(lp->pnpdev);
-#endif
- kfree(el3_root_dev);
+ el3_common_remove (el3_root_dev);
el3_root_dev = next_dev;
}
+
+#ifdef CONFIG_EISA
+ eisa_driver_unregister (&el3_eisa_driver);
+#endif
}
-#endif /* MODULE */
+
+module_init (el3_init_module);
+module_exit (el3_cleanup_module);
/*
* Local variables:
- See http://www.zip.com.au/~akpm/linux/#3c59x-2.3 for more details.
- Also see Documentation/networking/vortex.txt
+
+ LK1.1.19 10Nov09 Marc Zyngier <maz@wild-wind.fr.eu.org>
+ - EISA sysfs integration.
*/
/*
#define DRV_NAME "3c59x"
-#define DRV_VERSION "LK1.1.18"
-#define DRV_RELDATE "1 Jul 2002"
+#define DRV_VERSION "LK1.1.19"
+#define DRV_RELDATE "10 Nov 2002"
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <linux/highmem.h>
-
+#include <linux/eisa.h>
#include <asm/irq.h> /* For NR_IRQS only. */
#include <asm/bitops.h>
#include <asm/io.h>
/* The addresses of transmit- and receive-in-place skbuffs. */
struct sk_buff* rx_skbuff[RX_RING_SIZE];
struct sk_buff* tx_skbuff[TX_RING_SIZE];
- struct net_device *next_module; /* NULL if PCI device */
unsigned int cur_rx, cur_tx; /* The next free ring entry */
unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
struct net_device_stats stats;
dma_addr_t tx_skb_dma; /* Allocated DMA address for bus master ctrl DMA. */
/* PCI configuration space information. */
- struct pci_dev *pdev;
+ struct device *gendev;
char *cb_fn_base; /* CardBus function status addr space. */
/* Some values here only for performance evaluation and path-coverage */
u32 power_state[16];
};
+#define DEVICE_PCI(dev) (((dev)->bus == &pci_bus_type) ? to_pci_dev((dev)) : NULL)
+
+#define VORTEX_PCI(vp) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL)
+
+#ifdef CONFIG_EISA
+#define DEVICE_EISA(dev) (((dev)->bus == &eisa_bus_type) ? to_eisa_device((dev)) : NULL)
+#else
+#define DEVICE_EISA(dev) NULL
+#endif
+
+#define VORTEX_EISA(vp) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL)
+
/* The action to take with a media selection timer tick.
Note that we deviate from the 3Com order by checking 10base2 before AUI.
*/
{ "Default", 0, 0xFF, XCVR_10baseT, 10000},
};
-static int vortex_probe1(struct pci_dev *pdev, long ioaddr, int irq,
+static int vortex_probe1(struct device *gendev, long ioaddr, int irq,
int chip_idx, int card_idx);
static void vortex_up(struct net_device *dev);
static void vortex_down(struct net_device *dev);
/* #define dev_alloc_skb dev_alloc_skb_debug */
-/* A list of all installed Vortex EISA devices, for removing the driver module. */
-static struct net_device *root_vortex_eisa_dev;
-
/* Variables to work-around the Compaq PCI BIOS32 problem. */
static int compaq_ioaddr, compaq_irq, compaq_device_id = 0x5900;
+static struct net_device *compaq_net_device;
static int vortex_cards_found;
#endif /* CONFIG_PM */
-/* returns count found (>= 0), or negative on error */
-static int __init vortex_eisa_init (void)
+#ifdef CONFIG_EISA
+static struct eisa_device_id vortex_eisa_ids[] = {
+ { "TCM5920" },
+ { "TCM5970" },
+ { "" }
+};
+
+static int vortex_eisa_probe (struct device *device);
+static int vortex_eisa_remove (struct device *device);
+
+static struct eisa_driver vortex_eisa_driver = {
+ .id_table = vortex_eisa_ids,
+ .driver = {
+ .name = "3c59x",
+ .probe = vortex_eisa_probe,
+ .remove = vortex_eisa_remove
+ }
+};
+
+static int vortex_eisa_probe (struct device *device)
{
long ioaddr;
- int rc;
- int orig_cards_found = vortex_cards_found;
+ struct eisa_device *edev;
- /* Now check all slots of the EISA bus. */
- if (!EISA_bus)
- return 0;
+ edev = to_eisa_device (device);
+ ioaddr = edev->base_addr;
- for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
- int device_id;
+ if (!request_region(ioaddr, VORTEX_TOTAL_SIZE, DRV_NAME))
+ return -EBUSY;
- if (request_region(ioaddr, VORTEX_TOTAL_SIZE, DRV_NAME) == NULL)
- continue;
+ if (vortex_probe1(device, ioaddr, inw(ioaddr + 0xC88) >> 12,
+ EISA_TBL_OFFSET, vortex_cards_found)) {
+ release_region (ioaddr, VORTEX_TOTAL_SIZE);
+ return -ENODEV;
+ }
- /* Check the standard EISA ID register for an encoded '3Com'. */
- if (inw(ioaddr + 0xC80) != 0x6d50) {
- release_region (ioaddr, VORTEX_TOTAL_SIZE);
- continue;
- }
+ vortex_cards_found++;
- /* Check for a product that we support, 3c59{2,7} any rev. */
- device_id = (inb(ioaddr + 0xC82)<<8) + inb(ioaddr + 0xC83);
- if ((device_id & 0xFF00) != 0x5900) {
- release_region (ioaddr, VORTEX_TOTAL_SIZE);
- continue;
- }
+ return 0;
+}
- rc = vortex_probe1(NULL, ioaddr, inw(ioaddr + 0xC88) >> 12,
- EISA_TBL_OFFSET, vortex_cards_found);
- if (rc == 0)
- vortex_cards_found++;
- else
- release_region (ioaddr, VORTEX_TOTAL_SIZE);
+static int vortex_eisa_remove (struct device *device)
+{
+ struct eisa_device *edev;
+ struct net_device *dev;
+ struct vortex_private *vp;
+ long ioaddr;
+
+ edev = to_eisa_device (device);
+ dev = eisa_get_drvdata (edev);
+
+ if (!dev) {
+ printk("vortex_eisa_remove called for Compaq device!\n");
+ BUG();
}
+ vp = dev->priv;
+ ioaddr = dev->base_addr;
+
+ unregister_netdev (dev);
+ outw (TotalReset|0x14, ioaddr + EL3_CMD);
+ release_region (ioaddr, VORTEX_TOTAL_SIZE);
+
+ kfree (dev);
+ return 0;
+}
+#endif
+
+/* returns count found (>= 0), or negative on error */
+static int __init vortex_eisa_init (void)
+{
+ int orig_cards_found = vortex_cards_found;
+
+ /* Now check all slots of the EISA bus. */
+ if (!EISA_bus)
+ return 0;
+
+#ifdef CONFIG_EISA
+ if (eisa_driver_register (&vortex_eisa_driver) < 0) {
+ eisa_driver_unregister (&vortex_eisa_driver);
+ }
+#endif
+
/* Special code to work-around the Compaq PCI BIOS32 problem. */
if (compaq_ioaddr) {
vortex_probe1(NULL, compaq_ioaddr, compaq_irq,
if (pci_enable_device (pdev)) {
rc = -EIO;
} else {
- rc = vortex_probe1 (pdev, pci_resource_start (pdev, 0), pdev->irq,
- ent->driver_data, vortex_cards_found);
+ rc = vortex_probe1 (&pdev->dev, pci_resource_start (pdev, 0),
+ pdev->irq, ent->driver_data, vortex_cards_found);
if (rc == 0)
vortex_cards_found++;
}
}
/*
- * Start up the PCI device which is described by *pdev.
+ * Start up the PCI/EISA device which is described by *gendev.
* Return 0 on success.
*
- * NOTE: pdev can be NULL, for the case of an EISA driver
+ * NOTE: pdev can be NULL, for the case of a Compaq device
*/
-static int __devinit vortex_probe1(struct pci_dev *pdev,
+static int __devinit vortex_probe1(struct device *gendev,
long ioaddr, int irq,
int chip_idx, int card_idx)
{
static int printed_version;
int retval, print_info;
struct vortex_chip_info * const vci = &vortex_info_tbl[chip_idx];
- char *print_name;
+ char *print_name = "3c59x";
+ struct pci_dev *pdev = NULL;
+ struct eisa_device *edev = NULL;
if (!printed_version) {
printk (version);
printed_version = 1;
}
- print_name = pdev ? pdev->slot_name : "3c59x";
+ if (gendev) {
+ if ((pdev = DEVICE_PCI(gendev))) {
+ print_name = pdev->slot_name;
+ }
+
+ if ((edev = DEVICE_EISA(gendev))) {
+ print_name = edev->dev.bus_id;
+ }
+ }
dev = alloc_etherdev(sizeof(*vp));
retval = -ENOMEM;
vp->io_size = vci->io_size;
vp->card_idx = card_idx;
- /* module list only for EISA devices */
- if (pdev == NULL) {
- vp->next_module = root_vortex_eisa_dev;
- root_vortex_eisa_dev = dev;
+ /* module list only for Compaq device */
+ if (gendev == NULL) {
+ compaq_net_device = dev;
}
/* PCI-only startup logic */
spin_lock_init(&vp->lock);
spin_lock_init(&vp->mdio_lock);
- vp->pdev = pdev;
+ vp->gendev = gendev;
/* Makes sure rings are at least 16 byte aligned. */
vp->rx_ring = pci_alloc_consistent(pdev, sizeof(struct boom_rx_desc) * RX_RING_SIZE
* instead of a module list */
if (pdev)
pci_set_drvdata(pdev, dev);
+ if (edev)
+ eisa_set_drvdata (edev, dev);
vp->media_override = 7;
if (option >= 0) {
dev->watchdog_timeo = (watchdog * HZ) / 1000;
if (pdev && vp->enable_wol) {
vp->pm_state_valid = 1;
- pci_save_state(vp->pdev, vp->power_state);
+ pci_save_state(VORTEX_PCI(vp), vp->power_state);
acpi_set_WOL(dev);
}
retval = register_netdev(dev);
unsigned int config;
int i;
- if (vp->pdev && vp->enable_wol) {
- pci_set_power_state(vp->pdev, 0); /* Go active */
- pci_restore_state(vp->pdev, vp->power_state);
+ if (VORTEX_PCI(vp) && vp->enable_wol) {
+ pci_set_power_state(VORTEX_PCI(vp), 0); /* Go active */
+ pci_restore_state(VORTEX_PCI(vp), vp->power_state);
}
/* Before initializing select the active media port. */
break; /* Bad news! */
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
- vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
+ vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
}
if (i != RX_RING_SIZE) {
int j;
if (vp->bus_master) {
/* Set the bus-master controller to transfer the packet. */
int len = (skb->len + 3) & ~3;
- outl( vp->tx_skb_dma = pci_map_single(vp->pdev, skb->data, len, PCI_DMA_TODEVICE),
+ outl( vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE),
ioaddr + Wn7_MasterAddr);
outw(len, ioaddr + Wn7_MasterLen);
vp->tx_skb = skb;
vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded | AddTCPChksum | AddUDPChksum);
if (!skb_shinfo(skb)->nr_frags) {
- vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->data,
+ vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
skb->len, PCI_DMA_TODEVICE));
vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb->len | LAST_FRAG);
} else {
int i;
- vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->data,
+ vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
skb->len-skb->data_len, PCI_DMA_TODEVICE));
vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb->len-skb->data_len);
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
vp->tx_ring[entry].frag[i+1].addr =
- cpu_to_le32(pci_map_single(vp->pdev,
+ cpu_to_le32(pci_map_single(VORTEX_PCI(vp),
(void*)page_address(frag->page) + frag->page_offset,
frag->size, PCI_DMA_TODEVICE));
}
}
#else
- vp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->data, skb->len, PCI_DMA_TODEVICE));
+ vp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, skb->len, PCI_DMA_TODEVICE));
vp->tx_ring[entry].length = cpu_to_le32(skb->len | LAST_FRAG);
vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded);
#endif
if (status & DMADone) {
if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) {
outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
- pci_unmap_single(vp->pdev, vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
+ pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
dev_kfree_skb_irq(vp->tx_skb); /* Release the transferred buffer */
if (inw(ioaddr + TxFree) > 1536) {
/*
#if DO_ZEROCOPY
int i;
for (i=0; i<=skb_shinfo(skb)->nr_frags; i++)
- pci_unmap_single(vp->pdev,
+ pci_unmap_single(VORTEX_PCI(vp),
le32_to_cpu(vp->tx_ring[entry].frag[i].addr),
le32_to_cpu(vp->tx_ring[entry].frag[i].length)&0xFFF,
PCI_DMA_TODEVICE);
#else
- pci_unmap_single(vp->pdev,
+ pci_unmap_single(VORTEX_PCI(vp),
le32_to_cpu(vp->tx_ring[entry].addr), skb->len, PCI_DMA_TODEVICE);
#endif
dev_kfree_skb_irq(skb);
/* 'skb_put()' points to the start of sk_buff data area. */
if (vp->bus_master &&
! (inw(ioaddr + Wn7_MasterStatus) & 0x8000)) {
- dma_addr_t dma = pci_map_single(vp->pdev, skb_put(skb, pkt_len),
+ dma_addr_t dma = pci_map_single(VORTEX_PCI(vp), skb_put(skb, pkt_len),
pkt_len, PCI_DMA_FROMDEVICE);
outl(dma, ioaddr + Wn7_MasterAddr);
outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
outw(StartDMAUp, ioaddr + EL3_CMD);
while (inw(ioaddr + Wn7_MasterStatus) & 0x8000)
;
- pci_unmap_single(vp->pdev, dma, pkt_len, PCI_DMA_FROMDEVICE);
+ pci_unmap_single(VORTEX_PCI(vp), dma, pkt_len, PCI_DMA_FROMDEVICE);
} else {
insl(ioaddr + RX_FIFO, skb_put(skb, pkt_len),
(pkt_len + 3) >> 2);
if (pkt_len < rx_copybreak && (skb = dev_alloc_skb(pkt_len + 2)) != 0) {
skb->dev = dev;
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
- pci_dma_sync_single(vp->pdev, dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+ pci_dma_sync_single(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
/* 'skb_put()' points to the start of sk_buff data area. */
memcpy(skb_put(skb, pkt_len),
vp->rx_skbuff[entry]->tail,
skb = vp->rx_skbuff[entry];
vp->rx_skbuff[entry] = NULL;
skb_put(skb, pkt_len);
- pci_unmap_single(vp->pdev, dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+ pci_unmap_single(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
vp->rx_nocopy++;
}
skb->protocol = eth_type_trans(skb, dev);
}
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
- vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
+ vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
vp->rx_skbuff[entry] = skb;
}
vp->rx_ring[entry].status = 0; /* Clear complete bit. */
if (vp->full_bus_master_tx)
outl(0, ioaddr + DownListPtr);
- if (vp->pdev && vp->enable_wol) {
- pci_save_state(vp->pdev, vp->power_state);
+ if (VORTEX_PCI(vp) && vp->enable_wol) {
+ pci_save_state(VORTEX_PCI(vp), vp->power_state);
acpi_set_WOL(dev);
}
}
if (vp->full_bus_master_rx) { /* Free Boomerang bus master Rx buffers. */
for (i = 0; i < RX_RING_SIZE; i++)
if (vp->rx_skbuff[i]) {
- pci_unmap_single( vp->pdev, le32_to_cpu(vp->rx_ring[i].addr),
+ pci_unmap_single( VORTEX_PCI(vp), le32_to_cpu(vp->rx_ring[i].addr),
PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
dev_kfree_skb(vp->rx_skbuff[i]);
vp->rx_skbuff[i] = 0;
int k;
for (k=0; k<=skb_shinfo(skb)->nr_frags; k++)
- pci_unmap_single(vp->pdev,
+ pci_unmap_single(VORTEX_PCI(vp),
le32_to_cpu(vp->tx_ring[i].frag[k].addr),
le32_to_cpu(vp->tx_ring[i].frag[k].length)&0xFFF,
PCI_DMA_TODEVICE);
#else
- pci_unmap_single(vp->pdev, le32_to_cpu(vp->tx_ring[i].addr), skb->len, PCI_DMA_TODEVICE);
+ pci_unmap_single(VORTEX_PCI(vp), le32_to_cpu(vp->tx_ring[i].addr), skb->len, PCI_DMA_TODEVICE);
#endif
dev_kfree_skb(skb);
vp->tx_skbuff[i] = 0;
struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
strcpy(info.driver, DRV_NAME);
strcpy(info.version, DRV_VERSION);
- if (vp->pdev)
- strcpy(info.bus_info, vp->pdev->slot_name);
- else
- sprintf(info.bus_info, "EISA 0x%lx %d",
- dev->base_addr, dev->irq);
+ if (VORTEX_PCI(vp))
+ strcpy(info.bus_info, VORTEX_PCI(vp)->slot_name);
+ else {
+ if (VORTEX_EISA(vp))
+ sprintf (info.bus_info, vp->gendev->bus_id);
+ else
+ sprintf(info.bus_info, "EISA 0x%lx %d",
+ dev->base_addr, dev->irq);
+ }
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
outw(RxEnable, ioaddr + EL3_CMD);
/* Change the power state to D3; RxEnable doesn't take effect. */
- pci_enable_wake(vp->pdev, 0, 1);
- pci_set_power_state(vp->pdev, 3);
+ pci_enable_wake(VORTEX_PCI(vp), 0, 1);
+ pci_set_power_state(VORTEX_PCI(vp), 3);
}
struct vortex_private *vp;
if (!dev) {
- printk("vortex_remove_one called for EISA device!\n");
+ printk("vortex_remove_one called for Compaq device!\n");
BUG();
}
/* 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 (VORTEX_PCI(vp) && vp->enable_wol) {
+ pci_set_power_state(VORTEX_PCI(vp), 0); /* Go active */
if (vp->pm_state_valid)
- pci_restore_state(vp->pdev, vp->power_state);
+ pci_restore_state(VORTEX_PCI(vp), vp->power_state);
}
pci_free_consistent(pdev,
static void __exit vortex_eisa_cleanup (void)
{
- struct net_device *dev, *tmp;
struct vortex_private *vp;
long ioaddr;
- dev = root_vortex_eisa_dev;
-
- while (dev) {
- vp = dev->priv;
- ioaddr = dev->base_addr;
+#ifdef CONFIG_EISA
+ /* Take care of the EISA devices */
+ eisa_driver_unregister (&vortex_eisa_driver);
+#endif
+
+ if (compaq_net_device) {
+ vp = compaq_net_device->priv;
+ ioaddr = compaq_net_device->base_addr;
- unregister_netdev (dev);
+ unregister_netdev (compaq_net_device);
outw (TotalReset, ioaddr + EL3_CMD);
release_region (ioaddr, VORTEX_TOTAL_SIZE);
- tmp = dev;
- dev = vp->next_module;
-
- kfree (tmp);
+ kfree (compaq_net_device);
}
}