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

📄 de2104x.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	return 0;}static int de_nway_reset(struct net_device *dev){	struct de_private *de = dev->priv;	u32 status;	if (de->media_type != DE_MEDIA_TP_AUTO)		return -EINVAL;	if (netif_carrier_ok(de->dev))		de_link_down(de);	status = dr32(SIAStatus);	dw32(SIAStatus, (status & ~NWayState) | NWayRestart);	if (netif_msg_link(de))		printk(KERN_INFO "%s: link nway restart, status %x,%x\n",		       de->dev->name, status, dr32(SIAStatus));	return 0;}static void de_get_regs(struct net_device *dev, struct ethtool_regs *regs,			void *data){	struct de_private *de = dev->priv;	regs->version = (DE_REGS_VER << 2) | de->de21040;	spin_lock_irq(&de->lock);	__de_get_regs(de, data);	spin_unlock_irq(&de->lock);}static struct ethtool_ops de_ethtool_ops = {	.get_link		= ethtool_op_get_link,	.get_tx_csum		= ethtool_op_get_tx_csum,	.get_sg			= ethtool_op_get_sg,	.get_drvinfo		= de_get_drvinfo,	.get_regs_len		= de_get_regs_len,	.get_settings		= de_get_settings,	.set_settings		= de_set_settings,	.get_msglevel		= de_get_msglevel,	.set_msglevel		= de_set_msglevel,	.get_eeprom		= de_get_eeprom,	.nway_reset		= de_nway_reset,	.get_regs		= de_get_regs,};static void __init de21040_get_mac_address (struct de_private *de){	unsigned i;	dw32 (ROMCmd, 0);	/* Reset the pointer with a dummy write. */	for (i = 0; i < 6; i++) {		int value, boguscnt = 100000;		do			value = dr32(ROMCmd);		while (value < 0 && --boguscnt > 0);		de->dev->dev_addr[i] = value;		udelay(1);		if (boguscnt <= 0)			printk(KERN_WARNING PFX "timeout reading 21040 MAC address byte %u\n", i);	}}static void __init de21040_get_media_info(struct de_private *de){	unsigned int i;	de->media_type = DE_MEDIA_TP;	de->media_supported |= SUPPORTED_TP | SUPPORTED_10baseT_Full |			       SUPPORTED_10baseT_Half | SUPPORTED_AUI;	de->media_advertise = de->media_supported;	for (i = 0; i < DE_MAX_MEDIA; i++) {		switch (i) {		case DE_MEDIA_AUI:		case DE_MEDIA_TP:		case DE_MEDIA_TP_FD:			de->media[i].type = i;			de->media[i].csr13 = t21040_csr13[i];			de->media[i].csr14 = t21040_csr14[i];			de->media[i].csr15 = t21040_csr15[i];			break;		default:			de->media[i].type = DE_MEDIA_INVALID;			break;		}	}}/* Note: this routine returns extra data bits for size detection. */static unsigned __init tulip_read_eeprom(void __iomem *regs, int location, int addr_len){	int i;	unsigned retval = 0;	void __iomem *ee_addr = regs + ROMCmd;	int read_cmd = location | (EE_READ_CMD << addr_len);	writel(EE_ENB & ~EE_CS, ee_addr);	writel(EE_ENB, ee_addr);	/* Shift the read command bits out. */	for (i = 4 + addr_len; i >= 0; i--) {		short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;		writel(EE_ENB | dataval, ee_addr);		readl(ee_addr);		writel(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);		readl(ee_addr);		retval = (retval << 1) | ((readl(ee_addr) & EE_DATA_READ) ? 1 : 0);	}	writel(EE_ENB, ee_addr);	readl(ee_addr);	for (i = 16; i > 0; i--) {		writel(EE_ENB | EE_SHIFT_CLK, ee_addr);		readl(ee_addr);		retval = (retval << 1) | ((readl(ee_addr) & EE_DATA_READ) ? 1 : 0);		writel(EE_ENB, ee_addr);		readl(ee_addr);	}	/* Terminate the EEPROM access. */	writel(EE_ENB & ~EE_CS, ee_addr);	return retval;}static void __init de21041_get_srom_info (struct de_private *de){	unsigned i, sa_offset = 0, ofs;	u8 ee_data[DE_EEPROM_SIZE + 6] = {};	unsigned ee_addr_size = tulip_read_eeprom(de->regs, 0xff, 8) & 0x40000 ? 8 : 6;	struct de_srom_info_leaf *il;	void *bufp;	/* download entire eeprom */	for (i = 0; i < DE_EEPROM_WORDS; i++)		((u16 *)ee_data)[i] =			le16_to_cpu(tulip_read_eeprom(de->regs, i, ee_addr_size));	/* DEC now has a specification but early board makers	   just put the address in the first EEPROM locations. */	/* This does  memcmp(eedata, eedata+16, 8) */#ifndef CONFIG_MIPS_COBALT	for (i = 0; i < 8; i ++)		if (ee_data[i] != ee_data[16+i])			sa_offset = 20;#endif	/* store MAC address */	for (i = 0; i < 6; i ++)		de->dev->dev_addr[i] = ee_data[i + sa_offset];	/* get offset of controller 0 info leaf.  ignore 2nd byte. */	ofs = ee_data[SROMC0InfoLeaf];	if (ofs >= (sizeof(ee_data) - sizeof(struct de_srom_info_leaf) - sizeof(struct de_srom_media_block)))		goto bad_srom;	/* get pointer to info leaf */	il = (struct de_srom_info_leaf *) &ee_data[ofs];	/* paranoia checks */	if (il->n_blocks == 0)		goto bad_srom;	if ((sizeof(ee_data) - ofs) <	    (sizeof(struct de_srom_info_leaf) + (sizeof(struct de_srom_media_block) * il->n_blocks)))		goto bad_srom;	/* get default media type */	switch (DE_UNALIGNED_16(&il->default_media)) {	case 0x0001:  de->media_type = DE_MEDIA_BNC; break;	case 0x0002:  de->media_type = DE_MEDIA_AUI; break;	case 0x0204:  de->media_type = DE_MEDIA_TP_FD; break;	default: de->media_type = DE_MEDIA_TP_AUTO; break;	}		if (netif_msg_probe(de))		printk(KERN_INFO "de%d: SROM leaf offset %u, default media %s\n",		       de->board_idx, ofs,		       media_name[de->media_type]);	/* init SIA register values to defaults */	for (i = 0; i < DE_MAX_MEDIA; i++) {		de->media[i].type = DE_MEDIA_INVALID;		de->media[i].csr13 = 0xffff;		de->media[i].csr14 = 0xffff;		de->media[i].csr15 = 0xffff;	}	/* parse media blocks to see what medias are supported,	 * and if any custom CSR values are provided	 */	bufp = ((void *)il) + sizeof(*il);	for (i = 0; i < il->n_blocks; i++) {		struct de_srom_media_block *ib = bufp;		unsigned idx;		/* index based on media type in media block */		switch(ib->opts & MediaBlockMask) {		case 0: /* 10baseT */			de->media_supported |= SUPPORTED_TP | SUPPORTED_10baseT_Half					  | SUPPORTED_Autoneg;			idx = DE_MEDIA_TP;			de->media[DE_MEDIA_TP_AUTO].type = DE_MEDIA_TP_AUTO;			break;		case 1: /* BNC */			de->media_supported |= SUPPORTED_BNC;			idx = DE_MEDIA_BNC;			break;		case 2: /* AUI */			de->media_supported |= SUPPORTED_AUI;			idx = DE_MEDIA_AUI;			break;		case 4: /* 10baseT-FD */			de->media_supported |= SUPPORTED_TP | SUPPORTED_10baseT_Full					  | SUPPORTED_Autoneg;			idx = DE_MEDIA_TP_FD;			de->media[DE_MEDIA_TP_AUTO].type = DE_MEDIA_TP_AUTO;			break;		default:			goto bad_srom;		}		de->media[idx].type = idx;		if (netif_msg_probe(de))			printk(KERN_INFO "de%d:   media block #%u: %s",			       de->board_idx, i,			       media_name[de->media[idx].type]);		bufp += sizeof (ib->opts);		if (ib->opts & MediaCustomCSRs) {			de->media[idx].csr13 = DE_UNALIGNED_16(&ib->csr13);			de->media[idx].csr14 = DE_UNALIGNED_16(&ib->csr14);			de->media[idx].csr15 = DE_UNALIGNED_16(&ib->csr15);			bufp += sizeof(ib->csr13) + sizeof(ib->csr14) +				sizeof(ib->csr15);			if (netif_msg_probe(de))				printk(" (%x,%x,%x)\n",				       de->media[idx].csr13,				       de->media[idx].csr14,				       de->media[idx].csr15);				       		} else if (netif_msg_probe(de))			printk("\n");		if (bufp > ((void *)&ee_data[DE_EEPROM_SIZE - 3]))			break;	}	de->media_advertise = de->media_supported;fill_defaults:	/* fill in defaults, for cases where custom CSRs not used */	for (i = 0; i < DE_MAX_MEDIA; i++) {		if (de->media[i].csr13 == 0xffff)			de->media[i].csr13 = t21041_csr13[i];		if (de->media[i].csr14 == 0xffff)			de->media[i].csr14 = t21041_csr14[i];		if (de->media[i].csr15 == 0xffff)			de->media[i].csr15 = t21041_csr15[i];	}	de->ee_data = kmalloc(DE_EEPROM_SIZE, GFP_KERNEL);	if (de->ee_data)		memcpy(de->ee_data, &ee_data[0], DE_EEPROM_SIZE);	return;bad_srom:	/* for error cases, it's ok to assume we support all these */	for (i = 0; i < DE_MAX_MEDIA; i++)		de->media[i].type = i;	de->media_supported =		SUPPORTED_10baseT_Half |		SUPPORTED_10baseT_Full |		SUPPORTED_Autoneg |		SUPPORTED_TP |		SUPPORTED_AUI |		SUPPORTED_BNC;	goto fill_defaults;}static int __init de_init_one (struct pci_dev *pdev,				  const struct pci_device_id *ent){	struct net_device *dev;	struct de_private *de;	int rc;	void __iomem *regs;	unsigned long pciaddr;	static int board_idx = -1;	board_idx++;#ifndef MODULE	if (board_idx == 0)		printk("%s", version);#endif	/* allocate a new ethernet device structure, and fill in defaults */	dev = alloc_etherdev(sizeof(struct de_private));	if (!dev)		return -ENOMEM;	SET_MODULE_OWNER(dev);	SET_NETDEV_DEV(dev, &pdev->dev);	dev->open = de_open;	dev->stop = de_close;	dev->set_multicast_list = de_set_rx_mode;	dev->hard_start_xmit = de_start_xmit;	dev->get_stats = de_get_stats;	dev->ethtool_ops = &de_ethtool_ops;	dev->tx_timeout = de_tx_timeout;	dev->watchdog_timeo = TX_TIMEOUT;	de = dev->priv;	de->de21040 = ent->driver_data == 0 ? 1 : 0;	de->pdev = pdev;	de->dev = dev;	de->msg_enable = (debug < 0 ? DE_DEF_MSG_ENABLE : debug);	de->board_idx = board_idx;	spin_lock_init (&de->lock);	init_timer(&de->media_timer);	if (de->de21040)		de->media_timer.function = de21040_media_timer;	else		de->media_timer.function = de21041_media_timer;	de->media_timer.data = (unsigned long) de;	netif_carrier_off(dev);	netif_stop_queue(dev);	/* wake up device, assign resources */	rc = pci_enable_device(pdev);	if (rc)		goto err_out_free;	/* reserve PCI resources to ensure driver atomicity */	rc = pci_request_regions(pdev, DRV_NAME);	if (rc)		goto err_out_disable;	/* check for invalid IRQ value */	if (pdev->irq < 2) {		rc = -EIO;		printk(KERN_ERR PFX "invalid irq (%d) for pci dev %s\n",		       pdev->irq, pci_name(pdev));		goto err_out_res;	}	dev->irq = pdev->irq;	/* obtain and check validity of PCI I/O address */	pciaddr = pci_resource_start(pdev, 1);	if (!pciaddr) {		rc = -EIO;		printk(KERN_ERR PFX "no MMIO resource for pci dev %s\n",		       pci_name(pdev));		goto err_out_res;	}	if (pci_resource_len(pdev, 1) < DE_REGS_SIZE) {		rc = -EIO;		printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n",		       pci_resource_len(pdev, 1), pci_name(pdev));		goto err_out_res;	}	/* remap CSR registers */	regs = ioremap_nocache(pciaddr, DE_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, pci_name(pdev));		goto err_out_res;	}	dev->base_addr = (unsigned long) regs;	de->regs = regs;	de_adapter_wake(de);	/* make sure hardware is not running */	rc = de_reset_mac(de);	if (rc) {		printk(KERN_ERR PFX "Cannot reset MAC, pci dev %s\n",		       pci_name(pdev));		goto err_out_iomap;	}	/* get MAC address, initialize default media type and	 * get list of supported media	 */	if (de->de21040) {		de21040_get_mac_address(de);		de21040_get_media_info(de);	} else {		de21041_get_srom_info(de);	}	/* register new network interface with kernel */	rc = register_netdev(dev);	if (rc)		goto err_out_iomap;	/* print info about board and interface just registered */	printk (KERN_INFO "%s: %s at 0x%lx, "		"%02x:%02x:%02x:%02x:%02x:%02x, "		"IRQ %d\n",		dev->name,		de->de21040 ? "21040" : "21041",		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);	/* enable busmastering */	pci_set_master(pdev);	/* put adapter to sleep */	de_adapter_sleep(de);	return 0;err_out_iomap:	kfree(de->ee_data);	iounmap(regs);err_out_res:	pci_release_regions(pdev);err_out_disable:	pci_disable_device(pdev);err_out_free:	free_netdev(dev);	return rc;}static void __exit de_remove_one (struct pci_dev *pdev){	struct net_device *dev = pci_get_drvdata(pdev);	struct de_private *de = dev->priv;	if (!dev)		BUG();	unregister_netdev(dev);	kfree(de->ee_data);	iounmap(de->regs);	pci_release_regions(pdev);	pci_disable_device(pdev);	pci_set_drvdata(pdev, NULL);	free_netdev(dev);}#ifdef CONFIG_PMstatic int de_suspend (struct pci_dev *pdev, pm_message_t state){	struct net_device *dev = pci_get_drvdata (pdev);	struct de_private *de = dev->priv;	rtnl_lock();	if (netif_running (dev)) {		del_timer_sync(&de->media_timer);		disable_irq(dev->irq);		spin_lock_irq(&de->lock);		de_stop_hw(de);		netif_stop_queue(dev);		netif_device_detach(dev);		netif_carrier_off(dev);		spin_unlock_irq(&de->lock);		enable_irq(dev->irq);				/* Update the error counts. */		__de_get_stats(de);		synchronize_irq(dev->irq);		de_clean_rings(de);		de_adapter_sleep(de);		pci_disable_device(pdev);	} else {		netif_device_detach(dev);	}	rtnl_unlock();	return 0;}static int de_resume (struct pci_dev *pdev){	struct net_device *dev = pci_get_drvdata (pdev);	struct de_private *de = dev->priv;	rtnl_lock();	if (netif_device_present(dev))		goto out;	if (netif_running(dev)) {		pci_enable_device(pdev);		de_init_hw(de);		netif_device_attach(dev);	} else {		netif_device_attach(dev);	}out:	rtnl_unlock();	return 0;}#endif /* CONFIG_PM */static struct pci_driver de_driver = {	.name		= DRV_NAME,	.id_table	= de_pci_tbl,	.probe		= de_init_one,	.remove		= __exit_p(de_remove_one),#ifdef CONFIG_PM	.suspend	= de_suspend,	.resume		= de_resume,#endif};static int __init de_init (void){#ifdef MODULE	printk("%s", version);#endif	return pci_module_init (&de_driver);}static void __exit de_exit (void){	pci_unregister_driver (&de_driver);}module_init(de_init);module_exit(de_exit);

⌨️ 快捷键说明

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