/* this one removes one(!!) instance only */
static void
prism54_remove(struct pci_dev *pdev)
{
	struct net_device *ndev = pci_get_drvdata(pdev);
	islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
	BUG_ON(!priv);

	if (!__in_cleanup_module) {
		printk(KERN_DEBUG "%s: hot unplug detected\n", ndev->name);
		islpci_set_state(priv, PRV_STATE_OFF);
	}

	printk(KERN_DEBUG "%s: removing device\n", ndev->name);

	unregister_netdev(ndev);

	/* free the interrupt request */

	if (islpci_get_state(priv) != PRV_STATE_OFF) {
		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,
		 * see bug #17 */
		/* pci_set_power_state(pdev, 3);*/	/* try to power-off */
	}

	free_irq(pdev->irq, priv);

	/* free the PCI memory and unmap the remapped page */
	islpci_free_memory(priv);

	pci_set_drvdata(pdev, NULL);
	free_netdev(ndev);
	priv = NULL;

	pci_clear_mwi(pdev);

	pci_release_regions(pdev);

	pci_disable_device(pdev);
}
static int
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) : NULL;
	BUG_ON(!priv);


	pci_save_state(pdev);

	
	isl38xx_disable_interrupts(priv->device_base);

	islpci_set_state(priv, PRV_STATE_OFF);

	netif_stop_queue(ndev);
	netif_device_detach(ndev);

	return 0;
}
Exemple #3
0
static void
prism54_remove(struct pci_dev *pdev)
{
	struct net_device *ndev = pci_get_drvdata(pdev);
	islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
	BUG_ON(!priv);

	if (!__in_cleanup_module) {
		printk(KERN_DEBUG "%s: hot unplug detected\n", ndev->name);
		islpci_set_state(priv, PRV_STATE_OFF);
	}

	printk(KERN_DEBUG "%s: removing device\n", ndev->name);

	unregister_netdev(ndev);

	

	if (islpci_get_state(priv) != PRV_STATE_OFF) {
		isl38xx_disable_interrupts(priv->device_base);
		islpci_set_state(priv, PRV_STATE_OFF);
		
			
	}

	free_irq(pdev->irq, priv);

	
	islpci_free_memory(priv);

	pci_set_drvdata(pdev, NULL);
	free_netdev(ndev);
	priv = NULL;

	pci_clear_mwi(pdev);

	pci_release_regions(pdev);

	pci_disable_device(pdev);
}
Exemple #4
0
static int
prism54_bring_down(islpci_private *priv)
{
	void __iomem *device_base = priv->device_base;
	u32 reg;
	/* we are going to shutdown the device */
	islpci_set_state(priv, PRV_STATE_PREBOOT);

	/* disable all device interrupts in case they weren't */
	isl38xx_disable_interrupts(priv->device_base);  

	/* For safety reasons, we may want to ensure that no DMA transfer is
	 * currently in progress by emptying the TX and RX queues. */

	/* wait until interrupts have finished executing on other CPUs */
	synchronize_irq(priv->pdev->irq);

	reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
	reg &= ~(ISL38XX_CTRL_STAT_RESET | ISL38XX_CTRL_STAT_RAMBOOT);
	writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
	wmb();
	udelay(ISL38XX_WRITEIO_DELAY);

	reg |= ISL38XX_CTRL_STAT_RESET;
	writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
	wmb();
	udelay(ISL38XX_WRITEIO_DELAY);

	/* clear the Reset bit */
	reg &= ~ISL38XX_CTRL_STAT_RESET;
	writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
	wmb();

	/* wait a while for the device to reset */
	set_current_state(TASK_UNINTERRUPTIBLE);
	schedule_timeout(50*HZ/1000);

	return 0;
}
static int
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) : NULL;
	BUG_ON(!priv);


	pci_save_state(pdev);

	/* tell the device not to trigger interrupts for now... */
	isl38xx_disable_interrupts(priv->device_base);

	/* from now on assume the hardware was already powered down
	   and don't touch it anymore */
	islpci_set_state(priv, PRV_STATE_OFF);

	netif_stop_queue(ndev);
	netif_device_detach(ndev);

	return 0;
}
Exemple #6
0
int
islpci_reset(islpci_private *priv, int reload_firmware)
{
	isl38xx_control_block *cb =    /* volatile not needed */
		(isl38xx_control_block *) priv->control_block;
	unsigned counter;
	int rc;

	if (reload_firmware)
		islpci_set_state(priv, PRV_STATE_PREBOOT);
	else
		islpci_set_state(priv, PRV_STATE_POSTBOOT);

	printk(KERN_DEBUG "%s: resetting device...\n", priv->ndev->name);

	/* disable all device interrupts in case they weren't */
	isl38xx_disable_interrupts(priv->device_base);

	/* flush all management queues */
	priv->index_mgmt_tx = 0;
	priv->index_mgmt_rx = 0;

	/* clear the indexes in the frame pointer */
	for (counter = 0; counter < ISL38XX_CB_QCOUNT; counter++) {
		cb->driver_curr_frag[counter] = cpu_to_le32(0);
		cb->device_curr_frag[counter] = cpu_to_le32(0);
	}

	/* reset the mgmt receive queue */
	for (counter = 0; counter < ISL38XX_CB_MGMT_QSIZE; counter++) {
		isl38xx_fragment *frag = &cb->rx_data_mgmt[counter];
		frag->size = cpu_to_le16(MGMT_FRAME_SIZE);
		frag->flags = 0;
		frag->address = cpu_to_le32(priv->mgmt_rx[counter].pci_addr);
	}

	for (counter = 0; counter < ISL38XX_CB_RX_QSIZE; counter++) {
		cb->rx_data_low[counter].address =
		    cpu_to_le32((u32) priv->pci_map_rx_address[counter]);
	}

	/* since the receive queues are filled with empty fragments, now we can
	 * set the corresponding indexes in the Control Block */
	priv->control_block->driver_curr_frag[ISL38XX_CB_RX_DATA_LQ] =
	    cpu_to_le32(ISL38XX_CB_RX_QSIZE);
	priv->control_block->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] =
	    cpu_to_le32(ISL38XX_CB_MGMT_QSIZE);

	/* reset the remaining real index registers and full flags */
	priv->free_data_rx = 0;
	priv->free_data_tx = 0;
	priv->data_low_tx_full = 0;

	if (reload_firmware) { /* Should we load the firmware ? */
	/* now that the data structures are cleaned up, upload
	 * firmware and reset interface */
		rc = islpci_upload_fw(priv);
		if (rc) {
			printk(KERN_ERR "%s: islpci_reset: failure\n",
				priv->ndev->name);
			return rc;
		}
	}

	/* finally reset interface */
	rc = islpci_reset_if(priv);
	if (rc)
		printk(KERN_ERR "prism54: Your card/socket may be faulty, or IRQ line too busy :(\n");
	return rc;
}
static int
prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct net_device *ndev;
	u8 latency_tmr;
	u32 mem_addr;
	islpci_private *priv;
	int rvalue;

	/* Enable the pci device */
	if (pci_enable_device(pdev)) {
		printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME);
		return -ENODEV;
	}

	/* check whether the latency timer is set correctly */
	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_tmr);
#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_TRACING, "latency timer: %x\n", latency_tmr);
#endif
	if (latency_tmr < PCIDEVICE_LATENCY_TIMER_MIN) {
		/* set the latency timer */
		pci_write_config_byte(pdev, PCI_LATENCY_TIMER,
				      PCIDEVICE_LATENCY_TIMER_VAL);
	}

	/* enable PCI DMA */
	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
		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.
	 *
	 *	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
	 */
	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) {
		printk(KERN_ERR "%s: pci_request_regions failure (rc=%d)\n",
		       DRV_NAME, rvalue);
		goto do_pci_disable_device;
	}

	/* check if the memory window is indeed set */
	rvalue = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &mem_addr);
	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_release_regions;
	}

	/* enable PCI bus-mastering */
	DEBUG(SHOW_TRACING, "%s: pci_set_master(pdev)\n", DRV_NAME);
	pci_set_master(pdev);

	/* enable MWI */
	pci_try_set_mwi(pdev);

	/* 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_clear_mwi;
	}

	priv = netdev_priv(ndev);
	islpci_set_state(priv, PRV_STATE_PREBOOT); /* we are attempting to boot */

	/* card is in unknown state yet, might have some interrupts pending */
	isl38xx_disable_interrupts(priv->device_base);

	/* request for the interrupt before uploading the firmware */
	rvalue = request_irq(pdev->irq, islpci_interrupt,
			     IRQF_SHARED, ndev->name, priv);

	if (rvalue) {
		/* error, could not hook the handler to the irq */
		printk(KERN_ERR "%s: could not install IRQ handler\n",
		       ndev->name);
		goto do_unregister_netdev;
	}

	/* firmware upload is triggered in islpci_open */

	return 0;

      do_unregister_netdev:
	unregister_netdev(ndev);
	islpci_free_memory(priv);
	pci_set_drvdata(pdev, NULL);
	free_netdev(ndev);
	priv = NULL;
      do_pci_clear_mwi:
	pci_clear_mwi(pdev);
      do_pci_release_regions:
	pci_release_regions(pdev);
      do_pci_disable_device:
	pci_disable_device(pdev);
	return -EIO;
}
Exemple #8
0
static int
prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct net_device *ndev;
	u8 latency_tmr;
	u32 mem_addr;
	islpci_private *priv;
	int rvalue;

	
	if (pci_enable_device(pdev)) {
		printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME);
		return -ENODEV;
	}

	
	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_tmr);
