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

📄 3c509.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 3 页
字号:
			netif_wake_queue (dev);		}		if (status & (AdapterFailure | RxEarly | StatsFull | TxComplete)) {			/* Handle all uncommon interrupts. */			if (status & StatsFull)				/* Empty statistics. */				update_stats(dev);			if (status & RxEarly) {				/* Rx early is unused. */				el3_rx(dev);				outw(AckIntr | RxEarly, ioaddr + EL3_CMD);			}			if (status & TxComplete) {			/* Really Tx error. */				struct el3_private *lp = (struct el3_private *)dev->priv;				short tx_status;				int i = 4;				while (--i>0 && (tx_status = inb(ioaddr + TX_STATUS)) > 0) {					if (tx_status & 0x38) lp->stats.tx_aborted_errors++;					if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD);					if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD);					outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */				}			}			if (status & AdapterFailure) {				/* Adapter failure requires Rx reset and reinit. */				outw(RxReset, ioaddr + EL3_CMD);				/* Set the Rx filter to the current state. */				outw(SetRxFilter | RxStation | RxBroadcast					 | (dev->flags & IFF_ALLMULTI ? RxMulticast : 0)					 | (dev->flags & IFF_PROMISC ? RxProm : 0),					 ioaddr + EL3_CMD);				outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */				outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD);			}		}		if (--i < 0) {			printk("%s: Infinite loop in interrupt, status %4.4x.\n",				   dev->name, status);			/* Clear all interrupts. */			outw(AckIntr | 0xFF, ioaddr + EL3_CMD);			break;		}		/* Acknowledge the IRQ. */		outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); /* Ack IRQ */	}	if (el3_debug > 4) {		printk("%s: exiting interrupt, status %4.4x.\n", dev->name,			   inw(ioaddr + EL3_STATUS));	}	spin_unlock(&lp->lock);	return;}static struct net_device_stats *el3_get_stats(struct net_device *dev){	struct el3_private *lp = (struct el3_private *)dev->priv;	unsigned long flags;	/*	 *	This is fast enough not to bother with disable IRQ	 *	stuff.	 */	 	spin_lock_irqsave(&lp->lock, flags);	update_stats(dev);	spin_unlock_irqrestore(&lp->lock, flags);	return &lp->stats;}/*  Update statistics.  We change to register window 6, so this should be run	single-threaded if the device is active. This is expected to be a rare	operation, and it's simpler for the rest of the driver to assume that	window 1 is always valid rather than use a special window-state variable.	*/static void update_stats(struct net_device *dev){	struct el3_private *lp = (struct el3_private *)dev->priv;	int ioaddr = dev->base_addr;	if (el3_debug > 5)		printk("   Updating the statistics.\n");	/* Turn off statistics updates while reading. */	outw(StatsDisable, ioaddr + EL3_CMD);	/* Switch to the stats window, and read everything. */	EL3WINDOW(6);	lp->stats.tx_carrier_errors 	+= inb(ioaddr + 0);	lp->stats.tx_heartbeat_errors	+= inb(ioaddr + 1);	/* Multiple collisions. */	   inb(ioaddr + 2);	lp->stats.collisions		+= inb(ioaddr + 3);	lp->stats.tx_window_errors	+= inb(ioaddr + 4);	lp->stats.rx_fifo_errors	+= inb(ioaddr + 5);	lp->stats.tx_packets		+= inb(ioaddr + 6);	/* Rx packets	*/		   inb(ioaddr + 7);	/* Tx deferrals */		   inb(ioaddr + 8);	inw(ioaddr + 10);	/* Total Rx and Tx octets. */	inw(ioaddr + 12);	/* Back to window 1, and turn statistics back on. */	EL3WINDOW(1);	outw(StatsEnable, ioaddr + EL3_CMD);	return;}static intel3_rx(struct net_device *dev){	struct el3_private *lp = (struct el3_private *)dev->priv;	int ioaddr = dev->base_addr;	short rx_status;	if (el3_debug > 5)		printk("   In rx_packet(), status %4.4x, rx_status %4.4x.\n",			   inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));	while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {		if (rx_status & 0x4000) { /* Error, update stats. */			short error = rx_status & 0x3800;			outw(RxDiscard, ioaddr + EL3_CMD);			lp->stats.rx_errors++;			switch (error) {			case 0x0000:		lp->stats.rx_over_errors++; break;			case 0x0800:		lp->stats.rx_length_errors++; break;			case 0x1000:		lp->stats.rx_frame_errors++; break;			case 0x1800:		lp->stats.rx_length_errors++; break;			case 0x2000:		lp->stats.rx_frame_errors++; break;			case 0x2800:		lp->stats.rx_crc_errors++; break;			}		} else {			short pkt_len = rx_status & 0x7ff;			struct sk_buff *skb;			skb = dev_alloc_skb(pkt_len+5);			lp->stats.rx_bytes += pkt_len;			if (el3_debug > 4)				printk("Receiving packet size %d status %4.4x.\n",					   pkt_len, rx_status);			if (skb != NULL) {				skb->dev = dev;				skb_reserve(skb, 2);     /* Align IP on 16 byte */				/* 'skb->data' points to the start of sk_buff data area. */#ifdef  __powerpc__				insl_unswapped(ioaddr+RX_FIFO, skb_put(skb,pkt_len),							   (pkt_len + 3) >> 2);#else				insl(ioaddr + RX_FIFO, skb_put(skb,pkt_len),					 (pkt_len + 3) >> 2);#endif				outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */				skb->protocol = eth_type_trans(skb,dev);				netif_rx(skb);				dev->last_rx = jiffies;				lp->stats.rx_packets++;				continue;			}			outw(RxDiscard, ioaddr + EL3_CMD);			lp->stats.rx_dropped++;			if (el3_debug)				printk("%s: Couldn't allocate a sk_buff of size %d.\n",					   dev->name, pkt_len);		}		inw(ioaddr + EL3_STATUS); 				/* Delay. */		while (inw(ioaddr + EL3_STATUS) & 0x1000)			printk(KERN_DEBUG "	Waiting for 3c509 to discard packet, status %x.\n",				   inw(ioaddr + EL3_STATUS) );	}	return 0;}/* *     Set or clear the multicast filter for this adaptor. */static voidset_multicast_list(struct net_device *dev){	unsigned long flags;	struct el3_private *lp = (struct el3_private *)dev->priv;	int ioaddr = dev->base_addr;	if (el3_debug > 1) {		static int old;		if (old != dev->mc_count) {			old = dev->mc_count;			printk("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);		}	}	spin_lock_irqsave(&lp->lock, flags);	if (dev->flags&IFF_PROMISC) {		outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,			 ioaddr + EL3_CMD);	}	else if (dev->mc_count || (dev->flags&IFF_ALLMULTI)) {		outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast, ioaddr + EL3_CMD);	}	else                outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);	spin_unlock_irqrestore(&lp->lock, flags);}static intel3_close(struct net_device *dev){	int ioaddr = dev->base_addr;	if (el3_debug > 2)		printk("%s: Shutting down ethercard.\n", dev->name);	netif_stop_queue(dev);	/* Turn off statistics ASAP.  We update lp->stats below. */	outw(StatsDisable, ioaddr + EL3_CMD);	/* Disable the receiver and transmitter. */	outw(RxDisable, ioaddr + EL3_CMD);	outw(TxDisable, ioaddr + EL3_CMD);	if (dev->if_port == 3)		/* Turn off thinnet power.  Green! */		outw(StopCoax, ioaddr + EL3_CMD);	else if (dev->if_port == 0) {		/* Disable link beat and jabber, if_port may change ere next open(). */		EL3WINDOW(4);		outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);	}	free_irq(dev->irq, dev);	/* Switching back to window 0 disables the IRQ. */	EL3WINDOW(0);	/* But we explicitly zero the IRQ line select anyway. */	outw(0x0f00, ioaddr + WN0_IRQ);	update_stats(dev);	return 0;}/** * 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);		if (copy_to_user (useraddr, &info, sizeof (info)))			return -EFAULT;		return 0;	}	/* get message-level */	case ETHTOOL_GMSGLVL: {		struct ethtool_value edata = {ETHTOOL_GMSGLVL};		edata.data = el3_debug;		if (copy_to_user(useraddr, &edata, sizeof(edata)))			return -EFAULT;		return 0;	}	/* set message-level */	case ETHTOOL_SMSGLVL: {		struct ethtool_value edata;		if (copy_from_user(&edata, useraddr, sizeof(edata)))			return -EFAULT;		el3_debug = edata.data;		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/* Parameters that may be passed into the module. */static int debug = -1;static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1};MODULE_PARM(debug,"i");MODULE_PARM(irq,"1-8i");MODULE_PARM(xcvr,"1-8i");MODULE_PARM(max_interrupt_work, "i");MODULE_PARM_DESC(debug, "EtherLink III debug level (0-6)");MODULE_PARM_DESC(irq, "EtherLink III IRQ number(s) (assigned)");MODULE_PARM_DESC(xcvr,"EtherLink III tranceiver(s) (0=internal, 1=external)");MODULE_PARM_DESC(max_interrupt_work, "EtherLink III maximum events handled per interrupt");#ifdef CONFIG_ISAPNPMODULE_PARM(nopnp, "i");MODULE_PARM_DESC(nopnp, "EtherLink III disable ISA PnP support (0-1)");#endif	/* CONFIG_ISAPNP */intinit_module(void){	int el3_cards = 0;	if (debug >= 0)		el3_debug = debug;	el3_root_dev = NULL;	while (el3_probe(0) == 0) {		if (irq[el3_cards] > 1)			el3_root_dev->irq = irq[el3_cards];		if (xcvr[el3_cards] >= 0)			el3_root_dev->if_port = xcvr[el3_cards];		el3_cards++;	}	return el3_cards ? 0 : -ENODEV;}voidcleanup_module(void){	struct net_device *next_dev;	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */	while (el3_root_dev) {		struct el3_private *lp = (struct el3_private *)el3_root_dev->priv;#ifdef CONFIG_MCA				if(lp->mca_slot!=-1)			mca_mark_as_unused(lp->mca_slot);#endif					next_dev = lp->next_dev;		unregister_netdev(el3_root_dev);		release_region(el3_root_dev->base_addr, EL3_IO_EXTENT);		kfree(el3_root_dev);		el3_root_dev = next_dev;	}}#endif /* MODULE *//* * Local variables: *  compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c 3c509.c" *  version-control: t *  kept-new-versions: 5 *  tab-width: 4 * End: */

⌨️ 快捷键说明

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