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

📄 acenic.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
{	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;	idx = readl(&regs->CmdPrd);	writel(*(u32 *)(cmd), &regs->CmdRng[idx]);	idx = (idx + 1) % CMD_RING_ENTRIES;	writel(idx, &regs->CmdPrd);}static int __init ace_init(struct net_device *dev){	struct ace_private *ap;	struct ace_regs *regs;	struct ace_info *info = NULL;	unsigned long myjif;	u64 tmp_ptr;	u32 tig_ver, mac1, mac2, tmp, pci_state;	int board_idx, ecode = 0;	short i;	unsigned char cache_size;	ap = dev->priv;	regs = ap->regs;	board_idx = ap->board_idx;	/*	 * aman@sgi.com - its useful to do a NIC reset here to	 * address the `Firmware not running' problem subsequent	 * to any crashes involving the NIC	 */	writel(HW_RESET | (HW_RESET << 24), &regs->HostCtrl);	wmb();	/*	 * Don't access any other registes before this point!	 */#ifdef __BIG_ENDIAN	/*	 * This will most likely need BYTE_SWAP once we switch	 * to using __raw_writel()	 */#ifdef __parisc__	writel((WORD_SWAP | BYTE_SWAP | CLR_INT |		((WORD_SWAP | BYTE_SWAP | CLR_INT) << 24)),	       &regs->HostCtrl);#else	writel((WORD_SWAP | CLR_INT | ((WORD_SWAP | CLR_INT) << 24)),	       &regs->HostCtrl);#endif#else	writel((CLR_INT | WORD_SWAP | ((CLR_INT | WORD_SWAP) << 24)),	       &regs->HostCtrl);#endif	mb();	/*	 * Stop the NIC CPU and clear pending interrupts	 */	writel(readl(&regs->CpuCtrl) | CPU_HALT, &regs->CpuCtrl);	writel(0, &regs->Mb0Lo);	tig_ver = readl(&regs->HostCtrl) >> 28;	switch(tig_ver){#ifndef CONFIG_ACENIC_OMIT_TIGON_I	case 4:		printk(KERN_INFO "  Tigon I  (Rev. 4), Firmware: %i.%i.%i, ",		       tigonFwReleaseMajor, tigonFwReleaseMinor,		       tigonFwReleaseFix);		writel(0, &regs->LocalCtrl);		ap->version = 1;		break;#endif	case 6:		printk(KERN_INFO "  Tigon II (Rev. %i), Firmware: %i.%i.%i, ",		       tig_ver, tigon2FwReleaseMajor, tigon2FwReleaseMinor,		       tigon2FwReleaseFix);		writel(readl(&regs->CpuBCtrl) | CPU_HALT, &regs->CpuBCtrl);		/*		 * The SRAM bank size does _not_ indicate the amount		 * of memory on the card, it controls the _bank_ size!		 * Ie. a 1MB AceNIC will have two banks of 512KB.		 */		writel(SRAM_BANK_512K, &regs->LocalCtrl);		writel(SYNC_SRAM_TIMING, &regs->MiscCfg);		ap->version = 2;		break;	default:		printk(KERN_WARNING "  Unsupported Tigon version detected "		       "(%i), ", tig_ver);		ecode = -ENODEV;		goto init_error;	}	/*	 * ModeStat _must_ be set after the SRAM settings as this change	 * seems to corrupt the ModeStat and possible other registers.	 * The SRAM settings survive resets and setting it to the same	 * value a second time works as well. This is what caused the	 * `Firmware not running' problem on the Tigon II.	 */#ifdef __BIG_ENDIAN	writel(ACE_BYTE_SWAP_DMA | ACE_WARN | ACE_FATAL | ACE_BYTE_SWAP_BD |	       ACE_WORD_SWAP_BD | ACE_NO_JUMBO_FRAG, &regs->ModeStat);#else	writel(ACE_BYTE_SWAP_DMA | ACE_WARN | ACE_FATAL |	       ACE_WORD_SWAP_BD | ACE_NO_JUMBO_FRAG, &regs->ModeStat);#endif	mb();	mac1 = 0;	for(i = 0; i < 4; i++) {		mac1 = mac1 << 8;		tmp = read_eeprom_byte(dev, 0x8c+i);		if (tmp < 0) {			ecode = -EIO;			goto init_error;		} else			mac1 |= (tmp & 0xff);	}	mac2 = 0;	for(i = 4; i < 8; i++) {		mac2 = mac2 << 8;		tmp = read_eeprom_byte(dev, 0x8c+i);		if (tmp < 0) {			ecode = -EIO;			goto init_error;		} else			mac2 |= (tmp & 0xff);	}	writel(mac1, &regs->MacAddrHi);	writel(mac2, &regs->MacAddrLo);	printk("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",	       (mac1 >> 8) & 0xff, mac1 & 0xff, (mac2 >> 24) &0xff,	       (mac2 >> 16) & 0xff, (mac2 >> 8) & 0xff, mac2 & 0xff);	dev->dev_addr[0] = (mac1 >> 8) & 0xff;	dev->dev_addr[1] = mac1 & 0xff;	dev->dev_addr[2] = (mac2 >> 24) & 0xff;	dev->dev_addr[3] = (mac2 >> 16) & 0xff;	dev->dev_addr[4] = (mac2 >> 8) & 0xff;	dev->dev_addr[5] = mac2 & 0xff;	/*	 * 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(ap->pdev, PCI_CACHE_LINE_SIZE, &cache_size);	cache_size <<= 2;	if (cache_size != SMP_CACHE_BYTES) {		printk(KERN_INFO "  PCI cache line size set incorrectly "		       "(%i bytes) by BIOS/FW, ", 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(ap->pdev, PCI_CACHE_LINE_SIZE,					      SMP_CACHE_BYTES >> 2);		}	}	pci_state = readl(&regs->PciState);	printk(KERN_INFO "  PCI bus width: %i bits, speed: %iMHz, "	       "latency: %i clks\n",	       	(pci_state & PCI_32BIT) ? 32 : 64,		(pci_state & PCI_66MHZ) ? 66 : 33, 		ap->pci_latency);	/*	 * Set the max DMA transfer size. Seems that for most systems	 * the performance is better when no MAX parameter is	 * set. However for systems enabling PCI write and invalidate,	 * DMA writes must be set to the L1 cache line size to get	 * optimal performance.	 *	 * The default is now to turn the PCI write and invalidate off	 * - that is what Alteon does for NT.	 */	tmp = READ_CMD_MEM | WRITE_CMD_MEM;	if (ap->version >= 2) {		tmp |= (MEM_READ_MULTIPLE | (pci_state & PCI_66MHZ));		/*		 * Tuning parameters only supported for 8 cards		 */		if (board_idx == BOARD_IDX_OVERFLOW ||		    dis_pci_mem_inval[board_idx]) {			if (ap->pci_command & PCI_COMMAND_INVALIDATE) {				ap->pci_command &= ~PCI_COMMAND_INVALIDATE;				pci_write_config_word(ap->pdev, PCI_COMMAND,						      ap->pci_command);				printk(KERN_INFO "  Disabling PCI memory "				       "write and invalidate\n");			}		} else if (ap->pci_command & PCI_COMMAND_INVALIDATE) {			printk(KERN_INFO "  PCI memory write & invalidate "			       "enabled by BIOS, enabling counter measures\n");			switch(SMP_CACHE_BYTES) {			case 16:				tmp |= DMA_WRITE_MAX_16;				break;			case 32:				tmp |= DMA_WRITE_MAX_32;				break;			case 64:				tmp |= DMA_WRITE_MAX_64;				break;			case 128:				tmp |= DMA_WRITE_MAX_128;				break;			default:				printk(KERN_INFO "  Cache line size %i not "				       "supported, PCI write and invalidate "				       "disabled\n", SMP_CACHE_BYTES);				ap->pci_command &= ~PCI_COMMAND_INVALIDATE;				pci_write_config_word(ap->pdev, PCI_COMMAND,						      ap->pci_command);			}		}	}#ifdef __sparc__	/*	 * On this platform, we know what the best dma settings	 * are.  We use 64-byte maximum bursts, because if we	 * burst larger than the cache line size (or even cross	 * a 64byte boundry in a single burst) the UltraSparc	 * PCI controller will disconnect at 64-byte multiples.	 *	 * Read-multiple will be properly enabled above, and when	 * set will give the PCI controller proper hints about	 * prefetching.	 */	tmp &= ~DMA_READ_WRITE_MASK;	tmp |= DMA_READ_MAX_64;	tmp |= DMA_WRITE_MAX_64;#endif#ifdef __alpha__	tmp &= ~DMA_READ_WRITE_MASK;	tmp |= DMA_READ_MAX_128;	/*	 * All the docs sy MUST NOT. Well, I did.	 * Nothing terrible happens, if we load wrong size.	 * Bit w&i still works better!	 */	tmp |= DMA_WRITE_MAX_128;#endif	writel(tmp, &regs->PciState);#if 0	/*	 * I have received reports from people having problems when this	 * bit is enabled.	 */	if (!(ap->pci_command & PCI_COMMAND_FAST_BACK)) {		printk(KERN_INFO "  Enabling PCI Fast Back to Back\n");		ap->pci_command |= PCI_COMMAND_FAST_BACK;		pci_write_config_word(ap->pdev, PCI_COMMAND, ap->pci_command);	}#endif			/*	 * Configure DMA attributes.	 */	if (!pci_set_dma_mask(ap->pdev, 0xffffffffffffffffULL)) {		ap->pci_using_dac = 1;	} else if (!pci_set_dma_mask(ap->pdev, 0xffffffffULL)) {		ap->pci_using_dac = 0;	} else {		ecode = -ENODEV;		goto init_error;	}	/*	 * Initialize the generic info block and the command+event rings	 * and the control blocks for the transmit and receive rings	 * as they need to be setup once and for all.	 */	if (!(info = pci_alloc_consistent(ap->pdev, sizeof(struct ace_info),					  &ap->info_dma))) {		ecode = -EAGAIN;		goto init_error;	}	ap->info = info;	/*	 * Get the memory for the skb rings.	 */	if (!(ap->skb = kmalloc(sizeof(struct ace_skb), GFP_KERNEL))) {		ecode = -EAGAIN;		goto init_error;	}	ecode = request_irq(dev->irq, ace_interrupt, SA_SHIRQ, dev->name, dev);	if (ecode) {		printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",		       dev->name, dev->irq);		goto init_error;	}	/*	 * Register the device here to be able to catch allocated	 * interrupt handlers in case the firmware doesn't come up.	 */	ap->next = root_dev;	root_dev = dev;#ifdef INDEX_DEBUG	spin_lock_init(&ap->debug_lock);	ap->last_tx = TX_RING_ENTRIES - 1;	ap->last_std_rx = 0;	ap->last_mini_rx = 0;#endif

⌨️ 快捷键说明

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