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

📄 tlan.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************* * *  Linux ThunderLAN Driver * *  tlan.c *  by James Banks * *  (C) 1997-1998 Caldera, Inc. *  (C) 1998 James Banks *  (C) 1999, 2000 Torben Mathiasen * *  This software may be used and distributed according to the terms *  of the GNU Public License, incorporated herein by reference. * ** This file is best viewed/edited with columns>=132. * ** Useful (if not required) reading: * *		Texas Instruments, ThunderLAN Programmer's Guide, *			TI Literature Number SPWU013A *			available in PDF format from www.ti.com *		Level One, LXT901 and LXT970 Data Sheets *			available in PDF format from www.level1.com *		National Semiconductor, DP83840A Data Sheet *			available in PDF format from www.national.com *		Microchip Technology, 24C01A/02A/04A Data Sheet *			available in PDF format from www.microchip.com * * Change History * *	Tigran Aivazian <tigran@sco.com>:	TLan_PciProbe() now uses *						new PCI BIOS interface. *	Alan Cox	<alan@redhat.com>:	Fixed the out of memory *						handling. *       *	Torben Mathiasen <torben.mathiasen@compaq.com> New Maintainer! * *	v1.1 Dec 20, 1999    - Removed linux version checking *			       Patch from Tigran Aivazian.  *			     - v1.1 includes Alan's SMP updates. *			     - We still have problems on SMP though, *			       but I'm looking into that.  *			 *	v1.2 Jan 02, 2000    - Hopefully fixed the SMP deadlock. *			     - Removed dependency of HZ being 100. *			     - We now allow higher priority timers to  *			       overwrite timers like TLAN_TIMER_ACTIVITY *			       Patch from John Cagle <john.cagle@compaq.com>. *			     - Fixed a few compiler warnings. * *	v1.3 Feb 04, 2000    - Fixed the remaining HZ issues. *			     - Removed call to pci_present().  *			     - Removed SA_INTERRUPT flag from irq handler. *			     - Added __init and __initdata to reduce resisdent  *			       code size. *			     - Driver now uses module_init/module_exit. *			     - Rewrote init_module and tlan_probe to *			       share a lot more code. We now use tlan_probe *			       with builtin and module driver. *			     - Driver ported to new net API.  *			     - tlan.txt has been reworked to reflect current  *			       driver (almost) *			     - Other minor stuff * *	v1.4 Feb 10, 2000    - Updated with more changes required after Dave's *	                       network cleanup in 2.3.43pre7 (Tigran & myself) *	                     - Minor stuff. * *	v1.5 March 22, 2000  - Fixed another timer bug that would hang the driver *			       if no cable/link were present. *			     - Cosmetic changes. *			     - TODO: Port completely to new PCI/DMA API *			     	     Auto-Neg fallback. * * 	v1.6 April 04, 2000  - Fixed driver support for kernel-parameters. Haven't * 			       tested it though, as the kernel support is currently  * 			       broken (2.3.99p4p3). * 			     - Updated tlan.txt accordingly. * 			     - Adjusted minimum/maximum frame length. * 			     - There is now a TLAN website up at  * 			       http://tlan.kernel.dk * * 	v1.7 April 07, 2000  - Started to implement custom ioctls. Driver now * 			       reports PHY information when used with Donald * 			       Beckers userspace MII diagnostics utility. * * 	v1.8 April 23, 2000  - Fixed support for forced speed/duplex settings. * 			     - Added link information to Auto-Neg and forced * 			       modes. When NIC operates with auto-neg the driver * 			       will report Link speed & duplex modes as well as * 			       link partner abilities. When forced link is used, * 			       the driver will report status of the established * 			       link. * 			       Please read tlan.txt for additional information.  * 			     - Removed call to check_region(), and used  * 			       return value of request_region() instead. *	 *	v1.8a May 28, 2000   - Minor updates. * *	v1.9 July 25, 2000   - Fixed a few remaining Full-Duplex issues. *	                     - Updated with timer fixes from Andrew Morton. *	                     - Fixed module race in TLan_Open. *	                     - Added routine to monitor PHY status. *	                     - Added activity led support for Proliant devices. * *	v1.10 Aug 30, 2000   - Added support for EISA based tlan controllers  *			       like the Compaq NetFlex3/E.  *			     - Rewrote tlan_probe to better handle multiple *			       bus probes. Probing and device setup is now *			       done through TLan_Probe and TLan_init_one. Actual *			       hardware probe is done with kernel API and  *			       TLan_EisaProbe. *			     - Adjusted debug information for probing. *			     - Fixed bug that would cause general debug information  *			       to be printed after driver removal.  *			     - Added transmit timeout handling. *			     - Fixed OOM return values in tlan_probe.  *			     - Fixed possible mem leak in tlan_exit  *			       (now tlan_remove_one). *			     - Fixed timer bug in TLan_phyMonitor. *			     - This driver version is alpha quality, please *			       send me any bug issues you may encounter. * *	v1.11 Aug 31, 2000   - Do not try to register irq 0 if no irq line was  *			       set for EISA cards. *			     - Added support for NetFlex3/E with nibble-rate *			       10Base-T PHY. This is untestet as I haven't got *			       one of these cards. *			     - Fixed timer being added twice. *			     - Disabled PhyMonitoring by default as this is *			       work in progress. Define MONITOR to enable it. *			     - Now we don't display link info with PHYs that *			       doesn't support it (level1). *			     - Incresed tx_timeout beacuse of auto-neg. *			     - Adjusted timers for forced speeds. * *	v1.12 Oct 12, 2000   - Minor fixes (memleak, init, etc.) * *******************************************************************************/                                                                                #include <linux/module.h>#include "tlan.h"#include <linux/init.h>#include <linux/ioport.h>#include <linux/pci.h>#include <linux/etherdevice.h>#include <linux/delay.h>#include <linux/spinlock.h>typedef u32 (TLanIntVectorFunc)( struct net_device *, u16 );/* For removing EISA devices */static	struct net_device	*TLan_Eisa_Devices;static	int		TLanDevicesInstalled;/* Force speed, duplex and aui settings */static	int		aui;static	int		duplex; static	int		speed;MODULE_AUTHOR("Maintainer: Torben Mathiasen <torben.mathiasen@compaq.com>");MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");MODULE_PARM(aui, "i");MODULE_PARM(duplex, "i");MODULE_PARM(speed, "i");MODULE_PARM(debug, "i");EXPORT_NO_SYMBOLS;/* Define this to enable Link beat monitoring */#undef MONITOR/* Turn on debugging. See linux/Documentation/networking/tlan.txt for details */static  int		debug;static	int		bbuf;static	u8		*TLanPadBuffer;static	char		TLanSignature[] = "TLAN";static const char *tlan_banner = "ThunderLAN driver v1.12\n";static int tlan_have_pci;static int tlan_have_eisa;const char *media[] = {	"10BaseT-HD ", "10BaseT-FD ","100baseTx-HD ", 	"100baseTx-FD", "100baseT4", 0};int media_map[] = { 0x0020, 0x0040, 0x0080, 0x0100, 0x0200,};static struct board {	const char	*deviceLabel;	u32	   	flags;	u16	   	addrOfs;} board_info[] __devinitdata = {	{ "Compaq Netelligent 10 T PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },	{ "Compaq Netelligent 10/100 TX PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },	{ "Compaq Integrated NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },	{ "Compaq NetFlex-3/P", TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },	{ "Compaq NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },	{ "Compaq Netelligent Integrated 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },	{ "Compaq Netelligent Dual 10/100 TX PCI UTP", TLAN_ADAPTER_NONE, 0x83 },	{ "Compaq Netelligent 10/100 TX Embedded UTP", TLAN_ADAPTER_NONE, 0x83 },	{ "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 },	{ "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xF8 },	{ "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xF8 },	{ "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },	{ "Compaq Netelligent 10 T/2 PCI UTP/Coax", TLAN_ADAPTER_NONE, 0x83 },	{ "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED | 	/* EISA card */	                        TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },		{ "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */};static struct pci_device_id tlan_pci_tbl[] __devinitdata = {	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETFLEX_3P_INTEGRATED,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETFLEX_3P,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETFLEX_3P_BNC,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_PROLIANT,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_DUAL,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 },	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_DESKPRO_4000_5233MMX,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 },	{ PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2183,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },	{ PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2325,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },	{ PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_T2,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },	{ 0,}};MODULE_DEVICE_TABLE(pci, tlan_pci_tbl);		static void	TLan_EisaProbe( void );static void	TLan_Eisa_Cleanup( void );static int      TLan_Init( struct net_device * );static int	TLan_Open( struct net_device *dev );static int	TLan_StartTx( struct sk_buff *, struct net_device *);static void	TLan_HandleInterrupt( int, void *, struct pt_regs *);static int	TLan_Close( struct net_device *);static struct	net_device_stats *TLan_GetStats( struct net_device *);static void	TLan_SetMulticastList( struct net_device *);static int	TLan_ioctl( struct net_device *dev, struct ifreq *rq, int cmd);static int      TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent);static void	TLan_tx_timeout( struct net_device *dev);static int 	tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent);static u32	TLan_HandleInvalid( struct net_device *, u16 );static u32	TLan_HandleTxEOF( struct net_device *, u16 );static u32	TLan_HandleStatOverflow( struct net_device *, u16 );static u32	TLan_HandleRxEOF( struct net_device *, u16 );static u32	TLan_HandleDummy( struct net_device *, u16 );static u32	TLan_HandleTxEOC( struct net_device *, u16 );static u32	TLan_HandleStatusCheck( struct net_device *, u16 );static u32	TLan_HandleRxEOC( struct net_device *, u16 );static void	TLan_Timer( unsigned long );static void	TLan_ResetLists( struct net_device * );static void	TLan_FreeLists( struct net_device * );static void	TLan_PrintDio( u16 );static void	TLan_PrintList( TLanList *, char *, int );static void	TLan_ReadAndClearStats( struct net_device *, int );static void	TLan_ResetAdapter( struct net_device * );static void	TLan_FinishReset( struct net_device * );static void	TLan_SetMac( struct net_device *, int areg, char *mac );static void	TLan_PhyPrint( struct net_device * );static void	TLan_PhyDetect( struct net_device * );static void	TLan_PhyPowerDown( struct net_device * );static void	TLan_PhyPowerUp( struct net_device * );static void	TLan_PhyReset( struct net_device * );static void	TLan_PhyStartLink( struct net_device * );static void	TLan_PhyFinishAutoNeg( struct net_device * );#ifdef MONITORstatic void     TLan_PhyMonitor( struct net_device * );#endif/*static int	TLan_PhyNop( struct net_device * );static int	TLan_PhyInternalCheck( struct net_device * );static int	TLan_PhyInternalService( struct net_device * );static int	TLan_PhyDp83840aCheck( struct net_device * );*/static int	TLan_MiiReadReg( struct net_device *, u16, u16, u16 * );static void	TLan_MiiSendData( u16, u32, unsigned );static void	TLan_MiiSync( u16 );static void	TLan_MiiWriteReg( struct net_device *, u16, u16, u16 );static void	TLan_EeSendStart( u16 );static int	TLan_EeSendByte( u16, u8, int );static void	TLan_EeReceiveByte( u16, u8 *, int );static int	TLan_EeReadByte( struct net_device *, u8, u8 * );static TLanIntVectorFunc *TLanIntVector[TLAN_INT_NUMBER_OF_INTS] = {	TLan_HandleInvalid,	TLan_HandleTxEOF,	TLan_HandleStatOverflow,	TLan_HandleRxEOF,	TLan_HandleDummy,	TLan_HandleTxEOC,	TLan_HandleStatusCheck,	TLan_HandleRxEOC};static inline voidTLan_SetTimer( struct net_device *dev, u32 ticks, u32 type ){	TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv;	unsigned long flags;	spin_lock_irqsave(&priv->lock, flags);	if ( priv->timer.function != NULL &&		priv->timerType != TLAN_TIMER_ACTIVITY ) { 		spin_unlock_irqrestore(&priv->lock, flags);		return;	}	priv->timer.function = &TLan_Timer;	spin_unlock_irqrestore(&priv->lock, flags);	priv->timer.data = (unsigned long) dev;	priv->timerSetAt = jiffies;	priv->timerType = type;	mod_timer(&priv->timer, jiffies + ticks);	} /* TLan_SetTimer *//***********************************************************************************************************************************************************	ThunderLAN Driver Primary Functions	These functions are more or less common to all Linux network drivers.***********************************************************************************************************************************************************/	/***************************************************************	 *	tlan_remove_one	 *	 *	Returns:	 *		Nothing	 *	Parms:	 *		None	 *	 *	Goes through the TLanDevices list and frees the device	 *	structs and memory associated with each device (lists	 *	and buffers).  It also ureserves the IO port regions	 *	associated with this device.	 *	 **************************************************************/static void __devexit tlan_remove_one( struct pci_dev *pdev){	struct net_device *dev = pdev->driver_data;	TLanPrivateInfo	*priv = (TLanPrivateInfo *) dev->priv;		unregister_netdev( dev );	if ( priv->dmaStorage ) {		kfree( priv->dmaStorage );	}	release_region( dev->base_addr, 0x10 );		kfree( dev );		} static struct pci_driver tlan_driver = {	name:		"tlan",	id_table:	tlan_pci_tbl,	probe:		tlan_init_one,	remove:		tlan_remove_one,	};static int __init tlan_probe(void){	static int	pad_allocated = 0;		printk(KERN_INFO "%s", tlan_banner);		TLanPadBuffer = (u8 *) kmalloc(TLAN_MIN_FRAME_SIZE, 					(GFP_KERNEL | GFP_DMA));	if (TLanPadBuffer == NULL) {		printk(KERN_ERR "TLAN: Could not allocate memory for pad buffer.\n");		return -ENOMEM;	}	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_module_init(&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);		return ((TLanDevicesInstalled > 0) ? 0 : -ENODEV);}	static int __devinit tlan_init_one( struct pci_dev *pdev,				    const struct pci_device_id *ent){	return TLan_probe1( pdev, pci_resource_start(pdev, 0), pdev->irq,			0, ent);}/*	***************************************************************	 *	tlan_probe1

⌨️ 快捷键说明

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