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

📄 dl2k.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 4 页
字号:
			/* 16 byte align the IP header */			skb_reserve (skb, 2);			np->rx_ring[entry].fraginfo =			    cpu_to_le64 (pci_map_single					 (np->pdev, skb->tail, np->rx_buf_sz,					  PCI_DMA_FROMDEVICE));		}		np->rx_ring[entry].fraginfo |=		    cpu_to_le64 (np->rx_buf_sz) << 48;		np->rx_ring[entry].status = 0;		entry = (entry + 1) % RX_RING_SIZE;	}	np->old_rx = entry;	spin_unlock(&np->rx_lock);	return 0;}static voidrio_error (struct net_device *dev, int int_status){	long ioaddr = dev->base_addr;	struct netdev_private *np = dev->priv;	u16 macctrl;	/* Link change event */	if (int_status & LinkEvent) {		if (mii_wait_link (dev, 10) == 0) {			printk (KERN_INFO "%s: Link up\n", dev->name);			if (np->phy_media)				mii_get_media_pcs (dev);			else				mii_get_media (dev);			if (np->speed == 1000)				np->tx_coalesce = tx_coalesce;			else 				np->tx_coalesce = 1;			macctrl = 0;			macctrl |= (np->vlan) ? AutoVLANuntagging : 0;			macctrl |= (np->full_duplex) ? DuplexSelect : 0;			macctrl |= (np->tx_flow) ? 				TxFlowControlEnable : 0;			macctrl |= (np->rx_flow) ? 				RxFlowControlEnable : 0;			writew(macctrl,	ioaddr + MACCtrl);			np->link_status = 1;			netif_carrier_on(dev);		} else {			printk (KERN_INFO "%s: Link off\n", dev->name);			np->link_status = 0;			netif_carrier_off(dev);		}	}	/* UpdateStats statistics registers */	if (int_status & UpdateStats) {		get_stats (dev);	}	/* PCI Error, a catastronphic error related to the bus interface 	   occurs, set GlobalReset and HostReset to reset. */	if (int_status & HostError) {		printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",			dev->name, int_status);		writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);		mdelay (500);	}}static struct net_device_stats *get_stats (struct net_device *dev){	long ioaddr = dev->base_addr;	struct netdev_private *np = dev->priv;#ifdef MEM_MAPPING	int i;#endif	unsigned int stat_reg;	/* All statistics registers need to be acknowledged,	   else statistic overflow could cause problems */		np->stats.rx_packets += readl (ioaddr + FramesRcvOk);	np->stats.tx_packets += readl (ioaddr + FramesXmtOk);	np->stats.rx_bytes += readl (ioaddr + OctetRcvOk);	np->stats.tx_bytes += readl (ioaddr + OctetXmtOk);	np->stats.multicast = readl (ioaddr + McstFramesRcvdOk);	np->stats.collisions += readl (ioaddr + SingleColFrames) 			     +  readl (ioaddr + MultiColFrames); 		/* detailed tx errors */	stat_reg = readw (ioaddr + FramesAbortXSColls);	np->stats.tx_aborted_errors += stat_reg;	np->stats.tx_errors += stat_reg;	stat_reg = readw (ioaddr + CarrierSenseErrors);	np->stats.tx_carrier_errors += stat_reg;	np->stats.tx_errors += stat_reg;	/* Clear all other statistic register. */	readl (ioaddr + McstOctetXmtOk);	readw (ioaddr + BcstFramesXmtdOk);	readl (ioaddr + McstFramesXmtdOk);	readw (ioaddr + BcstFramesRcvdOk);	readw (ioaddr + MacControlFramesRcvd);	readw (ioaddr + FrameTooLongErrors);	readw (ioaddr + InRangeLengthErrors);	readw (ioaddr + FramesCheckSeqErrors);	readw (ioaddr + FramesLostRxErrors);	readl (ioaddr + McstOctetXmtOk);	readl (ioaddr + BcstOctetXmtOk);	readl (ioaddr + McstFramesXmtdOk);	readl (ioaddr + FramesWDeferredXmt);	readl (ioaddr + LateCollisions);	readw (ioaddr + BcstFramesXmtdOk);	readw (ioaddr + MacControlFramesXmtd);	readw (ioaddr + FramesWEXDeferal);#ifdef MEM_MAPPING	for (i = 0x100; i <= 0x150; i += 4)		readl (ioaddr + i);#endif	readw (ioaddr + TxJumboFrames);	readw (ioaddr + RxJumboFrames);	readw (ioaddr + TCPCheckSumErrors);	readw (ioaddr + UDPCheckSumErrors);	readw (ioaddr + IPCheckSumErrors);	return &np->stats;}static intclear_stats (struct net_device *dev){	long ioaddr = dev->base_addr;#ifdef MEM_MAPPING	int i;#endif 	/* All statistics registers need to be acknowledged,	   else statistic overflow could cause problems */	readl (ioaddr + FramesRcvOk);	readl (ioaddr + FramesXmtOk);	readl (ioaddr + OctetRcvOk);	readl (ioaddr + OctetXmtOk);	readl (ioaddr + McstFramesRcvdOk);	readl (ioaddr + SingleColFrames);	readl (ioaddr + MultiColFrames);	readl (ioaddr + LateCollisions);	/* detailed rx errors */			readw (ioaddr + FrameTooLongErrors);	readw (ioaddr + InRangeLengthErrors);	readw (ioaddr + FramesCheckSeqErrors);	readw (ioaddr + FramesLostRxErrors);	/* detailed tx errors */	readw (ioaddr + FramesAbortXSColls);	readw (ioaddr + CarrierSenseErrors);	/* Clear all other statistic register. */	readl (ioaddr + McstOctetXmtOk);	readw (ioaddr + BcstFramesXmtdOk);	readl (ioaddr + McstFramesXmtdOk);	readw (ioaddr + BcstFramesRcvdOk);	readw (ioaddr + MacControlFramesRcvd);	readl (ioaddr + McstOctetXmtOk);	readl (ioaddr + BcstOctetXmtOk);	readl (ioaddr + McstFramesXmtdOk);	readl (ioaddr + FramesWDeferredXmt);	readw (ioaddr + BcstFramesXmtdOk);	readw (ioaddr + MacControlFramesXmtd);	readw (ioaddr + FramesWEXDeferal);#ifdef MEM_MAPPING	for (i = 0x100; i <= 0x150; i += 4)		readl (ioaddr + i);#endif 	readw (ioaddr + TxJumboFrames);	readw (ioaddr + RxJumboFrames);	readw (ioaddr + TCPCheckSumErrors);	readw (ioaddr + UDPCheckSumErrors);	readw (ioaddr + IPCheckSumErrors);	return 0;}intchange_mtu (struct net_device *dev, int new_mtu){	struct netdev_private *np = dev->priv;	int max = (np->jumbo) ? MAX_JUMBO : 1536;	if ((new_mtu < 68) || (new_mtu > max)) {		return -EINVAL;	}	dev->mtu = new_mtu;	return 0;}static voidset_multicast (struct net_device *dev){	long ioaddr = dev->base_addr;	u32 hash_table[2];	u16 rx_mode = 0;	struct netdev_private *np = dev->priv;		hash_table[0] = hash_table[1] = 0;	/* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */	hash_table[1] |= cpu_to_le32(0x02000000);	if (dev->flags & IFF_PROMISC) {		/* Receive all frames promiscuously. */		rx_mode = ReceiveAllFrames;	} else if ((dev->flags & IFF_ALLMULTI) || 			(dev->mc_count > multicast_filter_limit)) {		/* Receive broadcast and multicast frames */		rx_mode = ReceiveBroadcast | ReceiveMulticast | ReceiveUnicast;	} else if (dev->mc_count > 0) {		int i;		struct dev_mc_list *mclist;		/* Receive broadcast frames and multicast frames filtering 		   by Hashtable */		rx_mode =		    ReceiveBroadcast | ReceiveMulticastHash | ReceiveUnicast;		for (i=0, mclist = dev->mc_list; mclist && i < dev->mc_count; 				i++, mclist=mclist->next) 		{			int bit, index = 0;			int crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr);			/* The inverted high significant 6 bits of CRC are			   used as an index to hashtable */			for (bit = 0; bit < 6; bit++)				if (crc & (1 << (31 - bit)))					index |= (1 << bit);			hash_table[index / 32] |= (1 << (index % 32));		}	} else {		rx_mode = ReceiveBroadcast | ReceiveUnicast;	}	if (np->vlan) {		/* ReceiveVLANMatch field in ReceiveMode */		rx_mode |= ReceiveVLANMatch;	}	writel (hash_table[0], ioaddr + HashTable0);	writel (hash_table[1], ioaddr + HashTable1);	writew (rx_mode, ioaddr + ReceiveMode);}static intrio_ethtool_ioctl (struct net_device *dev, void __user *useraddr){	struct netdev_private *np = dev->priv;       	u32 ethcmd;		if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))		return -EFAULT;	switch (ethcmd) {		case ETHTOOL_GDRVINFO: {			struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };			strcpy(info.driver, "DL2K");			strcpy(info.version, DRV_VERSION);			strcpy(info.bus_info, pci_name(np->pdev));			memset(&info.fw_version, 0, sizeof(info.fw_version));			if (copy_to_user(useraddr, &info, sizeof(info)))				return -EFAULT;			return 0;		}	 			case ETHTOOL_GSET: {			struct ethtool_cmd cmd = { ETHTOOL_GSET };			if (np->phy_media) {				/* fiber device */				cmd.supported = SUPPORTED_Autoneg | 							SUPPORTED_FIBRE;				cmd.advertising= ADVERTISED_Autoneg |							ADVERTISED_FIBRE;				cmd.port = PORT_FIBRE;				cmd.transceiver = XCVR_INTERNAL;				} else {				/* copper device */				cmd.supported = SUPPORTED_10baseT_Half | 					SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half					| SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full |					SUPPORTED_Autoneg | SUPPORTED_MII;				cmd.advertising = ADVERTISED_10baseT_Half |					ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Half |					ADVERTISED_100baseT_Full | ADVERTISED_1000baseT_Full|					ADVERTISED_Autoneg | ADVERTISED_MII;				cmd.port = PORT_MII;				cmd.transceiver = XCVR_INTERNAL;			}			if ( np->link_status ) { 				cmd.speed = np->speed;				cmd.duplex = np->full_duplex ? 						    DUPLEX_FULL : DUPLEX_HALF;			} else {				cmd.speed = -1;				cmd.duplex = -1;			}			if ( np->an_enable)				cmd.autoneg = AUTONEG_ENABLE;			else				cmd.autoneg = AUTONEG_DISABLE;						cmd.phy_address = np->phy_addr;			if (copy_to_user(useraddr, &cmd,					sizeof(cmd)))				return -EFAULT;			return 0;				   		}		case ETHTOOL_SSET: {			struct ethtool_cmd cmd;			if (copy_from_user(&cmd, useraddr, sizeof(cmd)))				return -EFAULT;			netif_carrier_off(dev);			if (cmd.autoneg == AUTONEG_ENABLE) {				if (np->an_enable)					return 0;				else {					np->an_enable = 1;					mii_set_media(dev);					return 0;					}				} else {				np->an_enable = 0;				if (np->speed == 1000){					cmd.speed = SPEED_100;								cmd.duplex = DUPLEX_FULL;					printk("Warning!! Can't disable Auto negotiation in 1000Mbps, change to Manul 100Mbps, Full duplex.\n");					}				switch(cmd.speed + cmd.duplex){								case SPEED_10 + DUPLEX_HALF:					np->speed = 10;					np->full_duplex = 0;					break;								case SPEED_10 + DUPLEX_FULL:					np->speed = 10;					np->full_duplex = 1;					break;				case SPEED_100 + DUPLEX_HALF:					np->speed = 100;					np->full_duplex = 0;					break;				case SPEED_100 + DUPLEX_FULL:					np->speed = 100;					np->full_duplex = 1;					break;				case SPEED_1000 + DUPLEX_HALF:/* not supported */				case SPEED_1000 + DUPLEX_FULL:/* not supported */				default:					return -EINVAL;					}				mii_set_media(dev);			}		return 0;		   		}#ifdef ETHTOOL_GLINK				case ETHTOOL_GLINK:{		struct ethtool_value link = { ETHTOOL_GLINK };		link.data = np->link_status;		if (copy_to_user(useraddr, &link, sizeof(link)))			return -EFAULT;		return 0;		}			   #endif		default:		return -EOPNOTSUPP;	}	}static intrio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd){	int phy_addr;	struct netdev_private *np = dev->priv;	struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru;		struct netdev_desc *desc;	int i;	phy_addr = np->phy_addr;	switch (cmd) {	case SIOCETHTOOL:		return rio_ethtool_ioctl(dev, rq->ifr_data);			case SIOCDEVPRIVATE:		break;		case SIOCDEVPRIVATE + 1:		miidata->out_value = mii_read (dev, phy_addr, miidata->reg_num);		break;	case SIOCDEVPRIVATE + 2:		mii_write (dev, phy_addr, miidata->reg_num, miidata->in_value);		break;	case SIOCDEVPRIVATE + 3:		break;	case SIOCDEVPRIVATE + 4:		break;	case SIOCDEVPRIVATE + 5:		netif_stop_queue (dev);		break;	case SIOCDEVPRIVATE + 6:		netif_wake_queue (dev);		break;	case SIOCDEVPRIVATE + 7:		printk		    ("tx_full=%x cur_tx=%lx old_tx=%lx cur_rx=%lx old_rx=%lx\n",		     netif_queue_stopped(dev), np->cur_tx, np->old_tx, np->cur_rx,		     np->old_rx);		break;	case SIOCDEVPRIVATE + 8:		printk("TX ring:\n");		for (i = 0; i < TX_RING_SIZE; i++) {			desc = &np->tx_ring[i];			printk			    ("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x",			     i,			     (u32) (np->tx_ring_dma + i * sizeof (*desc)),			     (u32) desc->next_desc,			     (u32) desc->status, (u32) (desc->fraginfo >> 32),			     (u32) desc->fraginfo);			printk ("\n");		}		printk ("\n");		break;	default:		return -EOPNOTSUPP;	}	return 0;}#define EEP_READ 0x0200#define EEP_BUSY 0x8000/* Read the EEPROM word *//* We use I/O instruction to read/write eeprom to avoid fail on some machines */intread_eeprom (long ioaddr, int eep_addr){	int i = 1000;	outw (EEP_READ | (eep_addr & 0xff), ioaddr + EepromCtrl);	while (i-- > 0) {		if (!(inw (ioaddr + EepromCtrl) & EEP_BUSY)) {			return inw (ioaddr + EepromData);		}	}	return 0;}enum phy_ctrl_bits {	MII_READ = 0x00, MII_CLK = 0x01, MII_DATA1 = 0x02, MII_WRITE = 0x04,	MII_DUPLEX = 0x08,};#define mii_delay() readb(ioaddr)static voidmii_sendbit (struct net_device *dev, u32 data){	long ioaddr = dev->base_addr + PhyCtrl;	data = (data) ? MII_DATA1 : 0;	data |= MII_WRITE;	data |= (readb (ioaddr) & 0xf8) | MII_WRITE;	writeb (data, ioaddr);	mii_delay ();	writeb (data | MII_CLK, ioaddr);	mii_delay ();}

⌨️ 快捷键说明

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