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

📄 3c523.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 3 页
字号:
		elmc_attn586();	/* ack inter. */		if (stat & STAT_CX) {			/* command with I-bit set complete */			elmc_xmt_int(dev);		}		if (stat & STAT_FR) {			/* received a frame */			elmc_rcv_int(dev);		}#ifndef NO_NOPCOMMANDS		if (stat & STAT_CNA) {			/* CU went 'not ready' */			if (netif_running(dev)) {				printk(KERN_WARNING "%s: oops! CU has left active state. stat: %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);			}		}#endif		if (stat & STAT_RNR) {			/* RU went 'not ready' */			if (p->scb->status & RU_SUSPEND) {				/* special case: RU_SUSPEND */				WAIT_4_SCB_CMD();				p->scb->cmd = RUC_RESUME;				elmc_attn586();			} else {				printk(KERN_WARNING "%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);				elmc_rnr_int(dev);			}		}		WAIT_4_SCB_CMD();	/* wait for ack. (elmc_xmt_int can be faster than ack!!) */		if (p->scb->cmd) {	/* timed out? */			break;		}	}}/******************************************************* * receive-interrupt */static void elmc_rcv_int(struct net_device *dev){	int status;	unsigned short totlen;	struct sk_buff *skb;	struct rbd_struct *rbd;	struct priv *p = (struct priv *) dev->priv;	for (; (status = p->rfd_top->status) & STAT_COMPL;) {		rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);		if (status & STAT_OK) {		/* frame received without error? */			if ((totlen = rbd->status) & RBD_LAST) {	/* the first and the last buffer? */				totlen &= RBD_MASK;	/* length of this frame */				rbd->status = 0;				skb = (struct sk_buff *) dev_alloc_skb(totlen + 2);				if (skb != NULL) {					skb->dev = dev;					skb_reserve(skb, 2);	/* 16 byte alignment */					skb_put(skb,totlen);					eth_copy_and_sum(skb, (char *) p->base+(unsigned long) rbd->buffer,totlen,0);					skb->protocol = eth_type_trans(skb, dev);					netif_rx(skb);					dev->last_rx = jiffies;					p->stats.rx_packets++;					p->stats.rx_bytes += totlen;				} else {					p->stats.rx_dropped++;				}			} else {				printk(KERN_WARNING "%s: received oversized frame.\n", dev->name);				p->stats.rx_dropped++;			}		} else {	/* frame !(ok), only with 'save-bad-frames' */			printk(KERN_WARNING "%s: oops! rfd-error-status: %04x\n", dev->name, status);			p->stats.rx_errors++;		}		p->rfd_top->status = 0;		p->rfd_top->last = RFD_SUSP;		p->rfd_last->last = 0;	/* delete RU_SUSP  */		p->rfd_last = p->rfd_top;		p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next);	/* step to next RFD */	}}/********************************************************** * handle 'Receiver went not ready'. */static void elmc_rnr_int(struct net_device *dev){	struct priv *p = (struct priv *) dev->priv;	p->stats.rx_errors++;	WAIT_4_SCB_CMD();	/* wait for the last cmd */	p->scb->cmd = RUC_ABORT;	/* usually the RU is in the 'no resource'-state .. abort it now. */	elmc_attn586();	WAIT_4_SCB_CMD();	/* wait for accept cmd. */	alloc_rfa(dev, (char *) p->rfd_first);	startrecv586(dev);	/* restart RU */	printk(KERN_WARNING "%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status);}/********************************************************** * handle xmit - interrupt */static void elmc_xmt_int(struct net_device *dev){	int status;	struct priv *p = (struct priv *) dev->priv;	status = p->xmit_cmds[p->xmit_last]->cmd_status;	if (!(status & STAT_COMPL)) {		printk(KERN_WARNING "%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(KERN_WARNING "%s: late collision detected.\n", dev->name);			p->stats.collisions++;		} else if (status & TCMD_NOCARRIER) {			p->stats.tx_carrier_errors++;			printk(KERN_WARNING "%s: no carrier detected.\n", dev->name);		} else if (status & TCMD_LOSTCTS) {			printk(KERN_WARNING "%s: loss of CTS detected.\n", dev->name);		} else if (status & TCMD_UNDERRUN) {			p->stats.tx_fifo_errors++;			printk(KERN_WARNING "%s: DMA underrun detected.\n", dev->name);		} else if (status & TCMD_MAXCOLL) {			printk(KERN_WARNING "%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	netif_wake_queue(dev);}/*********************************************************** * (re)start the receiver */static void startrecv586(struct net_device *dev){	struct priv *p = (struct priv *) dev->priv;	p->scb->rfa_offset = make16(p->rfd_first);	p->scb->cmd = RUC_START;	elmc_attn586();		/* start cmd. */	WAIT_4_SCB_CMD();	/* wait for accept cmd. (no timeout!!) */}/****************************************************** * timeout */ static void elmc_timeout(struct net_device *dev){	struct priv *p = (struct priv *) dev->priv;	/* COMMAND-UNIT active? */	if (p->scb->status & CU_ACTIVE) {#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_ABORT;		elmc_attn586();		WAIT_4_SCB_CMD();		p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);		p->scb->cmd = CUC_START;		elmc_attn586();		WAIT_4_SCB_CMD();		netif_wake_queue(dev);	} else {#ifdef DEBUG		printk("%s: xmitter timed out, try to restart! stat: %04x\n", dev->name, p->scb->status);		printk("%s: command-stats: %04x %04x\n", dev->name, p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status);#endif		elmc_close(dev);		elmc_open(dev);	}} /****************************************************** * send frame */static int elmc_send_packet(struct sk_buff *skb, struct net_device *dev){	int len;	int i;#ifndef NO_NOPCOMMANDS	int next_nop;#endif	struct priv *p = (struct priv *) dev->priv;	netif_stop_queue(dev);	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	p->xmit_buffs[0]->size = TBD_LAST | len;	for (i = 0; i < 16; i++) {		p->scb->cbl_offset = make16(p->xmit_cmds[0]);		p->scb->cmd = CUC_START;		p->xmit_cmds[0]->cmd_status = 0;			elmc_attn586();		dev->trans_start = jiffies;		if (!i) {			dev_kfree_skb(skb);		}		WAIT_4_SCB_CMD();		if ((p->scb->status & CU_ACTIVE)) {	/* test it, because CU sometimes doesn't start immediately */			break;		}		if (p->xmit_cmds[0]->cmd_status) {			break;		}		if (i == 15) {			printk(KERN_WARNING "%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;	p->xmit_cmds[p->xmit_count]->cmd_link = 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;	if (p->xmit_count != p->xmit_last)		netif_wake_queue(dev);	dev_kfree_skb(skb);#endif	return 0;}/******************************************* * Someone wanna have the statistics */static struct net_device_stats *elmc_get_stats(struct net_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 -= crc;	aln = p->scb->aln_errs;	p->scb->aln_errs -= aln;	rsc = p->scb->rsc_errs;	p->scb->rsc_errs -= rsc;	ovrn = p->scb->ovrn_errs;	p->scb->ovrn_errs -= ovrn;	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 .. */#ifdef ELMC_MULTICASTstatic void set_multicast_list(struct net_device *dev){	if (!dev->start) {		/* without a running interface, promiscuous doesn't work */		return;	}	dev->start = 0;	alloc586(dev);	init586(dev);	startrecv586(dev);	dev->start = 1;}#endif/** * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls * @dev: network interface on which out-of-band action is to be performed * @useraddr: userspace address to which data is to be read and returned * * Process the various commands of the SIOCETHTOOL interface. */static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr){	u32 ethcmd;	/* dev_ioctl() in ../../net/core/dev.c has already checked	   capable(CAP_NET_ADMIN), so don't bother with that here.  */	if (get_user(ethcmd, (u32 *)useraddr))		return -EFAULT;	switch (ethcmd) {	case ETHTOOL_GDRVINFO: {		struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };		strcpy (info.driver, DRV_NAME);		strcpy (info.version, DRV_VERSION);		sprintf(info.bus_info, "MCA 0x%lx", dev->base_addr);		if (copy_to_user (useraddr, &info, sizeof (info)))			return -EFAULT;		return 0;	}	default:		break;	}	return -EOPNOTSUPP;}/** * netdev_ioctl: Handle network interface ioctls * @dev: network interface on which out-of-band action is to be performed * @rq: user request data * @cmd: command issued by user * * Process the various out-of-band ioctls passed to this driver. */static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd){	int rc = 0;	switch (cmd) {	case SIOCETHTOOL:		rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);		break;	default:		rc = -EOPNOTSUPP;		break;	}	return rc;} /*************************************************************************/#ifdef MODULE/* Increase if needed ;) */#define MAX_3C523_CARDS 4static struct net_device dev_elmc[MAX_3C523_CARDS];static int irq[MAX_3C523_CARDS];static int io[MAX_3C523_CARDS];MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_3C523_CARDS) "i");MODULE_PARM(io, "1-" __MODULE_STRING(MAX_3C523_CARDS) "i");MODULE_PARM_DESC(io, "EtherLink/MC I/O base address(es)");MODULE_PARM_DESC(irq, "EtherLink/MC IRQ number(s)");int init_module(void){	int this_dev,found = 0;	/* Loop until we either can't find any more cards, or we have MAX_3C523_CARDS */		for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) 		{		struct net_device *dev = &dev_elmc[this_dev];		dev->irq=irq[this_dev];		dev->base_addr=io[this_dev];		dev->init=elmc_probe;		if(register_netdev(dev)!=0) {			if(io[this_dev]==0) break;			printk(KERN_WARNING "3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);		} else found++;	}	if(found==0) {		if(io[0]==0) printk(KERN_NOTICE "3c523.c: No 3c523 cards found\n");		return -ENXIO;	} else return 0;}void cleanup_module(void){	int this_dev;	for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {		struct net_device *dev = &dev_elmc[this_dev];		if(dev->priv) {			/* shutdown interrupts on the card */			elmc_id_reset586();			if (dev->irq != 0) {				/* this should be done by close, but if we failed to				   initialize properly something may have gotten hosed. */				free_irq(dev->irq, dev);				dev->irq = 0;			}			if (dev->base_addr != 0) {				release_region(dev->base_addr, ELMC_IO_EXTENT);				dev->base_addr = 0;			}			irq[this_dev] = 0;			io[this_dev] = 0;			unregister_netdev(dev);			mca_set_adapter_procfn(((struct priv *) (dev->priv))->slot,			       NULL, NULL);			kfree(dev->priv);			dev->priv = NULL;		}	}}#endif				/* MODULE */

⌨️ 快捷键说明

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