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

📄 c2.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	return NETDEV_TX_OK;}static struct net_device_stats *c2_get_stats(struct net_device *netdev){	struct c2_port *c2_port = netdev_priv(netdev);	return &c2_port->netstats;}static void c2_tx_timeout(struct net_device *netdev){	struct c2_port *c2_port = netdev_priv(netdev);	if (netif_msg_timer(c2_port))		pr_debug("%s: tx timeout\n", netdev->name);	c2_tx_clean(c2_port);}static int c2_change_mtu(struct net_device *netdev, int new_mtu){	int ret = 0;	if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)		return -EINVAL;	netdev->mtu = new_mtu;	if (netif_running(netdev)) {		c2_down(netdev);		c2_up(netdev);	}	return ret;}/* Initialize network device */static struct net_device *c2_devinit(struct c2_dev *c2dev,				     void __iomem * mmio_addr){	struct c2_port *c2_port = NULL;	struct net_device *netdev = alloc_etherdev(sizeof(*c2_port));	if (!netdev) {		pr_debug("c2_port etherdev alloc failed");		return NULL;	}	SET_NETDEV_DEV(netdev, &c2dev->pcidev->dev);	netdev->open = c2_up;	netdev->stop = c2_down;	netdev->hard_start_xmit = c2_xmit_frame;	netdev->get_stats = c2_get_stats;	netdev->tx_timeout = c2_tx_timeout;	netdev->change_mtu = c2_change_mtu;	netdev->watchdog_timeo = C2_TX_TIMEOUT;	netdev->irq = c2dev->pcidev->irq;	c2_port = netdev_priv(netdev);	c2_port->netdev = netdev;	c2_port->c2dev = c2dev;	c2_port->msg_enable = netif_msg_init(debug, default_msg);	c2_port->tx_ring.count = C2_NUM_TX_DESC;	c2_port->rx_ring.count = C2_NUM_RX_DESC;	spin_lock_init(&c2_port->tx_lock);	/* Copy our 48-bit ethernet hardware address */	memcpy_fromio(netdev->dev_addr, mmio_addr + C2_REGS_ENADDR, 6);	/* Validate the MAC address */	if (!is_valid_ether_addr(netdev->dev_addr)) {		pr_debug("Invalid MAC Address\n");		c2_print_macaddr(netdev);		free_netdev(netdev);		return NULL;	}	c2dev->netdev = netdev;	return netdev;}static int __devinit c2_probe(struct pci_dev *pcidev,			      const struct pci_device_id *ent){	int ret = 0, i;	unsigned long reg0_start, reg0_flags, reg0_len;	unsigned long reg2_start, reg2_flags, reg2_len;	unsigned long reg4_start, reg4_flags, reg4_len;	unsigned kva_map_size;	struct net_device *netdev = NULL;	struct c2_dev *c2dev = NULL;	void __iomem *mmio_regs = NULL;	printk(KERN_INFO PFX "AMSO1100 Gigabit Ethernet driver v%s loaded\n",		DRV_VERSION);	/* Enable PCI device */	ret = pci_enable_device(pcidev);	if (ret) {		printk(KERN_ERR PFX "%s: Unable to enable PCI device\n",			pci_name(pcidev));		goto bail0;	}	reg0_start = pci_resource_start(pcidev, BAR_0);	reg0_len = pci_resource_len(pcidev, BAR_0);	reg0_flags = pci_resource_flags(pcidev, BAR_0);	reg2_start = pci_resource_start(pcidev, BAR_2);	reg2_len = pci_resource_len(pcidev, BAR_2);	reg2_flags = pci_resource_flags(pcidev, BAR_2);	reg4_start = pci_resource_start(pcidev, BAR_4);	reg4_len = pci_resource_len(pcidev, BAR_4);	reg4_flags = pci_resource_flags(pcidev, BAR_4);	pr_debug("BAR0 size = 0x%lX bytes\n", reg0_len);	pr_debug("BAR2 size = 0x%lX bytes\n", reg2_len);	pr_debug("BAR4 size = 0x%lX bytes\n", reg4_len);	/* Make sure PCI base addr are MMIO */	if (!(reg0_flags & IORESOURCE_MEM) ||	    !(reg2_flags & IORESOURCE_MEM) || !(reg4_flags & IORESOURCE_MEM)) {		printk(KERN_ERR PFX "PCI regions not an MMIO resource\n");		ret = -ENODEV;		goto bail1;	}	/* Check for weird/broken PCI region reporting */	if ((reg0_len < C2_REG0_SIZE) ||	    (reg2_len < C2_REG2_SIZE) || (reg4_len < C2_REG4_SIZE)) {		printk(KERN_ERR PFX "Invalid PCI region sizes\n");		ret = -ENODEV;		goto bail1;	}	/* Reserve PCI I/O and memory resources */	ret = pci_request_regions(pcidev, DRV_NAME);	if (ret) {		printk(KERN_ERR PFX "%s: Unable to request regions\n",			pci_name(pcidev));		goto bail1;	}	if ((sizeof(dma_addr_t) > 4)) {		ret = pci_set_dma_mask(pcidev, DMA_64BIT_MASK);		if (ret < 0) {			printk(KERN_ERR PFX "64b DMA configuration failed\n");			goto bail2;		}	} else {		ret = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);		if (ret < 0) {			printk(KERN_ERR PFX "32b DMA configuration failed\n");			goto bail2;		}	}	/* Enables bus-mastering on the device */	pci_set_master(pcidev);	/* Remap the adapter PCI registers in BAR4 */	mmio_regs = ioremap_nocache(reg4_start + C2_PCI_REGS_OFFSET,				    sizeof(struct c2_adapter_pci_regs));	if (mmio_regs == 0UL) {		printk(KERN_ERR PFX			"Unable to remap adapter PCI registers in BAR4\n");		ret = -EIO;		goto bail2;	}	/* Validate PCI regs magic */	for (i = 0; i < sizeof(c2_magic); i++) {		if (c2_magic[i] != readb(mmio_regs + C2_REGS_MAGIC + i)) {			printk(KERN_ERR PFX "Downlevel Firmware boot loader "				"[%d/%Zd: got 0x%x, exp 0x%x]. Use the cc_flash "			       "utility to update your boot loader\n",				i + 1, sizeof(c2_magic),				readb(mmio_regs + C2_REGS_MAGIC + i),				c2_magic[i]);			printk(KERN_ERR PFX "Adapter not claimed\n");			iounmap(mmio_regs);			ret = -EIO;			goto bail2;		}	}	/* Validate the adapter version */	if (be32_to_cpu(readl(mmio_regs + C2_REGS_VERS)) != C2_VERSION) {		printk(KERN_ERR PFX "Version mismatch "			"[fw=%u, c2=%u], Adapter not claimed\n",			be32_to_cpu(readl(mmio_regs + C2_REGS_VERS)),			C2_VERSION);		ret = -EINVAL;		iounmap(mmio_regs);		goto bail2;	}	/* Validate the adapter IVN */	if (be32_to_cpu(readl(mmio_regs + C2_REGS_IVN)) != C2_IVN) {		printk(KERN_ERR PFX "Downlevel FIrmware level. You should be using "		       "the OpenIB device support kit. "		       "[fw=0x%x, c2=0x%x], Adapter not claimed\n",			be32_to_cpu(readl(mmio_regs + C2_REGS_IVN)),			C2_IVN);		ret = -EINVAL;		iounmap(mmio_regs);		goto bail2;	}	/* Allocate hardware structure */	c2dev = (struct c2_dev *) ib_alloc_device(sizeof(*c2dev));	if (!c2dev) {		printk(KERN_ERR PFX "%s: Unable to alloc hardware struct\n",			pci_name(pcidev));		ret = -ENOMEM;		iounmap(mmio_regs);		goto bail2;	}	memset(c2dev, 0, sizeof(*c2dev));	spin_lock_init(&c2dev->lock);	c2dev->pcidev = pcidev;	c2dev->cur_tx = 0;	/* Get the last RX index */	c2dev->cur_rx =	    (be32_to_cpu(readl(mmio_regs + C2_REGS_HRX_CUR)) -	     0xffffc000) / sizeof(struct c2_rxp_desc);	/* Request an interrupt line for the driver */	ret = request_irq(pcidev->irq, c2_interrupt, IRQF_SHARED, DRV_NAME, c2dev);	if (ret) {		printk(KERN_ERR PFX "%s: requested IRQ %u is busy\n",			pci_name(pcidev), pcidev->irq);		iounmap(mmio_regs);		goto bail3;	}	/* Set driver specific data */	pci_set_drvdata(pcidev, c2dev);	/* Initialize network device */	if ((netdev = c2_devinit(c2dev, mmio_regs)) == NULL) {		iounmap(mmio_regs);		goto bail4;	}	/* Save off the actual size prior to unmapping mmio_regs */	kva_map_size = be32_to_cpu(readl(mmio_regs + C2_REGS_PCI_WINSIZE));	/* Unmap the adapter PCI registers in BAR4 */	iounmap(mmio_regs);	/* Register network device */	ret = register_netdev(netdev);	if (ret) {		printk(KERN_ERR PFX "Unable to register netdev, ret = %d\n",			ret);		goto bail5;	}	/* Disable network packets */	netif_stop_queue(netdev);	/* Remap the adapter HRXDQ PA space to kernel VA space */	c2dev->mmio_rxp_ring = ioremap_nocache(reg4_start + C2_RXP_HRXDQ_OFFSET,					       C2_RXP_HRXDQ_SIZE);	if (c2dev->mmio_rxp_ring == 0UL) {		printk(KERN_ERR PFX "Unable to remap MMIO HRXDQ region\n");		ret = -EIO;		goto bail6;	}	/* Remap the adapter HTXDQ PA space to kernel VA space */	c2dev->mmio_txp_ring = ioremap_nocache(reg4_start + C2_TXP_HTXDQ_OFFSET,					       C2_TXP_HTXDQ_SIZE);	if (c2dev->mmio_txp_ring == 0UL) {		printk(KERN_ERR PFX "Unable to remap MMIO HTXDQ region\n");		ret = -EIO;		goto bail7;	}	/* Save off the current RX index in the last 4 bytes of the TXP Ring */	C2_SET_CUR_RX(c2dev, c2dev->cur_rx);	/* Remap the PCI registers in adapter BAR0 to kernel VA space */	c2dev->regs = ioremap_nocache(reg0_start, reg0_len);	if (c2dev->regs == 0UL) {		printk(KERN_ERR PFX "Unable to remap BAR0\n");		ret = -EIO;		goto bail8;	}	/* Remap the PCI registers in adapter BAR4 to kernel VA space */	c2dev->pa = reg4_start + C2_PCI_REGS_OFFSET;	c2dev->kva = ioremap_nocache(reg4_start + C2_PCI_REGS_OFFSET,				     kva_map_size);	if (c2dev->kva == 0UL) {		printk(KERN_ERR PFX "Unable to remap BAR4\n");		ret = -EIO;		goto bail9;	}	/* Print out the MAC address */	c2_print_macaddr(netdev);	ret = c2_rnic_init(c2dev);	if (ret) {		printk(KERN_ERR PFX "c2_rnic_init failed: %d\n", ret);		goto bail10;	}	if (c2_register_device(c2dev))		goto bail10;	return 0; bail10:	iounmap(c2dev->kva); bail9:	iounmap(c2dev->regs); bail8:	iounmap(c2dev->mmio_txp_ring); bail7:	iounmap(c2dev->mmio_rxp_ring); bail6:	unregister_netdev(netdev); bail5:	free_netdev(netdev); bail4:	free_irq(pcidev->irq, c2dev); bail3:	ib_dealloc_device(&c2dev->ibdev); bail2:	pci_release_regions(pcidev); bail1:	pci_disable_device(pcidev); bail0:	return ret;}static void __devexit c2_remove(struct pci_dev *pcidev){	struct c2_dev *c2dev = pci_get_drvdata(pcidev);	struct net_device *netdev = c2dev->netdev;	/* Unregister with OpenIB */	c2_unregister_device(c2dev);	/* Clean up the RNIC resources */	c2_rnic_term(c2dev);	/* Remove network device from the kernel */	unregister_netdev(netdev);	/* Free network device */	free_netdev(netdev);	/* Free the interrupt line */	free_irq(pcidev->irq, c2dev);	/* missing: Turn LEDs off here */	/* Unmap adapter PA space */	iounmap(c2dev->kva);	iounmap(c2dev->regs);	iounmap(c2dev->mmio_txp_ring);	iounmap(c2dev->mmio_rxp_ring);	/* Free the hardware structure */	ib_dealloc_device(&c2dev->ibdev);	/* Release reserved PCI I/O and memory resources */	pci_release_regions(pcidev);	/* Disable PCI device */	pci_disable_device(pcidev);	/* Clear driver specific data */	pci_set_drvdata(pcidev, NULL);}static struct pci_driver c2_pci_driver = {	.name = DRV_NAME,	.id_table = c2_pci_table,	.probe = c2_probe,	.remove = __devexit_p(c2_remove),};static int __init c2_init_module(void){	return pci_register_driver(&c2_pci_driver);}static void __exit c2_exit_module(void){	pci_unregister_driver(&c2_pci_driver);}module_init(c2_init_module);module_exit(c2_exit_module);

⌨️ 快捷键说明

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