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

📄 tlan.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************** * *  Linux ThunderLAN Driver * *  tlan.c *  by James Banks * *  (C) 1997-1998 Caldera, Inc. *  (C) 1998 James Banks * *  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. * ********************************************************************/#include <linux/module.h>#include "tlan.h"#include <linux/ioport.h>#include <linux/pci.h>#include <linux/etherdevice.h>#include <linux/delay.h>typedef u32 (TLanIntVectorFunc)( struct device *, u16 );#ifdef MODULEstatic	struct device	*TLanDevices = NULL;static	int		TLanDevicesInstalled = 0;static	int		aui = 0;static	int		sa_int = 0;static	int		duplex = 0;static	int		speed = 0;#endifstatic  int		debug = 0;static	int		bbuf = 0;static	u8		*TLanPadBuffer;static	char		TLanSignature[] = "TLAN";static	int		TLanVersionMajor = 1;static	int		TLanVersionMinor = 0;static	TLanAdapterEntry TLanAdapterList[] = {	{ PCI_VENDOR_ID_COMPAQ, 	  PCI_DEVICE_ID_NETELLIGENT_10,	  "Compaq Netelligent 10 T PCI UTP",	  TLAN_ADAPTER_ACTIVITY_LED,	  0x83	},	{ PCI_VENDOR_ID_COMPAQ,	  PCI_DEVICE_ID_NETELLIGENT_10_100,	  "Compaq Netelligent 10/100 TX PCI UTP",	  TLAN_ADAPTER_ACTIVITY_LED,	  0x83	}, 	{ PCI_VENDOR_ID_COMPAQ,	  PCI_DEVICE_ID_NETFLEX_3P_INTEGRATED,	  "Compaq Integrated NetFlex-3/P",	  TLAN_ADAPTER_NONE,	  0x83	}, 	{ PCI_VENDOR_ID_COMPAQ,	  PCI_DEVICE_ID_NETFLEX_3P,	  "Compaq NetFlex-3/P",	  TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY,	  0x83	},	{ PCI_VENDOR_ID_COMPAQ,	  PCI_DEVICE_ID_NETFLEX_3P_BNC,	  "Compaq NetFlex-3/P",	  TLAN_ADAPTER_NONE,	  0x83	},	{ PCI_VENDOR_ID_COMPAQ,	  PCI_DEVICE_ID_NETELLIGENT_10_100_PROLIANT,	  "Compaq Netelligent Integrated 10/100 TX UTP",	  TLAN_ADAPTER_NONE,	  0x83	},	{ PCI_VENDOR_ID_COMPAQ,	  PCI_DEVICE_ID_NETELLIGENT_10_100_DUAL,	  "Compaq Netelligent Dual 10/100 TX PCI UTP",	  TLAN_ADAPTER_NONE,	  0x83	},	{ PCI_VENDOR_ID_COMPAQ,	  PCI_DEVICE_ID_DESKPRO_4000_5233MMX,	  "Compaq Netelligent 10/100 TX Embedded UTP",	  TLAN_ADAPTER_NONE,	  0x83	},	{ PCI_VENDOR_ID_OLICOM,	  PCI_DEVICE_ID_OLICOM_OC2183,	  "Olicom OC-2183/2185",	  TLAN_ADAPTER_USE_INTERN_10,	  0xF8	},	{ PCI_VENDOR_ID_OLICOM,	  PCI_DEVICE_ID_OLICOM_OC2325,	  "Olicom OC-2325",	  TLAN_ADAPTER_UNMANAGED_PHY,	  0xF8	},	{ PCI_VENDOR_ID_OLICOM,	  PCI_DEVICE_ID_OLICOM_OC2326,	  "Olicom OC-2326",	  TLAN_ADAPTER_USE_INTERN_10,	  0xF8	},	{ PCI_VENDOR_ID_COMPAQ,	  PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100,	  "Compaq Netelligent 10/100 TX UTP",	  TLAN_ADAPTER_ACTIVITY_LED,	  0x83	},	{ PCI_VENDOR_ID_COMPAQ,	  PCI_DEVICE_ID_NETELLIGENT_10_T2,	  "Compaq Netelligent 10 T/2 PCI UTP/Coax",	  TLAN_ADAPTER_NONE,	  0x83	},	{ 0,	  0,	  NULL,	  0,	  0	} /* End of List */};static int	TLan_PciProbe( u8 *, u8 *, u8 *, u32 *, u32 * );static int	TLan_Init( struct device * );static int	TLan_Open(struct device *dev);static int	TLan_StartTx(struct sk_buff *, struct device *);static void	TLan_HandleInterrupt(int, void *, struct pt_regs *);static int	TLan_Close(struct device *);static struct	net_device_stats *TLan_GetStats( struct device * );static void	TLan_SetMulticastList( struct device * );static u32	TLan_HandleInvalid( struct device *, u16 );static u32	TLan_HandleTxEOF( struct device *, u16 );static u32	TLan_HandleStatOverflow( struct device *, u16 );static u32	TLan_HandleRxEOF( struct device *, u16 );static u32	TLan_HandleDummy( struct device *, u16 );static u32	TLan_HandleTxEOC( struct device *, u16 );static u32	TLan_HandleStatusCheck( struct device *, u16 );static u32	TLan_HandleRxEOC( struct device *, u16 );static void	TLan_Timer( unsigned long );static void	TLan_ResetLists( struct device * );static void	TLan_FreeLists( struct device * );static void	TLan_PrintDio( u16 );static void	TLan_PrintList( TLanList *, char *, int );static void	TLan_ReadAndClearStats( struct device *, int );static void	TLan_ResetAdapter( struct device * );static void	TLan_FinishReset( struct device * );static void	TLan_SetMac( struct device *, int areg, char *mac );static void	TLan_PhyPrint( struct device * );static void	TLan_PhyDetect( struct device * );static void	TLan_PhyPowerDown( struct device * );static void	TLan_PhyPowerUp( struct device * );static void	TLan_PhyReset( struct device * );static void	TLan_PhyStartLink( struct device * );static void	TLan_PhyFinishAutoNeg( struct device * );/*static int	TLan_PhyNop( struct device * );static int	TLan_PhyInternalCheck( struct device * );static int	TLan_PhyInternalService( struct device * );static int	TLan_PhyDp83840aCheck( struct device * );*/static int	TLan_MiiReadReg( struct device *, u16, u16, u16 * );static void	TLan_MiiSendData( u16, u32, unsigned );static void	TLan_MiiSync( u16 );static void	TLan_MiiWriteReg( struct 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 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 device *dev, u32 ticks, u32 type ){	TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv;	cli();	if ( priv->timer.function != NULL ) {		return;	}	priv->timer.function = &TLan_Timer;	sti();	priv->timer.data = (unsigned long) dev;	priv->timer.expires = jiffies + ticks;	priv->timerSetAt = jiffies;	priv->timerType = type;	add_timer( &priv->timer );} /* TLan_SetTimer *//***********************************************************************************************************************************************************	ThunderLAN Driver Primary Functions	These functions are more or less common to all Linux network drivers.***********************************************************************************************************************************************************/#ifdef MODULE	/***************************************************************	 *	init_module	 *	 *	Returns:	 *		0 if module installed ok, non-zero if not.	 *	Parms:	 *		None	 *	 *	This function begins the setup of the driver creating a	 *	pad buffer, finding all TLAN devices (matching	 *	TLanAdapterList entries), and creating and initializing a	 *	device structure for each adapter.	 *	 **************************************************************/extern int init_module(void){	TLanPrivateInfo	*priv;	struct device	*dev;	size_t		dev_size;	u8		dfn;	u32		index;	int		failed;	int		found;	u32		io_base;	u8		irq;	u8		rev;	printk( "TLAN driver, v%d.%d, (C) 1997-8 Caldera, Inc.\n",		TLanVersionMajor,		TLanVersionMinor	      );	TLanPadBuffer = (u8 *) kmalloc( TLAN_MIN_FRAME_SIZE,					( GFP_KERNEL | GFP_DMA )				      );	if ( TLanPadBuffer == NULL ) {		printk( "TLAN:  Could not allocate memory for pad buffer.\n" );		return -ENOMEM;	}	memset( TLanPadBuffer, 0, TLAN_MIN_FRAME_SIZE );	dev_size = sizeof(struct device) + sizeof(TLanPrivateInfo);	while ( ( found = TLan_PciProbe( &dfn, &irq, &rev, &io_base, &index ) ) ) {		dev = (struct device *) kmalloc( dev_size, GFP_KERNEL );		if ( dev == NULL ) {			printk( "TLAN:  Could not allocate memory for device.\n" );			continue;		}		memset( dev, 0, dev_size );		dev->priv = priv = ( (void *) dev ) + sizeof(struct device);		dev->name = priv->devName;		strcpy( priv->devName, "    " );		dev->base_addr = io_base;		dev->irq = irq;		dev->init = TLan_Init;		priv->adapter =    &TLanAdapterList[index];		priv->adapterRev = rev;		priv->aui =        aui;		if ( ( duplex != 1 ) && ( duplex != 2 ) ) {			duplex = 0;		}		priv->duplex =     duplex;		if ( ( speed != 10 ) && ( speed != 100 ) ) {			speed = 0;		}		priv->speed =      speed;		priv->sa_int =     sa_int;		priv->debug =      debug;		ether_setup( dev );		failed = register_netdev( dev );		if ( failed ) {			printk( "TLAN:  Could not register device.\n" );			kfree( dev );		} else {			priv->nextDevice = TLanDevices;			TLanDevices = dev;			TLanDevicesInstalled++;			printk("TLAN:  %s irq=%2d io=%04x, %s, Rev. %d\n",				dev->name,				(int) dev->irq,				(int) dev->base_addr,				priv->adapter->deviceLabel,				priv->adapterRev );		}	}		/* printk( "TLAN:  Found %d device(s).\n", TLanDevicesInstalled ); */    return ( ( TLanDevicesInstalled >= 0 ) ? 0 : -ENODEV );} /* init_module */	/***************************************************************	 *	cleanup_module	 *	 *	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.	 *	 **************************************************************/extern void cleanup_module(void){	struct device	*dev;	TLanPrivateInfo	*priv;	while ( TLanDevicesInstalled ) {		dev = TLanDevices;		priv = (TLanPrivateInfo *) dev->priv;		if ( priv->dmaStorage ) {			kfree( priv->dmaStorage );		}		release_region( dev->base_addr, 0x10 );		unregister_netdev( dev );		TLanDevices = priv->nextDevice;		kfree( dev );		TLanDevicesInstalled--;	}	kfree( TLanPadBuffer );} /* cleanup_module */#else /* MODULE */	/***************************************************************	 *	tlan_probe	 *	 *	Returns:	 *		0 on success, error code on error	 *	Parms:	 *		dev	device struct to use if adapter is	 *			found.	 *	 *	The name is lower case to fit in with all the rest of	 *	the netcard_probe names.  This function looks for a/	 *	another TLan based adapter, setting it up with the	 *	provided device struct if one is found.	 *	 **************************************************************/	 extern int tlan_probe( struct device *dev ){	TLanPrivateInfo	*priv;	static int	pad_allocated = 0;	int		found;	u8		dfn, irq, rev;	u32		io_base, index;	found = TLan_PciProbe( &dfn, &irq, &rev, &io_base, &index );	if ( ! found ) {		return -ENODEV;	}	dev->priv = kmalloc( sizeof(TLanPrivateInfo), GFP_KERNEL );		if ( dev->priv == NULL ) {		printk( "TLAN:  Could not allocate memory for device.\n" );		return  -ENOMEM;	}	memset( dev->priv, 0, sizeof(TLanPrivateInfo) );	if ( ! pad_allocated ) {		TLanPadBuffer = (u8 *) kmalloc( TLAN_MIN_FRAME_SIZE, //						( GFP_KERNEL | GFP_DMA )						( GFP_KERNEL )					      );		if ( TLanPadBuffer == NULL ) {			printk( "TLAN:  Could not allocate memory for padding.\n" );			kfree( dev->priv );			return -ENOMEM;		} else {			pad_allocated = 1;			memset( TLanPadBuffer, 0, TLAN_MIN_FRAME_SIZE );		}	}	priv = (TLanPrivateInfo *) dev->priv;	dev->name = priv->devName;	strcpy( priv->devName, "    " );	dev = init_etherdev( dev, sizeof(TLanPrivateInfo) );	dev->base_addr = io_base;	dev->irq = irq;	priv->adapter =    &TLanAdapterList[index];	priv->adapterRev = rev;	priv->aui =        dev->mem_start & 0x01;	priv->duplex =     ( ( dev->mem_start & 0x0C ) == 0x0C ) ? 0 : ( dev->mem_start & 0x0C ) >> 2;

⌨️ 快捷键说明

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