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

📄 ibmtr.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/* ibmtr.c:  A shared-memory IBM Token Ring 16/4 driver for linux * *	Written 1993 by Mark Swanson and Peter De Schrijver. *	This software may be used and distributed according to the terms *	of the GNU Public License, incorporated herein by reference. * *	This device driver should work with Any IBM Token Ring Card that does *	not use DMA. * *	I used Donald Becker's (becker@cesdis.gsfc.nasa.gov) device driver work *	as a base for most of my initial work. * *	Changes by Peter De Schrijver (Peter.Deschrijver@linux.cc.kuleuven.ac.be) : * *	+ changed name to ibmtr.c in anticipation of other tr boards. *	+ changed reset code and adapter open code. *	+ added SAP open code. *	+ a first attempt to write interrupt, transmit and receive routines. * *	Changes by David W. Morris (dwm@shell.portal.com) : *	941003 dwm: - Restructure tok_probe for multiple adapters, devices. *	+ Add comments, misc reorg for clarity. *	+ Flatten interrupt handler levels. * *	Changes by Farzad Farid (farzy@zen.via.ecp.fr) *	and Pascal Andre (andre@chimay.via.ecp.fr) (March 9 1995) : *	+ multi ring support clean up. *	+ RFC1042 compliance enhanced. * *	Changes by Pascal Andre (andre@chimay.via.ecp.fr) (September 7 1995) : *	+ bug correction in tr_tx *	+ removed redundant information display *	+ some code reworking * *	Changes by Michel Lespinasse (walken@via.ecp.fr), *	Yann Doussot (doussot@via.ecp.fr) and Pascal Andre (andre@via.ecp.fr) *	(February 18, 1996) : *	+ modified shared memory and mmio access port the driver to *	  alpha platform (structure access -> readb/writeb) * *	Changes by Steve Kipisz (bungy@ibm.net or kipisz@vnet.ibm.com) *	(January 18 1996): *	+ swapped WWOR and WWCR in ibmtr.h *	+ moved some init code from tok_probe into trdev_init.  The *	  PCMCIA code can call trdev_init to complete initializing *	  the driver. *	+ added -DPCMCIA to support PCMCIA *	+ detecting PCMCIA Card Removal in interrupt handler.  If *	  ISRP is FF, then a PCMCIA card has been removed * *	Changes by Paul Norton (pnorton@cts.com) : *	+ restructured the READ.LOG logic to prevent the transmit SRB *	  from being rudely overwritten before the transmit cycle is *	  complete. (August 15 1996) *	+ completed multiple adapter support. (November 20 1996) *	+ implemented csum_partial_copy in tr_rx and increased receive  *        buffer size and count. Minor fixes. (March 15, 1997) * *	Changes by Christopher Turcksin <wabbit@rtfc.demon.co.uk> *	+ Now compiles ok as a module again. * *	Changes by Paul Norton (pnorton@ieee.org) : *      + moved the header manipulation code in tr_tx and tr_rx to *        net/802/tr.c. (July 12 1997) *      + add retry and timeout on open if cable disconnected. (May 5 1998) *      + lifted 2000 byte mtu limit. now depends on shared-RAM size. *        May 25 1998) *      + can't allocate 2k recv buff at 8k shared-RAM. (20 October 1998) * *      Changes by Joel Sloan (jjs@c-me.com) : *      + disable verbose debug messages by default - to enable verbose *	  debugging, edit the IBMTR_DEBUG_MESSAGES define below  * *	Changes by Tim Hockin (thockin@isunix.it.ilstu.edu) : *	+ added spinlocks for SMP sanity (10 March 1999) *//* change the define of IBMTR_DEBUG_MESSAGES to a nonzero value in the event that chatty debug messages are desired - jjs 12/30/98 */#define IBMTR_DEBUG_MESSAGES 0#ifdef PCMCIA#define MODULE#endif#include <linux/module.h>#ifdef PCMCIA#undef MODULE#endif#define NO_AUTODETECT 1#undef NO_AUTODETECT#undef ENABLE_PAGING#define FALSE 0#define TRUE (!FALSE)/* changes the output format of driver initialisation */#define TR_NEWFORMAT	1#define TR_VERBOSE	0/* some 95 OS send many non UI frame; this allow removing the warning */#define TR_FILTERNONUI	1/* version and credits */static char *version ="ibmtr.c: v1.3.57   8/ 7/94 Peter De Schrijver and Mark Swanson\n""         v2.1.125 10/20/98 Paul Norton <pnorton@ieee.org>\n""         v2.2.0   12/30/98 Joel Sloan <jjs@c-me.com>\n";static char pcchannelid[] = {	0x05, 0x00, 0x04, 0x09,	0x04, 0x03, 0x04, 0x0f,	0x03, 0x06, 0x03, 0x01,	0x03, 0x01, 0x03, 0x00,	0x03, 0x09, 0x03, 0x09,	0x03, 0x00, 0x02, 0x00};static char mcchannelid[] = {	0x04, 0x0d, 0x04, 0x01,	0x05, 0x02, 0x05, 0x03,	0x03, 0x06, 0x03, 0x03,	0x05, 0x08, 0x03, 0x04,	0x03, 0x05, 0x03, 0x01,	0x03, 0x08, 0x02, 0x00};#include <linux/kernel.h>#include <linux/sched.h>#include <linux/errno.h>#include <linux/sched.h>#include <linux/timer.h>#include <linux/in.h>#include <linux/ioport.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/skbuff.h>#include <linux/interrupt.h>#include <linux/delay.h>#include <linux/netdevice.h>#include <linux/trdevice.h>#include <linux/stddef.h>#include <linux/init.h>#include <net/checksum.h>#include <asm/io.h>#include <asm/spinlock.h>#include <asm/system.h>#include <asm/bitops.h>#include "ibmtr.h"#define DPRINTK(format, args...) printk("%s: " format, dev->name , ## args)#define DPRINTD(format, args...) DummyCall("%s: " format, dev->name , ## args)#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))#if TR_NEWFORMAT/* this allows displaying full adapter information */const char *channel_def[] __initdata = { 	"ISA", "MCA", "ISA P&P" };__initfunc(char *adapter_def(char type)){	switch (type) 	{	      case 0xF : return "PC Adapter | PC Adapter II | Adapter/A";	      case 0xE : return "16/4 Adapter | 16/4 Adapter/A (long)";	      case 0xD : return "16/4 Adapter/A (short) | 16/4 ISA-16 Adapter";	      case 0xC : return "Auto 16/4 Adapter";	      default  : return "adapter (unknown type)";	};};#endif#if !TR_NEWFORMATunsigned char ibmtr_debug_trace=1;  /*  Patch or otherwise alter to                                         control tokenring tracing.  */#elseunsigned char ibmtr_debug_trace=0;#endif#define TRC_INIT 0x01              /*  Trace initialization & PROBEs */#define TRC_INITV 0x02             /*  verbose init trace points     */int		ibmtr_probe(struct device *dev);static int	ibmtr_probe1(struct device *dev, int ioaddr);static unsigned char	get_sram_size(struct tok_info *adapt_info);static int	tok_init_card(struct device *dev);void		tok_interrupt(int irq, void *dev_id, struct pt_regs *regs);static int	trdev_init(struct device *dev);static void 	initial_tok_int(struct device *dev);static void 	open_sap(unsigned char type,struct device *dev);void		tok_open_adapter(unsigned long dev_addr);static		void tr_rx(struct device *dev);static		void tr_tx(struct device *dev);static int	tok_open(struct device *dev);static int	tok_close(struct device *dev);static int	tok_send_packet(struct sk_buff *skb, struct device *dev);static struct net_device_stats * tok_get_stats(struct device *dev);void		ibmtr_readlog(struct device *dev);void		ibmtr_reset_timer(struct timer_list *tmr, struct device *dev);int             ibmtr_change_mtu(struct device *dev, int mtu);static unsigned int ibmtr_portlist[] __initdata = {	0xa20, 0xa24, 0};static __u32 ibmtr_mem_base = 0xd0000;__initfunc(static void PrtChanID(char *pcid, short stride) ){	short i, j;	for (i=0, j=0; i<24; i++, j+=stride)		printk("%1x", ((int) pcid[j]) & 0x0f);	printk("\n");}__initfunc(static void HWPrtChanID (__u32 pcid, short stride)){	short i, j;	for (i=0, j=0; i<24; i++, j+=stride)		printk("%1x", ((int)readb(pcid + j)) & 0x0f);	printk("\n");}/* *	ibmtr_probe():  Routine specified in the network device structure *	to probe for an IBM Token Ring Adapter.  Routine outline: *	I.    Interrogate hardware to determine if an adapter exists *	      and what the speeds and feeds are *	II.   Setup data structures to control execution based upon *	      adapter characteristics. *	III.  Initialize adapter operation * *	We expect ibmtr_probe to be called once for each device entry *	which references it. */ __initfunc(int ibmtr_probe(struct device *dev)){        int i;        int base_addr = dev ? dev->base_addr : 0;        if (base_addr > 0x1ff)         {         	/*        	 *	Check a single specified location.  		 */ 		 	        if (ibmtr_probe1(dev, base_addr)) 	        {#ifndef MODULE		       tr_freedev(dev);#endif		       return -ENODEV;		} else		       return 0;	}        else if (base_addr != 0)   /* Don't probe at all. */	        return -ENXIO;	for (i = 0; ibmtr_portlist[i]; i++) 	{	        int ioaddr = ibmtr_portlist[i];		if (check_region(ioaddr, IBMTR_IO_EXTENT))		        continue;                if (ibmtr_probe1(dev, ioaddr)) {#ifndef MODULE		        tr_freedev(dev);#endif		} else			return 0;        }        return -ENODEV;}__initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr)){	unsigned char segment=0, intr=0, irq=0, i=0, j=0, cardpresent=NOTOK,temp=0;	__u32 t_mmio=0;	struct tok_info *ti=0;	__u32 cd_chanid;	unsigned char *tchanid, ctemp;	unsigned long timeout;#ifndef MODULE	dev = init_trdev(dev,0);#endif	/*	Query the adapter PIO base port which will return	 *	indication of where MMIO was placed. We also have a	 *	coded interrupt number.	 */       	segment = inb(PIOaddr);		/*	 *	Out of range values so we'll assume non-existent IO device 	 */	 	if (segment < 0x40 || segment > 0xe0)                return -ENODEV;	/*	 *	Compute the linear base address of the MMIO area	 *	as LINUX doesn't care about segments	 */	t_mmio=(((__u32)(segment & 0xfc) << 11) + 0x80000);	intr = segment & 0x03;   /* low bits is coded interrupt # */	if (ibmtr_debug_trace & TRC_INIT)		DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %08X intr: %d\n",                         PIOaddr, (int)segment, t_mmio, (int)intr);	/*	 *	Now we will compare expected 'channelid' strings with	 *	what we is there to learn of ISA/MCA or not TR card	 */	 	cd_chanid = (CHANNEL_ID + t_mmio);  /* for efficiency */	tchanid=pcchannelid;	cardpresent=TR_ISA;  /* try ISA */	/*	 *	Suboptimize knowing first byte different	 */	ctemp = readb(cd_chanid) & 0x0f;	if (ctemp != *tchanid) { /* NOT ISA card, try MCA */		tchanid=mcchannelid;		cardpresent=TR_MCA;		if (ctemp != *tchanid)  /* Neither ISA nor MCA */			cardpresent=NOTOK;	}	if (cardpresent != NOTOK) 	{		/* 		 *	Know presumed type, try rest of ID 		 */		for (i=2,j=1; i<=46; i=i+2,j++) 		{			if ((readb(cd_chanid+i) & 0x0f) != tchanid[j]) {				cardpresent=NOTOK;   /* match failed, not TR card */				break;			}		}	}	/* 	 *	If we have an ISA board check for the ISA P&P version,	 *	as it has different IRQ settings 	 */	if (cardpresent == TR_ISA && (readb(AIPFID + t_mmio)==0x0e))	        cardpresent=TR_ISAPNP;	if (cardpresent == NOTOK) { /* "channel_id" did not match, report */		if (ibmtr_debug_trace & TRC_INIT) {			DPRINTK("Channel ID string not found for PIOaddr: %4hx\n", PIOaddr);			DPRINTK("Expected for ISA: ");  PrtChanID(pcchannelid,1);			DPRINTK("           found: ");  HWPrtChanID(cd_chanid,2);			DPRINTK("Expected for MCA: ");  PrtChanID(mcchannelid,1);		}                return -ENODEV;	}	/* Now, allocate some of the pl0 buffers for this driver.. */	ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL);	if (ti == NULL) 		return -ENOMEM;	memset(ti, 0, sizeof(struct tok_info));	ti->mmio= t_mmio;	ti->readlog_pending = 0;	dev->priv = ti;     /* this seems like the logical use of the                         field ... let's try some empirical tests                         using the token-info structure -- that                         should fit with out future hope of multiple                         adapter support as well /dwm   */	switch (cardpresent) 	{		case TR_ISA:			if (intr==0)				irq=9; /* irq2 really is irq9 */			if (intr==1)				irq=3;			if (intr==2)				irq=6;			if (intr==3)				irq=7;			ti->global_int_enable=GLOBAL_INT_ENABLE+((irq==9) ? 2 : irq);			ti->adapter_int_enable=PIOaddr+ADAPTINTREL;			ti->sram=0;#if !TR_NEWFORMAT			DPRINTK("ti->global_int_enable: %04X\n",ti->global_int_enable);#endif			break;		case TR_MCA:			if (intr==0)				irq=9;			if (intr==1)				irq=3;			if (intr==2)				irq=10;			if (intr==3)				irq=11;			ti->global_int_enable=0;			ti->adapter_int_enable=0;			ti->sram=((__u32)(inb(PIOaddr+ADAPTRESETREL) & 0xfe) << 12);			break;		case TR_ISAPNP:			if (intr==0)				irq=9;			if (intr==1)				irq=3;			if (intr==2)				irq=10;			if (intr==3)				irq=11;			timeout = jiffies + TR_SPIN_INTERVAL;			while(!readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN))

⌨️ 快捷键说明

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