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

📄 ni52.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
					}					else						p->stats.rx_dropped++;				}				else				{					int rstat;						 /* free all RBD's until RBD_LAST is set */					totlen = 0;					while(!((rstat=rbd->status) & RBD_LAST))					{						totlen += rstat & RBD_MASK;						if(!rstat)						{							printk("%s: Whoops .. no end mark in RBD list\n",dev->name);							break;						}						rbd->status = 0;						rbd = (struct rbd_struct *) make32(rbd->next);					}					totlen += rstat & RBD_MASK;					rbd->status = 0;					printk("%s: received oversized frame! length: %d\n",dev->name,totlen);					p->stats.rx_dropped++;			 }		}		else /* frame !(ok), only with 'save-bad-frames' */		{			printk("%s: oops! rfd-error-status: %04x\n",dev->name,status);			p->stats.rx_errors++;		}		p->rfd_top->stat_high = 0;		p->rfd_top->last = RFD_SUSP; /* maybe exchange by RFD_LAST */		p->rfd_top->rbd_offset = 0xffff;		p->rfd_last->last = 0;				/* delete RFD_SUSP	*/		p->rfd_last = p->rfd_top;		p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */		p->scb->rfa_offset = make16(p->rfd_top);		if(debuglevel > 0)			printk("%d",cnt++);	}	if(automatic_resume)	{		WAIT_4_SCB_CMD();		p->scb->cmd_ruc = RUC_RESUME;		ni_attn586();		WAIT_4_SCB_CMD_RUC();	}#ifdef WAIT_4_BUSY	{		int i;		for(i=0;i<1024;i++)		{			if(p->rfd_top->status)				break;			DELAY_16();			if(i == 1023)				printk("%s: RU hasn't fetched next RFD (not busy/complete)\n",dev->name);		}	}#endif#if 0	if(!at_least_one)	{		int i;		volatile struct rfd_struct *rfds=p->rfd_top;		volatile struct rbd_struct *rbds;		printk("%s: received a FC intr. without having a frame: %04x %d\n",dev->name,status,old_at_least);		for(i=0;i< (p->num_recv_buffs+4);i++)		{			rbds = (struct rbd_struct *) make32(rfds->rbd_offset);			printk("%04x:%04x ",rfds->status,rbds->status);			rfds = (struct rfd_struct *) make32(rfds->next);		}		printk("\nerrs: %04x %04x stat: %04x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->status);		printk("\nerrs: %04x %04x rus: %02x, cus: %02x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->rus,(int)p->scb->cus);	}	old_at_least = at_least_one;#endif	if(debuglevel > 0)		printk("r");}/********************************************************** * handle 'Receiver went not ready'. */static void ni52_rnr_int(struct device *dev){	struct priv *p = (struct priv *) dev->priv;	p->stats.rx_errors++;	WAIT_4_SCB_CMD();		/* wait for the last cmd, WAIT_4_FULLSTAT?? */	p->scb->cmd_ruc = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */	ni_attn586();	WAIT_4_SCB_CMD_RUC();		/* wait for accept cmd. */	alloc_rfa(dev,(char *)p->rfd_first);/* maybe add a check here, before restarting the RU */	startrecv586(dev); /* restart RU */	printk("%s: Receive-Unit restarted. Status: %04x\n",dev->name,p->scb->rus);}/********************************************************** * handle xmit - interrupt */static void ni52_xmt_int(struct device *dev){	int status;	struct priv *p = (struct priv *) dev->priv;	if(debuglevel > 0)		printk("X");	status = p->xmit_cmds[p->xmit_last]->cmd_status;	if(!(status & STAT_COMPL))		printk("%s: strange .. xmit-int without a 'COMPLETE'\n",dev->name);	if(status & STAT_OK)	{		p->stats.tx_packets++;		p->stats.collisions += (status & TCMD_MAXCOLLMASK);	}	else	{		p->stats.tx_errors++;		if(status & TCMD_LATECOLL) {			printk("%s: late collision detected.\n",dev->name);			p->stats.collisions++;		}		else if(status & TCMD_NOCARRIER) {			p->stats.tx_carrier_errors++;			printk("%s: no carrier detected.\n",dev->name);		}		else if(status & TCMD_LOSTCTS)			printk("%s: loss of CTS detected.\n",dev->name);		else if(status & TCMD_UNDERRUN) {			p->stats.tx_fifo_errors++;			printk("%s: DMA underrun detected.\n",dev->name);		}		else if(status & TCMD_MAXCOLL) {			printk("%s: Max. collisions exceeded.\n",dev->name);			p->stats.collisions += 16;		}	}#if (NUM_XMIT_BUFFS > 1)	if( (++p->xmit_last) == NUM_XMIT_BUFFS)		p->xmit_last = 0;#endif	dev->tbusy = 0;	mark_bh(NET_BH);}/*********************************************************** * (re)start the receiver */static void startrecv586(struct device *dev){	struct priv *p = (struct priv *) dev->priv;	WAIT_4_SCB_CMD();	WAIT_4_SCB_CMD_RUC();	p->scb->rfa_offset = make16(p->rfd_first);	p->scb->cmd_ruc = RUC_START;	ni_attn586();		/* start cmd. */	WAIT_4_SCB_CMD_RUC();	/* wait for accept cmd. (no timeout!!) */}/****************************************************** * send frame */static int ni52_send_packet(struct sk_buff *skb, struct device *dev){	int len,i;#ifndef NO_NOPCOMMANDS	int next_nop;#endif	struct priv *p = (struct priv *) dev->priv;	if(dev->tbusy)	{		int tickssofar = jiffies - dev->trans_start;		if (tickssofar < 5)			return 1;#ifndef NO_NOPCOMMANDS		if(p->scb->cus & CU_ACTIVE) /* COMMAND-UNIT active? */		{			dev->tbusy = 0;#ifdef DEBUG			printk("%s: strange ... timeout with CU active?!?\n",dev->name);			printk("%s: X0: %04x N0: %04x N1: %04x %d\n",dev->name,(int)p->xmit_cmds[0]->cmd_status,(int)p->nop_cmds[0]->cmd_status,(int)p->nop_cmds[1]->cmd_status,(int)p->nop_point);#endif			p->scb->cmd_cuc = CUC_ABORT;			ni_attn586();			WAIT_4_SCB_CMD();			p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);			p->scb->cmd_cuc = CUC_START;			ni_attn586();			WAIT_4_SCB_CMD();			dev->trans_start = jiffies;			return 0;		}		else#endif		{#ifdef DEBUG			printk("%s: xmitter timed out, try to restart! stat: %02x\n",dev->name,p->scb->cus);			printk("%s: command-stats: %04x %04x\n",dev->name,p->xmit_cmds[0]->cmd_status,p->xmit_cmds[1]->cmd_status);			printk("%s: check, whether you set the right interrupt number!\n",dev->name);#endif			ni52_close(dev);			ni52_open(dev);		}		dev->trans_start = jiffies;		return 0;	}	if(skb->len > XMIT_BUFF_SIZE)	{		printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len);		return 0;	}	if (test_and_set_bit(0, (void*)&dev->tbusy)) {		printk("%s: Transmitter access conflict.\n", dev->name);		return 1;	}#if(NUM_XMIT_BUFFS > 1)	else if(test_and_set_bit(0,(void *) &p->lock)) {		printk("%s: Queue was locked\n",dev->name);		return 1;	}#endif	else	{		memcpy((char *)p->xmit_cbuffs[p->xmit_count],(char *)(skb->data),skb->len);		len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;#if (NUM_XMIT_BUFFS == 1)#	ifdef NO_NOPCOMMANDS#ifdef DEBUG		if(p->scb->cus & CU_ACTIVE)		{			printk("%s: Hmmm .. CU is still running and we wanna send a new packet.\n",dev->name);			printk("%s: stat: %04x %04x\n",dev->name,p->scb->cus,p->xmit_cmds[0]->cmd_status);		}#endif		p->xmit_buffs[0]->size = TBD_LAST | len;		for(i=0;i<16;i++)		{			p->xmit_cmds[0]->cmd_status = 0;			WAIT_4_SCB_CMD();			if( (p->scb->cus & CU_STATUS) == CU_SUSPEND)				p->scb->cmd_cuc = CUC_RESUME;			else			{				p->scb->cbl_offset = make16(p->xmit_cmds[0]);				p->scb->cmd_cuc = CUC_START;			}			ni_attn586();			dev->trans_start = jiffies;			if(!i)				dev_kfree_skb(skb);			WAIT_4_SCB_CMD();			if( (p->scb->cus & CU_ACTIVE)) /* test it, because CU sometimes doesn't start immediately */				break;			if(p->xmit_cmds[0]->cmd_status)				break;			if(i==15)				printk("%s: Can't start transmit-command.\n",dev->name);		}#	else		next_nop = (p->nop_point + 1) & 0x1;		p->xmit_buffs[0]->size = TBD_LAST | len;		p->xmit_cmds[0]->cmd_link	 = p->nop_cmds[next_nop]->cmd_link																= make16((p->nop_cmds[next_nop]));		p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;		p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));		dev->trans_start = jiffies;		p->nop_point = next_nop;		dev_kfree_skb(skb);#	endif#else		p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;		if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS )			next_nop = 0;		p->xmit_cmds[p->xmit_count]->cmd_status	= 0;	/* linkpointer of xmit-command already points to next nop cmd */		p->nop_cmds[next_nop]->cmd_link = make16((p->nop_cmds[next_nop]));		p->nop_cmds[next_nop]->cmd_status = 0;		p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));		dev->trans_start = jiffies;		p->xmit_count = next_nop;		{			long flags;			save_flags(flags);			cli();			if(p->xmit_count != p->xmit_last)				dev->tbusy = 0;			p->lock = 0;			restore_flags(flags);		}		dev_kfree_skb(skb);#endif	}	return 0;}/******************************************* * Someone wanna have the statistics */static struct net_device_stats *ni52_get_stats(struct device *dev){	struct priv *p = (struct priv *) dev->priv;	unsigned short crc,aln,rsc,ovrn;	crc = p->scb->crc_errs; /* get error-statistic from the ni82586 */	p->scb->crc_errs = 0;	aln = p->scb->aln_errs;	p->scb->aln_errs = 0;	rsc = p->scb->rsc_errs;	p->scb->rsc_errs = 0;	ovrn = p->scb->ovrn_errs;	p->scb->ovrn_errs = 0;	p->stats.rx_crc_errors += crc;	p->stats.rx_fifo_errors += ovrn;	p->stats.rx_frame_errors += aln;	p->stats.rx_dropped += rsc;	return &p->stats;}/******************************************************** * Set MC list .. */static void set_multicast_list(struct device *dev){	if(!dev->start)	{		printk("%s: Can't apply promiscuous/multicastmode to a not running interface.\n",dev->name);		return;	}	dev->start = 0;	ni_disint();	alloc586(dev);	init586(dev);	startrecv586(dev);	ni_enaint();	dev->start = 1;}#ifdef MODULEstatic char devicename[9] = { 0, };static struct device dev_ni52 = {	devicename,	/* "ni5210": device name inserted by net_init.c */	0, 0, 0, 0,	0x300, 9,	 /* I/O address, IRQ */	0, 0, 0, NULL, ni52_probe };/* set: io,irq,memstart,memend or set it when calling insmod */int irq=9;int io=0x300;long memstart=0; /* e.g 0xd0000 */long memend=0;	 /* e.g 0xd4000 */MODULE_PARM(io, "i");MODULE_PARM(irq, "i");MODULE_PARM(memstart, "l");MODULE_PARM(memend, "l");int init_module(void){	if(io <= 0x0 || !memend || !memstart || irq < 2) {		printk("ni52: Autoprobing not allowed for modules.\nni52: Set symbols 'io' 'irq' 'memstart' and 'memend'\n");		return -ENODEV;	}	dev_ni52.irq = irq;	dev_ni52.base_addr = io;	dev_ni52.mem_end = memend;	dev_ni52.mem_start = memstart;	if (register_netdev(&dev_ni52) != 0)		return -EIO;	return 0;}void cleanup_module(void){	release_region(dev_ni52.base_addr, NI52_TOTAL_SIZE);	unregister_netdev(&dev_ni52);	kfree(dev_ni52.priv);	dev_ni52.priv = NULL;}#endif /* MODULE */#if 0/* * DUMP .. we expect a not running CMD unit and enough space */void ni52_dump(struct device *dev,void *ptr){	struct priv *p = (struct priv *) dev->priv;	struct dump_cmd_struct *dump_cmd = (struct dump_cmd_struct *) ptr;	int i;	p->scb->cmd_cuc = CUC_ABORT;	ni_attn586();	WAIT_4_SCB_CMD();	WAIT_4_SCB_CMD_RUC();	dump_cmd->cmd_status = 0;	dump_cmd->cmd_cmd = CMD_DUMP | CMD_LAST;	dump_cmd->dump_offset = make16((dump_cmd + 1));	dump_cmd->cmd_link = 0xffff;	p->scb->cbl_offset = make16(dump_cmd);	p->scb->cmd_cuc = CUC_START;	ni_attn586();	WAIT_4_STAT_COMPL(dump_cmd);	if( (dump_cmd->cmd_status & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK) )				printk("%s: Can't get dump information.\n",dev->name);	for(i=0;i<170;i++) {		printk("%02x ",(int) ((unsigned char *) (dump_cmd + 1))[i]);		if(i % 24 == 23)			printk("\n");	}	printk("\n");}#endif/* * END: linux/drivers/net/ni52.c */

⌨️ 快捷键说明

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