#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_TRACING, "latency timer: %x\n", latency_tmr);
#endif
	if (latency_tmr < PCIDEVICE_LATENCY_TIMER_MIN) {
		
		pci_write_config_byte(pdev, PCI_LATENCY_TIMER,
				      PCIDEVICE_LATENCY_TIMER_VAL);
	}

	
	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
		printk(KERN_ERR "%s: 32-bit PCI DMA not supported", DRV_NAME);
		goto do_pci_disable_device;
        }

	
	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");
	}

	
	rvalue = pci_request_regions(pdev, DRV_NAME);
	if (rvalue) {
		printk(KERN_ERR "%s: pci_request_regions failure (rc=%d)\n",
		       DRV_NAME, rvalue);
		goto do_pci_disable_device;
	}

	
	rvalue = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &mem_addr);
	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_release_regions;
	}

	
	DEBUG(SHOW_TRACING, "%s: pci_set_master(pdev)\n", DRV_NAME);
	pci_set_master(pdev);

	
	pci_try_set_mwi(pdev);

	
	if (!(ndev = islpci_setup(pdev))) {
		
		printk(KERN_ERR "%s: could not configure network device\n",
		       DRV_NAME);
		goto do_pci_clear_mwi;
	}

	priv = netdev_priv(ndev);
	islpci_set_state(priv, PRV_STATE_PREBOOT); 

	
	isl38xx_disable_interrupts(priv->device_base);

	
	rvalue = request_irq(pdev->irq, &islpci_interrupt,
			     IRQF_SHARED, ndev->name, priv);

	if (rvalue) {
		
		printk(KERN_ERR "%s: could not install IRQ handler\n",
		       ndev->name);
		goto do_unregister_netdev;
	}

	

	return 0;

      do_unregister_netdev:
	unregister_netdev(ndev);
	islpci_free_memory(priv);
	pci_set_drvdata(pdev, NULL);
	free_netdev(ndev);
	priv = NULL;
      do_pci_clear_mwi:
	pci_clear_mwi(pdev);
      do_pci_release_regions:
	pci_release_regions(pdev);
      do_pci_disable_device:
	pci_disable_device(pdev);
	return -EIO;
}