⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prism2_pci.c

📁 uClinux2.6上兼容PRISM2.0芯片组的USB设备驱动程序.
💻 C
字号:
#define WLAN_HOSTIF WLAN_PCI#include "hfa384x.c"#include "prism2mgmt.c"#include "prism2mib.c"#include "prism2sta.c"#define PCI_SIZE		0x1000		/* Memory size - 4K bytes *//* ISL3874A 11Mb/s WLAN controller */#define PCIVENDOR_INTERSIL	0x1260UL#define PCIDEVICE_ISL3874	0x3873UL /* [MSM] yeah I know...the ID says 					    3873. Trust me, it's a 3874. *//* Samsung SWL-2210P 11Mb/s WLAN controller (uses ISL3874A) */#define PCIVENDOR_SAMSUNG      0x167dUL#define PCIDEVICE_SWL_2210P    0xa000UL#define PCIVENDOR_NETGEAR      0x1385UL /* for MA311 *//* PCI Class & Sub-Class code, Network-'Other controller' */#define PCI_CLASS_NETWORK_OTHERS 0x280/*----------------------------------------------------------------* 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 __devinitprism2sta_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);	/* Initialize the hw data */        hfa384x_create(hw, wlandev->netdev->irq, 0, 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 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	/* 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;}static void __devexit prism2sta_remove_pci(struct pci_dev *pdev){       	wlandevice_t		*wlandev;	hfa384x_t	*hw;	wlandev = (wlandevice_t *) pci_get_drvdata(pdev);	hw = wlandev->priv;	p80211netdev_hwremoved(wlandev);	/* reset hardware */	prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);        if (pdev->irq)		free_irq(pdev->irq, wlandev);	unregister_wlandev(wlandev);	/* free local stuff */	if (hw) {		hfa384x_destroy(hw);		kfree(hw);	}	iounmap((void*) wlandev->netdev->mem_start);	wlan_unsetup(wlandev);	pci_release_regions(pdev);        pci_disable_device(pdev);	pci_set_drvdata(pdev, NULL);	kfree(wlandev);}static struct pci_device_id pci_id_tbl[] = {	{		PCIVENDOR_INTERSIL, PCIDEVICE_ISL3874,			PCI_ANY_ID, PCI_ANY_ID,		0, 0, 		/* Driver data, we just put the name here */		(unsigned long)"Intersil Prism2.5 ISL3874 11Mb/s WLAN Controller"	},	{		PCIVENDOR_INTERSIL, 0x3872,			PCI_ANY_ID, PCI_ANY_ID,		0, 0, 		/* Driver data, we just put the name here */		(unsigned long)"Intersil Prism2.5 ISL3872 11Mb/s WLAN Controller"	},        {                PCIVENDOR_SAMSUNG, PCIDEVICE_SWL_2210P,               PCI_ANY_ID, PCI_ANY_ID,               0, 0,               /* Driver data, we just put the name here */               (unsigned long)"Samsung MagicLAN SWL-2210P 11Mb/s WLAN Controller"	},	{ /* for NetGear MA311 */		PCIVENDOR_NETGEAR, 0x3872,		PCI_ANY_ID, PCI_ANY_ID,		0, 0,		/* Driver data, we just put the name here */		(unsigned long)"Netgear MA311 WLAN Controller"	},	{		0, 0, 0, 0, 0, 0, 0	}};MODULE_DEVICE_TABLE(pci, pci_id_tbl);/* Function declared here because of ptr reference below */static int  __devinit prism2sta_probe_pci(struct pci_dev *pdev, 				const struct pci_device_id *id);static void  __devexit prism2sta_remove_pci(struct pci_dev *pdev);struct pci_driver prism2_pci_drv_id = {        .name = "prism2_pci",        .id_table = pci_id_tbl,        .probe = prism2sta_probe_pci,        .remove = prism2sta_remove_pci,#ifdef CONFIG_PM        .suspend = prism2sta_suspend_pci,        .resume = prism2sta_resume_pci,#endif};#ifdef MODULEstatic int __init prism2pci_init(void){        WLAN_LOG_NOTICE("%s Loaded\n", version);	return pci_module_init(&prism2_pci_drv_id);};static void __exit prism2pci_cleanup(void){	pci_unregister_driver(&prism2_pci_drv_id);};module_init(prism2pci_init);module_exit(prism2pci_cleanup);#endifint hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis){	int		result = 0;	unsigned long	timeout;	UINT16	reg;	DBFENTER;	/* Assert reset and wait awhile 	 * (note: these delays are _really_ long, but they appear to be	 *        necessary.)	 */	hfa384x_setreg(hw, 0xc5, HFA384x_PCICOR);	timeout = jiffies + HZ/4;	while(time_before(jiffies, timeout)) udelay(5);	if (genesis) {		hfa384x_setreg(hw, genesis, HFA384x_PCIHCR);		timeout = jiffies + HZ/4;		while(time_before(jiffies, timeout)) udelay(5);	}	/* Clear the reset and wait some more 	 */	hfa384x_setreg(hw, 0x45, HFA384x_PCICOR);	timeout = jiffies + HZ/2;	while(time_before(jiffies, timeout)) udelay(5);		/* Wait for f/w to complete initialization (CMD:BUSY == 0) 	 */	timeout = jiffies + 2*HZ;	reg = hfa384x_getreg(hw, HFA384x_CMD);	while ( HFA384x_CMD_ISBUSY(reg) && time_before( jiffies, timeout) ) {		reg = hfa384x_getreg(hw, HFA384x_CMD);		udelay(10);	}	if (HFA384x_CMD_ISBUSY(reg)) {		WLAN_LOG_WARNING("corereset: Timed out waiting for cmd register.\n");		result=1;	}	DBFEXIT;	return result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -