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

📄 acenic.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  "acenic.c: v0.49 12/13/2000  Jes Sorensen, linux-acenic@SunSITE.auc.dk\n"  "                            http://home.cern.ch/~jes/gige/acenic.html\n";static struct net_device *root_dev = NULL;static int probed __initdata = 0;int __init acenic_probe (ACE_PROBE_ARG){#ifdef NEW_NETINIT	struct net_device *dev;#endif	struct ace_private *ap;	struct pci_dev *pdev = NULL;	int boards_found = 0;	int version_disp;	if (probed)		return -ENODEV;	probed++;	if (!pci_present())		/* is PCI support present? */		return -ENODEV;	version_disp = 0;	while ((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET<<8, pdev))) {		if (!((pdev->vendor == PCI_VENDOR_ID_ALTEON) &&		      ((pdev->device == PCI_DEVICE_ID_ALTEON_ACENIC_FIBRE) ||		       (pdev->device == PCI_DEVICE_ID_ALTEON_ACENIC_COPPER)))&&		    !((pdev->vendor == PCI_VENDOR_ID_3COM) &&		      (pdev->device == PCI_DEVICE_ID_3COM_3C985)) &&		    !((pdev->vendor == PCI_VENDOR_ID_NETGEAR) &&		      ((pdev->device == PCI_DEVICE_ID_NETGEAR_GA620) || 		       (pdev->device == PCI_DEVICE_ID_NETGEAR_GA620T))) &&		/*		 * Farallon used the DEC vendor ID on their cards by		 * mistake for a while		 */		    !((pdev->vendor == PCI_VENDOR_ID_DEC) &&		      (pdev->device == PCI_DEVICE_ID_FARALLON_PN9000SX)) &&		    !((pdev->vendor == PCI_VENDOR_ID_SGI) &&		      (pdev->device == PCI_DEVICE_ID_SGI_ACENIC)))			continue;		dev = init_etherdev(NULL, sizeof(struct ace_private));		if (dev == NULL) {			printk(KERN_ERR "acenic: Unable to allocate "			       "net_device structure!\n");			break;		}		SET_MODULE_OWNER(dev);		if (!dev->priv)			dev->priv = kmalloc(sizeof(*ap), GFP_KERNEL);		if (!dev->priv) {			printk(KERN_ERR "acenic: Unable to allocate memory\n");			return -ENOMEM;		}		ap = dev->priv;		ap->pdev = pdev;		dev->irq = pdev->irq;		dev->open = &ace_open;		dev->hard_start_xmit = &ace_start_xmit;		dev->stop = &ace_close;		dev->get_stats = &ace_get_stats;		dev->set_multicast_list = &ace_set_multicast_list;		dev->do_ioctl = &ace_ioctl;		dev->set_mac_address = &ace_set_mac_addr;		dev->change_mtu = &ace_change_mtu;		/* display version info if adapter is found */		if (!version_disp)		{			/* set display flag to TRUE so that */			/* we only display this string ONCE */			version_disp = 1;			printk(version);		}		/*		 * Enable master mode before we start playing with the		 * pci_command word since pci_set_master() will modify		 * it.		 */		pci_set_master(pdev);		pci_read_config_word(pdev, PCI_COMMAND, &ap->pci_command);		/* OpenFirmware on Mac's does not set this - DOH.. */ 		if (!(ap->pci_command & PCI_COMMAND_MEMORY)) {			printk(KERN_INFO "%s: Enabling PCI Memory Mapped "			       "access - was not enabled by BIOS/Firmware\n",			       dev->name);			ap->pci_command = ap->pci_command | PCI_COMMAND_MEMORY;			pci_write_config_word(ap->pdev, PCI_COMMAND,					      ap->pci_command);			wmb();		}		pci_read_config_byte(pdev, PCI_LATENCY_TIMER,				     &ap->pci_latency);		if (ap->pci_latency <= 0x40) {			ap->pci_latency = 0x40;			pci_write_config_byte(pdev, PCI_LATENCY_TIMER,					      ap->pci_latency);		}		/*		 * Remap the regs into kernel space - this is abuse of		 * dev->base_addr since it was means for I/O port		 * addresses but who gives a damn.		 */		dev->base_addr = pci_resource_start(pdev, 0);		ap->regs = (struct ace_regs *)ioremap(dev->base_addr, 0x4000);		if (!ap->regs) {			printk(KERN_ERR "%s:  Unable to map I/O register, "			       "AceNIC %i will be disabled.\n",			       dev->name, boards_found);			break;		}		switch(pdev->vendor) {		case PCI_VENDOR_ID_ALTEON:			strncpy(ap->name, "AceNIC Gigabit Ethernet",				sizeof (ap->name));			printk(KERN_INFO "%s: Alteon AceNIC ", dev->name);			break;		case PCI_VENDOR_ID_3COM:			strncpy(ap->name, "3Com 3C985 Gigabit Ethernet",				sizeof (ap->name));			printk(KERN_INFO "%s: 3Com 3C985 ", dev->name);			break;		case PCI_VENDOR_ID_NETGEAR:			strncpy(ap->name, "NetGear GA620 Gigabit Ethernet",				sizeof (ap->name));			printk(KERN_INFO "%s: NetGear GA620 ", dev->name);			break;		case PCI_VENDOR_ID_DEC:			if (pdev->device == PCI_DEVICE_ID_FARALLON_PN9000SX) {				strncpy(ap->name, "Farallon PN9000-SX "					"Gigabit Ethernet", sizeof (ap->name));				printk(KERN_INFO "%s: Farallon PN9000-SX ",				       dev->name);				break;			}		case PCI_VENDOR_ID_SGI:			strncpy(ap->name, "SGI AceNIC Gigabit Ethernet",				sizeof (ap->name));			printk(KERN_INFO "%s: SGI AceNIC ", dev->name);			break;		default: 			strncpy(ap->name, "Unknown AceNIC based Gigabit "				"Ethernet", sizeof (ap->name));			printk(KERN_INFO "%s: Unknown AceNIC ", dev->name);			break;		}		ap->name [sizeof (ap->name) - 1] = '\0';		printk("Gigabit Ethernet at 0x%08lx, ", dev->base_addr);#ifdef __sparc__		printk("irq %s\n", __irq_itoa(dev->irq));#else		printk("irq %i\n", dev->irq);#endif#ifdef CONFIG_ACENIC_OMIT_TIGON_I		if ((readl(&ap->regs->HostCtrl) >> 28) == 4) {			printk(KERN_ERR "%s: Driver compiled without Tigon I"			       " support - NIC disabled\n", dev->name);			ace_init_cleanup(dev);			continue;		}#endif		if (ace_allocate_descriptors(dev))			continue;#ifdef MODULE		if (boards_found >= ACE_MAX_MOD_PARMS)			ap->board_idx = BOARD_IDX_OVERFLOW;		else			ap->board_idx = boards_found;#else		ap->board_idx = BOARD_IDX_STATIC;#endif		if (ace_init(dev))			continue;		boards_found++;	}	/*	 * If we're at this point we're going through ace_probe() for	 * the first time.  Return success (0) if we've initialized 1	 * or more boards. Otherwise, return failure (-ENODEV).	 */	if (boards_found > 0)		return 0;	else		return -ENODEV;}#ifdef MODULEMODULE_AUTHOR("Jes Sorensen <jes@linuxcare.com>");MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver");MODULE_PARM(link, "1-" __MODULE_STRING(8) "i");MODULE_PARM(trace, "1-" __MODULE_STRING(8) "i");MODULE_PARM(tx_coal_tick, "1-" __MODULE_STRING(8) "i");MODULE_PARM(max_tx_desc, "1-" __MODULE_STRING(8) "i");MODULE_PARM(rx_coal_tick, "1-" __MODULE_STRING(8) "i");MODULE_PARM(max_rx_desc, "1-" __MODULE_STRING(8) "i");#endifvoid __exit ace_module_cleanup(void){	struct ace_private *ap;	struct ace_regs *regs;	struct net_device *next;	short i;	while (root_dev) {		ap = root_dev->priv;		next = ap->next;		regs = ap->regs;		writel(readl(&regs->CpuCtrl) | CPU_HALT, &regs->CpuCtrl);		if (ap->version >= 2)			writel(readl(&regs->CpuBCtrl) | CPU_HALT,			       &regs->CpuBCtrl);		/*		 * This clears any pending interrupts		 */		writel(1, &regs->Mb0Lo);		/*		 * Make sure no other CPUs are processing interrupts		 * on the card before the buffers are being released.		 * Otherwise one might experience some `interesting'		 * effects.		 *		 * Then release the RX buffers - jumbo buffers were		 * already released in ace_close().		 */		synchronize_irq();		for (i = 0; i < RX_STD_RING_ENTRIES; i++) {			struct sk_buff *skb = ap->skb->rx_std_skbuff[i].skb;			if (skb) {				dma_addr_t mapping;				mapping = ap->skb->rx_std_skbuff[i].mapping;				ap->rx_std_ring[i].size = 0;				ap->skb->rx_std_skbuff[i].skb = NULL;				pci_unmap_single(ap->pdev, mapping,						 ACE_STD_BUFSIZE - (2 + 16),						 PCI_DMA_FROMDEVICE);				dev_kfree_skb(skb);			}		}		if (ap->version >= 2) {			for (i = 0; i < RX_MINI_RING_ENTRIES; i++) {				struct sk_buff *skb = ap->skb->rx_mini_skbuff[i].skb;				if (skb) {					dma_addr_t mapping;					mapping = ap->skb->rx_mini_skbuff[i].mapping;					ap->rx_mini_ring[i].size = 0;					ap->skb->rx_mini_skbuff[i].skb = NULL;					pci_unmap_single(ap->pdev, mapping,							 ACE_MINI_BUFSIZE - (2 + 16),							 PCI_DMA_FROMDEVICE);					dev_kfree_skb(skb);				}			}		}		for (i = 0; i < RX_JUMBO_RING_ENTRIES; i++) {			struct sk_buff *skb = ap->skb->rx_jumbo_skbuff[i].skb;			if (skb) {				dma_addr_t mapping;				mapping = ap->skb->rx_jumbo_skbuff[i].mapping;				ap->rx_jumbo_ring[i].size = 0;				ap->skb->rx_jumbo_skbuff[i].skb = NULL;				pci_unmap_single(ap->pdev, mapping,						 ACE_JUMBO_BUFSIZE - (2 + 16),						 PCI_DMA_FROMDEVICE);				dev_kfree_skb(skb);			}		}		ace_init_cleanup(root_dev);		kfree(root_dev);		root_dev = next;	}}int __init ace_module_init(void){	int status;	root_dev = NULL;#ifdef NEW_NETINIT	status = acenic_probe();#else	status = acenic_probe(NULL);#endif	return status;}#if (LINUX_VERSION_CODE < 0x02032a)#ifdef MODULEint init_module(void){	return ace_module_init();}void cleanup_module(void){	ace_module_cleanup();}#endif#elsemodule_init(ace_module_init);module_exit(ace_module_cleanup);#endifstatic void ace_free_descriptors(struct net_device *dev){	struct ace_private *ap = dev->priv;	int size;	if (ap->rx_std_ring != NULL) {		size = (sizeof(struct rx_desc) *			(RX_STD_RING_ENTRIES +			 RX_JUMBO_RING_ENTRIES +			 RX_MINI_RING_ENTRIES +			 RX_RETURN_RING_ENTRIES));		pci_free_consistent(ap->pdev, size,				    ap->rx_std_ring,				    ap->rx_ring_base_dma);		ap->rx_std_ring = NULL;		ap->rx_jumbo_ring = NULL;		ap->rx_mini_ring = NULL;		ap->rx_return_ring = NULL;	}	if (ap->evt_ring != NULL) {		size = (sizeof(struct event) * EVT_RING_ENTRIES);		pci_free_consistent(ap->pdev, size,				    ap->evt_ring,				    ap->evt_ring_dma);		ap->evt_ring = NULL;	}	if (ap->evt_prd != NULL) {		pci_free_consistent(ap->pdev, sizeof(u32),				    (void *)ap->evt_prd, ap->evt_prd_dma);		ap->evt_prd = NULL;	}	if (ap->rx_ret_prd != NULL) {		pci_free_consistent(ap->pdev, sizeof(u32),				    (void *)ap->rx_ret_prd, ap->rx_ret_prd_dma);		ap->rx_ret_prd = NULL;	}	if (ap->tx_csm != NULL) {		pci_free_consistent(ap->pdev, sizeof(u32),				    (void *)ap->tx_csm, ap->tx_csm_dma);		ap->tx_csm = NULL;	}}static int ace_allocate_descriptors(struct net_device *dev){	struct ace_private *ap = dev->priv;	int size;	size = (sizeof(struct rx_desc) *		(RX_STD_RING_ENTRIES +		 RX_JUMBO_RING_ENTRIES +		 RX_MINI_RING_ENTRIES +		 RX_RETURN_RING_ENTRIES));	ap->rx_std_ring = pci_alloc_consistent(ap->pdev, size,					       &ap->rx_ring_base_dma);	if (ap->rx_std_ring == NULL)		goto fail;	ap->rx_jumbo_ring = ap->rx_std_ring + RX_STD_RING_ENTRIES;	ap->rx_mini_ring = ap->rx_jumbo_ring + RX_JUMBO_RING_ENTRIES;	ap->rx_return_ring = ap->rx_mini_ring + RX_MINI_RING_ENTRIES;	size = (sizeof(struct event) * EVT_RING_ENTRIES);	ap->evt_ring = pci_alloc_consistent(ap->pdev, size, &ap->evt_ring_dma);	if (ap->evt_ring == NULL)		goto fail;	size = (sizeof(struct tx_desc) * TX_RING_ENTRIES);	ap->tx_ring = pci_alloc_consistent(ap->pdev, size, &ap->tx_ring_dma);	if (ap->tx_ring == NULL)		goto fail;	ap->evt_prd = pci_alloc_consistent(ap->pdev, sizeof(u32),					   &ap->evt_prd_dma);	if (ap->evt_prd == NULL)		goto fail;	ap->rx_ret_prd = pci_alloc_consistent(ap->pdev, sizeof(u32),					      &ap->rx_ret_prd_dma);	if (ap->rx_ret_prd == NULL)		goto fail;	ap->tx_csm = pci_alloc_consistent(ap->pdev, sizeof(u32),					  &ap->tx_csm_dma);	if (ap->tx_csm == NULL)		goto fail;	return 0;fail:	/* Clean up. */	ace_init_cleanup(dev);	return 1;}/* * Generic cleanup handling data allocated during init. Used when the * module is unloaded or if an error occurs during initialization */static void ace_init_cleanup(struct net_device *dev){	struct ace_private *ap;	ap = dev->priv;	ace_free_descriptors(dev);	if (ap->info)		pci_free_consistent(ap->pdev, sizeof(struct ace_info),				    ap->info, ap->info_dma);	if (ap->skb)		kfree(ap->skb);	if (ap->trace_buf)		kfree(ap->trace_buf);	if (dev->irq)		free_irq(dev->irq, dev);	unregister_netdev(dev);	iounmap(ap->regs);}/* * Commands are considered to be slow. */static inline void ace_issue_cmd(struct ace_regs *regs, struct cmd *cmd){	u32 idx;

⌨️ 快捷键说明

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