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

📄 8139cp.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 3 页
字号:
			pci_unmap_single(cp->pdev, cp->rx_skb[i].mapping,					 cp->rx_buf_sz, PCI_DMA_FROMDEVICE);			dev_kfree_skb(cp->rx_skb[i].skb);		}	}	for (i = 0; i < CP_TX_RING_SIZE; i++) {		if (cp->tx_skb[i].skb) {			struct sk_buff *skb = cp->tx_skb[i].skb;			pci_unmap_single(cp->pdev, cp->tx_skb[i].mapping,					 skb->len, PCI_DMA_TODEVICE);			dev_kfree_skb(skb);			cp->net_stats.tx_dropped++;		}	}	memset(&cp->rx_skb, 0, sizeof(struct ring_info) * CP_RX_RING_SIZE);	memset(&cp->tx_skb, 0, sizeof(struct ring_info) * CP_TX_RING_SIZE);}static void cp_free_rings (struct cp_private *cp){	cp_clean_rings(cp);	pci_free_consistent(cp->pdev, CP_RING_BYTES, cp->rx_ring, cp->ring_dma);	cp->rx_ring = NULL;	cp->tx_ring = NULL;}static int cp_open (struct net_device *dev){	struct cp_private *cp = dev->priv;	int rc;	if (netif_msg_ifup(cp))		printk(KERN_DEBUG "%s: enabling interface\n", dev->name);	cp->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);	rc = cp_alloc_rings(cp);	if (rc)		return rc;	cp_init_hw(cp);	rc = request_irq(dev->irq, cp_interrupt, SA_SHIRQ, dev->name, dev);	if (rc)		goto err_out_hw;	netif_start_queue(dev);	return 0;err_out_hw:	cp_stop_hw(cp);	cp_free_rings(cp);	return rc;}static int cp_close (struct net_device *dev){	struct cp_private *cp = dev->priv;	if (netif_msg_ifdown(cp))		printk(KERN_DEBUG "%s: disabling interface\n", dev->name);	netif_stop_queue(dev);	cp_stop_hw(cp);	free_irq(dev->irq, dev);	cp_free_rings(cp);	return 0;}static char mii_2_8139_map[8] = {	BasicModeCtrl,	BasicModeStatus,	0,	0,	NWayAdvert,	NWayLPAR,	NWayExpansion,	0};static int mdio_read(struct net_device *dev, int phy_id, int location){	struct cp_private *cp = dev->priv;	return location < 8 && mii_2_8139_map[location] ?	       readw(cp->regs + mii_2_8139_map[location]) : 0;}static void mdio_write(struct net_device *dev, int phy_id, int location,		       int value){	struct cp_private *cp = dev->priv;	if (location == 0) {		cpw8(Cfg9346, Cfg9346_Unlock);		cpw16(BasicModeCtrl, value);		cpw8(Cfg9346, Cfg9346_Lock);	} else if (location < 8 && mii_2_8139_map[location])		cpw16(mii_2_8139_map[location], value);}static int cp_ethtool_ioctl (struct cp_private *cp, 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);		strcpy (info.bus_info, cp->pdev->slot_name);		if (copy_to_user (useraddr, &info, sizeof (info)))			return -EFAULT;		return 0;	}	/* get settings */	case ETHTOOL_GSET: {		struct ethtool_cmd ecmd = { ETHTOOL_GSET };		spin_lock_irq(&cp->lock);		mii_ethtool_gset(&cp->mii_if, &ecmd);		spin_unlock_irq(&cp->lock);		if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))			return -EFAULT;		return 0;	}	/* set settings */	case ETHTOOL_SSET: {		int r;		struct ethtool_cmd ecmd;		if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))			return -EFAULT;		spin_lock_irq(&cp->lock);		r = mii_ethtool_sset(&cp->mii_if, &ecmd);		spin_unlock_irq(&cp->lock);		return r;	}	/* restart autonegotiation */	case ETHTOOL_NWAY_RST: {		return mii_nway_restart(&cp->mii_if);	}	/* get link status */	case ETHTOOL_GLINK: {		struct ethtool_value edata = {ETHTOOL_GLINK};		edata.data = mii_link_ok(&cp->mii_if);		if (copy_to_user(useraddr, &edata, sizeof(edata)))			return -EFAULT;		return 0;	}	/* get message-level */	case ETHTOOL_GMSGLVL: {		struct ethtool_value edata = {ETHTOOL_GMSGLVL};		edata.data = cp->msg_enable;		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;		cp->msg_enable = edata.data;		return 0;	}	default:		break;	}	return -EOPNOTSUPP;}static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd){	struct cp_private *cp = dev->priv;	int rc = 0;	if (!netif_running(dev))		return -EINVAL;	switch (cmd) {	case SIOCETHTOOL:		return cp_ethtool_ioctl(cp, (void *) rq->ifr_data);	default:		rc = -EOPNOTSUPP;		break;	}	return rc;}/* Serial EEPROM section. *//*  EEPROM_Ctrl bits. */#define EE_SHIFT_CLK	0x04	/* EEPROM shift clock. */#define EE_CS			0x08	/* EEPROM chip select. */#define EE_DATA_WRITE	0x02	/* EEPROM chip data in. */#define EE_WRITE_0		0x00#define EE_WRITE_1		0x02#define EE_DATA_READ	0x01	/* EEPROM chip data out. */#define EE_ENB			(0x80 | EE_CS)/* Delay between EEPROM clock transitions.   No extra delay is needed with 33Mhz PCI, but 66Mhz may change this. */#define eeprom_delay()	readl(ee_addr)/* The EEPROM commands include the alway-set leading bit. */#define EE_WRITE_CMD	(5)#define EE_READ_CMD		(6)#define EE_ERASE_CMD	(7)static int __devinit read_eeprom (void *ioaddr, int location, int addr_len){	int i;	unsigned retval = 0;	void *ee_addr = ioaddr + Cfg9346;	int read_cmd = location | (EE_READ_CMD << addr_len);	writeb (EE_ENB & ~EE_CS, ee_addr);	writeb (EE_ENB, ee_addr);	eeprom_delay ();	/* Shift the read command bits out. */	for (i = 4 + addr_len; i >= 0; i--) {		int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;		writeb (EE_ENB | dataval, ee_addr);		eeprom_delay ();		writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);		eeprom_delay ();	}	writeb (EE_ENB, ee_addr);	eeprom_delay ();	for (i = 16; i > 0; i--) {		writeb (EE_ENB | EE_SHIFT_CLK, ee_addr);		eeprom_delay ();		retval =		    (retval << 1) | ((readb (ee_addr) & EE_DATA_READ) ? 1 :				     0);		writeb (EE_ENB, ee_addr);		eeprom_delay ();	}	/* Terminate the EEPROM access. */	writeb (~EE_CS, ee_addr);	eeprom_delay ();	return retval;}static int __devinit cp_init_one (struct pci_dev *pdev,				  const struct pci_device_id *ent){	struct net_device *dev;	struct cp_private *cp;	int rc;	void *regs;	long pciaddr;	unsigned addr_len, i;	u8 pci_rev, cache_size;	u16 pci_command;#ifndef MODULE	static int version_printed;	if (version_printed++ == 0)		printk("%s", version);#endif	pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);	if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&	    pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pci_rev < 0x20) {		printk(KERN_ERR PFX "pci dev %s (id %04x:%04x rev %02x) is not an 8139C+ compatible chip\n",		       pdev->slot_name, pdev->vendor, pdev->device, pci_rev);		printk(KERN_ERR PFX "Try the \"8139too\" driver instead.\n");		return -ENODEV;	}	dev = alloc_etherdev(sizeof(struct cp_private));	if (!dev)		return -ENOMEM;	SET_MODULE_OWNER(dev);	cp = dev->priv;	cp->pdev = pdev;	cp->dev = dev;	cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug);	spin_lock_init (&cp->lock);	cp->mii_if.dev = dev;	cp->mii_if.mdio_read = mdio_read;	cp->mii_if.mdio_write = mdio_write;	cp->mii_if.phy_id = CP_INTERNAL_PHY;	rc = pci_enable_device(pdev);	if (rc)		goto err_out_free;	rc = pci_request_regions(pdev, DRV_NAME);	if (rc)		goto err_out_disable;	if (pdev->irq < 2) {		rc = -EIO;		printk(KERN_ERR PFX "invalid irq (%d) for pci dev %s\n",		       pdev->irq, pdev->slot_name);		goto err_out_res;	}	pciaddr = pci_resource_start(pdev, 1);	if (!pciaddr) {		rc = -EIO;		printk(KERN_ERR PFX "no MMIO resource for pci dev %s\n",		       pdev->slot_name);		goto err_out_res;	}	if (pci_resource_len(pdev, 1) < CP_REGS_SIZE) {		rc = -EIO;		printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n",		       pci_resource_len(pdev, 1), pdev->slot_name);		goto err_out_res;	}	regs = ioremap_nocache(pciaddr, CP_REGS_SIZE);	if (!regs) {		rc = -EIO;		printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n",		       pci_resource_len(pdev, 1), pciaddr, pdev->slot_name);		goto err_out_res;	}	dev->base_addr = (unsigned long) regs;	cp->regs = regs;	cp_stop_hw(cp);	/* read MAC address from EEPROM */	addr_len = read_eeprom (regs, 0, 8) == 0x8129 ? 8 : 6;	for (i = 0; i < 3; i++)		((u16 *) (dev->dev_addr))[i] =		    le16_to_cpu (read_eeprom (regs, i + 7, addr_len));	dev->open = cp_open;	dev->stop = cp_close;	dev->set_multicast_list = cp_set_rx_mode;	dev->hard_start_xmit = cp_start_xmit;	dev->get_stats = cp_get_stats;	dev->do_ioctl = cp_ioctl;#if 0	dev->tx_timeout = cp_tx_timeout;	dev->watchdog_timeo = TX_TIMEOUT;#endif#ifdef CP_TX_CHECKSUM	dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;#endif	dev->irq = pdev->irq;	rc = register_netdev(dev);	if (rc)		goto err_out_iomap;	printk (KERN_INFO "%s: %s at 0x%lx, "		"%02x:%02x:%02x:%02x:%02x:%02x, "		"IRQ %d\n",		dev->name,		"RTL-8139C+",		dev->base_addr,		dev->dev_addr[0], dev->dev_addr[1],		dev->dev_addr[2], dev->dev_addr[3],		dev->dev_addr[4], dev->dev_addr[5],		dev->irq);	pci_set_drvdata(pdev, dev);	/*	 * Looks like this is necessary to deal with on all architectures,	 * even this %$#%$# N440BX Intel based thing doesn't get it right.	 * Ie. having two NICs in the machine, one will have the cache	 * line set at boot time, the other will not.	 */	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_size);	cache_size <<= 2;	if (cache_size != SMP_CACHE_BYTES) {		printk(KERN_INFO "%s: PCI cache line size set incorrectly "		       "(%i bytes) by BIOS/FW, ", dev->name, cache_size);		if (cache_size > SMP_CACHE_BYTES)			printk("expecting %i\n", SMP_CACHE_BYTES);		else {			printk("correcting to %i\n", SMP_CACHE_BYTES);			pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,					      SMP_CACHE_BYTES >> 2);		}	}	/* enable busmastering and memory-write-invalidate */	pci_read_config_word(pdev, PCI_COMMAND, &pci_command);	if (!(pci_command & PCI_COMMAND_INVALIDATE)) {		pci_command |= PCI_COMMAND_INVALIDATE;		pci_write_config_word(pdev, PCI_COMMAND, pci_command);	}	pci_set_master(pdev);	return 0;err_out_iomap:	iounmap(regs);err_out_res:	pci_release_regions(pdev);err_out_disable:	pci_disable_device(pdev);err_out_free:	kfree(dev);	return rc;}static void __devexit cp_remove_one (struct pci_dev *pdev){	struct net_device *dev = pci_get_drvdata(pdev);	struct cp_private *cp = dev->priv;	if (!dev)		BUG();	unregister_netdev(dev);	iounmap(cp->regs);	pci_release_regions(pdev);	pci_disable_device(pdev);	pci_set_drvdata(pdev, NULL);	kfree(dev);}static struct pci_driver cp_driver = {	name:		DRV_NAME,	id_table:	cp_pci_tbl,	probe:		cp_init_one,	remove:		__devexit_p(cp_remove_one),};static int __init cp_init (void){#ifdef MODULE	printk("%s", version);#endif	return pci_module_init (&cp_driver);}static void __exit cp_exit (void){	pci_unregister_driver (&cp_driver);}module_init(cp_init);module_exit(cp_exit);

⌨️ 快捷键说明

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