/*
- *
* Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
*
*
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/init.h> /* For __init, __exit */
+#include <linux/dma-mapping.h>
#include "prismcompat.h"
#include "islpci_dev.h"
MODULE_DESCRIPTION("The Prism54 802.11 Wireless LAN adapter");
MODULE_LICENSE("GPL");
+static int init_pcitm = 0;
+module_param(init_pcitm, int, 0);
+
/* In this order: vendor, device, subvendor, subdevice, class, class_mask,
- * driver_data
- * If you have an update for this please contact prism54-devel@prism54.org
+ * driver_data
+ * If you have an update for this please contact prism54-devel@prism54.org
* The latest list can be found at http://prism54.org/supported_cards.php */
static const struct pci_device_id prism54_id_tbl[] = {
- /* 3COM 3CRWE154G72 Wireless LAN adapter */
- {
- PCIVENDOR_3COM, PCIDEVICE_3COM6001,
- PCIVENDOR_3COM, PCIDEVICE_3COM6001,
- 0, 0, 0
- },
-
- /* D-Link Air Plus Xtreme G A1 - DWL-g650 A1 */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_DLINK, 0x3202UL,
- 0, 0, 0
- },
-
- /* I-O Data WN-G54/CB - WN-G54/CB */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_IODATA, 0xd019UL,
- 0, 0, 0
- },
-
- /* Netgear WG511 */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_NETGEAR, 0x4800UL,
- 0, 0, 0
- },
-
- /* Tekram Technology clones, Allnet, Netcomm, Zyxel */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_TTL, 0x1605UL,
- 0, 0, 0
- },
-
- /* SMC2802W */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_SMC, 0x2802UL,
- 0, 0, 0
- },
-
- /* SMC2835W */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_SMC, 0x2835UL,
- 0, 0, 0
- },
-
- /* Corega CG-WLCB54GT */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_ATI, 0xc104UL,
- 0, 0, 0
- },
-
- /* I4 Z-Com XG-600 */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_I4, 0x0014UL,
- 0, 0, 0
- },
-
- /* I4 Z-Com XG-900 and clones Macer, Ovislink, Planex, Peabird, */
- /* Sitecom, Xterasys */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_I4, 0x0020UL,
- 0, 0, 0
- },
-
- /* SMC 2802W V2 */
+ /* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
{
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_ACCTON, 0xee03UL,
+ 0x1260, 0x3890,
+ PCI_ANY_ID, PCI_ANY_ID,
0, 0, 0
},
- /* SMC 2835W V2 */
+ /* 3COM 3CRWE154G72 Wireless LAN adapter */
{
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_SMC, 0xa835UL,
+ 0x10b7, 0x6001,
+ PCI_ANY_ID, PCI_ANY_ID,
0, 0, 0
},
/* Intersil PRISM Indigo Wireless LAN adapter */
{
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3877,
+ 0x1260, 0x3877,
PCI_ANY_ID, PCI_ANY_ID,
0, 0, 0
},
- /* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
- /* Default */
+ /* Intersil PRISM Javelin/Xbow Wireless LAN adapter */
{
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
+ 0x1260, 0x3886,
PCI_ANY_ID, PCI_ANY_ID,
0, 0, 0
},
static int prism54_probe(struct pci_dev *, const struct pci_device_id *);
static void prism54_remove(struct pci_dev *);
-static int prism54_suspend(struct pci_dev *, u32 state);
+static int prism54_suspend(struct pci_dev *, pm_message_t state);
static int prism54_resume(struct pci_dev *);
static struct pci_driver prism54_driver = {
/* .enable_wake ; we don't support this yet */
};
-static void
-prism54_get_card_model(struct net_device *ndev)
-{
- islpci_private *priv;
- char *modelp;
- int notwork = 0;
-
- priv = netdev_priv(ndev);
- switch (priv->pdev->subsystem_device) {
- case PCIDEVICE_ISL3877:
- modelp = "PRISM Indigo";
- break;
- case PCIDEVICE_ISL3886:
- modelp = "PRISM Javelin / Xbow";
- break;
- case PCIDEVICE_3COM6001:
- modelp = "3COM 3CRWE154G72";
- break;
- case 0x3202UL:
- modelp = "D-Link DWL-g650 A1";
- break;
- case 0xd019UL:
- modelp = "WN-G54/CB";
- break;
- case 0x4800UL:
- modelp = "Netgear WG511";
- break;
- case 0x2802UL:
- modelp = "SMC2802W";
- break;
- case 0xee03UL:
- modelp = "SMC2802W V2";
- notwork = 1;
- break;
- case 0x2835UL:
- modelp = "SMC2835W";
- break;
- case 0xa835UL:
- modelp = "SMC2835W V2";
- notwork = 1;
- break;
- case 0xc104UL:
- modelp = "CG-WLCB54GT";
- break;
- case 0x1605UL:
- modelp = "Tekram Technology clone";
- break;
- /* Let's leave this one out for now since it seems bogus/wrong
- * Even if the manufacturer did use 0x0000UL it may not be correct
- * by their part, therefore deserving no name ;) */
- /* case 0x0000UL:
- * modelp = "SparkLAN WL-850F";
- * break;*/
-
- /* We have two reported for the one below :( */
- case 0x0014UL:
- modelp = "I4 Z-Com XG-600 and clones";
- break;
- case 0x0020UL:
- modelp = "I4 Z-Com XG-900 and clones";
- break;
-/* Default it */
-/*
- case PCIDEVICE_ISL3890:
- modelp = "PRISM Duette/GT";
- break;
-*/
- default:
- modelp = "PRISM Duette/GT";
- }
- printk(KERN_DEBUG "%s: %s driver detected card model: %s\n",
- ndev->name, DRV_NAME, modelp);
- if ( notwork ) {
- printk(KERN_DEBUG "%s: %s Warning - This may not work\n",
- ndev->name, DRV_NAME);
- }
- return;
-}
-
/******************************************************************************
Module initialization functions
******************************************************************************/
islpci_private *priv;
int rvalue;
- /* TRACE(DRV_NAME); */
-
-
/* Enable the pci device */
if (pci_enable_device(pdev)) {
printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME);
}
/* enable PCI DMA */
- if (pci_set_dma_mask(pdev, 0xffffffff)) {
+ if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
printk(KERN_ERR "%s: 32-bit PCI DMA not supported", DRV_NAME);
goto do_pci_disable_device;
}
/* 0x40 is the programmable timer to configure the response timeout (TRDY_TIMEOUT)
* 0x41 is the programmable timer to configure the retry timeout (RETRY_TIMEOUT)
- * The RETRY_TIMEOUT is used to set the number of retries that the core, as a
- * Master, will perform before abandoning a cycle. The default value for
- * RETRY_TIMEOUT is 0x80, which far exceeds the PCI 2.1 requirement for new
- * devices. A write of zero to the RETRY_TIMEOUT register disables this
- * function to allow use with any non-compliant legacy devices that may
- * execute more retries.
+ * The RETRY_TIMEOUT is used to set the number of retries that the core, as a
+ * Master, will perform before abandoning a cycle. The default value for
+ * RETRY_TIMEOUT is 0x80, which far exceeds the PCI 2.1 requirement for new
+ * devices. A write of zero to the RETRY_TIMEOUT register disables this
+ * function to allow use with any non-compliant legacy devices that may
+ * execute more retries.
*
- * Writing zero to both these two registers will disable both timeouts and
- * *can* solve problems caused by devices that are slow to respond.
+ * Writing zero to both these two registers will disable both timeouts and
+ * *can* solve problems caused by devices that are slow to respond.
+ * Make this configurable - MSW
*/
- /* I am taking these out, we should not be poking around in the
- * programmable timers - MSW
- */
-/* Do not zero the programmable timers
- pci_write_config_byte(pdev, 0x40, 0);
- pci_write_config_byte(pdev, 0x41, 0);
-*/
+ if ( init_pcitm >= 0 ) {
+ pci_write_config_byte(pdev, 0x40, (u8)init_pcitm);
+ pci_write_config_byte(pdev, 0x41, (u8)init_pcitm);
+ } else {
+ printk(KERN_INFO "PCI TRDY/RETRY unchanged\n");
+ }
/* request the pci device I/O regions */
rvalue = pci_request_regions(pdev, DRV_NAME);
if (rvalue || !mem_addr) {
printk(KERN_ERR "%s: PCI device memory region not configured; fix your BIOS or CardBus bridge/drivers\n",
DRV_NAME);
- goto do_pci_disable_device;
+ goto do_pci_release_regions;
}
/* enable PCI bus-mastering */
pci_set_master(pdev);
/* enable MWI */
- pci_set_mwi(pdev);
+ if (!pci_set_mwi(pdev))
+ printk(KERN_INFO "%s: pci_set_mwi(pdev) succeeded\n", DRV_NAME);
/* setup the network device interface and its structure */
if (!(ndev = islpci_setup(pdev))) {
/* error configuring the driver as a network device */
printk(KERN_ERR "%s: could not configure network device\n",
DRV_NAME);
- goto do_pci_release_regions;
+ goto do_pci_clear_mwi;
}
priv = netdev_priv(ndev);
/* request for the interrupt before uploading the firmware */
rvalue = request_irq(pdev->irq, &islpci_interrupt,
- SA_SHIRQ, ndev->name, priv);
+ IRQF_SHARED, ndev->name, priv);
if (rvalue) {
/* error, could not hook the handler to the irq */
/* firmware upload is triggered in islpci_open */
- /* Pretty card model discovery output */
- prism54_get_card_model(ndev);
-
return 0;
do_unregister_netdev:
unregister_netdev(ndev);
islpci_free_memory(priv);
- pci_set_drvdata(pdev, 0);
+ pci_set_drvdata(pdev, NULL);
free_netdev(ndev);
- priv = 0;
+ priv = NULL;
+ do_pci_clear_mwi:
+ pci_clear_mwi(pdev);
do_pci_release_regions:
pci_release_regions(pdev);
do_pci_disable_device:
prism54_remove(struct pci_dev *pdev)
{
struct net_device *ndev = pci_get_drvdata(pdev);
- islpci_private *priv = ndev ? netdev_priv(ndev) : 0;
+ islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
BUG_ON(!priv);
if (!__in_cleanup_module) {
isl38xx_disable_interrupts(priv->device_base);
islpci_set_state(priv, PRV_STATE_OFF);
/* This bellow causes a lockup at rmmod time. It might be
- * because some interrupts still linger after rmmod time,
+ * because some interrupts still linger after rmmod time,
* see bug #17 */
/* pci_set_power_state(pdev, 3);*/ /* try to power-off */
}
/* free the PCI memory and unmap the remapped page */
islpci_free_memory(priv);
- pci_set_drvdata(pdev, 0);
+ pci_set_drvdata(pdev, NULL);
free_netdev(ndev);
- priv = 0;
+ priv = NULL;
+
+ pci_clear_mwi(pdev);
pci_release_regions(pdev);
}
int
-prism54_suspend(struct pci_dev *pdev, u32 state)
+prism54_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *ndev = pci_get_drvdata(pdev);
- islpci_private *priv = ndev ? netdev_priv(ndev) : 0;
+ islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
BUG_ON(!priv);
- printk(KERN_NOTICE "%s: got suspend request (state %d)\n",
- ndev->name, state);
- pci_save_state(pdev, priv->pci_state);
+ pci_save_state(pdev);
/* tell the device not to trigger interrupts for now... */
isl38xx_disable_interrupts(priv->device_base);
prism54_resume(struct pci_dev *pdev)
{
struct net_device *ndev = pci_get_drvdata(pdev);
- islpci_private *priv = ndev ? netdev_priv(ndev) : 0;
+ islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
+ int err;
+
BUG_ON(!priv);
printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
- pci_restore_state(pdev, priv->pci_state);
+ err = pci_enable_device(pdev);
+ if (err) {
+ printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
+ ndev->name);
+ return err;
+ }
+
+ pci_restore_state(pdev);
/* alright let's go into the PREBOOT state */
islpci_reset(priv, 1);
__bug_on_wrong_struct_sizes ();
- return pci_module_init(&prism54_driver);
+ return pci_register_driver(&prism54_driver);
}
/* by the time prism54_module_exit() terminates, as a postcondition