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

📄 ibmtr.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
				if (time_after(jiffies, timeout)) {					DPRINTK("Hardware timeout during initialization.\n");					kfree_s(ti, sizeof(struct tok_info));					return -ENODEV;			        }			ti->sram=((__u32)readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)<<12);			ti->global_int_enable=PIOaddr+ADAPTINTREL;			ti->adapter_int_enable=PIOaddr+ADAPTINTREL;			break;	}	if (ibmtr_debug_trace & TRC_INIT) { /* just report int */		DPRINTK("irq=%d",irq);		if (ibmtr_debug_trace & TRC_INITV) { /* full chat in verbose only */			DPRINTK(", ti->mmio=%08X",ti->mmio);			printk(", segment=%02X",segment);		}		printk(".\n");	}	/* Get hw address of token ring card */#if !TR_NEWFORMAT	DPRINTK("hw address: ");#endif	j=0;	for (i=0; i<0x18; i=i+2) 	{		/* technical reference states to do this */		temp = readb(ti->mmio + AIP + i) & 0x0f;#if !TR_NEWFORMAT		printk("%1X",ti->hw_address[j]=temp);#else		ti->hw_address[j]=temp;#endif		if(j&1)			dev->dev_addr[(j/2)]=ti->hw_address[j]+(ti->hw_address[j-1]<<4);		++j;	}#ifndef TR_NEWFORMAT	printk("\n");#endif	/* get Adapter type:  'F' = Adapter/A, 'E' = 16/4 Adapter II,...*/	ti->adapter_type = readb(ti->mmio + AIPADAPTYPE);	/* get Data Rate:  F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */	ti->data_rate = readb(ti->mmio + AIPDATARATE);	/* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */	ti->token_release = readb(ti->mmio + AIPEARLYTOKEN);	/* How much shared RAM is on adapter ? */	ti->avail_shared_ram = get_sram_size(ti);	/* We need to set or do a bunch of work here based on previous results.. */	/* Support paging?  What sizes?:  F=no, E=16k, D=32k, C=16 & 32k */	ti->shared_ram_paging = readb(ti->mmio + AIPSHRAMPAGE);        /* Available DHB  4Mb size:   F=2048, E=4096, D=4464 */	switch (readb(ti->mmio + AIP4MBDHB)) {	case 0xe : 		ti->dhb_size4mb = 4096;		break; 	case 0xd : 		ti->dhb_size4mb = 4464;		break; 	default  : 		ti->dhb_size4mb = 2048;		break; 	}	/* Available DHB 16Mb size:  F=2048, E=4096, D=8192, C=16384, B=17960 */	switch (readb(ti->mmio + AIP16MBDHB)) {	case 0xe : 		ti->dhb_size16mb = 4096;		break; 	case 0xd : 		ti->dhb_size16mb = 8192;		break; 	case 0xc : 		ti->dhb_size16mb = 16384;		break; 	case 0xb : 		ti->dhb_size16mb = 17960;		break; 	default  : 		ti->dhb_size16mb = 2048;		break; 	}#if !TR_NEWFORMAT	DPRINTK("atype=%x, drate=%x, trel=%x, asram=%dK, srp=%x, "		"dhb(4mb=%x, 16mb=%x)\n",ti->adapter_type,		ti->data_rate, ti->token_release, ti->avail_shared_ram/2,		ti->shared_ram_paging, ti->dhb_size4mb, ti->dhb_size16mb);#endif	/*	We must figure out how much shared memory space this adapter	 *	will occupy so that if there are two adapters we can fit both	 *	in.  Given a choice, we will limit this adapter to 32K.  The	 *	maximum space will will use for two adapters is 64K so if the	 *	adapter we are working on demands 64K (it also doesn't support	 *	paging), then only one adapter can be supported.  	 */	/*	 *	determine how much of total RAM is mapped into PC space 	 */	ti->mapped_ram_size=1<<((((readb(ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)) >>2) & 0x03) + 4);	ti->page_mask=0;	if (ti->shared_ram_paging == 0xf) { /* No paging in adapter */		ti->mapped_ram_size = ti->avail_shared_ram;	} else {#ifdef ENABLE_PAGING		unsigned char pg_size;#endif#if !TR_NEWFORMAT		DPRINTK("shared ram page size: %dK\n",ti->mapped_ram_size/2);#endif#ifdef ENABLE_PAGING	switch(ti->shared_ram_paging) 	{		case 0xf:			break;		case 0xe:			ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;			pg_size=32;   /* 16KB page size */			break;		case 0xd:			ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;			pg_size=64;   /* 32KB page size */			break;		case 0xc:			ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;			ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;			DPRINTK("Dual size shared RAM page (code=0xC), don't support it!\n");			/* nb/dwm: I did this because RRR (3,2) bits are documented as			   R/O and I can't find how to select which page size			   Also, the above conditional statement sequence is invalid			   as page_mask will always be set by the second stmt */			kfree_s(ti, sizeof(struct tok_info));			return -ENODEV;			break;		default:			DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging);			kfree_s(ti, sizeof(struct tok_info));			return -ENODEV;			break;	}	if (ti->page_mask) {		if (pg_size > ti->mapped_ram_size) {			DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n",				pg_size, ti->mapped_ram_size);				ti->page_mask = 0;    /* reset paging */		} else {			ti->mapped_ram_size=ti->avail_shared_ram;			DPRINTK("Shared RAM paging enabled. Page size : %uK\n",				((ti->page_mask^ 0xff)+1)>>2);		}#endif	}	/* finish figuring the shared RAM address */	if (cardpresent==TR_ISA) {		static __u32 ram_bndry_mask[]={0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000};		__u32 new_base, rrr_32, chk_base, rbm;		rrr_32 = ((readb(ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2) & 0x00000003;		rbm = ram_bndry_mask[rrr_32];		new_base = (ibmtr_mem_base + (~rbm)) & rbm; /* up to boundary */		chk_base = new_base + (ti->mapped_ram_size<<9);		if (chk_base > (ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE)) {			DPRINTK("Shared RAM for this adapter (%05x) exceeds driver"				" limit (%05x), adapter not started.\n",				chk_base, ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE);			kfree_s(ti, sizeof(struct tok_info));                        return -ENODEV;		} else {  /* seems cool, record what we have figured out */			ti->sram_base = new_base >> 12;			ibmtr_mem_base = chk_base;		}	}#if !TR_NEWFORMAT	DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2);#endif	if (request_irq (dev->irq = irq, &tok_interrupt,0,"ibmtr", dev) != 0) {		DPRINTK("Could not grab irq %d.  Halting Token Ring driver.\n",irq);		kfree_s(ti, sizeof(struct tok_info));		return -ENODEV;	} /*?? Now, allocate some of the PIO PORTs for this driver.. */	request_region(PIOaddr,IBMTR_IO_EXTENT,"ibmtr");  /* record PIOaddr range								  as busy */#if !TR_NEWFORMAT	DPRINTK("%s",version); /* As we have passed card identification,                                  let the world know we're here! */#else	if (version) {	        printk("%s",version);                version = NULL;        }	DPRINTK("%s %s found\n",		channel_def[cardpresent-1], adapter_def(ti->adapter_type));	DPRINTK("using irq %d, PIOaddr %hx, %dK shared RAM.\n",	        irq, PIOaddr, ti->mapped_ram_size/2);	DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n",		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);#endif	/* Calculate the maximum DHB we can use */	switch (ti->mapped_ram_size) {	case  16 : /* 8KB shared RAM */		ti->dhb_size4mb  = MIN(ti->dhb_size4mb, 2048);		ti->rbuf_len4 = 1032;		ti->rbuf_cnt4 = 2;		ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048);		ti->rbuf_len16 = 1032;		ti->rbuf_cnt16 = 2;		break;	case  32 : /* 16KB shared RAM */		ti->dhb_size4mb  = MIN(ti->dhb_size4mb, 4464);		ti->rbuf_len4 = 520;		ti->rbuf_cnt4 = 9;		ti->dhb_size16mb = MIN(ti->dhb_size16mb, 4096);		ti->rbuf_len16 = 1032; /* 1024 usable */		ti->rbuf_cnt16 = 4;		break;	case  64 : /* 32KB shared RAM */		ti->dhb_size4mb  = MIN(ti->dhb_size4mb, 4464);		ti->rbuf_len4 = 1032;		ti->rbuf_cnt4 = 6;		ti->dhb_size16mb = MIN(ti->dhb_size16mb, 10240);		ti->rbuf_len16 = 1032;		ti->rbuf_cnt16 = 10;		break;	case 127 : /* 63KB shared RAM */		ti->dhb_size4mb  = MIN(ti->dhb_size4mb, 4464);		ti->rbuf_len4 = 1032;		ti->rbuf_cnt4 = 6;		ti->dhb_size16mb = MIN(ti->dhb_size16mb, 16384);		ti->rbuf_len16 = 1032;		ti->rbuf_cnt16 = 16;		break;	case 128 : /* 64KB shared RAM */		ti->dhb_size4mb  = MIN(ti->dhb_size4mb, 4464);		ti->rbuf_len4 = 1032;		ti->rbuf_cnt4 = 6;		ti->dhb_size16mb = MIN(ti->dhb_size16mb, 17960);		ti->rbuf_len16 = 1032;		ti->rbuf_cnt16 = 18;		break;	default  :		ti->dhb_size4mb  = 2048;		ti->rbuf_len4 = 1032;		ti->rbuf_cnt4 = 2;		ti->dhb_size16mb = 2048;		ti->rbuf_len16 = 1032;		ti->rbuf_cnt16 = 2;		break;	}	ti->maxmtu16 = (ti->rbuf_len16*ti->rbuf_cnt16)-((ti->rbuf_cnt16)<<3)-TR_HLEN;	ti->maxmtu4  = (ti->rbuf_len4*ti->rbuf_cnt4)-((ti->rbuf_cnt4)<<3)-TR_HLEN;	DPRINTK("Maximum MTU 16Mbps: %d, 4Mbps: %d\n",		ti->maxmtu16, ti->maxmtu4);	dev->base_addr=PIOaddr; /* set the value for device */	trdev_init(dev);	tok_init_card(dev);	return 0;  /* Return 0 to indicate we have found a Token Ring card. */}/* query the adapter for the size of shared RAM  */__initfunc(static unsigned char get_sram_size(struct tok_info *adapt_info)){	unsigned char avail_sram_code;	static unsigned char size_code[]={ 0,16,32,64,127,128 };	/* Adapter gives	   'F' -- use RRR bits 3,2	   'E' -- 8kb   'D' -- 16kb	   'C' -- 32kb  'A' -- 64KB	   'B' - 64KB less 512 bytes at top	   (WARNING ... must zero top bytes in INIT */	avail_sram_code=0xf-readb(adapt_info->mmio + AIPAVAILSHRAM);	if (avail_sram_code)		return size_code[avail_sram_code];	else  /* for code 'F', must compute size from RRR(3,2) bits */		return 1<<((readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4);}__initfunc(static int trdev_init(struct device *dev)){	struct tok_info *ti=(struct tok_info *)dev->priv;	ti->open_status		= CLOSED;	dev->init		= tok_init_card;	dev->open		= tok_open;	dev->stop		= tok_close;	dev->hard_start_xmit	= tok_send_packet;	dev->get_stats 		= tok_get_stats;	dev->set_multicast_list = NULL;	dev->change_mtu         = ibmtr_change_mtu;#ifndef MODULE	tr_setup(dev);#endif	return 0;}static int tok_open(struct device *dev){	struct tok_info *ti=(struct tok_info *)dev->priv;	/* init the spinlock */	ti->lock = (spinlock_t) SPIN_LOCK_UNLOCKED;	if (ti->open_status==CLOSED) tok_init_card(dev);	if (ti->open_status==IN_PROGRESS) sleep_on(&ti->wait_for_reset);	if (ti->open_status==SUCCESS) {		dev->tbusy=0;		dev->interrupt=0;		dev->start=1;		/* NEED to see smem size *AND* reset high 512 bytes if needed */		MOD_INC_USE_COUNT;		return 0;	} else return -EAGAIN;}static int tok_close(struct device *dev){	struct tok_info *ti=(struct tok_info *) dev->priv;	writeb(DIR_CLOSE_ADAPTER,	       ti->srb + offsetof(struct srb_close_adapter, command));	writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);	ti->open_status=CLOSED;	sleep_on(&ti->wait_for_tok_int);	if (readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)))		DPRINTK("close adapter failed: %02X\n",			(int)readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)));        dev->start = 0;	DPRINTK("Adapter closed.\n");	MOD_DEC_USE_COUNT;	return 0;}void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs){	unsigned char status;	struct tok_info *ti;	struct device *dev;	dev = dev_id;#if TR_VERBOSE	DPRINTK("Int from tok_driver, dev : %p\n",dev);#endif	ti  = (struct tok_info *) dev->priv;	spin_lock(&(ti->lock));      	/* Disable interrupts till processing is finished */	dev->interrupt=1;	writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);	/* Reset interrupt for ISA boards */        if (ti->adapter_int_enable)                outb(0,ti->adapter_int_enable);	else		outb(0,ti->global_int_enable);	switch (ti->do_tok_int) {	      case NOT_FIRST:		/*  Begin the regular interrupt handler HERE inline to avoid		    the extra levels of logic and call depth for the		    original solution.   */		status=readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);#ifdef PCMCIA      		/* Check if the PCMCIA card was pulled. */    		if (status == 0xFF)       		{		          DPRINTK("PCMCIA card removed.\n");			  spin_unlock(&(ti->lock));        		  dev->interrupt = 0;          		  return;       		}    	        /* Check ISRP EVEN too. */      	        if ( readb (ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) == 0xFF)    	        {         		 DPRINTK("PCMCIA card removed.\n");			 spin_unlock(&(ti->lock));         		 dev->interrupt = 0;         		 return;      		 }#endif		if (status & ADAP_CHK_INT) {			int i;			__u32 check_reason;			check_reason=ti->mmio + ntohs(readw(ti->sram + ACA_OFFSET + ACA_RW +WWCR_EVEN));			DPRINTK("Adapter check interrupt\n");

⌨️ 快捷键说明

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