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

📄 tlan.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
	memset(TLanPadBuffer, 0, TLAN_MIN_FRAME_SIZE);	pad_allocated = 1;	TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");		/* Use new style PCI probing. Now the kernel will	   do most of this for us */	pci_register_driver(&tlan_driver);	TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");	TLan_EisaProbe();			printk(KERN_INFO "TLAN: %d device%s installed, PCI: %d  EISA: %d\n", 		 TLanDevicesInstalled, TLanDevicesInstalled == 1 ? "" : "s",		 tlan_have_pci, tlan_have_eisa);	if (TLanDevicesInstalled == 0) {		pci_unregister_driver(&tlan_driver);		kfree(TLanPadBuffer);		return -ENODEV;	}	return 0;}	static int __devinit tlan_init_one( struct pci_dev *pdev,				    const struct pci_device_id *ent){	return TLan_probe1( pdev, -1, -1, 0, ent);}/*	***************************************************************	 *	tlan_probe1	 *	 *	Returns:	 *		0 on success, error code on error	 *	Parms: 	 *		none	 *	 *	The name is lower case to fit in with all the rest of	 *	the netcard_probe names.  This function looks for 	 *	another TLan based adapter, setting it up with the	 *	allocated device struct if one is found.	 *	tlan_probe has been ported to the new net API and	 *	now allocates its own device structure. This function	 *	is also used by modules.	 *	 **************************************************************/static int __devinit TLan_probe1(struct pci_dev *pdev, 				long ioaddr, int irq, int rev, const struct pci_device_id *ent ){	struct net_device  *dev;	TLanPrivateInfo    *priv;	u8		   pci_rev;	u16		   device_id;	int		   reg;	if (pdev && pci_enable_device(pdev))		return -EIO;	dev = init_etherdev(NULL, sizeof(TLanPrivateInfo));	if (dev == NULL) {		printk(KERN_ERR "TLAN: Could not allocate memory for device.\n");		return -ENOMEM;	}	SET_MODULE_OWNER(dev);		priv = dev->priv;	/* Is this a PCI device? */	if (pdev) {		u32 		   pci_io_base = 0;		priv->adapter = &board_info[ent->driver_data];		pci_read_config_byte ( pdev, PCI_REVISION_ID, &pci_rev);		for ( reg= 0; reg <= 5; reg ++ ) {			if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) {				pci_io_base = pci_resource_start(pdev, reg);				TLAN_DBG( TLAN_DEBUG_GNRL, "IO mapping is available at %x.\n",						pci_io_base);				break;			}		}		if (!pci_io_base) {			printk(KERN_ERR "TLAN: No IO mappings available\n");			unregister_netdev(dev);			kfree(dev);			return -ENODEV;		}				dev->base_addr = pci_io_base;		dev->irq = pdev->irq;		priv->adapterRev = pci_rev; 		pci_set_master(pdev);		pci_set_drvdata(pdev, dev);	} else	{     /* EISA card */		/* This is a hack. We need to know which board structure		 * is suited for this adapter */		device_id = inw(ioaddr + EISA_ID2);		priv->is_eisa = 1;		if (device_id == 0x20F1) {			priv->adapter = &board_info[13]; 	/* NetFlex-3/E */			priv->adapterRev = 23;			/* TLAN 2.3 */		} else {			priv->adapter = &board_info[14];			priv->adapterRev = 10;			/* TLAN 1.0 */		}		dev->base_addr = ioaddr;		dev->irq = irq;	}	/* Kernel parameters */	if (dev->mem_start) {		priv->aui    = dev->mem_start & 0x01;		priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0 : (dev->mem_start & 0x06) >> 1;		priv->speed  = ((dev->mem_start & 0x18) == 0x18) ? 0 : (dev->mem_start & 0x18) >> 3;			if (priv->speed == 0x1) {			priv->speed = TLAN_SPEED_10;		} else if (priv->speed == 0x2) {			priv->speed = TLAN_SPEED_100;		}		debug = priv->debug = dev->mem_end;	} else {		priv->aui    = aui[boards_found];		priv->speed  = speed[boards_found];		priv->duplex = duplex[boards_found];		priv->debug = debug;	}		/* This will be used when we get an adapter error from	 * within our irq handler */	INIT_LIST_HEAD(&priv->tlan_tqueue.list);	priv->tlan_tqueue.sync = 0;	priv->tlan_tqueue.routine = (void *)(void*)TLan_tx_timeout;	priv->tlan_tqueue.data = dev;	spin_lock_init(&priv->lock);		if (TLan_Init(dev)) {		printk(KERN_ERR "TLAN: Could not register device.\n");		unregister_netdev(dev);		kfree(dev);		return -EAGAIN;	} else {		TLanDevicesInstalled++;	boards_found++;		/* pdev is NULL if this is an EISA device */	if (pdev)		tlan_have_pci++;	else {		priv->nextDevice = TLan_Eisa_Devices;		TLan_Eisa_Devices = dev;		tlan_have_eisa++;	}		printk(KERN_INFO "TLAN: %s irq=%2d, io=%04x, %s, Rev. %d\n",			dev->name,			(int) dev->irq,			(int) dev->base_addr,			priv->adapter->deviceLabel,			priv->adapterRev);	return 0;	}}static void TLan_Eisa_Cleanup(void){	struct net_device *dev;	TLanPrivateInfo *priv;		while( tlan_have_eisa ) {		dev = TLan_Eisa_Devices;		priv = dev->priv;		if (priv->dmaStorage) {			kfree(priv->dmaStorage);		}		release_region( dev->base_addr, 0x10);		unregister_netdev( dev );		TLan_Eisa_Devices = priv->nextDevice;		kfree( dev );		tlan_have_eisa--;	}}			static void __exit tlan_exit(void){	pci_unregister_driver(&tlan_driver);	if (tlan_have_eisa)		TLan_Eisa_Cleanup();	kfree( TLanPadBuffer );}/* Module loading/unloading */module_init(tlan_probe);module_exit(tlan_exit);	/**************************************************************	 * 	TLan_EisaProbe	 *	 *  	Returns: 0 on success, 1 otherwise	 *	 *  	Parms:	 None	 *	 *	 *  	This functions probes for EISA devices and calls 	 *  	TLan_probe1 when one is found. 	 *	 *************************************************************/static void  __init TLan_EisaProbe (void) {	long 	ioaddr;	int 	rc = -ENODEV;	int 	irq;	u16	device_id;	if (!EISA_bus) {			TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n");		return;	}		/* Loop through all slots of the EISA bus */	for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {			TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", (int) ioaddr + 0xC80, inw(ioaddr + EISA_ID));		TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", (int) ioaddr + 0xC82, inw(ioaddr + EISA_ID2));		TLAN_DBG(TLAN_DEBUG_PROBE, "Probing for EISA adapter at IO: 0x%4x : ",				   	(int) ioaddr);		if (request_region(ioaddr, 0x10, TLanSignature) == NULL) 			goto out;		if (inw(ioaddr + EISA_ID) != 0x110E) {					release_region(ioaddr, 0x10);			goto out;		}				device_id = inw(ioaddr + EISA_ID2);		if (device_id !=  0x20F1 && device_id != 0x40F1) { 					release_region (ioaddr, 0x10);			goto out;		}			 	if (inb(ioaddr + EISA_CR) != 0x1) { 	/* Check if adapter is enabled */			release_region (ioaddr, 0x10);			goto out2;		}				if (debug == 0x10)					printk("Found one\n");		/* Get irq from board */		switch (inb(ioaddr + 0xCC0)) {			case(0x10):				irq=5;				break;			case(0x20):				irq=9;				break;			case(0x40):				irq=10;				break;			case(0x80):				irq=11;				break;			default:				goto out;		}               						/* Setup the newly found eisa adapter */		rc = TLan_probe1( NULL, ioaddr, irq,					12, NULL);		continue;				out:			if (debug == 0x10)				printk("None found\n");			continue;		out2:	if (debug == 0x10)				printk("Card found but it is not enabled, skipping\n");			continue;			}} /* TLan_EisaProbe */		/***************************************************************	 *	TLan_Init	 *	 *	Returns:	 *		0 on success, error code otherwise.	 *	Parms:	 *		dev	The structure of the device to be	 *			init'ed.	 *	 *	This function completes the initialization of the	 *	device structure and driver.  It reserves the IO	 *	addresses, allocates memory for the lists and bounce	 *	buffers, retrieves the MAC address from the eeprom	 *	and assignes the device's methods.	 *		 **************************************************************/static int TLan_Init( struct net_device *dev ){	int		dma_size;	int 		err;	int		i;	TLanPrivateInfo	*priv;	priv = dev->priv;		if (!priv->is_eisa)	/* EISA devices have already requested IO */		if (!request_region( dev->base_addr, 0x10, TLanSignature )) {			printk(KERN_ERR "TLAN: %s: IO port region 0x%lx size 0x%x in use.\n",				dev->name,				dev->base_addr,				0x10 );			return -EIO;		}		if ( bbuf ) {		dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )	           * ( sizeof(TLanList) + TLAN_MAX_FRAME_SIZE );	} else {		dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )	           * ( sizeof(TLanList) );	}	priv->dmaStorage = kmalloc(dma_size, GFP_KERNEL | GFP_DMA);	if ( priv->dmaStorage == NULL ) {		printk(KERN_ERR "TLAN:  Could not allocate lists and buffers for %s.\n",			dev->name );		release_region( dev->base_addr, 0x10 );		return -ENOMEM;	}	memset( priv->dmaStorage, 0, dma_size );	priv->rxList = (TLanList *) 		       ( ( ( (u32) priv->dmaStorage ) + 7 ) & 0xFFFFFFF8 );	priv->txList = priv->rxList + TLAN_NUM_RX_LISTS;	if ( bbuf ) {		priv->rxBuffer = (u8 *) ( priv->txList + TLAN_NUM_TX_LISTS );		priv->txBuffer = priv->rxBuffer				 + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE );	}	err = 0;	for ( i = 0;  i < 6 ; i++ )		err |= TLan_EeReadByte( dev,					(u8) priv->adapter->addrOfs + i,					(u8 *) &dev->dev_addr[i] );	if ( err ) {		printk(KERN_ERR "TLAN: %s: Error reading MAC from eeprom: %d\n",			dev->name,			err );	}	dev->addr_len = 6;		/* Device methods */	dev->open = &TLan_Open;	dev->hard_start_xmit = &TLan_StartTx;	dev->stop = &TLan_Close;	dev->get_stats = &TLan_GetStats;	dev->set_multicast_list = &TLan_SetMulticastList;	dev->do_ioctl = &TLan_ioctl;	dev->tx_timeout = &TLan_tx_timeout;	dev->watchdog_timeo = TX_TIMEOUT;	return 0;} /* TLan_Init */	/***************************************************************	 *	TLan_Open	 *	 *	Returns:	 *		0 on success, error code otherwise.	 *	Parms:	 *		dev	Structure of device to be opened.	 *	 *	This routine puts the driver and TLAN adapter in a	 *	state where it is ready to send and receive packets.	 *	It allocates the IRQ, resets and brings the adapter	 *	out of reset, and allows interrupts.  It also delays	 *	the startup for autonegotiation or sends a Rx GO	 *	command to the adapter, as appropriate.	 *	 **************************************************************/static int TLan_Open( struct net_device *dev ){	TLanPrivateInfo	*priv = dev->priv;	int		err;		priv->tlanRev = TLan_DioRead8( dev->base_addr, TLAN_DEF_REVISION );	err = request_irq( dev->irq, TLan_HandleInterrupt, SA_SHIRQ, TLanSignature, dev );		if ( err ) {		printk(KERN_ERR "TLAN:  Cannot open %s because IRQ %d is already in use.\n", dev->name, dev->irq );		return err;	}		init_timer(&priv->timer);	netif_start_queue(dev);		/* NOTE: It might not be necessary to read the stats before a			 reset if you don't care what the values are.	*/	TLan_ResetLists( dev );	TLan_ReadAndClearStats( dev, TLAN_IGNORE );	TLan_ResetAdapter( dev );	TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Opened.  TLAN Chip Rev: %x\n", dev->name, priv->tlanRev );	return 0;} /* TLan_Open */

⌨️ 快捷键说明

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