Пример #1
0
static int prism2sta_resume(struct usb_interface *interface)
{
	int result = 0;
	hfa384x_t *hw = NULL;
	wlandevice_t *wlandev;

	wlandev = (wlandevice_t *)usb_get_intfdata(interface);
	if (!wlandev)
		return -ENODEV;

	hw = wlandev->priv;
	if (!hw)
		return -ENODEV;

	/* Do a chip-level reset on the MAC */
	if (prism2_doreset) {
		result = hfa384x_corereset(hw,
					   prism2_reset_holdtime,
					   prism2_reset_settletime, 0);
		if (result != 0) {
			unregister_wlandev(wlandev);
			hfa384x_destroy(hw);
			dev_err(&interface->dev, "hfa384x_corereset() failed.\n");
			kfree(wlandev);
			kfree(hw);
			wlandev = NULL;
			return -ENODEV;
		}
	}

	prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable);

	return 0;
}
Пример #2
0
/*----------------------------------------------------------------
* prism2sta_event
*
* Handler for card services events.
*
* Arguments:
*	event		The event code
*	priority	hi/low - REMOVAL is the only hi
*	args		ptr to card services struct containing info about
*			pcmcia status
*
* Returns:
*	Zero on success, non-zero otherwise
*
* Side effects:
*
*
* Call context:
*	Both interrupt and process thread, depends on the event.
----------------------------------------------------------------*/
static int
prism2sta_event (
	event_t event,
	int priority,
	event_callback_args_t *args)
{
	int			result = 0;
	dev_link_t		*link = (dev_link_t *) args->client_data;
	wlandevice_t		*wlandev = (wlandevice_t*)link->priv;
	hfa384x_t		*hw = NULL;

	DBFENTER;

	if (wlandev) hw = wlandev->priv;

	switch (event)
	{
	case CS_EVENT_CARD_INSERTION:
		WLAN_LOG_DEBUG(5,"event is INSERTION\n");
		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
		prism2sta_config(link);
		if (!(link->state & DEV_CONFIG)) {
			wlandev->netdev->irq = 0;
			WLAN_LOG_ERROR(
				"%s: Initialization failed!\n", dev_info);
			wlandev->msdstate = WLAN_MSD_HWFAIL;
			break;
		}

		/* Fill in the rest of the hw struct */
		hw->irq = wlandev->netdev->irq;
		hw->iobase = wlandev->netdev->base_addr;
		hw->link = link;

		if (prism2_doreset) {
			result = hfa384x_corereset(hw,
					prism2_reset_holdtime,
					prism2_reset_settletime, 0);
			if ( result ) {
				WLAN_LOG_ERROR(
					"corereset() failed, result=%d.\n",
					result);
				wlandev->msdstate = WLAN_MSD_HWFAIL;
				break;
			}
		}

#if 0
		/*
		 * TODO: test_hostif() not implemented yet.
		 */
		result = hfa384x_test_hostif(hw);
		if (result) {
			WLAN_LOG_ERROR(
			"test_hostif() failed, result=%d.\n", result);
			wlandev->msdstate = WLAN_MSD_HWFAIL;
			break;
		}
#endif
		wlandev->msdstate = WLAN_MSD_HWPRESENT;
		break;

	case CS_EVENT_CARD_REMOVAL:
		WLAN_LOG_DEBUG(5,"event is REMOVAL\n");
		link->state &= ~DEV_PRESENT;

		if (wlandev) {
			p80211netdev_hwremoved(wlandev);
		}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
		if (link->state & DEV_CONFIG)
		{
			link->release.expires = jiffies + (HZ/20);
			add_timer(&link->release);
		}
#endif
		break;
	case CS_EVENT_RESET_REQUEST:
		WLAN_LOG_DEBUG(5,"event is RESET_REQUEST\n");
		WLAN_LOG_NOTICE(
			"prism2 card reset not supported "
			"due to post-reset user mode configuration "
			"requirements.\n");
		WLAN_LOG_NOTICE(
			"  From user mode, use "
			"'cardctl suspend;cardctl resume' "
			"instead.\n");
		break;
	case CS_EVENT_RESET_PHYSICAL:
	case CS_EVENT_CARD_RESET:
		WLAN_LOG_WARNING("Rx'd CS_EVENT_RESET_xxx, should not "
			"be possible since RESET_REQUEST was denied.\n");
		break;

	case CS_EVENT_PM_SUSPEND:
		WLAN_LOG_DEBUG(5,"event is SUSPEND\n");
		link->state |= DEV_SUSPEND;
		if (link->state & DEV_CONFIG)
		{
			prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
			pcmcia_release_configuration(link->handle);
		}
		break;

	case CS_EVENT_PM_RESUME:
		WLAN_LOG_DEBUG(5,"event is RESUME\n");
		link->state &= ~DEV_SUSPEND;
		if (link->state & DEV_CONFIG) {
			pcmcia_request_configuration(link->handle, &link->conf);
		}
		break;
	}

	DBFEXIT;
	return 0;  /* noone else does anthing with the return value */
}
Пример #3
0
/*----------------------------------------------------------------
* prism2sta_probe_plx
*
* Probe routine called when a PCI device w/ matching ID is found.
* This PLX implementation uses the following map:
*   BAR0: Unused
*   BAR1: ????
*   BAR2: PCMCIA attribute memory
*   BAR3: PCMCIA i/o space
* Here's the sequence:
*   - Allocate the PCI resources.
*   - Read the PCMCIA attribute memory to make sure we have a WLAN card
*   - Reset the MAC using the PCMCIA COR
*   - Initialize the netdev and wlan data
*   - Initialize the MAC
*
* Arguments:
*	pdev		ptr to pci device structure containing info about
*			pci configuration.
*	id		ptr to the device id entry that matched this device.
*
* Returns:
*	zero		- success
*	negative	- failed
*
* Side effects:
*
*
* Call context:
*	process thread
*
----------------------------------------------------------------*/
static int __devinit
prism2sta_probe_plx(
	struct pci_dev			*pdev,
	const struct pci_device_id	*id)
{
	int		result;
        phys_t	pccard_ioaddr;
	phys_t  pccard_attr_mem;
        unsigned int    pccard_attr_len;
	void __iomem *attr_mem = NULL;
	UINT32		plx_addr;
        wlandevice_t    *wlandev = NULL;
	hfa384x_t	*hw = NULL;
	int		reg;
        u32		regic;

	if (pci_enable_device(pdev))
		return -EIO;

	/* TMC7160 boards are special */
	if ((pdev->vendor == PCIVENDOR_NDC) &&
	    (pdev->device == PCIDEVICE_NCP130_ASIC)) {
		unsigned long delay;

		pccard_attr_mem = 0;
		pccard_ioaddr = pci_resource_start(pdev, 1);

		outb(0x45, pccard_ioaddr);
		delay = jiffies + 1*HZ;
		while (time_before(jiffies, delay));

		if (inb(pccard_ioaddr) != 0x45) {
			WLAN_LOG_ERROR("Initialize the TMC7160 failed. (0x%x)\n", inb(pccard_ioaddr));
			return -EIO;
		}

		pccard_ioaddr = pci_resource_start(pdev, 2);
		prism2_doreset = 0;

		WLAN_LOG_INFO("NDC NCP130 with TMC716(ASIC) PCI interface device found at io:0x%x, irq:%d\n", pccard_ioaddr, pdev->irq);
		goto init;
	}

	/* Collect the resource requirements */
	pccard_attr_mem = pci_resource_start(pdev, 2);
	pccard_attr_len = pci_resource_len(pdev, 2);
        if (pccard_attr_len < PLX_MIN_ATTR_LEN)
		return -EIO;

	pccard_ioaddr = pci_resource_start(pdev, 3);

	/* bjoern: We need to tell the card to enable interrupts, in
	 * case the serial eprom didn't do this already. See the
	 * PLX9052 data book, p8-1 and 8-24 for reference.
	 * [MSM]: This bit of code came from the orinoco_cs driver.
	 */
	plx_addr = pci_resource_start(pdev, 1);

	regic = 0;
	regic = inl(plx_addr+PLX_INTCSR);
	if(regic & PLX_INTCSR_INTEN) {
		WLAN_LOG_DEBUG(1,
			"%s: Local Interrupt already enabled\n", dev_info);
	} else {
		regic |= PLX_INTCSR_INTEN;
		outl(regic, plx_addr+PLX_INTCSR);
		regic = inl(plx_addr+PLX_INTCSR);
		if(!(regic & PLX_INTCSR_INTEN)) {
			WLAN_LOG_ERROR(
				"%s: Couldn't enable Local Interrupts\n",
				dev_info);
			return -EIO;
		}
	}

	/* These assignments are here in case of future mappings for
	 * io space and irq that might be similar to ioremap
	 */
        if (!request_mem_region(pccard_attr_mem, pci_resource_len(pdev, 2), "Prism2")) {
		WLAN_LOG_ERROR("%s: Couldn't reserve PCI memory region\n", dev_info);
		return -EIO;
        }

	attr_mem = ioremap(pccard_attr_mem, pccard_attr_len);

	WLAN_LOG_INFO("A PLX PCI/PCMCIA interface device found, "
		"phymem:0x%llx, phyio=0x%x, irq:%d, "
		"mem: 0x%lx\n",
		(unsigned long long)pccard_attr_mem, pccard_ioaddr, pdev->irq,
		(unsigned long)attr_mem);

	/* Verify whether PC card is present.
	 * [MSM] This needs improvement, the right thing to do is
	 * probably to walk the CIS looking for the vendor and product
	 * IDs.  It would be nice if this could be tied in with the
	 * etc/pcmcia/wlan-ng.conf file.  Any volunteers?  ;-)
	 */
	if (
	readb(attr_mem + 0) != 0x01 || readb(attr_mem + 2) != 0x03 ||
	readb(attr_mem + 4) != 0x00 || readb(attr_mem + 6) != 0x00 ||
	readb(attr_mem + 8) != 0xFF || readb(attr_mem + 10) != 0x17 ||
	readb(attr_mem + 12) != 0x04 || readb(attr_mem + 14) != 0x67) {
		WLAN_LOG_ERROR("Prism2 PC card CIS is invalid.\n");
		return -EIO;
        }
        WLAN_LOG_INFO("A PCMCIA WLAN adapter was found.\n");

        /* Write COR to enable PC card */
	writeb(COR_VALUE, attr_mem + COR_OFFSET);
	reg = readb(attr_mem + COR_OFFSET);

 init:

	/*
	 * Now do everything the same as a PCI device
	 * [MSM] TODO: We could probably factor this out of pcmcia/pci/plx
	 * and perhaps usb.  Perhaps a task for another day.......
	 */

	if ((wlandev = create_wlan()) == NULL) {
		WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
		result = -EIO;
		goto failed;
	}

	hw = wlandev->priv;

	if ( wlan_setup(wlandev) != 0 ) {
		WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
		result = -EIO;
		goto failed;
	}

	/* Setup netdevice's ability to report resources
	 * Note: the netdevice was allocated by wlan_setup()
	 */
        wlandev->netdev->irq = pdev->irq;
        wlandev->netdev->base_addr = pccard_ioaddr;
        wlandev->netdev->mem_start = (unsigned long)attr_mem;
        wlandev->netdev->mem_end = (unsigned long)attr_mem + pci_resource_len(pdev, 0);

	/* Initialize the hw data */
        hfa384x_create(hw, wlandev->netdev->irq, pccard_ioaddr, attr_mem);
	hw->wlandev = wlandev;

	/* Register the wlandev, this gets us a name and registers the
	 * linux netdevice.
	 */
	SET_MODULE_OWNER(wlandev->netdev);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
       SET_NETDEV_DEV(wlandev->netdev, &(pdev->dev));
#endif
        if ( register_wlandev(wlandev) != 0 ) {
		WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
		result = -EIO;
		goto failed;
        }

#if 0
	/* TODO: Move this and an irq test into an hfa384x_testif() routine.
	 */
	outw(PRISM2STA_MAGIC, HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
	reg=inw( HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
	if ( reg != PRISM2STA_MAGIC ) {
		WLAN_LOG_ERROR("MAC register access test failed!\n");
 		result = -EIO;
		goto failed;
	}
#endif

	/* Do a chip-level reset on the MAC */
	if (prism2_doreset) {
		result = hfa384x_corereset(hw,
				prism2_reset_holdtime,
				prism2_reset_settletime, 0);
		if (result != 0) {
			unregister_wlandev(wlandev);
			hfa384x_destroy(hw);
			WLAN_LOG_ERROR(
				"%s: hfa384x_corereset() failed.\n",
				dev_info);
			result = -EIO;
			goto failed;
		}
	}

	pci_set_drvdata(pdev, wlandev);

	/* Shouldn't actually hook up the IRQ until we
	 * _know_ things are alright.  A test routine would help.
	 */
       	request_irq(wlandev->netdev->irq, hfa384x_interrupt,
		SA_SHIRQ, wlandev->name, wlandev);

	wlandev->msdstate = WLAN_MSD_HWPRESENT;

	result = 0;

	goto done;

 failed:

	pci_set_drvdata(pdev, NULL);
	if (wlandev)	kfree(wlandev);
	if (hw)		kfree(hw);
        if (attr_mem)        iounmap(attr_mem);
	pci_release_regions(pdev);
        pci_disable_device(pdev);

 done:
	DBFEXIT;
        return result;
}
Пример #4
0
static int prism2sta_probe_usb(struct usb_interface *interface,
			       const struct usb_device_id *id)
{
	struct usb_device *dev;

	wlandevice_t *wlandev = NULL;
	hfa384x_t *hw = NULL;
	int result = 0;

	dev = interface_to_usbdev(interface);
	wlandev = create_wlan();
	if (!wlandev) {
		dev_err(&interface->dev, "Memory allocation failure.\n");
		result = -EIO;
		goto failed;
	}
	hw = wlandev->priv;

	if (wlan_setup(wlandev, &(interface->dev)) != 0) {
		dev_err(&interface->dev, "wlan_setup() failed.\n");
		result = -EIO;
		goto failed;
	}

	/* Initialize the hw data */
	hfa384x_create(hw, dev);
	hw->wlandev = wlandev;

	/* Register the wlandev, this gets us a name and registers the
	 * linux netdevice.
	 */
	SET_NETDEV_DEV(wlandev->netdev, &(interface->dev));

	/* Do a chip-level reset on the MAC */
	if (prism2_doreset) {
		result = hfa384x_corereset(hw,
					   prism2_reset_holdtime,
					   prism2_reset_settletime, 0);
		if (result != 0) {
			result = -EIO;
			dev_err(&interface->dev,
				"hfa384x_corereset() failed.\n");
			goto failed_reset;
		}
	}

	usb_get_dev(dev);

	wlandev->msdstate = WLAN_MSD_HWPRESENT;

	/* Try and load firmware, then enable card before we register */
	prism2_fwtry(dev, wlandev);
	prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable);

	if (register_wlandev(wlandev) != 0) {
		dev_err(&interface->dev, "register_wlandev() failed.\n");
		result = -EIO;
		goto failed_register;
	}

	goto done;

failed_register:
	usb_put_dev(dev);
failed_reset:
	wlan_unsetup(wlandev);
failed:
	kfree(wlandev);
	kfree(hw);
	wlandev = NULL;

done:
	usb_set_intfdata(interface, wlandev);
	return result;
}
Пример #5
0
/*----------------------------------------------------------------
* prism2sta_probe_pci
*
* Probe routine called when a PCI device w/ matching ID is found. 
* The ISL3874 implementation uses the following map:
*   BAR0: Prism2.x registers memory mapped, size=4k
* Here's the sequence:
*   - Allocate the PCI resources.  
*   - Read the PCMCIA attribute memory to make sure we have a WLAN card
*   - Reset the MAC 
*   - Initialize the netdev and wlan data
*   - Initialize the MAC
*
* Arguments:
*	pdev		ptr to pci device structure containing info about 
*			pci configuration.
*	id		ptr to the device id entry that matched this device.
*
* Returns: 
*	zero		- success
*	negative	- failed
*
* Side effects:
*	
*
* Call context:
*	process thread
*	
----------------------------------------------------------------*/
static int __devinit
prism2sta_probe_pci(
	struct pci_dev *pdev, 
	const struct pci_device_id *id)
{
	int		result;
	phys_t		phymem = 0;
	void		*mem = NULL;
        wlandevice_t    *wlandev = NULL;
	hfa384x_t	*hw = NULL;

	DBFENTER;

	/* Enable the pci device */
	if (pci_enable_device(pdev)) {
		WLAN_LOG_ERROR("%s: pci_enable_device() failed.\n", dev_info);
		result = -EIO;
		goto fail;
	}

	/* Figure out our resources */
	phymem = pci_resource_start(pdev, 0);

        if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "Prism2")) {
		printk(KERN_ERR "prism2: Cannot reserve PCI memory region\n");
		result = -EIO;
		goto fail;
        }

	mem = ioremap(phymem, PCI_SIZE);
	if ( mem == 0 ) {
		WLAN_LOG_ERROR("%s: ioremap() failed.\n", dev_info);
		result = -EIO;
		goto fail;
	}

	/* Log the device */
        WLAN_LOG_INFO("A Prism2.5 PCI device found, "
		"phymem:0x%llx, irq:%d, mem:0x%p\n", 
		(unsigned long long)phymem, pdev->irq, mem);
	
	if ((wlandev = create_wlan()) == NULL) {
		WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
		result = -EIO;
		goto fail;
	}
	hw = wlandev->priv;
	
	if ( wlan_setup(wlandev) != 0 ) {
		WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
		result = -EIO;
		goto fail;
	}

	/* Setup netdevice's ability to report resources 
	 * Note: the netdevice was allocated by wlan_setup()
	 */
        wlandev->netdev->irq = pdev->irq;
        wlandev->netdev->mem_start = (unsigned long) mem;
        wlandev->netdev->mem_end = wlandev->netdev->mem_start + 
		pci_resource_len(pdev, 0);

	/* Register the wlandev, this gets us a name and registers the
	 * linux netdevice.
	 */
	SET_MODULE_OWNER(wlandev->netdev);
        if ( register_wlandev(wlandev) != 0 ) {
		WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
		result = -EIO;
		goto fail;
        }

#if 0
	/* TODO: Move this and an irq test into an hfa384x_testif() routine.
	 */
	outw(PRISM2STA_MAGIC, HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
	reg=inw( HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
	if ( reg != PRISM2STA_MAGIC ) {
		WLAN_LOG_ERROR("MAC register access test failed!\n");
		result = -EIO;
		goto fail;
	}		
#endif

	/* Initialize the hw data */
        hfa384x_create(hw, wlandev->netdev->irq, 0, mem);
	hw->wlandev = wlandev;

	/* Do a chip-level reset on the MAC */
	if (prism2_doreset) {
		result = hfa384x_corereset(hw, 
				prism2_reset_holdtime, 
				prism2_reset_settletime, 0);
		if (result != 0) {
			WLAN_LOG_ERROR(
				"%s: hfa384x_corereset() failed.\n", 
				dev_info);
			unregister_wlandev(wlandev);
			hfa384x_destroy(hw);
			result = -EIO;
			goto fail;
		}
	}

        pci_set_drvdata(pdev, wlandev);

	/* Shouldn't actually hook up the IRQ until we 
	 * _know_ things are alright.  A test routine would help.
	 */
       	request_irq(wlandev->netdev->irq, hfa384x_interrupt, 
		SA_SHIRQ, wlandev->name, wlandev);

	wlandev->msdstate = WLAN_MSD_HWPRESENT;

	result = 0;
	goto done;

 fail:
	pci_set_drvdata(pdev, NULL);
	if (wlandev)	kfree(wlandev);
	if (hw)		kfree(hw);
        if (mem)        iounmap((void *) mem);
	pci_release_regions(pdev);
        pci_disable_device(pdev);

 done:
	DBFEXIT;
	return result;
}